mirror of
https://github.com/bigskysoftware/htmx.git
synced 2025-09-28 05:21:18 +00:00
Merge pull request #94 from twidi/handle-events-and-content-after-handleSwap-extensions
Handle events and content after `handleSwap` in extensions
This commit is contained in:
commit
6c8930028c
@ -5,7 +5,7 @@ htmx.defineExtension('morphdom-swap', {
|
||||
handleSwap: function (swapStyle, target, fragment) {
|
||||
if (swapStyle === 'morphdom') {
|
||||
morphdom(target, fragment.outerHTML);
|
||||
return true;
|
||||
return [target]; // let htmx handle the new content
|
||||
}
|
||||
}
|
||||
});
|
||||
|
22
src/htmx.js
22
src/htmx.js
@ -417,7 +417,7 @@ return (function () {
|
||||
while(fragment.childNodes.length > 0){
|
||||
var child = fragment.firstChild;
|
||||
parentNode.insertBefore(child, insertBefore);
|
||||
if (child.nodeType !== Node.TEXT_NODE) {
|
||||
if (child.nodeType !== Node.TEXT_NODE && child.nodeType !== Node.COMMENT_NODE) {
|
||||
settleInfo.tasks.push(makeAjaxLoadTask(child));
|
||||
}
|
||||
}
|
||||
@ -519,7 +519,17 @@ return (function () {
|
||||
for (var i = 0; i < extensions.length; i++) {
|
||||
var ext = extensions[i];
|
||||
try {
|
||||
if (ext.handleSwap(swapStyle, target, fragment, settleInfo)) {
|
||||
var newElements = ext.handleSwap(swapStyle, target, fragment, settleInfo);
|
||||
if (newElements) {
|
||||
if (typeof newElements.length !== 'undefined') {
|
||||
// if handleSwap returns an array (like) of elements, we handle them
|
||||
for (var j = 0; j < newElements.length; j++) {
|
||||
var child = newElements[j];
|
||||
if (child.nodeType !== Node.TEXT_NODE && child.nodeType !== Node.COMMENT_NODE) {
|
||||
settleInfo.tasks.push(makeAjaxLoadTask(child));
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
} catch (e) {
|
||||
@ -973,8 +983,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) {
|
||||
@ -1007,7 +1017,7 @@ return (function () {
|
||||
var eventResult = elt.dispatchEvent(event);
|
||||
withExtensions(elt, function (extension) {
|
||||
eventResult = eventResult && (extension.onEvent(eventName, event) !== false)
|
||||
});
|
||||
}, detail.extensions);
|
||||
return eventResult;
|
||||
}
|
||||
|
||||
@ -1426,7 +1436,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;
|
||||
|
71
test/ext/index.js
Normal file
71
test/ext/index.js
Normal file
@ -0,0 +1,71 @@
|
||||
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
|
||||
});
|
||||
|
||||
});
|
@ -18,4 +18,14 @@ describe("morphdom-swap extension", function() {
|
||||
btn.innerHTML.should.equal("Clicked!");
|
||||
});
|
||||
|
||||
});
|
||||
it('works with htmx elements in new content', function () {
|
||||
this.server.respondWith("GET", "/test", '<button>Clicked!<span hx-get="/test-inner" hx-trigger="load" hx-swap="morphdom"></span></button>');
|
||||
this.server.respondWith("GET", "/test-inner", 'Loaded!');
|
||||
var btn = make('<div hx-ext="morphdom-swap"><button hx-get="/test" hx-swap="morphdom">Click Me!</button></div>').querySelector('button');
|
||||
btn.click();
|
||||
this.server.respond(); // call /test via button trigger=click
|
||||
this.server.respond(); // call /test-inner via span trigger=load
|
||||
btn.innerHTML.should.equal("Clicked!Loaded!");
|
||||
});
|
||||
|
||||
});
|
||||
|
@ -90,6 +90,8 @@
|
||||
</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