From 022855e2be42dc2640856ff5be384e0563385c45 Mon Sep 17 00:00:00 2001 From: James Barlow <332269+manwithacat@users.noreply.github.com> Date: Fri, 24 Apr 2026 12:28:23 +0100 Subject: [PATCH] fix: support textContent swap style for hx-swap-oob (#3563) swapWithStyle() handled none, outerHTML, afterbegin, beforebegin, beforeend, afterend, and delete, but had no case for textContent. Falling through to the default branch caused textContent OOB swaps to be treated as innerHTML, parsing the response body as HTML instead of inserting it as literal text. Mirrors the main-swap textContent handling, which sets target.textContent directly without parsing as HTML. Fixes #3563 Co-Authored-By: Claude Opus 4.7 (1M context) --- src/htmx.js | 3 +++ test/attributes/hx-swap-oob.js | 22 ++++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/src/htmx.js b/src/htmx.js index 0e9bb0a97..0909aa57c 100644 --- a/src/htmx.js +++ b/src/htmx.js @@ -1818,6 +1818,9 @@ var htmx = (function() { case 'delete': swapDelete(target) return + case 'textContent': + target.textContent = fragment.textContent + return default: var extensions = getExtensions(elt) for (let i = 0; i < extensions.length; i++) { diff --git a/test/attributes/hx-swap-oob.js b/test/attributes/hx-swap-oob.js index b4e8bce03..df613a1b6 100644 --- a/test/attributes/hx-swap-oob.js +++ b/test/attributes/hx-swap-oob.js @@ -128,6 +128,28 @@ describe('hx-swap-oob attribute', function() { byId('d1').innerHTML.should.equal('Swapped5') }) + it('handles textContent response properly', function() { + this.server.respondWith('GET', '/test', "Clicked

Swapped

") + var div = make('
click me
') + make('
old
') + div.click() + this.server.respond() + div.innerHTML.should.equal('Clicked') + byId('d1').innerHTML.should.equal('Swapped') + byId('d1').textContent.should.equal('Swapped') + }) + + it('handles textContent oob swap with selector', function() { + this.server.respondWith('GET', '/test', "
Clicked
new
") + var div = make('
click me
') + make('
old
') + div.click() + this.server.respond() + div.innerHTML.should.equal('
Clicked
') + byId('d1').innerHTML.should.equal('new') + byId('d1').textContent.should.equal('new') + }) + it('oob swaps can be nested in content with config {"allowNestedOobSwaps": true}', function() { htmx.config.allowNestedOobSwaps = true this.server.respondWith('GET', '/test', "
Clicked
Swapped6
")