describe('hx-swap attribute', function() { beforeEach(function() { this.server = makeServer() clearWorkArea() }) afterEach(function() { this.server.restore() clearWorkArea() }) it('swap innerHTML properly', function() { this.server.respondWith('GET', '/test', 'Click Me') this.server.respondWith('GET', '/test2', 'Clicked!') var div = make('
') div.click() this.server.respond() div.innerHTML.should.equal('Click Me') var a = div.querySelector('a') a.click() this.server.respond() a.innerHTML.should.equal('Clicked!') }) it('swap textContent properly with HTML tags', function() { this.server.respondWith('GET', '/test', 'Click Me') var d1 = make('
') d1.click() should.equal(byId('d1'), d1) this.server.respond() d1.textContent.should.equal('Click Me') should.equal(byId('a1'), null) }) it('swap textContent properly with HTML tags and text', function() { this.server.respondWith('GET', '/test', 'text content Click Me') var d1 = make('
') d1.click() should.equal(byId('d1'), d1) this.server.respond() d1.textContent.should.equal('text content Click Me') should.equal(byId('a1'), null) }) it('swap textContent ignores OOB swaps', function() { this.server.respondWith('GET', '/test', 'hi Click Me') var d1 = make('
') var d2 = make('
some text
') d1.click() should.equal(byId('d1'), d1) should.equal(byId('d2'), d2) this.server.respond() d1.textContent.should.equal('hi Click Me') d2.outerHTML.should.equal('
some text
') should.equal(byId('a1'), null) }) it('swap textContent properly with text', function() { this.server.respondWith('GET', '/test', 'plain text') var div = make('
') div.click() should.equal(byId('d1'), div) this.server.respond() div.textContent.should.equal('plain text') should.equal(byId('a1'), null) }) it('swap outerHTML properly', function() { this.server.respondWith('GET', '/test', 'Click Me') this.server.respondWith('GET', '/test2', 'Clicked!') var div = make('
') div.click() should.equal(byId('d1'), div) this.server.respond() should.equal(byId('d1'), null) byId('a1').click() this.server.respond() byId('a1').innerHTML.should.equal('Clicked!') }) it('swap beforebegin properly', function() { var i = 0 this.server.respondWith('GET', '/test', function(xhr) { i++ xhr.respond(200, {}, '' + i + '') }) this.server.respondWith('GET', '/test2', '*') var div = make('
*
') var parent = div.parentElement div.click() this.server.respond() div.innerText.should.equal('*') removeWhiteSpace(parent.innerText).should.equal('1*') byId('a1').click() this.server.respond() removeWhiteSpace(parent.innerText).should.equal('**') div.click() this.server.respond() div.innerText.should.equal('*') removeWhiteSpace(parent.innerText).should.equal('*2*') byId('a2').click() this.server.respond() removeWhiteSpace(parent.innerText).should.equal('***') }) it('swap afterbegin properly', function() { var i = 0 this.server.respondWith('GET', '/test', function(xhr) { i++ xhr.respond(200, {}, '' + i) }) var div = make('
*
') div.click() this.server.respond() div.innerText.should.equal('1*') div.click() this.server.respond() div.innerText.should.equal('21*') div.click() this.server.respond() div.innerText.should.equal('321*') }) it('swap afterbegin properly with no initial content', function() { var i = 0 this.server.respondWith('GET', '/test', function(xhr) { i++ xhr.respond(200, {}, '' + i) }) var div = make('
') div.click() this.server.respond() div.innerText.should.equal('1') div.click() this.server.respond() div.innerText.should.equal('21') div.click() this.server.respond() div.innerText.should.equal('321') }) it('swap afterend properly', function() { var i = 0 this.server.respondWith('GET', '/test', function(xhr) { i++ xhr.respond(200, {}, '' + i + '') }) this.server.respondWith('GET', '/test2', '*') var div = make('
*
') var parent = div.parentElement div.click() this.server.respond() div.innerText.should.equal('*') removeWhiteSpace(parent.innerText).should.equal('*1') byId('a1').click() this.server.respond() removeWhiteSpace(parent.innerText).should.equal('**') div.click() this.server.respond() div.innerText.should.equal('*') removeWhiteSpace(parent.innerText).should.equal('*2*') byId('a2').click() this.server.respond() removeWhiteSpace(parent.innerText).should.equal('***') }) it('handles beforeend properly', function() { var i = 0 this.server.respondWith('GET', '/test', function(xhr) { i++ xhr.respond(200, {}, '' + i) }) var div = make('
*
') div.click() this.server.respond() div.innerText.should.equal('*1') div.click() this.server.respond() div.innerText.should.equal('*12') div.click() this.server.respond() div.innerText.should.equal('*123') }) it('handles beforeend properly with no initial content', function() { var i = 0 this.server.respondWith('GET', '/test', function(xhr) { i++ xhr.respond(200, {}, '' + i) }) var div = make('
') div.click() this.server.respond() div.innerText.should.equal('1') div.click() this.server.respond() div.innerText.should.equal('12') div.click() this.server.respond() div.innerText.should.equal('123') }) it('properly parses various swap specifications', function() { var swapSpec = htmx._('getSwapSpecification') // internal function for swap spec swapSpec(make('
')).swapStyle.should.equal('innerHTML') swapSpec(make("
")).swapStyle.should.equal('innerHTML') swapSpec(make("
")).swapDelay.should.equal(0) swapSpec(make("
")).settleDelay.should.equal(0) // set to 0 in tests swapSpec(make("
")).swapDelay.should.equal(10) swapSpec(make("
")).swapDelay.should.equal(0) swapSpec(make("
")).swapDelay.should.equal(0) swapSpec(make("
")).settleDelay.should.equal(10) swapSpec(make("
")).settleDelay.should.equal(0) swapSpec(make("
")).settleDelay.should.equal(0) swapSpec(make("
")).swapDelay.should.equal(10) swapSpec(make("
")).settleDelay.should.equal(11) swapSpec(make("
")).swapDelay.should.equal(10) swapSpec(make("
")).settleDelay.should.equal(11) swapSpec(make("
")).settleDelay.should.equal(0) swapSpec(make("
")).settleDelay.should.equal(0) swapSpec(make("
")).settleDelay.should.equal(0) swapSpec(make("
")).settleDelay.should.equal(0) swapSpec(make("
")).settleDelay.should.equal(11) swapSpec(make("
")).settleDelay.should.equal(11) swapSpec(make("
")).swapStyle.should.equal('innerHTML') swapSpec(make("
")).swapDelay.should.equal(10) swapSpec(make("
")).swapDelay.should.equal(0) swapSpec(make("
")).swapDelay.should.equal(0) swapSpec(make("
")).swapStyle.should.equal('innerHTML') swapSpec(make("
")).settleDelay.should.equal(10) swapSpec(make("
")).settleDelay.should.equal(0) swapSpec(make("
")).settleDelay.should.equal(0) swapSpec(make("
")).swapStyle.should.equal('innerHTML') swapSpec(make("
")).swapDelay.should.equal(10) swapSpec(make("
")).settleDelay.should.equal(11) swapSpec(make("
")).swapDelay.should.equal(0) swapSpec(make("
")).settleDelay.should.equal(0) swapSpec(make("
")).swapStyle.should.equal('innerHTML') swapSpec(make("
")).swapDelay.should.equal(10) swapSpec(make("
")).settleDelay.should.equal(11) swapSpec(make("
")).swapDelay.should.equal(10) swapSpec(make("
")).settleDelay.should.equal(0) swapSpec(make("
")).swapStyle.should.equal('customstyle') }) it('works with a swap delay', function(done) { this.server.respondWith('GET', '/test', 'Clicked!') var div = make("
") div.click() this.server.respond() div.innerText.should.equal('') setTimeout(function() { div.innerText.should.equal('Clicked!') done() }, 30) }) it('works immediately with no swap delay', function(done) { this.server.respondWith('GET', '/test', 'Clicked!') var div = make( "
" ) div.click() this.server.respond() div.innerText.should.equal('Clicked!') done() }) it('works with a settle delay', function(done) { this.server.respondWith('GET', '/test', "
") var div = make("
") div.click() this.server.respond() div.classList.contains('foo').should.equal(false) setTimeout(function() { byId('d1').classList.contains('foo').should.equal(true) done() }, 30) }) it('works with no settle delay', function(done) { this.server.respondWith( 'GET', '/test', "
" ) var div = make( "
" ) div.click() this.server.respond() div.classList.contains('foo').should.equal(false) setTimeout(function() { byId('d1').classList.contains('foo').should.equal(true) done() }, 30) }) it('swap outerHTML properly w/ data-* prefix', function() { this.server.respondWith('GET', '/test', 'Click Me') this.server.respondWith('GET', '/test2', 'Clicked!') var div = make('
') div.click() should.equal(byId('d1'), div) this.server.respond() should.equal(byId('d1'), null) byId('a1').click() this.server.respond() byId('a1').innerHTML.should.equal('Clicked!') }) it('swap none works properly', function() { this.server.respondWith('GET', '/test', 'Ooops, swapped') var div = make('
Foo
') div.click() this.server.respond() div.innerHTML.should.equal('Foo') }) it('swap outerHTML does not trigger htmx:afterSwap on original element', function() { this.server.respondWith('GET', '/test', 'Clicked!') var div = make('
') div.addEventListener('htmx:afterSwap', function() { count++ }) div.click() var count = 0 should.equal(byId('d1'), div) this.server.respond() should.equal(byId('d1'), null) count.should.equal(0) }) it('swap delete works properly', function() { this.server.respondWith('GET', '/test', 'Oops, deleted!') var div = make('
Foo
') div.click() this.server.respond() should.equal(byId('d1'), null) }) it('in presence of bad swap spec, it uses the default swap strategy', function() { var initialSwapStyle = htmx.config.defaultSwapStyle htmx.config.defaultSwapStyle = 'outerHTML' try { this.server.respondWith('GET', '/test', 'Clicked!') var div = make('
') var b1 = byId('b1') b1.click() this.server.respond() div.innerHTML.should.equal('Clicked!') } finally { htmx.config.defaultSwapStyle = initialSwapStyle } }) it('hx-swap ignoreTitle works', function() { window.document.title = 'Test Title' this.server.respondWith('GET', '/test', function(xhr) { xhr.respond(200, {}, "htmx rocks!Clicked!") }) var btn = make('') btn.click() this.server.respond() btn.innerText.should.equal('Clicked!') window.document.title.should.equal('Test Title') }) })