Sidane
Active member
I've run into an issue with extending a core XenForo Javascript event handler multiple times which hopefully someone can offer some guidance on.
I have two add-ons which are extending the element handler
This is a contrived example of what's happening.
My first add-on JS:
My second add-on JS:
Note that I'm using the
The issue I have comes when a third party add-on is extending
Example:
This third party add-on is effectively replacing the
If this third party add-on used the
A work around I can see is to ensure that my add-on Javascript is loaded after the third party add-on Javascript. That way I am extending the third party addon's event handler. But this introduces additional complexity to my add-ons and is a bit hacky as I need to ensure template modifications which load my add-on JS occur as late as possible in the template compilation. Even then there is no guarantee a further third party add-on I use in future won't load Javascript later in the document that blows away my changes again.
So two questions:
1) Is my add-on approach to extending the core XF
2) Is the best solution to this problem to have the third party add-on author modify their JS so it can work in tandem with other add-on JS that extends the same element handler?
I hope that all makes sense. Happy to clarify anything if necessary.
I have two add-ons which are extending the element handler
XF.QuickReply
. Specifically the #afterSubmit
method (see js/xf/message.js
around line #1206). I've run into an issue where another third-party add-on is also overriding the same method and wiping out my changes.This is a contrived example of what's happening.
My first add-on JS:
JavaScript:
var Sidane = window.Sidane || {};
!function($, window, document, _undefined)
{
"use strict";
XF.Element.extend("quick-reply", {
__backup: {
"afterSubmit": "_afterSubmitExtension1"
},
afterSubmit: function(e, data)
{
this._afterSubmitExtension1(e, data);
console.log("executing extension 1 after submit");
}
});
}
(jQuery, window, document);
My second add-on JS:
JavaScript:
var Sidane = window.Sidane || {};
!function($, window, document, _undefined)
{
"use strict";
XF.Element.extend("quick-reply", {
__backup: {
"afterSubmit": "_afterSubmitExtension2"
},
afterSubmit: function(e, data)
{
this._afterSubmitExtension2(e, data);
console.log("executing extension 2 after submit");
}
});
}
(jQuery, window, document);
Note that I'm using the
XF.Element.extend("quick-reply"....
here as described in this thread. That appears to be the correct way to override existing XenForo handlers.The issue I have comes when a third party add-on is extending
quick-reply
using the other approach described in that thread (i.e. XF.extend(XF.QuickReply....
).Example:
JavaScript:
var ThirdPartyAddon = window.ThirdPartyAddon || {}
!function($, window, document, _undefined)
{
"use strict";
ThirdPartyAddon.QuickReply = XF.extend(XF.QuickReply, {
__backup: {
'afterSubmit': '_afterSubmitThirdPartyAddon'
},
afterSubmit: function(e, data)
{
this._afterSubmitThirdPartyAddon(e, data);
console.log("third party add-on after submit")
}
});
XF.Element.register('quick-reply', 'ThirdPartyAddon.QuickReply');
}
(jQuery, window, document);
This third party add-on is effectively replacing the
quick-reply
element handler with its own extended implementation based off the core XF element handler. And because this Javascript is loaded after my add-on Javascript in the document source, my add-on changes are lost.
HTML:
<head>
<script src="/js/xf/message.js"></script> <!-- original core JS that defines XF.QuickReply -->
<script src="/js/sidane/extension1.js"></script> <!-- my first add-on JS that extends XF.QuickReply -->
<script src="/js/sidane/extension2.js"></script> <!-- my second add-on JS that extends XF.QuickReply -->
<script src="/js/third-party-addon/message.js"></script> <!-- third party add-on JS that overwrites my add-ons JS -->
</head>
If this third party add-on used the
XF.Element.extend("quick-reply"....
approach I believe all three add-ons would work correctly in tandem. I've verified that in my dev environment by modifying the third party add-on JS to use XF.Element.extend
.A work around I can see is to ensure that my add-on Javascript is loaded after the third party add-on Javascript. That way I am extending the third party addon's event handler. But this introduces additional complexity to my add-ons and is a bit hacky as I need to ensure template modifications which load my add-on JS occur as late as possible in the template compilation. Even then there is no guarantee a further third party add-on I use in future won't load Javascript later in the document that blows away my changes again.
So two questions:
1) Is my add-on approach to extending the core XF
quick-reply
element handler correct?2) Is the best solution to this problem to have the third party add-on author modify their JS so it can work in tandem with other add-on JS that extends the same element handler?
I hope that all makes sense. Happy to clarify anything if necessary.