fix bug with empty response after partial removal detection (#3569)

Co-authored-by: MichaelWest22 <michael.west@docuvera.com>
This commit is contained in:
MichaelWest22
2025-12-04 09:21:18 +13:00
committed by GitHub
parent 22205ce3f4
commit 7e7592aeb8
2 changed files with 51 additions and 1 deletions

View File

@@ -1318,7 +1318,7 @@ var htmx = (() => {
// Create main task if needed
let swapSpec = this.__parseSwapSpec(ctx.swap || this.config.defaultSwap);
// skip creating main swap if extracting partials resulted in empty response except for delete style
if (swapSpec.style === 'delete' || /\S/.test(fragment.innerHTML || '') || !partialTasks.length) {
if (swapSpec.style === 'delete' || fragment.childElementCount > 0 || /\S/.test(fragment.textContent) || !partialTasks.length) {
if (ctx.select) {
let selected = fragment.querySelectorAll(ctx.select);
fragment = document.createDocumentFragment();

View File

@@ -363,4 +363,54 @@ describe('swap() unit tests', function() {
document.activeElement.id.should.equal("i1")
})
it('swaps both main target and partial target when both are present', async function () {
createProcessedHTML("<div id='target'>Hello</div><div id='target_oob'>OOB</div>")
await htmx.swap({
"target":"#target",
"text":"<div>Hello me!</div><hx-partial hx-target='#target_oob' hx-swap='innerHTML'><div>OOB swap!</div></hx-partial>"
})
find('#target').innerText.should.equal("Hello me!");
find('#target_oob').innerText.should.equal("OOB swap!");
})
it('swaps only partial target when response contains only partial', async function () {
createProcessedHTML("<div id='target'>Original</div><div id='target_oob'>OOB Original</div>")
await htmx.swap({
"target":"#target",
"text":"<hx-partial hx-target='#target_oob' hx-swap='innerHTML'><div>OOB Updated</div></hx-partial>"
})
find('#target').innerText.should.equal("Original");
find('#target_oob').innerText.should.equal("OOB Updated");
})
it('does not swap main target when only whitespace and partial present', async function () {
createProcessedHTML("<div id='target'>Original</div><div id='target_oob'>OOB</div>")
await htmx.swap({
"target":"#target",
"text":"\n <hx-partial hx-target='#target_oob' hx-swap='innerHTML'><div>OOB swap!</div></hx-partial> \n"
})
find('#target').innerText.should.equal("Original");
find('#target_oob').innerText.should.equal("OOB swap!");
})
it('swaps both targets when empty element and partial present', async function () {
createProcessedHTML("<div id='target'>Original</div><div id='target_oob'>OOB</div>")
await htmx.swap({
"target":"#target",
"text":"<p></p><hx-partial hx-target='#target_oob' hx-swap='innerHTML'><div>OOB swap!</div></hx-partial>"
})
find('#target').querySelector('p').should.not.be.null;
find('#target_oob').innerText.should.equal("OOB swap!");
})
it('swaps both targets when plain text and partial present', async function () {
createProcessedHTML("<div id='target'>Original</div><div id='target_oob'>OOB</div>")
await htmx.swap({
"target":"#target",
"text":"Hello<hx-partial hx-target='#target_oob' hx-swap='innerHTML'><div>OOB swap!</div></hx-partial>"
})
find('#target').textContent.should.equal("Hello");
find('#target_oob').innerText.should.equal("OOB swap!");
})
})