mirror of
https://github.com/bigskysoftware/htmx.git
synced 2025-10-02 15:25:26 +00:00

Before this commit, the content that were swapped by an extension via `handleSwap` was not handled by htmx: elemtents with `hx-` attributes, scripts, no `load.htmx` event... With this commit, if the `handleSwap` command returns an array of newly added elements (only the first level), then they will be handled by htmx like it's done for internal swap. To not break existing extensions, `handleSwap` can still return `true` to tell that the swap was handled, assuming than there is no new elements to handle. A new test was added with a button that, when clicked, loads a text and a span with `hx-trigger=load`, both handled by an extension. This commit allows this span to be loaded. The return of the `morphdom-swap` extension was updated to return the target element, even if unchanged, to let htmx check in the maybe new content that there is something new to handle. This is tested in a new test.
72 lines
2.8 KiB
JavaScript
72 lines
2.8 KiB
JavaScript
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.push(evt.detail.elt);
|
|
}
|
|
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);
|
|
return [parentEl.appendChild(fragment)]; // return the newly added element
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
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.length.should.equal(1);
|
|
loadCalls[0].textContent.should.equal('Clicked!'); // the new button is loaded
|
|
});
|
|
|
|
it('handleSwap: new content is handled by htmx', function() {
|
|
this.server.respondWith("GET", "/test", '<button id="test-ext-testswap">Clicked!<span hx-get="/test-inner" hx-trigger="load"></span></button>');
|
|
this.server.respondWith("GET", "/test-inner", 'Loaded!');
|
|
make('<div hx-ext="ext-testswap"><button hx-get="/test" hx-swap="testswap">Click Me!</button></div>').querySelector('button').click();
|
|
|
|
this.server.respond(); // call /test via button trigger=click
|
|
var btn = byId('test-ext-testswap');
|
|
btn.textContent.should.equal('Clicked!');
|
|
afterSwapCalls.should.equal(1);
|
|
loadCalls.length.should.equal(1);
|
|
loadCalls[0].textContent.should.equal('Clicked!'); // the new button is loaded
|
|
|
|
this.server.respond(); // call /test-inner via span trigger=load
|
|
btn.textContent.should.equal("Clicked!Loaded!");
|
|
afterSwapCalls.should.equal(2);
|
|
loadCalls.length.should.equal(2);
|
|
loadCalls[1].textContent.should.equal('Loaded!'); // the new span is loaded
|
|
});
|
|
|
|
});
|