mirror of
https://github.com/bigskysoftware/htmx.git
synced 2025-10-02 15:25:26 +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) {
|
handleSwap: function (swapStyle, target, fragment) {
|
||||||
if (swapStyle === 'morphdom') {
|
if (swapStyle === 'morphdom') {
|
||||||
morphdom(target, fragment.outerHTML);
|
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){
|
while(fragment.childNodes.length > 0){
|
||||||
var child = fragment.firstChild;
|
var child = fragment.firstChild;
|
||||||
parentNode.insertBefore(child, insertBefore);
|
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));
|
settleInfo.tasks.push(makeAjaxLoadTask(child));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -519,7 +519,17 @@ return (function () {
|
|||||||
for (var i = 0; i < extensions.length; i++) {
|
for (var i = 0; i < extensions.length; i++) {
|
||||||
var ext = extensions[i];
|
var ext = extensions[i];
|
||||||
try {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -973,8 +983,8 @@ return (function () {
|
|||||||
return eventName === "processedNode.htmx"
|
return eventName === "processedNode.htmx"
|
||||||
}
|
}
|
||||||
|
|
||||||
function withExtensions(elt, toDo) {
|
function withExtensions(elt, toDo, extensions) {
|
||||||
forEach(getExtensions(elt), function(extension){
|
forEach(typeof extensions === 'undefined' ? getExtensions(elt) : extensions, function(extension){
|
||||||
try {
|
try {
|
||||||
toDo(extension);
|
toDo(extension);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -1007,7 +1017,7 @@ return (function () {
|
|||||||
var eventResult = elt.dispatchEvent(event);
|
var eventResult = elt.dispatchEvent(event);
|
||||||
withExtensions(elt, function (extension) {
|
withExtensions(elt, function (extension) {
|
||||||
eventResult = eventResult && (extension.onEvent(eventName, event) !== false)
|
eventResult = eventResult && (extension.onEvent(eventName, event) !== false)
|
||||||
});
|
}, detail.extensions);
|
||||||
return eventResult;
|
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 () {
|
xhr.onload = function () {
|
||||||
try {
|
try {
|
||||||
if (!triggerEvent(elt, 'beforeOnLoad.htmx', eventDetail)) return;
|
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!");
|
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>
|
</script>
|
||||||
|
|
||||||
<!-- extension tests -->
|
<!-- extension tests -->
|
||||||
|
<script src="ext/index.js"></script>
|
||||||
|
|
||||||
<script src="../src/ext/method-override.js"></script>
|
<script src="../src/ext/method-override.js"></script>
|
||||||
<script src="ext/method-override.js"></script>
|
<script src="ext/method-override.js"></script>
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user