mirror of
https://github.com/bigskysoftware/htmx.git
synced 2025-09-28 21:41:40 +00:00
Extension.handleSwap: trigger events for extensions defined on parents
If an element is replaced by an extension in `handleSwap`, the events (`afterSwap.htmx` and `afterSettle.htmx`) were not received by the `onLoad` method of extensions defined on parents of the target, because theses extensions were retrieved after the replacement, and so it was not possible to get through the parents, the target not being in the dom anymore. This commits loads the extensions for the target and save them in `eventDetail` before doing the swap, so they are accessible in `triggerEvent`, and passed to `withExtensions` that use this list if passed (else load them). A new test is added that fails without the updates in `htmx.js`.
This commit is contained in:
parent
7a0010f43c
commit
86febd3efc
@ -954,8 +954,8 @@ return (function () {
|
||||
return eventName === "processedNode.htmx"
|
||||
}
|
||||
|
||||
function withExtensions(elt, toDo) {
|
||||
forEach(getExtensions(elt), function(extension){
|
||||
function withExtensions(elt, toDo, extensions) {
|
||||
forEach(typeof extensions === 'undefined' ? getExtensions(elt) : extensions, function(extension){
|
||||
try {
|
||||
toDo(extension);
|
||||
} catch (e) {
|
||||
@ -988,7 +988,7 @@ return (function () {
|
||||
var eventResult = elt.dispatchEvent(event);
|
||||
withExtensions(elt, function (extension) {
|
||||
eventResult = eventResult && (extension.onEvent(eventName, event) !== false)
|
||||
});
|
||||
}, detail.extensions);
|
||||
return eventResult;
|
||||
}
|
||||
|
||||
@ -1407,7 +1407,7 @@ return (function () {
|
||||
}
|
||||
}
|
||||
|
||||
var eventDetail = {xhr: xhr, target: target};
|
||||
var eventDetail = {xhr: xhr, target: target, extensions: getExtensions(elt)};
|
||||
xhr.onload = function () {
|
||||
try {
|
||||
if (!triggerEvent(elt, 'beforeOnLoad.htmx', eventDetail)) return;
|
||||
|
50
test/ext/index.js
Normal file
50
test/ext/index.js
Normal file
@ -0,0 +1,50 @@
|
||||
describe("default extensions behavior", function() {
|
||||
|
||||
var loadCalls, afterSwapCalls, afterSettleCalls;
|
||||
|
||||
beforeEach(function () {
|
||||
loadCalls = afterSwapCalls = afterSettleCalls = 0;
|
||||
this.server = makeServer();
|
||||
clearWorkArea();
|
||||
|
||||
htmx.defineExtension("ext-testswap", {
|
||||
onEvent : function(name, evt) {
|
||||
if (name === "load.htmx") {
|
||||
loadCalls++;
|
||||
}
|
||||
if (name === "afterSwap.htmx") {
|
||||
afterSwapCalls++;
|
||||
}
|
||||
if (name === "afterSettle.htmx") {
|
||||
afterSettleCalls++;
|
||||
}
|
||||
},
|
||||
handleSwap: function (swapStyle, target, fragment, settleInfo) {
|
||||
// simple outerHTML replacement for tests
|
||||
var parentEl = target.parentElement;
|
||||
parentEl.removeChild(target);
|
||||
parentEl.appendChild(fragment)
|
||||
return true;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
this.server.restore();
|
||||
clearWorkArea();
|
||||
htmx.removeExtension("ext-testswap");
|
||||
});
|
||||
|
||||
it('handleSwap: afterSwap and afterSettle triggered if extension defined on parent', function () {
|
||||
this.server.respondWith("GET", "/test", '<button>Clicked!</button>');
|
||||
var div = make('<div hx-ext="ext-testswap"><button hx-get="/test" hx-swap="testswap">Click Me!</button></div>');
|
||||
var btn = div.firstChild;
|
||||
btn.click()
|
||||
this.server.respond();
|
||||
afterSwapCalls.should.equal(1);
|
||||
afterSettleCalls.should.equal(1);
|
||||
loadCalls.should.equal(0); // load.htmlx event on new added button is not triggered
|
||||
});
|
||||
});
|
@ -83,6 +83,8 @@
|
||||
<script src="attributes/hx-ws.js"></script>
|
||||
|
||||
<!-- extension tests -->
|
||||
<script src="ext/index.js"></script>
|
||||
|
||||
<script src="../src/ext/method-override.js"></script>
|
||||
<script src="ext/method-override.js"></script>
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user