Skip to content

Commit b0c87bf

Browse files
matthews314Matteo Smaila1cg
authored
Bugfix: swap="outerHTML" on <div> with style attribute leaves htmx-swapping class behind (#3341)
* Added regression test for swap=outerHTML unexpected behavior, checked it failes, implemented initial fix in htmx.js that makes (all) test(s) run and pass. * Renamed variable in my regression test to be more clear. * I noticed I wasn't using the copies of the attributes I introduced.Tests were passing and I know why, though. This means I miss one more regression test for the bug in cloneAttributes. * Added one more regression test for the fix in cloneAttributes. * Made preservation of htmx- prefixed classes more robust in cloneAttributes after I noted they could as well be removed by mergeTo.setAttribute in the second forEach loop. * Started as a typo-fix, ended up renaming regression tests to be more explicit. * Started as a typo-fix, ended up renaming regression tests to be more explicit. * Removed space that I accidentally added before. * Applied changes as requested by MichaelWest22. --------- Co-authored-by: Matteo Smaila <matteo.smaila@314softwaresolutions.com> Co-authored-by: 1cg <469183+1cg@users.noreply.github.com>
1 parent 7529444 commit b0c87bf

2 files changed

Lines changed: 31 additions & 1 deletion

File tree

src/htmx.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1413,7 +1413,7 @@ var htmx = (function() {
14131413
* @param {Element} mergeFrom
14141414
*/
14151415
function cloneAttributes(mergeTo, mergeFrom) {
1416-
forEach(mergeTo.attributes, function(attr) {
1416+
forEach(Array.from(mergeTo.attributes), function(attr) {
14171417
if (!mergeFrom.hasAttribute(attr.name) && shouldSettleAttribute(attr.name)) {
14181418
mergeTo.removeAttribute(attr.name)
14191419
}

test/core/regressions.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,35 @@ describe('Core htmx Regression Tests', function() {
292292
byId('datefield').click()
293293
})
294294

295+
it('swap=outerHTML clears htmx-swapping class when old node has a style attribute and no class', function(done) {
296+
this.server.respondWith('GET', '/test', '<div id="test-div">Test</div>')
297+
298+
var btn = make('<button hx-get="/test" hx-target="#test-div" hx-swap="outerHTML">Click Me!</button>')
299+
var div = make('<div id="test-div" style></div>')
300+
btn.click()
301+
302+
this.server.respond()
303+
304+
var div = byId('test-div')
305+
const isSwappingClassStillThere = div.classList.contains('htmx-swapping')
306+
isSwappingClassStillThere.should.equal(false)
307+
done()
308+
})
309+
310+
it('swap=outerHTML won\'t carry over user-defined classes when old node has a style attribute before the class attribute', function(done) {
311+
this.server.respondWith('GET', '/test', '<div id="test-div">Test</div>')
312+
313+
var btn = make('<button hx-get="/test" hx-target="#test-div" hx-swap="outerHTML">Click Me!</button>')
314+
var div = make('<div id="test-div" style class="my-class"></div>')
315+
btn.click()
316+
317+
this.server.respond()
318+
319+
var div = byId('test-div')
320+
div.classList.length.should.equal(0)
321+
done()
322+
})
323+
295324
it('a button clicked inside an htmx enabled link will prevent the link from navigating on click', function(done) {
296325
var defaultPrevented = 'unset'
297326
var link = make('<a href="/foo" hx-get="/foo"><button>test</button></a>')
@@ -333,4 +362,5 @@ describe('Core htmx Regression Tests', function() {
333362

334363
button.click()
335364
})
365+
336366
})

0 commit comments

Comments
 (0)