Version: 2.0.4
htmx._('makeFragment')('<html></html>').children.length.should.equal(0)
htmx._('makeFragment')('<html><body></body></html>').children.length.should.equal(0)
// NB - the tag name should be the *parent* element hosting the HTML since we use the fragment children
// for the swap
htmx._('makeFragment')('<td></td>').firstElementChild.tagName.should.equal('TD')
htmx._('makeFragment')('<thead></thead>').firstElementChild.tagName.should.equal('THEAD')
htmx._('makeFragment')('<col></col>').firstElementChild.tagName.should.equal('COL')
htmx._('makeFragment')('<tr></tr>').firstElementChild.tagName.should.equal('TR')
htmx._('makeFragment')('<html></html>').children.length.should.equal(0)
htmx._('makeFragment')('<html><body></body></html>').children.length.should.equal(0)
var fragment = htmx._('makeFragment')('<td></td>')
fragment.firstElementChild.tagName.should.equal('TD')
fragment = htmx._('makeFragment')('<thead></thead>')
fragment.firstElementChild.tagName.should.equal('THEAD')
fragment = htmx._('makeFragment')('<col></col>')
fragment.firstElementChild.tagName.should.equal('COL')
fragment = htmx._('makeFragment')('<tr></tr>')
fragment.firstElementChild.tagName.should.equal('TR')
htmx.config.useTemplateFragments = true
try {
var fragment = htmx._('makeFragment')('<td></td><div></div>')
fragment.children[0].tagName.should.equal('TD')
fragment.children[1].tagName.should.equal('DIV')
} finally {
htmx.config.useTemplateFragments = false
}
var xhr = new XMLHttpRequest()
xhr.open('GET', '/dummy')
htmx._('safelySetHeaderValue')(xhr, 'Example', 'привет')
// unfortunately I can't test the value :/
// https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest
chai.expect(htmx.parseInterval('1ms')).to.be.equal(1)
chai.expect(htmx.parseInterval('300ms')).to.be.equal(300)
chai.expect(htmx.parseInterval('1s')).to.be.equal(1000)
chai.expect(htmx.parseInterval('1.5s')).to.be.equal(1500)
chai.expect(htmx.parseInterval('2s')).to.be.equal(2000)
chai.expect(htmx.parseInterval('0ms')).to.be.equal(0)
chai.expect(htmx.parseInterval('0s')).to.be.equal(0)
chai.expect(htmx.parseInterval('0m')).to.be.equal(0)
chai.expect(htmx.parseInterval('0')).to.be.equal(0)
chai.expect(htmx.parseInterval('5')).to.be.equal(5)
chai.expect(htmx.parseInterval(null)).to.be.undefined
chai.expect(htmx.parseInterval('')).to.be.undefined
chai.expect(htmx.parseInterval('undefined')).to.be.undefined
chai.expect(htmx.parseInterval('true')).to.be.undefined
chai.expect(htmx.parseInterval('false')).to.be.undefined
chai.expect(htmx._('tokenizeString')('a,')).to.be.deep.equal(['a', ','])
chai.expect(htmx._('tokenizeString')('aa,')).to.be.deep.equal(['aa', ','])
chai.expect(htmx._('tokenizeString')('aa,aa')).to.be.deep.equal(['aa', ',', 'aa'])
chai.expect(htmx._('tokenizeString')('aa.aa')).to.be.deep.equal(['aa', '.', 'aa'])
var anchorThatShouldCancel = make("<a href='/foo'></a>")
htmx._('shouldCancel')({ type: 'click' }, anchorThatShouldCancel).should.equal(true)
anchorThatShouldCancel = make("<a href='#'></a>")
htmx._('shouldCancel')({ type: 'click' }, anchorThatShouldCancel).should.equal(true)
var anchorThatShouldNotCancel = make("<a href='#foo'></a>")
htmx._('shouldCancel')({ type: 'click' }, anchorThatShouldNotCancel).should.equal(false)
var form = make('<form></form>')
htmx._('shouldCancel')({ type: 'submit' }, form).should.equal(true)
form = make("<form><input id='i1' type='submit'></form>")
var input = byId('i1')
htmx._('shouldCancel')({ type: 'click' }, input).should.equal(true)
form = make("<form><button id='b1' type='submit'></form>")
var button = byId('b1')
htmx._('shouldCancel')({ type: 'click' }, button).should.equal(true)
form = make("<form id='f1'></form><input id='i1' form='f1' type='submit'><button id='b1' form='f1' type='submit'>")
input = byId('i1')
button = byId('b1')
htmx._('shouldCancel')({ type: 'click' }, input).should.equal(true)
htmx._('shouldCancel')({ type: 'click' }, button).should.equal(true)
make("<div foo='1'><div foo='2'><div foo='unset' id='d1'></div></div></div>")
var div = byId('d1')
should.equal(undefined, htmx._('getClosestAttributeValue')(div, 'foo'))
make("<div foo='1'><div foo='unset'><div id='d1'></div></div></div>")
var div = byId('d1')
should.equal(undefined, htmx._('getClosestAttributeValue')(div, 'foo'))
make("<div foo='unset'><div foo='2'><div id='d1'></div></div></div>")
var div = byId('d1')
should.equal('2', htmx._('getClosestAttributeValue')(div, 'foo'))
var form = make("<form enctype='multipart/form-data'></form>")
var value = htmx._('encodeParamsForBody')(null, form, {});
(value instanceof FormData).should.equal(true)
var div = make("<div id='d1' class='c1 c2'>")
div.should.equal(htmx.find('#d1'))
div.should.equal(htmx.find('.c1'))
div.should.equal(htmx.find('.c2'))
div.should.equal(htmx.find('.c1.c2'))
var div = make("<div><a id='a1'></a><a id='a2'></a></div>")
htmx.find(div, 'a').id.should.equal('a1')
var div = make("<div class='c1 c2 c3'><div class='c1 c2'><div class='c1'>")
htmx.findAll('.c1').length.should.equal(3)
htmx.findAll('.c2').length.should.equal(2)
htmx.findAll('.c3').length.should.equal(1)
var div = make("<div><div class='c1 c2 c3'><div class='c1 c2'><div class='c1'></div>")
htmx.findAll(div, '.c1').length.should.equal(3)
htmx.findAll(div, '.c2').length.should.equal(2)
htmx.findAll(div, '.c3').length.should.equal(1)
var div = make("<div><a id='a1'></a><a id='a2'></a></div>")
var a = htmx.find(div, 'a')
htmx.closest(a, 'div').should.equal(div)
var div = make('<div><a></a></div>')
var a = htmx.find(div, 'a')
htmx.remove(a)
div.innerHTML.should.equal('')
var div = make("<div><a id='a1'></a></div>")
var a = htmx.find(div, 'a')
htmx.remove('#a1')
div.innerHTML.should.equal('')
var div = make('<div></div>')
div.classList.contains('foo').should.equal(false)
htmx.addClass(div, 'foo')
div.classList.contains('foo').should.equal(true)
var div = make("<div id='div1'></div>")
div.classList.contains('foo').should.equal(false)
htmx.addClass('#div1', 'foo')
div.classList.contains('foo').should.equal(true)
var div = make('<div></div>')
div.classList.contains('foo').should.equal(false)
htmx.addClass(div, 'foo', 10)
div.classList.contains('foo').should.equal(false)
setTimeout(function() {
div.classList.contains('foo').should.equal(true)
done()
}, 20)
var div = make('<div></div>')
htmx.addClass(div, 'foo')
div.classList.contains('foo').should.equal(true)
htmx.removeClass(div, 'foo')
div.classList.contains('foo').should.equal(false)
var div = make("<div id='div1'></div>")
htmx.addClass(div, 'foo')
div.classList.contains('foo').should.equal(true)
htmx.removeClass('#div1', 'foo')
div.classList.contains('foo').should.equal(false)
var div = make('<div></div>')
htmx.addClass(div, 'foo')
div.classList.contains('foo').should.equal(true)
htmx.removeClass(div, 'foo', 10)
div.classList.contains('foo').should.equal(true)
setTimeout(function() {
div.classList.contains('foo').should.equal(false)
done()
}, 20)
var div = make('<div></div>')
div.classList.contains('foo').should.equal(false)
htmx.toggleClass(div, 'foo')
div.classList.contains('foo').should.equal(true)
htmx.toggleClass(div, 'foo')
div.classList.contains('foo').should.equal(false)
var div = make("<div id='div1'></div>")
div.classList.contains('foo').should.equal(false)
htmx.toggleClass('#div1', 'foo')
div.classList.contains('foo').should.equal(true)
htmx.toggleClass('#div1', 'foo')
div.classList.contains('foo').should.equal(false)
var div1 = make('<div></div>')
var div2 = make('<div></div>')
var div3 = make('<div></div>')
div1.classList.contains('foo').should.equal(false)
div2.classList.contains('foo').should.equal(false)
div3.classList.contains('foo').should.equal(false)
htmx.takeClass(div1, 'foo')
div1.classList.contains('foo').should.equal(true)
div2.classList.contains('foo').should.equal(false)
div3.classList.contains('foo').should.equal(false)
htmx.takeClass(div2, 'foo')
div1.classList.contains('foo').should.equal(false)
div2.classList.contains('foo').should.equal(true)
div3.classList.contains('foo').should.equal(false)
htmx.takeClass(div3, 'foo')
div1.classList.contains('foo').should.equal(false)
div2.classList.contains('foo').should.equal(false)
div3.classList.contains('foo').should.equal(true)
var div1 = make("<div id='div1'></div>")
var div2 = make("<div id='div2'></div>")
var div3 = make("<div id='div3'></div>")
div1.classList.contains('foo').should.equal(false)
div2.classList.contains('foo').should.equal(false)
div3.classList.contains('foo').should.equal(false)
htmx.takeClass('#div1', 'foo')
div1.classList.contains('foo').should.equal(true)
div2.classList.contains('foo').should.equal(false)
div3.classList.contains('foo').should.equal(false)
htmx.takeClass('#div2', 'foo')
div1.classList.contains('foo').should.equal(false)
div2.classList.contains('foo').should.equal(true)
div3.classList.contains('foo').should.equal(false)
htmx.takeClass('#div3', 'foo')
div1.classList.contains('foo').should.equal(false)
div2.classList.contains('foo').should.equal(false)
div3.classList.contains('foo').should.equal(true)
var calledEvent = false
var handler = htmx.on('htmx:evalDisallowedError', function() {
calledEvent = true
})
try {
htmx.config.allowEval = false
should.equal(htmx._('tokenizeString'), undefined)
} finally {
htmx.config.allowEval = true
htmx.off('htmx:evalDisallowedError', handler)
}
calledEvent.should.equal(true)
this.server.respondWith('GET', '/test', 'foo!')
var div = make('<div></div>')
htmx.ajax('GET', '/test', div)
this.server.respond()
div.innerHTML.should.equal('foo!')
this.server.respondWith('GET', '/test', 'foo!')
var div = make("<div id='d1'></div>")
htmx.ajax('GET', '/test', '#d1')
this.server.respond()
div.innerHTML.should.equal('foo!')
this.server.respondWith('GET', '/test', 'foo!')
var div = make("<div id='d1'></div>")
htmx.ajax('GET', '/test', '#d2')
this.server.respond()
document.body.innerHTML.should.not.equal('foo!')
this.server.respondWith('GET', '/test', 'foo!')
var div = make("<div id='d1'></div>")
htmx.ajax('GET', '/test', '#d2').then(
(value) => {
},
(reason) => {
done()
}
)
this.server.respond()
div.innerHTML.should.equal('')
this.server.respondWith('GET', '/test', 'foo!')
var div = make("<div id='d1'></div>")
htmx.ajax('GET', '/test', {
source: div,
target: '#d2'
}).then(
(value) => {
},
(reason) => {
done()
}
)
this.server.respond()
div.innerHTML.should.equal('')
this.server.respondWith('GET', '/test', 'foo!')
var div = make("<div id='d1'></div>")
htmx.ajax('GET', '/test', {
source: '#d2'
}).then(
(value) => {
},
(reason) => {
done()
}
)
this.server.respond()
div.innerHTML.should.equal('')
this.server.respondWith('GET', '/test', 'foo!')
var div = make("<div id='d1'></div>")
htmx.ajax('GET', '/test', {
source: div
})
this.server.respond()
div.innerHTML.should.equal('foo!')
this.server.respondWith('GET', '/test', "<p class='test'>foo!</p>")
var div = make("<div><div id='target'></div></div>")
htmx.ajax('GET', '/test', { target: '#target', swap: 'outerHTML' })
this.server.respond()
div.innerHTML.should.equal('<p class="test">foo!</p>')
this.server.respondWith('GET', '/test', "<div id='d1'>foo</div><div id='d2'>bar</div>")
var div = make("<div id='target'></div>")
htmx.ajax('GET', '/test', { target: '#target', select: '#d2' })
this.server.respond()
div.innerHTML.should.equal('<div id="d2">bar</div>')
this.server.respondWith('GET', '/test', [200, { 'HX-Reselect': '#d2' }, "<div id='d1'>foo</div><div id='d2'>bar</div>"])
var div = make("<div id='target'></div>")
htmx.ajax('GET', '/test', { target: '#target', select: '#d1' })
this.server.respond()
div.innerHTML.should.equal('<div id="d2">bar</div>')
// in IE we do not return a promise
if (typeof Promise !== 'undefined') {
this.server.respondWith('GET', '/test', 'foo!')
var div = make("<div id='d1'></div>")
var promise = htmx.ajax('GET', '/test', '#d1')
this.server.respond()
div.innerHTML.should.equal('foo!')
promise.then(function() {
done()
})
} else {
done()
}
this.server.respondWith('POST', '/test', function(xhr) {
var params = getParameters(xhr)
params.i1.should.equal('test')
xhr.respond(200, {}, 'Clicked!')
})
var div = make("<div id='d1'></div>")
htmx.ajax('POST', '/test', { target: '#d1', values: { i1: 'test' } })
this.server.respond()
div.innerHTML.should.equal('Clicked!')
this.server.respondWith('POST', '/test', function(xhr) {
var params = getParameters(xhr)
xhr.requestHeaders['Content-Type'].should.equal('application/x-www-form-urlencoded;charset=utf-8')
params.i1.should.equal('test')
xhr.respond(200, {}, 'Clicked!')
})
var div = make("<div id='d1'></div>")
htmx.ajax('POST', '/test', { target: '#d1', values: { i1: 'test' } })
this.server.respond()
div.innerHTML.should.equal('Clicked!')
this.server.respondWith('POST', '/test', function(xhr) {
var params = getParameters(xhr)
xhr.requestHeaders['Content-Type'].should.equal('application/json;charset=utf-8')
params.i1.should.equal('test')
xhr.respond(200, {}, 'Clicked!')
})
var div = make("<div id='d1'></div>")
htmx.ajax('POST', '/test', {
target: '#d1',
swap: 'innerHTML',
headers: {
'Content-Type': 'application/json'
},
values: { i1: 'test' }
})
this.server.respond()
div.innerHTML.should.equal('Clicked!')
this.server.respondWith('PATCH', '/test', 'patch')
this.server.respondWith('DELETE', '/test', 'delete')
var div = make('<div hx-patch="/test">click me</div>')
div.click()
this.server.respond()
div.innerHTML.should.equal('patch')
div.removeAttribute('hx-patch')
div.setAttribute('hx-delete', '/test')
htmx.process(div)
div.click()
this.server.respond()
div.innerHTML.should.equal('delete')
this.server.respondWith('GET', '/test', 'test')
var div = make('<div hx-get="/test" hx-trigger="load" hx-swap="beforeend"></div>')
this.server.respond()
div.innerHTML.should.equal('test')
div.setAttribute('hx-swap', 'afterbegin')
htmx.process(div)
this.server.respond()
div.innerHTML.should.equal('test')
// also tests on/off
this.server.respondWith('GET', '/test', "<div id='d1' hx-get='/test'></div>")
var helper = htmx.onLoad(function(elt) {
elt.setAttribute('foo', 'bar')
})
try {
var div = make("<div id='d1' hx-get='/test' hx-swap='outerHTML'></div>")
div.click()
this.server.respond()
byId('d1').getAttribute('foo').should.equal('bar')
htmx.off('htmx:load', helper)
} catch (error) {
// Clean up the event if the test fails, then throw it again
htmx.off('htmx:load', helper)
throw error
}
var div = make('<div/>')
var myEventCalled = false
var detailStr = ''
htmx.on('myEvent', function(evt) {
myEventCalled = true
detailStr = evt.detail.str
})
htmx.trigger(div, 'myEvent', { str: 'foo' })
myEventCalled.should.equal(true)
detailStr.should.equal('foo')
var div = make("<div id='div1'/>")
var myEventCalled = false
var detailStr = ''
htmx.on('myEvent', function(evt) {
myEventCalled = true
detailStr = evt.detail.str
})
htmx.trigger('#div1', 'myEvent', { str: 'foo' })
myEventCalled.should.equal(true)
detailStr.should.equal('foo')
var div = make('<div/>')
var myEventCalled = false
htmx.on('myEvent', function(evt) {
myEventCalled = true
})
htmx.trigger(div, 'myEvent')
myEventCalled.should.equal(true)
var output = make('<output id="output"/>')
htmx.swap('#output', '<div>Swapped!</div>', { swapStyle: 'innerHTML' })
output.innerHTML.should.be.equal('<div>Swapped!</div>')
var output = make('<output id="output"/>')
htmx.swap('#output', '<div><p id="select-me">Swapped!</p></div>', { swapStyle: 'innerHTML' }, { select: '#select-me' })
output.innerHTML.should.be.equal('<p id="select-me">Swapped!</p>')
var output = make('<output id="output"/>')
var oobDiv = make('<div id="oob"/>')
htmx.swap('#output', '<div id="oob" hx-swap-oob="innerHTML">OOB Swapped!</div><div>Swapped!</div>', { swapStyle: 'innerHTML' })
output.innerHTML.should.be.equal('<div>Swapped!</div>')
oobDiv.innerHTML.should.be.equal('OOB Swapped!')
var output = make('<output id="output"/>')
var oobDiv = make('<div id="oob"/>')
htmx.swap('#output', '<div id="oob">OOB Swapped!</div><div>Swapped!</div>', { swapStyle: 'innerHTML' }, { selectOOB: '#oob:innerHTML' })
output.innerHTML.should.be.equal('<div>Swapped!</div>')
oobDiv.innerHTML.should.be.equal('OOB Swapped!')
this.server.respondWith('DELETE', '/test', 'delete')
var parent = make('<div><div id="d1" hx-swap="delete" hx-delete="/test">click me</div></div>')
var div = htmx.find(parent, '#d1')
div.click()
div.remove()
parent.remove()
this.server.respond()
parent.children.length.should.equal(0)
this.server.respondWith('GET', '/test', 'delete')
var parent = make('<div><div id="d1" hx-swap="outerHTML" hx-get="/test">click me</div></div>')
var div = htmx.find(parent, '#d1')
div.click()
div.remove()
parent.remove()
this.server.respond()
parent.children.length.should.equal(0)
this.server.respondWith('GET', '/test', 'Clicked!')
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('Clicked!')
this.server.respondWith('GET', '/test', '<a hx-get="/test2">Click Me</a>')
this.server.respondWith('GET', '/test2', 'Clicked!')
var div = make('<div hx-get="/test"></div>')
div.click()
this.server.respond()
div.innerHTML.should.equal('<a hx-get="/test2">Click Me</a>')
var a = div.querySelector('a')
a.click()
this.server.respond()
a.innerHTML.should.equal('Clicked!')
this.server.respondWith('GET', '/test', '<a id="a1" hx-get="/test2">Click Me</a>')
this.server.respondWith('GET', '/test2', 'Clicked!')
var div = make('<div id="d1" hx-get="/test" hx-swap="outerHTML"></div>')
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!')
var i = 0
this.server.respondWith('GET', '/test', function(xhr) {
i++
xhr.respond(200, {}, '<a id="a' + i + '" hx-get="/test2" hx-swap="innerHTML">' + i + '</a>')
})
this.server.respondWith('GET', '/test2', '*')
var div = make('<div hx-get="/test" hx-swap="beforebegin">*</div>')
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('***')
var i = 0
this.server.respondWith('GET', '/test', function(xhr) {
i++
xhr.respond(200, {}, '' + i)
})
var div = make('<div hx-get="/test" hx-swap="afterbegin">*</div>')
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*')
var i = 0
this.server.respondWith('GET', '/test', function(xhr) {
i++
xhr.respond(200, {}, '' + i)
})
var div = make('<div hx-get="/test" hx-swap="afterbegin"></div>')
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')
var i = 0
this.server.respondWith('GET', '/test', function(xhr) {
i++
xhr.respond(200, {}, '<a id="a' + i + '" hx-get="/test2" hx-swap="innerHTML">' + i + '</a>')
})
this.server.respondWith('GET', '/test2', '*')
var div = make('<div hx-get="/test" hx-swap="afterend">*</div>')
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('***')
var i = 0
this.server.respondWith('GET', '/test', function(xhr) {
i++
xhr.respond(200, {}, '' + i)
})
var div = make('<div hx-get="/test" hx-swap="beforeend">*</div>')
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')
var i = 0
this.server.respondWith('GET', '/test', function(xhr) {
i++
xhr.respond(200, {}, '' + i)
})
var div = make('<div hx-get="/test" hx-swap="beforeend"></div>')
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')
this.server.respondWith('GET', '/test', 'Clicked!')
var btn = make('<button hx-get="/test" hx-target="#s1">Click Me!</button>')
var target = make('<span id="s1">Initial</span>')
btn.click()
target.innerHTML.should.equal('Initial')
this.server.respond()
target.innerHTML.should.equal('Clicked!')
this.server.respondWith('GET', '/test', [204, {}, 'No Content!'])
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
btn.innerHTML.should.equal('Click Me!')
this.server.respond()
btn.innerHTML.should.equal('Click Me!')
this.server.respondWith('GET', '/test-1', [200, {}, 'Content for Tab 1'])
this.server.respondWith('GET', '/test-2', [200, {}, 'Content for Tab 2'])
var target = make('<div id="target"></div>')
var btn1 = make('<button hx-get="/test-1" hx-target="#target">Tab 1</button>')
var btn2 = make('<button hx-get="/test-2" hx-target="#target">Tab 2</button>')
btn1.click()
target.innerHTML.should.equal('')
this.server.respond()
target.innerHTML.should.equal('Content for Tab 1')
btn2.click()
this.server.respond()
target.innerHTML.should.equal('Content for Tab 2')
this.server.respondWith('GET', '/test-1', [304, {}, 'Content for Tab 1'])
this.server.respondWith('GET', '/test-2', [304, {}, 'Content for Tab 2'])
btn1.click()
this.server.respond()
target.innerHTML.should.equal('Content for Tab 1')
btn2.click()
this.server.respond()
target.innerHTML.should.equal('Content for Tab 2')
this.server.respondWith('GET', '/test', 'Clicked!')
var form = make('<form hx-get="/test" hx-trigger="click">Click Me!</form>')
form.click()
form.innerHTML.should.equal('Click Me!')
this.server.respond()
form.innerHTML.should.equal('Clicked!')
this.server.respondWith('GET', '/test', 'Loaded!')
var div = make('<div hx-get="/test" hx-trigger="load">Load Me!</div>')
div.innerHTML.should.equal('Load Me!')
this.server.respond()
div.innerHTML.should.equal('Loaded!')
this.server.respondWith('GET', '/test', function(xhr) {
xhr.respond(200, {}, 'done')
xhr.overriddenMimeType.should.equal('text/html')
done()
})
var div = make('<div hx-get="/test">Click Me!</div>')
div.click()
this.server.respond()
var i = 1
this.server.respondWith('GET', '/test', function(xhr) {
xhr.respond(200, {}, 'click ' + i)
i++
})
var div = make('<div hx-get="/test"></div>')
div.click()
div.click()
this.server.respond()
div.innerHTML.should.equal('click 1')
this.server.respond()
div.innerHTML.should.equal('click 2')
var i = 1
this.server.respondWith('GET', '/test', function(xhr) {
xhr.respond(200, {}, 'click ' + i)
i++
})
var div = make('<div hx-get="/test"></div>')
div.click()
div.click()
div.click()
this.server.respondAll()
div.innerHTML.should.equal('click 2')
var i = 1
this.server.respondWith('GET', '/test', "<div id='d1'>foo</div><div id='d2'>bar</div>")
var div = make('<div hx-get="/test" hx-select="#d1"></div>')
div.click()
this.server.respond()
div.innerHTML.should.equal('<div id="d1">foo</div>')
this.server.respondWith('GET', '/test', "<html><body><div id='d1'>foo</div><div id='d2'>bar</div></body></html>")
var div = make('<div hx-get="/test" hx-select="#d1"></div>')
div.click()
this.server.respond()
div.innerHTML.should.equal('<div id="d1">foo</div>')
this.server.respondWith('GET', '/test', "<div hx-get='/test'><div width='bar' id='d1'></div></div>")
var div = make("<div hx-get='/test' hx-swap='outerHTML settle:10ms'><div id='d1'></div></div>")
div.click()
this.server.respond()
should.equal(byId('d1').getAttribute('width'), null)
setTimeout(function() {
should.equal(byId('d1').getAttribute('width'), 'bar')
done()
}, 20)
this.server.respondWith('GET', '/test', "<div hx-get='/test'><div width='bar' id=\"d1'\"></div></div>")
var div = make("<div hx-get='/test' hx-swap='outerHTML settle:10ms'><div id=\"d1'\"></div></div>")
div.click()
this.server.respond()
should.equal(byId("d1'").getAttribute('width'), null)
setTimeout(function() {
should.equal(byId("d1'").getAttribute('width'), 'bar')
done()
}, 20)
this.server.respondWith('GET', '/test', "<div hx-get='/test'><div width='bar' id='d1\"'></div></div>")
var div = make("<div hx-get='/test' hx-swap='outerHTML settle:10ms'><div id='d1\"'></div></div>")
div.click()
this.server.respond()
should.equal(byId('d1"').getAttribute('width'), null)
setTimeout(function() {
should.equal(byId('d1"').getAttribute('width'), 'bar')
done()
}, 20)
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
var form = make('<form hx-post="/test" hx-trigger="click">' +
'<select id="multiSelect" name="multiSelect" multiple="multiple">' +
'<option id="m1" value="m1">m1</option>' +
'<option id="m2" value="m2">m2</option>' +
'<option id="m3" value="m3">m3</option>' +
'<option id="m4" value="m4">m4</option>' +
'</select>' +
'</form>')
form.click()
this.server.respond()
values.should.deep.equal({})
byId('m1').selected = true
form.click()
this.server.respond()
values.should.deep.equal({ multiSelect: 'm1' })
byId('m1').selected = true
byId('m3').selected = true
form.click()
this.server.respond()
values.should.deep.equal({ multiSelect: ['m1', 'm3'] })
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
var form = make('<form hx-post="/test" hx-trigger="click">' +
'<select name="multiSelect" id="id_question_list" multiple="" tabindex="-1" aria-hidden="true">' +
'<option id="m1" value="m1">m1</option>' +
'<option id="m2" value="m2">m2</option>' +
'<option id="m3" value="m3">m3</option>' +
'<option id="m4" value="m4">m4</option>' +
'</select>' +
'</form>')
form.click()
this.server.respond()
values.should.deep.equal({})
byId('m1').selected = true
form.click()
this.server.respond()
values.should.deep.equal({ multiSelect: 'm1' })
byId('m1').selected = true
byId('m3').selected = true
form.click()
this.server.respond()
values.should.deep.equal({ multiSelect: ['m1', 'm3'] })
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
var form = make('<form hx-post="/test" hx-trigger="click">' +
'<select id="multiSelect" name="multiSelect" multiple="multiple">' +
'<option id="m1" value="m1">m1</option>' +
'<option id="m2" value="m2">m2</option>' +
'<option id="m3" value="m3">m3</option>' +
'<option id="m4" value="m4">m4</option>' +
'</select>' +
'<select id="multiSelect" name="multiSelect" multiple="multiple">' +
'<option id="m5" value="m5">m1</option>' +
'<option id="m6" value="m6">m2</option>' +
'<option id="m7" value="m7">m3</option>' +
'<option id="m8" value="m8">m4</option>' +
'</select>' +
'</form>')
form.click()
this.server.respond()
values.should.deep.equal({})
byId('m1').selected = true
form.click()
this.server.respond()
values.should.deep.equal({ multiSelect: 'm1' })
byId('m1').selected = true
byId('m3').selected = true
byId('m7').selected = true
byId('m8').selected = true
form.click()
this.server.respond()
values.should.deep.equal({ multiSelect: ['m1', 'm3', 'm7', 'm8'] })
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
var form = make('<form hx-post="/test" hx-trigger="click">' +
'<input id="multiEmail" name="multiEmail" multiple>' +
'</form>')
form.click()
this.server.respond()
values.should.deep.equal({ multiEmail: '' })
byId('multiEmail').value = 'foo@example.com'
form.click()
this.server.respond()
values.should.deep.equal({ multiEmail: 'foo@example.com' })
byId('multiEmail').value = 'foo@example.com,bar@example.com'
form.click()
this.server.respond()
values.should.deep.equal({ multiEmail: 'foo@example.com,bar@example.com' })
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
var form = make('<form hx-post="/test" hx-trigger="click">' +
'<input id="cb1" name="c1" value="cb1" type="checkbox">' +
'<input id="cb2" name="c1" value="cb2" type="checkbox">' +
'<input id="cb3" name="c1" value="cb3" type="checkbox">' +
'<input id="cb4" name="c2" value="cb4" type="checkbox">' +
'<input id="cb5" name="c2" value="cb5" type="checkbox">' +
'<input id="cb6" name="c3" value="cb6" type="checkbox">' +
'</form>')
form.click()
this.server.respond()
values.should.deep.equal({})
byId('cb1').checked = true
form.click()
this.server.respond()
values.should.deep.equal({ c1: 'cb1' })
byId('cb1').checked = true
byId('cb2').checked = true
form.click()
this.server.respond()
values.should.deep.equal({ c1: ['cb1', 'cb2'] })
byId('cb1').checked = true
byId('cb2').checked = true
byId('cb3').checked = true
form.click()
this.server.respond()
values.should.deep.equal({ c1: ['cb1', 'cb2', 'cb3'] })
byId('cb1').checked = true
byId('cb2').checked = true
byId('cb3').checked = true
byId('cb4').checked = true
form.click()
this.server.respond()
values.should.deep.equal({ c1: ['cb1', 'cb2', 'cb3'], c2: 'cb4' })
byId('cb1').checked = true
byId('cb2').checked = true
byId('cb3').checked = true
byId('cb4').checked = true
byId('cb5').checked = true
form.click()
this.server.respond()
values.should.deep.equal({ c1: ['cb1', 'cb2', 'cb3'], c2: ['cb4', 'cb5'] })
byId('cb1').checked = true
byId('cb2').checked = true
byId('cb3').checked = true
byId('cb4').checked = true
byId('cb5').checked = true
byId('cb6').checked = true
form.click()
this.server.respond()
values.should.deep.equal({ c1: ['cb1', 'cb2', 'cb3'], c2: ['cb4', 'cb5'], c3: 'cb6' })
byId('cb1').checked = true
byId('cb2').checked = false
byId('cb3').checked = true
byId('cb4').checked = false
byId('cb5').checked = true
byId('cb6').checked = true
form.click()
this.server.respond()
values.should.deep.equal({ c1: ['cb1', 'cb3'], c2: 'cb5', c3: 'cb6' })
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
var form = make('<form hx-post="/test" hx-trigger="click">' +
'<div role="radiogroup">' +
'<input id="rb1" name="r1" value="rb1" type="radio">' +
'<input id="rb2" name="r1" value="rb2" type="radio">' +
'<input id="rb3" name="r1" value="rb3" type="radio">' +
'<input id="rb4" name="r2" value="rb4" type="radio">' +
'<input id="rb5" name="r2" value="rb5" type="radio">' +
'<input id="rb6" name="r3" value="rb6" type="radio">' +
'</div>' +
'</form>')
form.click()
this.server.respond()
values.should.deep.equal({})
byId('rb1').checked = true
form.click()
this.server.respond()
values.should.deep.equal({ r1: 'rb1' })
this.server.respondWith('GET', '/test', "<div id='d1' hx-trigger='click consume' hx-get='/test2'></div>fooo")
this.server.respondWith('GET', '/test2', 'clicked')
var div = make("<div hx-get='/test'/>")
div.click()
this.server.respond()
byId('d1').click()
this.server.respond()
byId('d1').innerHTML.should.equal('clicked')
var globalWasCalled = false
window.callGlobal = function() {
globalWasCalled = true
}
try {
this.server.respondWith('GET', '/test', "<div></div><script type='text/javascript'>callGlobal()</script>")
var div = make("<div hx-get='/test'></div>")
div.click()
this.server.respond()
globalWasCalled.should.equal(true)
} finally {
delete window.callGlobal
}
var globalWasCalled = false
window.callGlobal = function() {
globalWasCalled = true
}
try {
this.server.respondWith('GET', '/test', "<script type='text/javascript'>callGlobal()</script>")
var div = make("<div hx-get='/test'></div>")
div.click()
this.server.respond()
globalWasCalled.should.equal(true)
} finally {
delete window.callGlobal
}
try {
window.foo = {}
this.server.respondWith('GET', '/test', "<script type='text/javascript'>foo.bar = function() { return 42 }</script>")
var div = make("<div hx-get='/test'></div>")
div.click()
this.server.respond()
foo.bar().should.equal(42)
} finally {
delete window.foo
}
var globalWasCalled = false
window.callGlobal = function() {
globalWasCalled = true
}
try {
this.server.respondWith('GET', '/test', "<div><script type='text/javascript'>callGlobal()</script></div>")
var div = make("<div hx-get='/test'></div>")
div.click()
this.server.respond()
globalWasCalled.should.equal(true)
} finally {
delete window.callGlobal
}
var globalWasCalled = false
window.callGlobal = function() {
globalWasCalled = true
}
try {
this.server.respondWith('GET', '/test', "<script type='text/javascript'>callGlobal()</script><div></div>")
var div = make("<div hx-get='/test'></div>")
div.click()
this.server.respond()
globalWasCalled.should.equal(true)
} finally {
delete window.callGlobal
}
var globalWasCalled = false
window.callGlobal = function() {
globalWasCalled = true
}
try {
this.server.respondWith('GET', '/test', '<div><script>callGlobal()</script></div>')
var div = make("<div hx-get='/test'></div>")
div.click()
this.server.respond()
globalWasCalled.should.equal(true)
} finally {
delete window.callGlobal
}
var globalWasCalled = false
window.callGlobal = function() {
globalWasCalled = true
}
try {
this.server.respondWith('GET', '/test', "<div><script type='text/samplescript'>callGlobal()</script></div>")
var div = make("<div hx-get='/test'></div>")
div.click()
this.server.respond()
globalWasCalled.should.equal(false)
} finally {
delete window.callGlobal
}
window.callGlobal = function() {
console.log('Here...')
window.tempVal = byId('d1').innerText
}
try {
this.server.respondWith('GET', '/test', "<div><script>callGlobal()</script><div id='d1'>After settle...</div> </div>")
var div = make("<div hx-get='/test'></div>")
div.click()
this.server.respond()
window.tempVal.should.equal('After settle...')
} finally {
delete window.callGlobal
delete window.tempVal
}
var path = null
var div = make("<div hx-get=''/>")
htmx.on(div, 'htmx:configRequest', function(evt) {
path = evt.detail.path
return false
})
div.click()
this.server.respond()
path.should.not.be.null
var path = null
var div = make('<div hx-get/>')
htmx.on(div, 'htmx:configRequest', function(evt) {
path = evt.detail.path
return false
})
div.click()
this.server.respond()
path.should.not.be.null
this.server.respondWith('GET', '/test', "<input id='i1' value='bar'/>")
var input = make("<input id='i1' hx-get='/test' value='foo' hx-swap='outerHTML settle:50' hx-trigger='click'/>")
input.click()
this.server.respond()
input = byId('i1')
input.value.should.equal('bar')
this.server.respondWith('GET', '/test', "<input id='i2' value='bar' autofocus/>")
var input = make("<input id='i1' hx-get='/test' value='foo' hx-swap='afterend' hx-trigger='click'/>")
input.focus()
input.click()
document.activeElement.should.equal(input)
this.server.respond()
var input2 = byId('i2')
document.activeElement.should.equal(input2)
this.server.respondWith('GET', '/test', "<div><input id='i2' value='bar' autofocus/></div>")
var input = make("<input id='i1' hx-get='/test' value='foo' hx-swap='afterend' hx-trigger='click'/>")
input.focus()
input.click()
document.activeElement.should.equal(input)
this.server.respond()
var input2 = byId('i2')
document.activeElement.should.equal(input2)
this.server.respondWith('GET', '/test', "<div><input id='i2' value='bar' autofocus='true'/></div>")
var input = make("<input id='i1' hx-get='/test' value='foo' hx-swap='afterend' hx-trigger='click'/>")
input.focus()
input.click()
document.activeElement.should.equal(input)
this.server.respond()
var input2 = byId('i2')
document.activeElement.should.equal(input2)
this.server.respondWith('POST', '/test', function(xhr) {
should.equal(xhr.requestHeaders['Content-Type'], undefined)
if (xhr.requestBody.get) { // IE 11 does not support
xhr.requestBody.get('i1').should.equal('foo')
}
xhr.respond(200, {}, 'body: ' + xhr.requestBody)
})
var form = make("<form hx-post='/test' hx-encoding='multipart/form-data' hx-trigger='click'>" +
"<input name='i1' id='i1' value='foo'/>" +
'</form>')
form.focus()
form.click()
this.server.respond()
var count = 0
this.server.respondWith('GET', '/test', function(xhr) {
count++
xhr.respond(200, {}, '')
})
var btn = make('<button hx-get="/test">Click Me!</button>')
htmx.remove(btn)
btn.click()
this.server.respond()
count.should.equal(0)
this.server.respondWith('GET', '/test', function(xhr) {
xhr.respond(200, {}, "<title class=''>htmx rocks!</title>Clicked!")
})
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerText.should.equal('Clicked!')
window.document.title.should.equal('htmx rocks!')
var originalTitle = window.document.title
this.server.respondWith('GET', '/test', function(xhr) {
xhr.respond(200, {}, "<svg class=''><title>" + originalTitle + 'UPDATE' + '</title></svg>Clicked!')
})
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerText.should.equal('Clicked!')
window.document.title.should.equal(originalTitle)
var originalTitle = window.document.title
var newTitle = originalTitle + '!!!'
this.server.respondWith('GET', '/test', function(xhr) {
xhr.respond(200, {}, "<title class=''>" + newTitle + "</title><svg class=''><title>foo</title></svg>Clicked!<title class=''>x</title>")
})
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerText.should.equal('Clicked!')
window.document.title.should.equal(newTitle)
this.server.respondWith('GET', '/test', function(xhr) {
xhr.respond(200, {}, '<title></> htmx rocks!</title>Clicked!')
})
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerText.should.equal('Clicked!')
window.document.title.should.equal('</> htmx rocks!')
this.server.respondWith('GET', '/test', function(xhr) {
xhr.respond(400, {}, 'Clicked!')
})
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerText.should.equal('Click Me!')
var handler = htmx.on('htmx:beforeSwap', function(event) {
if (event.detail.xhr.status === 400) {
event.detail.shouldSwap = true
}
})
this.server.respondWith('GET', '/test', function(xhr) {
xhr.respond(400, {}, 'Clicked!')
})
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerText.should.equal('Clicked!')
htmx.off('htmx:beforeSwap', handler)
var handler = htmx.on('htmx:beforeSwap', function(event) {
if (event.detail.xhr.status === 400) {
event.detail.shouldSwap = true
event.detail.target = byId('d1')
}
})
this.server.respondWith('GET', '/test', function(xhr) {
xhr.respond(400, {}, 'Clicked!')
})
var btn = make('<button hx-get="/test">Click Me!</button>')
var div = make('<div id="d1"></div>')
btn.click()
this.server.respond()
div.innerText.should.equal('Clicked!')
htmx.off('htmx:beforeSwap', handler)
var errors = 0
var handler = htmx.on('htmx:responseError', function() {
errors++
})
this.server.respondWith('GET', '/test1', function(xhr) {
xhr.respond(204, {}, 'Clicked!')
})
this.server.respondWith('GET', '/test2', function(xhr) {
xhr.respond(400, {}, 'Clicked!')
})
var btn1 = make('<button hx-get="/test1">Click Me!</button>')
var btn2 = make('<button hx-get="/test2">Click Me!</button>')
btn1.click()
btn2.click()
this.server.respond()
this.server.respond()
errors.should.equal(1)
htmx.off('htmx:responseError', handler)
var handler = htmx.on('htmx:beforeSwap', function(event) {
if (event.detail.xhr.status === 400) {
event.detail.shouldSwap = true
event.detail.serverResponse = event.detail.serverResponse + '!!'
}
})
this.server.respondWith('GET', '/test', function(xhr) {
xhr.respond(400, {}, 'Clicked!')
})
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerText.should.equal('Clicked!!!')
htmx.off('htmx:beforeSwap', handler)
try {
this.server.respondWith('GET', '/test', "<script id='setGlobalScript' src='setGlobal.js'></script>")
var div = make("<div hx-get='/test'></div>")
div.click()
this.server.respond()
byId('setGlobalScript').addEventListener('load', function() {
window.globalWasCalled.should.equal(true)
delete window.globalWasCalled
done()
})
} finally {
delete window.globalWasCalled
}
this.server.respondWith('GET', '/test', '<with:colon id="foobar">Foobar</with:colon>')
var btn = make('<button hx-get="/test">Give me colons!</button>')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('<with:colon id="foobar">Foobar</with:colon>')
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
make('<form hx-post="/test">' +
'<input type="text" name="t1" value="textValue">' +
'<button id="submit" type="submit" name="b1" value="buttonValue">button</button>' +
'</form>')
byId('submit').click()
this.server.respond()
values.should.deep.equal({ t1: 'textValue', b1: 'buttonValue' })
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
make('<form hx-post="/test">' +
'<input type="text" name="t1" value="textValue">' +
'<input id="submit" type="submit" name="b1" value="buttonValue">' +
'</form>')
byId('submit').click()
this.server.respond()
values.should.deep.equal({ t1: 'textValue', b1: 'buttonValue' })
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
make('<form>' +
'<input type="text" name="t1" value="textValue">' +
'<button id="submit" type="submit" name="b1" value="buttonValue" hx-post="/test">button</button>' +
'</form>')
byId('submit').click()
this.server.respond()
values.should.deep.equal({ t1: 'textValue', b1: 'buttonValue' })
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
make('<form>' +
'<input type="text" name="t1" value="textValue">' +
'<input id="submit" type="submit" name="b1" value="buttonValue" hx-post="/test">' +
'</form>')
byId('submit').click()
this.server.respond()
values.should.deep.equal({ t1: 'textValue', b1: 'buttonValue' })
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
make('<form id="externalForm" hx-post="/test">' +
'<input type="text" name="t1" value="textValue">' +
'</form>' +
'<button id="submit" form="externalForm" type="submit" name="b1" value="buttonValue">button</button>')
byId('submit').click()
this.server.respond()
values.should.deep.equal({ t1: 'textValue', b1: 'buttonValue' })
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
make('<form id="externalForm" hx-post="/test">' +
'<input type="text" name="t1" value="textValue">' +
'</form>' +
'<input id="submit" form="externalForm" type="submit" name="b1" value="buttonValue">')
byId('submit').click()
this.server.respond()
values.should.deep.equal({ t1: 'textValue', b1: 'buttonValue' })
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
make('<form hx-post="/test">' +
'<input type="hidden" name="action" value="A">' +
'<button id="btnA" type="submit">A</button>' +
'<button id="btnB" type="submit" name="action" value="B">B</button>' +
'<button id="btnC" type="submit" name="action" value="C">C</button>' +
'</form>')
byId('btnA').click()
this.server.respond()
values.should.deep.equal({ action: 'A' })
byId('btnB').click()
this.server.respond()
values.should.deep.equal({ action: ['A', 'B'] })
byId('btnC').click()
this.server.respond()
values.should.deep.equal({ action: ['A', 'C'] })
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
make('<form hx-post="/test">' +
'<input type="hidden" name="action" value="A">' +
'<input id="btnA" type="submit">A</input>' +
'<input id="btnB" type="submit" name="action" value="B">B</input>' +
'<input id="btnC" type="submit" name="action" value="C">C</input>' +
'</form>')
byId('btnA').click()
this.server.respond()
values.should.deep.equal({ action: 'A' })
byId('btnB').click()
this.server.respond()
values.should.deep.equal({ action: ['A', 'B'] })
byId('btnC').click()
this.server.respond()
values.should.deep.equal({ action: ['A', 'C'] })
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
make('<form id="externalForm" hx-post="/test">' +
'<input type="text" name="t1" value="textValue">' +
'<input type="hidden" name="b1" value="inputValue">' +
'</form>' +
'<form hx-post="/test2">' +
'<button id="submit" form="externalForm" type="submit" name="b1" value="buttonValue">button</button>' +
'</form>')
byId('submit').click()
this.server.respond()
values.should.deep.equal({ t1: 'textValue', b1: ['inputValue', 'buttonValue'] })
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
make('<form id="externalForm" hx-post="/test">' +
'<input type="text" name="t1" value="textValue">' +
'<input type="hidden" name="b1" value="inputValue">' +
'</form>' +
'<form hx-post="/test2">' +
'<input id="submit" form="externalForm" type="submit" name="b1" value="buttonValue">' +
'</form>')
byId('submit').click()
this.server.respond()
values.should.deep.equal({ t1: 'textValue', b1: ['inputValue', 'buttonValue'] })
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
make('<form id="externalForm" hx-post="/test">' +
' <input type="hidden" name="b1" value="inputValue">' +
'</form>' +
'<input type="text" name="t1" value="textValue" form="externalForm">' +
'<select name="s1" form="externalForm">' +
' <option value="someValue"></option>' +
' <option value="selectValue" selected></option>' +
'</select>' +
'<button id="submit" form="externalForm" type="submit" name="b1" value="buttonValue">button</button>')
byId('submit').click()
this.server.respond()
values.should.deep.equal({ t1: 'textValue', b1: ['inputValue', 'buttonValue'], s1: 'selectValue' })
var values
this.server.respondWith('POST', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(200, {}, '')
})
make('<dialog><form hx-post="/test"><button id="submit" formmethod="dialog" name="foo" value="bar">submit</button></form></dialog>')
byId('submit').click()
this.server.respond()
values.should.deep.equal({ foo: 'bar' })
var responded = false
this.server.respondWith('GET', '/test', function(xhr) {
responded = true
xhr.respond(200, {}, '')
})
make('<dialog><form hx-get="/test"><button id="submit" formmethod="dialog">submit</button></form></dialog>')
byId('submit').click()
this.server.respond()
responded.should.equal(true)
const template = '<form ' +
'id="hello" ' +
'hx-target="#hello" ' +
'hx-select="#hello" ' +
'hx-swap="outerHTML" ' +
'hx-post="/test">\n' +
'<input id="input" type="text" name="name" />\n' +
'<button name="value" type="submit">Submit</button>\n' +
'</form>\n' +
'<button id="outside" name="outside" form="hello" type="submit">Outside</button>'
var values
this.server.respondWith('/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(200, {}, template)
})
make(template)
const button = byId('outside')
button.focus()
button.click()
this.server.respond()
values.should.deep.equal({ name: '', outside: '' })
button.focus()
button.click()
this.server.respond()
values.should.deep.equal({ name: '', outside: '' })
var responseCode = null
this.server.respondWith('GET', '/test', function(xhr, id) {
xhr.respond(responseCode, { 'Content-Type': 'text/html' }, '' + responseCode)
})
responseCode = 200 // 200 should cause a swap by default
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('200')
responseCode = 204 // 204 should not cause a swap by default
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('Click Me!')
responseCode = 300 // 300 should cause a swap by default
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('300')
responseCode = 400 // 400 should not cause a swap by default
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('Click Me!')
responseCode = 500 // 500 should not cause a swap by default
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('Click Me!')
var originalResponseHandling = htmx.config.responseHandling
try {
htmx.config.responseHandling = [{ code: '...', swap: true }]
var responseCode = null
this.server.respondWith('GET', '/test', function(xhr, id) {
xhr.respond(responseCode, { 'Content-Type': 'text/html' }, '' + responseCode)
})
responseCode = 200 // 200 should cause a swap by default
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('200')
responseCode = 203 // 203 should not cause a swap by default
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('203')
responseCode = 300 // 300 should cause a swap by default
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('300')
responseCode = 400 // 400 should not cause a swap by default
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('400')
responseCode = 500 // 500 should not cause a swap by default
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('500')
} finally {
htmx.config.responseHandling = originalResponseHandling
}
var originalResponseHandling = htmx.config.responseHandling
try {
htmx.config.responseHandling = originalResponseHandling.slice()
htmx.config.responseHandling.unshift({ code: '444', swap: true, target: '#a-div' })
var responseCode = null
this.server.respondWith('GET', '/test', function(xhr, id) {
xhr.respond(responseCode, { 'Content-Type': 'text/html' }, '' + responseCode)
})
responseCode = 444
var div = make('<div id="a-div">Another Div</div>')
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('Click Me!')
div.innerHTML.should.equal('444')
} finally {
htmx.config.responseHandling = originalResponseHandling
}
var originalResponseHandling = htmx.config.responseHandling
try {
htmx.config.responseHandling = originalResponseHandling.slice()
htmx.config.responseHandling.unshift({ code: '444', swap: true, target: '#a-div', swapOverride: 'outerHTML' })
var responseCode = null
this.server.respondWith('GET', '/test', function(xhr, id) {
xhr.respond(responseCode, { 'Content-Type': 'text/html' }, '' + responseCode)
})
responseCode = 444
var div = make('<div><div id="a-div">Another Div</div></div>')
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('Click Me!')
div.innerHTML.should.equal('444')
} finally {
htmx.config.responseHandling = originalResponseHandling
}
var originalResponseHandling = htmx.config.responseHandling
try {
htmx.config.responseHandling = originalResponseHandling.slice()
htmx.config.responseHandling.unshift({ code: '444', swap: true, select: '.foo' })
var responseCode = null
this.server.respondWith('GET', '/test', function(xhr, id) {
xhr.respond(responseCode, { 'Content-Type': 'text/html' }, "<div><a class='foo'>" + responseCode + '</a></div>')
})
responseCode = 444
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('<a class="foo">444</a>')
} finally {
htmx.config.responseHandling = originalResponseHandling
}
var originalResponseHandling = htmx.config.responseHandling
var originalTitle = document.title
try {
htmx.config.responseHandling = originalResponseHandling.slice()
htmx.config.responseHandling.unshift({ code: '444', swap: true, ignoreTitle: true })
var responseCode = null
this.server.respondWith('GET', '/test', function(xhr, id) {
xhr.respond(responseCode, { 'Content-Type': 'text/html' }, '<title>Should Not Be Set</title>' + responseCode)
})
responseCode = 444
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('444')
document.title.should.equal(originalTitle)
} finally {
htmx.config.responseHandling = originalResponseHandling
}
var originalResponseHandling = htmx.config.responseHandling
var errorDetected = false
var handler = htmx.on('htmx:responseError', function() {
errorDetected = true
})
try {
htmx.config.responseHandling = originalResponseHandling.slice()
htmx.config.responseHandling.unshift({ code: '444', swap: true, error: false })
var responseCode = null
this.server.respondWith('GET', '/test', function(xhr, id) {
xhr.respond(responseCode, { 'Content-Type': 'text/html' }, '' + responseCode)
})
responseCode = 444
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('444')
errorDetected.should.equal(false)
} finally {
htmx.off('htmx:responseError', handler)
htmx.config.responseHandling = originalResponseHandling
}
var originalResponseHandling = htmx.config.responseHandling
var myEventWasTriggered = false
var handler = htmx.on('myEvent', function() {
myEventWasTriggered = true
})
try {
htmx.config.responseHandling = originalResponseHandling.slice()
htmx.config.responseHandling.unshift({ code: '444', swap: false, error: false, event: 'myEvent' })
var responseCode = null
this.server.respondWith('GET', '/test', function(xhr, id) {
xhr.respond(responseCode, { 'Content-Type': 'text/html' }, '' + responseCode)
})
responseCode = 444
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('Click Me!')
myEventWasTriggered.should.equal(true)
} finally {
htmx.off('htmx:responseError', handler)
htmx.config.responseHandling = originalResponseHandling
}
this.server.respondWith('POST', '/test', 'post')
var div = make('<div hx-post="/test">click me</div>')
div.click()
this.server.respond()
div.innerHTML.should.equal('post')
this.server.respondWith('PUT', '/test', 'put')
var div = make('<div hx-put="/test">click me</div>')
div.click()
this.server.respond()
div.innerHTML.should.equal('put')
this.server.respondWith('PATCH', '/test', 'patch')
var div = make('<div hx-patch="/test">click me</div>')
div.click()
this.server.respond()
div.innerHTML.should.equal('patch')
this.server.respondWith('DELETE', '/test', 'delete')
var div = make('<div hx-delete="/test">click me</div>')
div.click()
this.server.respond()
div.innerHTML.should.equal('delete')
var input = make('<input name="foo" value="bar"/>')
var vals = htmx._('getInputValues')(input).values
vals.foo.should.equal('bar')
var input = make('<input name="foo" value="bar"/>')
var vals = htmx._('getInputValues')(input, 'get').values
vals.foo.should.equal('bar')
var form = make('<form><input id="i1" name="foo" value="bar"/><input id="i2" name="do" value="rey"/></form>')
var input = byId('i1')
var vals = htmx._('getInputValues')(input).values
vals.foo.should.equal('bar')
vals.do.should.equal('rey')
var form = make('<form><input id="i1" name="foo" value="bar"/><input id="i2" name="do" value="rey"/></form>')
var input = byId('i1')
var vals = htmx._('getInputValues')(input, 'get').values
vals.foo.should.equal('bar')
should.equal(vals.do, undefined)
var form = make('<form><div id="d1"/><input id="i2" name="do" value="rey"/></form>')
var div = byId('d1')
var vals = htmx._('getInputValues')(div, 'post').values
vals.do.should.equal('rey')
var form = make('<form><div id="d1"/><input id="i2" name="do" value="rey"/></form>')
var div = byId('d1')
var vals = htmx._('getInputValues')(div, 'get').values
should.equal(vals.do, undefined)
var form = make('<form><input id="i1" name="foo" value="bar"/><input id="i2" name="do" value="rey"/></form>')
var vals = htmx._('getInputValues')(form, 'get').values
vals.foo.should.equal('bar')
vals.do.should.equal('rey')
var form = make('<form><input id="i1" name="foo" value="bar"/><input id="i2" name="do" value="rey"/></form>')
var vals = htmx._('getInputValues')(form, 'post').values
vals.foo.should.equal('bar')
vals.do.should.equal('rey')
var form = make('<form><input id="i1" name="foo" value="bar"/><input id="i2" name="do" value="rey"/><input id="i2" name="do" value="rey"/></form>')
var vals = htmx._('getInputValues')(form).values
vals.foo.should.equal('bar')
vals.do.should.deep.equal(['rey', 'rey'])
var form = make('<form><input id="i1" name="foo" value="bar"/><input id="i2" name="do" value="rey1"/><input id="i3" name="do" value="rey2"/></form>')
var vals = htmx._('getInputValues')(byId('i3')).values
vals.foo.should.equal('bar')
vals.do.should.deep.equal(['rey1', 'rey2'])
var form = make('<form><input id="i1" name="do" value=""/><input id="i2" name="do" value="rey"/><input id="i3" name="do" value=""/></form>')
var vals = htmx._('getInputValues')(byId('i3')).values
vals.do.should.deep.equal(['', 'rey', ''])
var form = make('<form id="f1"><input id="i1" name="foo" value="bar"/><input id="i2" name="do" value="rey"/><input id="i2" name="do" value="rey"/></form>')
var div = make('<div hx-include="#f1"></div>')
var vals = htmx._('getInputValues')(div).values
vals.foo.should.equal('bar')
vals.do.should.deep.equal(['rey', 'rey'])
var form = make('<form id="f1"><input id="i1" name="foo" value="bar"/><input id="i2" name="do" value="rey"/><input id="i2" name="do" value="rey"/></form>')
var div = make('<div hx-include="#i1"></div>')
var vals = htmx._('getInputValues')(div).values
vals.foo.should.equal('bar')
should.equal(vals.do, undefined)
var form = make('<form id="f1"><input id="i1" name="foo" value="bar"/><input id="i2" name="do" value="rey"/><input id="i2" name="do" value="rey"/></form>')
var div = make('<div hx-include="#i1, #i2"></div>')
var vals = htmx._('getInputValues')(div).values
vals.foo.should.equal('bar')
vals.do.should.deep.equal(['rey', 'rey'])
var form = make('<form id="f1"><input id="i1" name="foo" value="bar"/><input id="i2" name="do" value="rey"/><input id="i2" name="do" value="rey"/></form>')
var div = make('<div hx-include="#i1, #i2, #f1"></div>')
var vals = htmx._('getInputValues')(div).values
vals.foo.should.equal('bar')
vals.do.should.deep.equal(['rey', 'rey'])
htmx._('urlEncode')({}).should.equal('')
htmx._('urlEncode')({ foo: 'bar' }).should.equal('foo=bar')
htmx._('urlEncode')({ foo: 'bar', do: 'rey' }).should.equal('foo=bar&do=rey')
htmx._('urlEncode')({ foo: 'bar', do: ['rey', 'blah'] }).should.equal('foo=bar&do=rey&do=blah')
var form = make('<form hx-get="/foo"><input id="i1" name="foo" value="bar"/><input id="i2" name="do" value="rey"/><button id="b1" name="btn" value="bar"></button></form>')
var input = byId('i1')
var button = byId('b1')
// Listen for focusin on form as it'll bubble up from the button, and htmx binds on the form itself
form.addEventListener('focusin', function() {
var vals = htmx._('getInputValues')(form).values
vals.foo.should.equal('bar')
vals.do.should.equal('rey')
vals.btn.should.equal('bar')
done()
}, { once: true })
button.focus()
// Headless / Hardly-throttled CPU might result in 'focusin' not being fired, double it just in case
htmx.trigger(button, 'focusin')
var form = make('<form hx-get="/foo"><input id="i1" name="foo" value="bar"/><input id="i2" name="do" value="rey"/><input type="submit" id="s1" name="s1" value="bar"/></form>')
var input = byId('i1')
var button = byId('s1')
// Listen for focusin on form as it'll bubble up from the button, and htmx binds on the form itself
form.addEventListener('focusin', function() {
var vals = htmx._('getInputValues')(form).values
vals.foo.should.equal('bar')
vals.do.should.equal('rey')
vals.s1.should.equal('bar')
done()
}, { once: true })
button.focus()
// Headless / Hardly-throttled CPU might result in 'focusin' not being fired, double it just in case
htmx.trigger(button, 'focusin')
var form = make('<form hx-get="/foo"><input id="i1" name="foo" value="bar"/><input id="i2" name="do" value="rey"/><input type="submit" id="s1" name="s1" value="bar"/></form>')
var input = byId('i1')
var button = byId('s1')
button.focus()
input.focus()
var vals = htmx._('getInputValues')(form).values
vals.foo.should.equal('bar')
vals.do.should.equal('rey')
should.equal(vals.s1, undefined)
var form = make('<form hx-get="/foo"><input id="i1" name="foo" value="bar"/><input id="i2" name="do" value="rey"/><input type="submit" id="s1" name="s1" value="bar"/></form>')
var anchor = make('<button id="a1"></button>')
var button = byId('s1')
button.focus()
anchor.focus()
var vals = htmx._('getInputValues')(form).values
vals.foo.should.equal('bar')
vals.do.should.equal('rey')
should.equal(vals.s1, undefined)
var form = make('<form hx-get="/foo"><input id="i1" name="foo" value="bar"/><button type="submit" id="btn1" name="do" value="rey"><div id="div1"><span id="span1"></span></div></button></form>')
var nestedElt = byId('span1')
nestedElt.click()
var vals = htmx._('getInputValues')(form).values
vals.do.should.equal('rey')
this.server.respondWith('GET', '/test?i1=value', function(xhr) {
xhr.respond(200, {}, 'Clicked!')
})
var form = make('<form hx-trigger="click" hx-get="/test"><input name="i1" value="value"/><button id="b1">Click Me!</button></form>')
form.click()
this.server.respond()
form.innerHTML.should.equal('Clicked!')
this.server.respondWith('GET', '/test', function(xhr) {
xhr.requestBody.should.equal('i1=value')
xhr.respond(200, {}, 'Clicked!')
})
var form = make('<form hx-trigger="click" hx-get="/test"><input name="i1" value="value"/><button id="b1">Click Me!</button></form>')
try {
htmx.config.methodsThatUseUrlParams = []
form.click()
this.server.respond()
form.innerHTML.should.equal('Clicked!')
} finally {
htmx.config.methodsThatUseUrlParams = ['get']
}
this.server.respondWith('DELETE', '/test', function(xhr) {
xhr.requestBody.should.equal('i1=value')
xhr.respond(200, {}, 'Clicked!')
})
var form = make('<form hx-trigger="click" hx-delete="/test"><input name="i1" value="value"/><button id="b1">Click Me!</button></form>')
form.click()
this.server.respond()
form.innerHTML.should.equal('Clicked!')
this.server.respondWith('DELETE', '/test?i1=value', function(xhr) {
xhr.respond(200, {}, 'Clicked!')
})
var form = make('<form hx-trigger="click" hx-delete="/test"><input name="i1" value="value"/><button id="b1">Click Me!</button></form>')
try {
htmx.config.methodsThatUseUrlParams.push('delete')
form.click()
this.server.respond()
form.innerHTML.should.equal('Clicked!')
} finally {
htmx.config.methodsThatUseUrlParams = ['get']
}
var input = make('<form><input name="foo" value="bar"/><fieldset disabled><input name="do" value="rey"/></fieldset></form>')
var vals = htmx._('getInputValues')(input, 'get').values
vals.foo.should.equal('bar')
should.equal(vals.do, undefined)
// See https://web.dev/articles/more-capable-form-controls
class TestElement extends HTMLElement {
static formAssociated = true
constructor() {
super()
this._form = null
}
formAssociatedCallback(form) {
if (this._form) {
this._form.removeEventListener('formdata', this.handleFormData)
}
this._form = form
this._form.addEventListener('formdata', this.handleFormData)
}
handleFormData({
formData
}) {
formData.append('foo', 'bar')
}
}
customElements.define('test-element', TestElement)
var form = make('<form hx-post="/test"><test-element></test-element></form>')
var vals = htmx._('getInputValues')(form, 'get').values
vals.foo.should.equal('bar')
var form = make('<form hx-post="/test"><input name="foo" value="bar"/></form>')
var vals = htmx._('getInputValues')(form, 'get').values
function updateToNull() { vals.foo = null }
updateToNull.should.not.throw()
vals.foo.should.equal('null')
var form = make('<input name="foo" value="bar"/>')
var vals = htmx._('getInputValues')(form, 'get').values
function makeSearchParams() { return new URLSearchParams(vals).toString() }
makeSearchParams.should.not.throw()
makeSearchParams().should.equal('foo=bar')
this.server.respondWith('GET', '/test?foo=bar&bar=foo&foo=bar&foo2=bar2', function(xhr) {
xhr.respond(200, {}, 'Clicked!')
})
var form = make('<form hx-get="/test">' +
'<input name="foo" value="bar">' +
'<input name="bar" value="foo">' +
'<input name="foo" value="bar">' +
'<input name="foo2" value="bar2">' +
'<button id="b1">Click Me!</button>' +
'</form>')
byId('b1').click()
this.server.respond()
form.innerHTML.should.equal('Clicked!')
this.server.respondWith('POST', '/test', function(xhr) {
xhr.requestBody.should.equal('foo=bar&bar=foo&foo=bar&foo2=bar2')
xhr.respond(200, {}, 'Clicked!')
})
var form = make('<form hx-post="/test">' +
'<input name="foo" value="bar">' +
'<input name="bar" value="foo">' +
'<input name="foo" value="bar">' +
'<input name="foo2" value="bar2">' +
'<button id="b1">Click Me!</button>' +
'</form>')
byId('b1').click()
this.server.respond()
form.innerHTML.should.equal('Clicked!')
this.server.respondWith('POST', '/test', function(xhr) {
should.equal(xhr.requestHeaders['Content-Type'], undefined)
const file = xhr.requestBody.get('file')
file.should.instanceOf(File)
file.name.should.equal('test.txt')
xhr.respond(200, {}, 'OK')
})
const form = make('<form hx-post="/test" hx-target="#result" hx-encoding="multipart/form-data">' +
'<input type="file" name="file">' +
'<button type="submit"></button>' +
'</form>')
const input = form.querySelector('input')
const file = new File(['Test'], 'test.txt', { type: 'text/plain' })
const dataTransfer = new DataTransfer()
dataTransfer.items.add(file)
input.files = dataTransfer.files
const result = make('<div id="result"></div>')
form.querySelector('button').click()
this.server.respond()
result.innerHTML.should.equal('OK')
this.server.respondWith('POST', '/test', function(xhr) {
should.equal(xhr.requestHeaders['Content-Type'], undefined)
const file = xhr.requestBody.get('file')
file.should.instanceOf(File)
file.name.should.equal('test.txt')
xhr.respond(200, {}, 'OK')
})
const div = make('<div hx-encoding="multipart/form-data"></div>')
htmx.ajax('POST', '/test', {
source: div,
values: {
file: new File(['Test'], 'test.txt', { type: 'text/plain' })
}
})
this.server.respond()
div.innerHTML.should.equal('OK')
this.server.respondWith('GET', '/test', function(xhr) {
xhr.requestHeaders['HX-Request'].should.be.equal('true')
xhr.respond(200, {}, '')
})
var div = make('<div hx-get="/test"></div>')
div.click()
this.server.respond()
this.server.respondWith('GET', '/test', function(xhr) {
xhr.requestHeaders['HX-Trigger'].should.equal('d1')
xhr.respond(200, {}, '')
})
var div = make('<div id="d1" hx-get="/test"></div>')
div.click()
this.server.respond()
this.server.respondWith('GET', '/test', function(xhr) {
xhr.requestHeaders['HX-Trigger-Name'].should.equal('n1')
xhr.respond(200, {}, '')
})
var div = make('<button name="n1" hx-get="/test"></button>')
div.click()
this.server.respond()
this.server.respondWith('GET', '/test', function(xhr) {
xhr.requestHeaders['HX-Target'].should.equal('d1')
xhr.respond(200, {}, '')
})
var div = make('<div hx-target="#d1" hx-get="/test"></div><div id="d1" ></div>')
div.click()
this.server.respond()
this.server.respondWith('GET', '/test', [200, { 'HX-Trigger': 'foo' }, ''])
var div = make('<div hx-get="/test"></div>')
var invokedEvent = false
div.addEventListener('foo', function(evt) {
invokedEvent = true
})
div.click()
this.server.respond()
invokedEvent.should.equal(true)
this.server.respondWith('GET', '/test', [200, { 'HX-Trigger': 'foo.bar' }, ''])
var div = make('<div hx-get="/test"></div>')
var invokedEvent = false
div.addEventListener('foo.bar', function(evt) {
invokedEvent = true
})
div.click()
this.server.respond()
invokedEvent.should.equal(true)
this.server.respondWith('GET', '/test', [200, { 'hx-trigger': 'foo' }, ''])
var div = make('<div hx-get="/test"></div>')
var invokedEvent = false
div.addEventListener('foo', function(evt) {
invokedEvent = true
})
div.click()
this.server.respond()
invokedEvent.should.equal(true)
this.server.respondWith('GET', '/test', [200, { 'HX-Trigger': 'namespace:foo' }, ''])
var div = make('<div hx-get="/test"></div>')
var invokedEvent = false
div.addEventListener('namespace:foo', function(evt) {
invokedEvent = true
})
div.click()
this.server.respond()
invokedEvent.should.equal(true)
this.server.respondWith('GET', '/test', [200, { 'HX-Trigger': '{"foo":null}' }, ''])
var div = make('<div hx-get="/test"></div>')
var invokedEvent = false
div.addEventListener('foo', function(evt) {
invokedEvent = true
should.equal(null, evt.detail.value)
evt.detail.elt.should.equal(div)
})
div.click()
this.server.respond()
invokedEvent.should.equal(true)
this.server.respondWith('GET', '/test', [200, { 'HX-Trigger': '{"foo":[1, 2, 3]}' }, ''])
var div = make('<div hx-get="/test"></div>')
var invokedEvent = false
div.addEventListener('foo', function(evt) {
invokedEvent = true
evt.detail.elt.should.equal(div)
evt.detail.value.should.deep.equal([1, 2, 3])
})
div.click()
this.server.respond()
invokedEvent.should.equal(true)
this.server.respondWith('GET', '/test', [200, { 'HX-Trigger': '{"foo":{"a":1, "b":2}}' }, ''])
var div = make('<div hx-get="/test"></div>')
var invokedEvent = false
div.addEventListener('foo', function(evt) {
invokedEvent = true
evt.detail.elt.should.equal(div)
evt.detail.a.should.equal(1)
evt.detail.b.should.equal(2)
})
div.click()
this.server.respond()
invokedEvent.should.equal(true)
this.server.respondWith('GET', '/test', [200, { 'HX-Trigger': '{"foo":{"target":"#testdiv"}}' }, ''])
var div = make('<div hx-get="/test"></div>')
var testdiv = make('<div id="testdiv"></div>')
var invokedEvent = false
testdiv.addEventListener('foo', function(evt) {
invokedEvent = true
evt.detail.elt.should.equal(testdiv)
})
div.click()
this.server.respond()
invokedEvent.should.equal(true)
this.server.respondWith('GET', '/test', [200, { 'HX-Trigger': '{not: valid}' }, ''])
var div = make('<div hx-get="/test"></div>')
div.click()
this.server.respond()
this.server.respondWith('GET', '/test', [200, { 'HX-Trigger': 'foo' }, ''])
var div = make('<div hx-swap="outerHTML" hx-get="/test"></div>')
var invokedEvent = false
var handler = htmx.on('foo', function(evt) {
invokedEvent = true
})
div.click()
this.server.respond()
invokedEvent.should.equal(true)
htmx.off('foo', handler)
this.server.respondWith('GET', '/test', [200, { 'HX-Trigger': 'foo, bar' }, ''])
var div = make('<div hx-get="/test"></div>')
var invokedEventFoo = false
var invokedEventBar = false
div.addEventListener('foo', function(evt) {
invokedEventFoo = true
})
div.addEventListener('bar', function(evt) {
invokedEventBar = true
})
div.click()
this.server.respond()
invokedEventFoo.should.equal(true)
invokedEventBar.should.equal(true)
this.server.respondWith('GET', '/test', [200, { 'HX-Trigger': 'foo,bar' }, ''])
var div = make('<div hx-get="/test"></div>')
var invokedEventFoo = false
var invokedEventBar = false
div.addEventListener('foo', function(evt) {
invokedEventFoo = true
})
div.addEventListener('bar', function(evt) {
invokedEventBar = true
})
div.click()
this.server.respond()
invokedEventFoo.should.equal(true)
invokedEventBar.should.equal(true)
this.server.respondWith('GET', '/test', [200, { 'HX-Trigger': 'foo.bar,bar.baz' }, ''])
var div = make('<div hx-get="/test"></div>')
var invokedEventFoo = false
var invokedEventBar = false
div.addEventListener('foo.bar', function(evt) {
invokedEventFoo = true
})
div.addEventListener('bar.baz', function(evt) {
invokedEventBar = true
})
div.click()
this.server.respond()
invokedEventFoo.should.equal(true)
invokedEventBar.should.equal(true)
this.server.respondWith('GET', '/test', [200, { 'HX-Trigger': 'namespace:foo,bar' }, ''])
var div = make('<div hx-get="/test"></div>')
var invokedEventFoo = false
var invokedEventBar = false
div.addEventListener('namespace:foo', function(evt) {
invokedEventFoo = true
})
div.addEventListener('bar', function(evt) {
invokedEventBar = true
})
div.click()
this.server.respond()
invokedEventFoo.should.equal(true)
invokedEventBar.should.equal(true)
this.server.respondWith('GET', '/test', [200, { 'HX-Retarget': '#d2' }, 'Result'])
var div1 = make('<div id="d1" hx-get="/test"></div>')
var div2 = make('<div id="d2"></div>')
div1.click()
this.server.respond()
div1.innerHTML.should.equal('')
div2.innerHTML.should.equal('Result')
this.server.respondWith('GET', '/test', [200, { 'HX-Reswap': 'innerHTML' }, 'Result'])
var div1 = make('<div id="d1" hx-get="/test" hx-swap="outerHTML"></div>')
div1.click()
this.server.respond()
div1.innerHTML.should.equal('Result')
this.server.respondWith('GET', '/test', [200, { 'HX-Reselect': '#d2' }, "<div id='d1'>foo</div><div id='d2'>bar</div>"])
var div = make('<div hx-get="/test" hx-select="#d1"></div>')
div.click()
this.server.respond()
div.innerHTML.should.equal('<div id="d2">bar</div>')
this.server.respondWith('GET', '/test', [200, { 'HX-Trigger-After-Swap': 'foo' }, ''])
var div = make('<div hx-swap="outerHTML" hx-get="/test"></div>')
var invokedEvent = false
var handler = htmx.on('foo', function(evt) {
invokedEvent = true
})
div.click()
this.server.respond()
invokedEvent.should.equal(true)
htmx.off('foo', handler)
this.server.respondWith('GET', '/test', [200, { 'HX-Trigger-After-Swap': 'foo, bar' }, ''])
var div = make('<div hx-swap="outerHTML" hx-get="/test"></div>')
var invokedEventFoo = false
var invokedEventBar = false
var handlerFoo = htmx.on('foo', function(evt) {
invokedEventFoo = true
})
var handlerBar = htmx.on('bar', function(evt) {
invokedEventBar = true
})
div.click()
this.server.respond()
invokedEventFoo.should.equal(true)
invokedEventBar.should.equal(true)
htmx.off('foo', handlerFoo)
htmx.off('bar', handlerBar)
this.server.respondWith('GET', '/test', [200, { 'HX-Trigger-After-Settle': 'foo' }, ''])
var div = make('<div hx-swap="outerHTML" hx-get="/test"></div>')
var invokedEvent = false
var handler = htmx.on('foo', function(evt) {
invokedEvent = true
})
div.click()
this.server.respond()
invokedEvent.should.equal(true)
htmx.off('foo', handler)
this.server.respondWith('GET', '/test', [200, { 'HX-Trigger-After-Settle': 'foo, bar' }, ''])
var div = make('<div hx-swap="outerHTML" hx-get="/test"></div>')
var invokedEventFoo = false
var invokedEventBar = false
var handlerFoo = htmx.on('foo', function(evt) {
invokedEventFoo = true
})
var handlerBar = htmx.on('bar', function(evt) {
invokedEventBar = true
})
div.click()
this.server.respond()
invokedEventFoo.should.equal(true)
invokedEventBar.should.equal(true)
htmx.off('foo', handlerFoo)
htmx.off('bar', handlerBar)
this.server.respondWith('GET', '/test', [200, { 'HX-Location': '{"path":"/test2", "target":"#testdiv"}' }, ''])
this.server.respondWith('GET', '/test2', [200, {}, '<div>Yay! Welcome</div>'])
var div = make('<div id="testdiv" hx-trigger="click" hx-get="/test"></div>')
div.click()
this.server.respond()
this.server.respond()
div.innerHTML.should.equal('<div>Yay! Welcome</div>')
this.server.respondWith('GET', '/test', function(xhr) {
xhr.requestHeaders['HX-Request'].should.be.equal('true')
xhr.respond(200, {}, '')
})
htmx._('loadHistoryFromServer')('/test')
this.server.respond()
this.server.respondWith('GET', '/test', function(xhr) {
xhr.requestHeaders['HX-History-Restore-Request'].should.be.equal('true')
xhr.respond(200, {}, '')
})
htmx._('loadHistoryFromServer')('/test')
this.server.respond()
this.server.respondWith('GET', '/test', function(xhr) {
chai.assert(typeof xhr.requestHeaders['HX-Current-URL'] !== 'undefined', 'HX-Current-URL should not be undefined')
xhr.respond(200, {}, '')
})
htmx._('loadHistoryFromServer')('/test')
this.server.respond()
var btn = make('<svg onclick="document.getElementById(\'contents\').classList.toggle(\'show\')" class="hamburger" viewBox="0 0 100 80" width="25" height="25" style="margin-bottom:-5px">\n' +
'<rect width="100" height="20" style="fill:rgb(52, 101, 164)" rx="10"></rect>\n' +
'<rect y="30" width="100" height="20" style="fill:rgb(52, 101, 164)" rx="10"></rect>\n' +
'<rect y="60" width="100" height="20" style="fill:rgb(52, 101, 164)" rx="10"></rect>\n' +
'</svg>')
this.server.respondWith('GET', '/index2a.php',
"<div id='message' hx-swap-oob='true'>I came from message oob swap I should be second</div>" +
"<div id='message2' hx-swap-oob='true'>I came from a message2 oob swap I should be third but I am in the wrong spot</div>" +
"I'm page2 content (non-swap) I should be first")
var h1 = make('' +
"<div id='page2' ></div>" +
"<div id='message'></div>" +
"<div id='message2'></div>" +
"<h1 hx-get='/index2a.php' hx-target='#page2' hx-trigger='click'>Kutty CLICK ME</h1>")
h1.click()
this.server.respond()
htmx.find('#page2').innerHTML.should.equal("I'm page2 content (non-swap) I should be first")
htmx.find('#message').innerHTML.should.equal('I came from message oob swap I should be second')
htmx.find('#message2').innerHTML.should.equal('I came from a message2 oob swap I should be third but I am in the wrong spot')
this.server.respondWith('POST', '/htmx.php', function(xhr) {
xhr.respond(200, {}, xhr.requestBody)
})
var form = make('<form hx-trigger="click" hx-post="/htmx.php">\n' +
'<input type="text" name="variable" value="">\n' +
'<button type="submit">Submit</button>\n' +
'</form>')
form.click()
this.server.respond()
form.innerHTML.should.equal('variable=')
this.server.respondWith('GET', '/test', 'Foo<form><input name="id"/></form>')
var div = make('<div hx-get="/test">Get It</div>')
div.click()
this.server.respond()
div.innerText.should.contain('Foo')
this.server.respondWith('GET', '/test', "Foo\n<div id=''></div>")
var div = make('<div hx-get="/test">Get It</div>')
div.click()
this.server.respond()
div.innerText.should.contain('Foo')
this.server.respondWith('GET', '/test', "Foo <div id='ViewModel.Test'></div>")
var div = make('<div hx-get="/test">Get It</div>')
div.click()
this.server.respond()
div.innerText.should.contain('Foo')
this.server.respondWith('GET', '/test', "<div id='d1' @foo='bar'>Foo</div>")
var div = make('<div hx-get="/test">Get It</div>')
div.click()
this.server.respond()
byId('d1').getAttribute('@foo').should.equal('bar')
this.server.respondWith('GET', '/test', "<div id='d1' @foo='bar'>Foo</div>")
var div = make('<div hx-get="/test"><div id="d1">Foo</div></div>')
div.click()
this.server.respond()
byId('d1').getAttribute('@foo').should.equal('bar')
this.server.respondWith('GET', '/test', "<div id='d1'>Replaced</div>")
var input = make('<input hx-trigger="click" hx-get="/test" id="i1" hx-swap="outerHTML">')
input.focus()
input.click()
this.server.respond()
byId('d1').innerText.should.equal('Replaced')
this.server.respondWith('POST', '/test', 'Submitted')
var defaultPrevented = false
htmx.on('click', function(evt) {
defaultPrevented = evt.defaultPrevented
})
var form = make('<form hx-post="/test" hx-trigger="click[false]"></form>')
form.click()
this.server.respond()
defaultPrevented.should.equal(true)
this.server.respondWith('GET', '/test', 'triggered')
make('<div id="d1" hx-trigger="click from:body" hx-get="/test"></div>' +
' <div id="d2" hx-trigger="click from:body" hx-get="/test"></div>')
var div1 = byId('d1')
var div2 = byId('d2')
document.body.click()
this.server.respond()
div2.innerHTML.should.equal('triggered')
div1.innerHTML.should.equal('triggered')
this.server.respondWith('POST', '/test', 'posted')
var form = make('<div id="d1"></div><form _="on htmx:afterRequest reset() me" hx-post="/test" hx-target="#d1">' +
' <input type="text" name="input" id="i1"/>' +
' <input type="submit" id="s1"/>' +
'</form>')
htmx.trigger(form, 'htmx:load') // have to manually trigger the load event for non-AJAX dynamic content
var div1 = byId('d1')
var input = byId('i1')
input.value = 'foo'
var submit = byId('s1')
input.value.should.equal('foo')
submit.click()
this.server.respond()
div1.innerHTML.should.equal('posted')
input.value.should.equal('') // form should be reset
this.server.respondWith('GET', '/test', 'triggered')
make('<div>' +
' <div id="d1"></div>' +
' <img src="img/bars.svg" usemap="#workmap" width="400" height="379">' +
'' +
' <map name="workmap">' +
' <area shape="rect" coords="34,44,270,350" alt="Computer" hx-get="/test" hx-target="#d1">' +
' </map>' +
'</div>')
var div1 = byId('d1')
var area = document.getElementsByTagName('area')[0]
area.click()
this.server.respond()
div1.innerHTML.should.equal('triggered')
this.server.respondWith('GET', '/test', "Foo<span id='example'>Bar</span>")
make('<form hx-select="#example">\n' +
' <button id="b1" hx-select="unset" hx-get="/test">Initial</button>\n' +
'</form>')
var btn = byId('b1')
btn.click()
this.server.respond()
btn.innerText.should.equal('FooBar')
const template = '<form id="formtest"> \n' +
'<input hx-get="/test" hx-target="#formtest" hx-trigger="click" type="text" id="id_email" value="test@test.com" />\n' +
'</form>'
const response = '<form id="formtest">\n' +
'<input hx-get="/test" hx-target="#formtest" hx-trigger="click" type="email" id="id_email" value="supertest@test.com" />\n' +
'</form>'
this.server.respondWith('GET', '/test', response)
make(template)
var input = byId('id_email')
// HTMX only attempts to restore the selection on inputs that have a current selection and are active.
// additionally we can't set the selection on email inputs (that's the whole bug) so start as a text input where you can set selection
// and replace with an email
input.focus()
input.selectionStart = 3
input.selectionEnd = 3
input.click()
this.server.respond()
var input = byId('id_email')
input.value.should.equal('supertest@test.com')
window.i = 0 // set count to 0
this.server.respondWith('GET', '/test', '<script>console.trace(); window.i++</script>') // increment the count by 1
// make a div w/ a short settle delay to make the problem more obvious
var div = make('<div hx-get="/test" hx-swap="innerHTML settle:5ms"/>')
div.click()
this.server.respond()
setTimeout(function() {
window.i.should.equal(1)
delete window.i
done()
}, 50)
window.i = 0 // set count to 0
this.server.respondWith('GET', '/test', '<p>foo</p><div><script>console.trace(); window.i++</script></div>') // increment the count by 1
// make a div w/ a short settle delay to make the problem more obvious
var div = make('<div hx-get="/test" hx-swap="innerHTML settle:5ms"/>')
div.click()
this.server.respond()
setTimeout(function() {
window.i.should.equal(1)
delete window.i
done()
}, 50)
htmx.config.allowScriptTags = false
window.i = 0 // set count to 0
this.server.respondWith('GET', '/test', '<script>console.trace(); window.i++</script>') // increment the count by 1
// make a div w/ a short settle delay to make the problem more obvious
var div = make('<div hx-get="/test" hx-swap="innerHTML settle:5ms"/>')
div.click()
this.server.respond()
setTimeout(function() {
window.i.should.equal(0)
htmx.config.allowScriptTags = true
delete window.i
done()
}, 50)
htmx.config.allowScriptTags = false
window.i = 0 // set count to 0
this.server.respondWith('GET', '/test', '<div><script>console.trace(); window.i++</script></div>') // increment the count by 1
// make a div w/ a short settle delay to make the problem more obvious
var div = make('<div hx-get="/test" hx-swap="innerHTML settle:5ms"/>')
div.click()
this.server.respond()
setTimeout(function() {
window.i.should.equal(0)
htmx.config.allowScriptTags = true
delete window.i
done()
}, 50)
this.server.respondWith('GET', '/test', 'Clicked!')
var btn = make('<button hx-disable hx-get="/test">Initial</button>')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('Initial')
this.server.respondWith('GET', '/test', 'Clicked!')
var div = make('<div hx-disable><button id="b1" hx-get="/test">Initial</button></div>')
var btn = byId('b1')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('Initial')
this.server.respondWith('GET', '/test', 'Clicked!')
var btn = make('<button id="b1" hx-get="/test">Initial</button>')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('Clicked!')
this.server.respondWith('GET', '/test', 'Clicked a second time')
btn.setAttribute('hx-disable', '')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('Clicked!')
this.server.respondWith('GET', '/test', 'Clicked!')
var btn = make('<button id="b1" hx-get="/test">Initial</button>')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('Clicked!')
this.server.respondWith('GET', '/test', 'Clicked a second time')
btn.setAttribute('hx-disable', '')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('Clicked!')
btn.removeAttribute('hx-disable')
htmx.process(btn)
btn.click()
this.server.respond()
btn.innerHTML.should.equal('Clicked a second time')
this.server.respondWith('GET', '/test', 'Clicked!')
var div = make('<div><button id="b1" hx-get="/test">Initial</button></div>')
var btn = byId('b1')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('Clicked!')
this.server.respondWith('GET', '/test', 'Clicked a second time')
div.setAttribute('hx-disable', '')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('Clicked!')
this.server.respondWith('GET', '/test', 'Clicked!')
var div = make('<div><button id="b1" hx-get="/test">Initial</button></div>')
var btn = byId('b1')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('Clicked!')
this.server.respondWith('GET', '/test', 'Clicked a second time')
div.setAttribute('hx-disable', '')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('Clicked!')
div.removeAttribute('hx-disable')
htmx.process(div)
btn.click()
this.server.respond()
btn.innerHTML.should.equal('Clicked a second time')
this.timeout(4000)
htmx.config.selfRequestsOnly = false
// should trigger send error, rather than reject
var listener = htmx.on('htmx:sendError', function() {
htmx.config.selfRequestsOnly = true
htmx.off('htmx:sendError', listener)
done()
})
this.server.restore() // use real xhrs
// will 404, but should respond
var btn = make('<button hx-get="https://hypermedia.systems/www/test">Initial</button>')
btn.click()
var btn = make("<button hx-disable hx-on:click='window.foo = true'>Foo</button>")
btn.click()
should.equal(window.foo, undefined)
delete window.foo
var div = make("<div hx-disable><button id='b1' hx-on:click='window.foo = true'>Foo</button></div>")
var btn = byId('b1')
btn.click()
should.equal(window.foo, undefined)
delete window.foo
var btn = make("<button hx-on:click='window.foo = true'>Foo</button>")
btn.click()
should.equal(window.foo, true)
delete window.foo
btn.setAttribute('hx-disable', '')
btn.click()
should.equal(window.foo, undefined)
delete window.foo
var div = make("<div><button id='b1' hx-on:click='window.foo = true'>Foo</button></div>")
var btn = byId('b1')
btn.click()
should.equal(window.foo, true)
delete window.foo
div.setAttribute('hx-disable', '')
btn.click()
should.equal(window.foo, undefined)
delete window.foo
this.timeout(4000)
// should trigger send error, rather than reject
var listener = htmx.on('htmx:invalidPath', function() {
htmx.off('htmx:invalidPath', listener)
done()
})
this.server.restore() // use real xhrs
// will 404, but should respond
var btn = make('<button hx-get="https://hypermedia.systems/www/test">Initial</button>')
btn.click()
this.timeout(4000)
// should trigger send error, rather than reject
var pathVerifier = htmx.on('htmx:validateUrl', function(evt) {
evt.preventDefault()
htmx.off('htmx:validateUrl', pathVerifier)
})
var listener = htmx.on('htmx:invalidPath', function() {
htmx.off('htmx:invalidPath', listener)
done()
})
this.server.restore() // use real xhrs
// will 404, but should respond
var btn = make('<button hx-get="https://hypermedia.systems/www/test">Initial</button>')
btn.click()
this.timeout(4000)
// should trigger send error, rather than reject
var pathVerifier = htmx.on('htmx:validateUrl', function(evt) {
if (evt.detail.sameHost === false) {
evt.preventDefault()
}
htmx.off('htmx:validateUrl', pathVerifier)
})
var listener = htmx.on('htmx:invalidPath', function() {
htmx.off('htmx:invalidPath', listener)
done()
})
this.server.restore() // use real xhrs
// will 404, but should respond
var btn = make('<button hx-get="https://hypermedia.systems/www/test">Initial</button>')
btn.click()
var globalWasCalled = false
window.callGlobal = function() {
globalWasCalled = true
}
try {
htmx.config.allowScriptTags = false
this.server.respondWith('GET', '/test', '<div><script>callGlobal()</script></div>')
var div = make("<div hx-get='/test'></div>")
div.click()
this.server.respond()
globalWasCalled.should.equal(false)
} finally {
htmx.config.allowScriptTags = true
delete window.callGlobal
}
var div = make('<div hx-target="root"></div>')
htmx.defineExtension('test/shadowdom.js', {
init: function(api) {
api.getTarget(div).should.equal(getWorkArea().shadowRoot)
}
})
var div = make('<div hx-target="global #work-area"></div>')
htmx.defineExtension('test/shadowdom.js', {
init: function(api) {
api.getTarget(div).should.equal(getWorkArea())
}
})
var div = make('<div hx-target="host"></div>')
htmx.defineExtension('test/shadowdom.js', {
init: function(api) {
api.getTarget(div).should.equal(getWorkArea())
}
})
this.server.respondWith('GET', '/test', 'Clicked!')
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('Clicked!')
this.server.respondWith('GET', '/test', '<a hx-get="/test2">Click Me</a>')
this.server.respondWith('GET', '/test2', 'Clicked!')
var div = make('<div hx-get="/test"></div>')
div.click()
this.server.respond()
div.innerHTML.should.equal('<a hx-get="/test2">Click Me</a>')
var a = div.querySelector('a')
a.click()
this.server.respond()
a.innerHTML.should.equal('Clicked!')
this.server.respondWith('GET', '/test', '<a id="a1" hx-get="/test2">Click Me</a>')
this.server.respondWith('GET', '/test2', 'Clicked!')
var div = make('<div id="d1" hx-get="/test" hx-swap="outerHTML"></div>')
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!')
var i = 0
this.server.respondWith('GET', '/test', function(xhr) {
i++
xhr.respond(200, {}, '<a id="a' + i + '" hx-get="/test2" hx-swap="innerHTML">' + i + '</a>')
})
this.server.respondWith('GET', '/test2', '*')
// extra wrapping div here because `ShadowRoot` doesn't support `innerText` or `child.parentElement`
var div = make('<div><div hx-get="/test" hx-swap="beforebegin">*</div></div>').children[0]
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('***')
var i = 0
this.server.respondWith('GET', '/test', function(xhr) {
i++
xhr.respond(200, {}, '' + i)
})
var div = make('<div hx-get="/test" hx-swap="afterbegin">*</div>')
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*')
var i = 0
this.server.respondWith('GET', '/test', function(xhr) {
i++
xhr.respond(200, {}, '' + i)
})
var div = make('<div hx-get="/test" hx-swap="afterbegin"></div>')
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')
var i = 0
this.server.respondWith('GET', '/test', function(xhr) {
i++
xhr.respond(200, {}, '<a id="a' + i + '" hx-get="/test2" hx-swap="innerHTML">' + i + '</a>')
})
this.server.respondWith('GET', '/test2', '*')
// extra wrapping div here because `ShadowRoot` doesn't support `innerText` or `child.parentElement`
var div = make('<div><div hx-get="/test" hx-swap="afterend">*</div></div>').children[0]
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('***')
var i = 0
this.server.respondWith('GET', '/test', function(xhr) {
i++
xhr.respond(200, {}, '' + i)
})
var div = make('<div hx-get="/test" hx-swap="beforeend">*</div>')
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')
var i = 0
this.server.respondWith('GET', '/test', function(xhr) {
i++
xhr.respond(200, {}, '' + i)
})
var div = make('<div hx-get="/test" hx-swap="beforeend"></div>')
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')
this.server.respondWith('GET', '/test', 'Clicked!')
var btn = make('<button hx-get="/test" hx-target="#s1">Click Me!</button>')
var target = make('<span id="s1">Initial</span>')
btn.click()
target.innerHTML.should.equal('Initial')
this.server.respond()
target.innerHTML.should.equal('Clicked!')
this.server.respondWith('GET', '/test', [204, {}, 'No Content!'])
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
btn.innerHTML.should.equal('Click Me!')
this.server.respond()
btn.innerHTML.should.equal('Click Me!')
this.server.respondWith('GET', '/test-1', [200, {}, 'Content for Tab 1'])
this.server.respondWith('GET', '/test-2', [200, {}, 'Content for Tab 2'])
var target = make('<div id="target"></div>')
var btn1 = make('<button hx-get="/test-1" hx-target="#target">Tab 1</button>')
var btn2 = make('<button hx-get="/test-2" hx-target="#target">Tab 2</button>')
btn1.click()
target.innerHTML.should.equal('')
this.server.respond()
target.innerHTML.should.equal('Content for Tab 1')
btn2.click()
this.server.respond()
target.innerHTML.should.equal('Content for Tab 2')
this.server.respondWith('GET', '/test-1', [304, {}, 'Content for Tab 1'])
this.server.respondWith('GET', '/test-2', [304, {}, 'Content for Tab 2'])
btn1.click()
this.server.respond()
target.innerHTML.should.equal('Content for Tab 1')
btn2.click()
this.server.respond()
target.innerHTML.should.equal('Content for Tab 2')
this.server.respondWith('GET', '/test', 'Clicked!')
var form = make('<form hx-get="/test" hx-trigger="click">Click Me!</form>')
form.click()
form.innerHTML.should.equal('Click Me!')
this.server.respond()
form.innerHTML.should.equal('Clicked!')
this.server.respondWith('GET', '/test', 'Loaded!')
var div = make('<div hx-get="/test" hx-trigger="load">Load Me!</div>')
div.innerHTML.should.equal('Load Me!')
this.server.respond()
div.innerHTML.should.equal('Loaded!')
this.server.respondWith('GET', '/test', function(xhr) {
xhr.respond(200, {}, 'done')
xhr.overriddenMimeType.should.equal('text/html')
done()
})
var div = make('<div hx-get="/test">Click Me!</div>')
div.click()
this.server.respond()
var i = 1
this.server.respondWith('GET', '/test', function(xhr) {
xhr.respond(200, {}, 'click ' + i)
i++
})
var div = make('<div hx-get="/test"></div>')
div.click()
div.click()
this.server.respond()
div.innerHTML.should.equal('click 1')
this.server.respond()
div.innerHTML.should.equal('click 2')
var i = 1
this.server.respondWith('GET', '/test', function(xhr) {
xhr.respond(200, {}, 'click ' + i)
i++
})
var div = make('<div hx-get="/test"></div>')
div.click()
div.click()
div.click()
this.server.respondAll()
div.innerHTML.should.equal('click 2')
var i = 1
this.server.respondWith('GET', '/test', "<div id='d1'>foo</div><div id='d2'>bar</div>")
var div = make('<div hx-get="/test" hx-select="#d1"></div>')
div.click()
this.server.respond()
div.innerHTML.should.equal('<div id="d1">foo</div>')
this.server.respondWith('GET', '/test', "<html><body><div id='d1'>foo</div><div id='d2'>bar</div></body></html>")
var div = make('<div hx-get="/test" hx-select="#d1"></div>')
div.click()
this.server.respond()
div.innerHTML.should.equal('<div id="d1">foo</div>')
this.server.respondWith('GET', '/test', "<div hx-get='/test'><div width='bar' id='d1'></div></div>")
var div = make("<div hx-get='/test' hx-swap='outerHTML settle:10ms'><div id='d1'></div></div>")
div.click()
this.server.respond()
should.equal(byId('d1').getAttribute('width'), null)
setTimeout(function() {
should.equal(byId('d1').getAttribute('width'), 'bar')
done()
}, 20)
this.server.respondWith('GET', '/test', "<div hx-get='/test'><div width='bar' id=\"d1'\"></div></div>")
var div = make("<div hx-get='/test' hx-swap='outerHTML settle:10ms'><div id=\"d1'\"></div></div>")
div.click()
this.server.respond()
should.equal(byId("d1'").getAttribute('width'), null)
setTimeout(function() {
should.equal(byId("d1'").getAttribute('width'), 'bar')
done()
}, 20)
this.server.respondWith('GET', '/test', "<div hx-get='/test'><div width='bar' id='d1\"'></div></div>")
var div = make("<div hx-get='/test' hx-swap='outerHTML settle:10ms'><div id='d1\"'></div></div>")
div.click()
this.server.respond()
should.equal(byId('d1"').getAttribute('width'), null)
setTimeout(function() {
should.equal(byId('d1"').getAttribute('width'), 'bar')
done()
}, 20)
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
var form = make('<form hx-post="/test" hx-trigger="click">' +
'<select id="multiSelect" name="multiSelect" multiple="multiple">' +
'<option id="m1" value="m1">m1</option>' +
'<option id="m2" value="m2">m2</option>' +
'<option id="m3" value="m3">m3</option>' +
'<option id="m4" value="m4">m4</option>' +
'</select>' +
'</form>')
form.click()
this.server.respond()
values.should.deep.equal({})
byId('m1').selected = true
form.click()
this.server.respond()
values.should.deep.equal({ multiSelect: 'm1' })
byId('m1').selected = true
byId('m3').selected = true
form.click()
this.server.respond()
values.should.deep.equal({ multiSelect: ['m1', 'm3'] })
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
var form = make('<form hx-post="/test" hx-trigger="click">' +
'<select name="multiSelect" id="id_question_list" multiple="" tabindex="-1" aria-hidden="true">' +
'<option id="m1" value="m1">m1</option>' +
'<option id="m2" value="m2">m2</option>' +
'<option id="m3" value="m3">m3</option>' +
'<option id="m4" value="m4">m4</option>' +
'</select>' +
'</form>')
form.click()
this.server.respond()
values.should.deep.equal({})
byId('m1').selected = true
form.click()
this.server.respond()
values.should.deep.equal({ multiSelect: 'm1' })
byId('m1').selected = true
byId('m3').selected = true
form.click()
this.server.respond()
values.should.deep.equal({ multiSelect: ['m1', 'm3'] })
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
var form = make('<form hx-post="/test" hx-trigger="click">' +
'<select id="multiSelect" name="multiSelect" multiple="multiple">' +
'<option id="m1" value="m1">m1</option>' +
'<option id="m2" value="m2">m2</option>' +
'<option id="m3" value="m3">m3</option>' +
'<option id="m4" value="m4">m4</option>' +
'</select>' +
'<select id="multiSelect" name="multiSelect" multiple="multiple">' +
'<option id="m5" value="m5">m1</option>' +
'<option id="m6" value="m6">m2</option>' +
'<option id="m7" value="m7">m3</option>' +
'<option id="m8" value="m8">m4</option>' +
'</select>' +
'</form>')
form.click()
this.server.respond()
values.should.deep.equal({})
byId('m1').selected = true
form.click()
this.server.respond()
values.should.deep.equal({ multiSelect: 'm1' })
byId('m1').selected = true
byId('m3').selected = true
byId('m7').selected = true
byId('m8').selected = true
form.click()
this.server.respond()
values.should.deep.equal({ multiSelect: ['m1', 'm3', 'm7', 'm8'] })
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
var form = make('<form hx-post="/test" hx-trigger="click">' +
'<input id="multiEmail" name="multiEmail" multiple>' +
'</form>')
form.click()
this.server.respond()
values.should.deep.equal({ multiEmail: '' })
byId('multiEmail').value = 'foo@example.com'
form.click()
this.server.respond()
values.should.deep.equal({ multiEmail: 'foo@example.com' })
byId('multiEmail').value = 'foo@example.com,bar@example.com'
form.click()
this.server.respond()
values.should.deep.equal({ multiEmail: 'foo@example.com,bar@example.com' })
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
var form = make('<form hx-post="/test" hx-trigger="click">' +
'<input id="cb1" name="c1" value="cb1" type="checkbox">' +
'<input id="cb2" name="c1" value="cb2" type="checkbox">' +
'<input id="cb3" name="c1" value="cb3" type="checkbox">' +
'<input id="cb4" name="c2" value="cb4" type="checkbox">' +
'<input id="cb5" name="c2" value="cb5" type="checkbox">' +
'<input id="cb6" name="c3" value="cb6" type="checkbox">' +
'</form>')
form.click()
this.server.respond()
values.should.deep.equal({})
byId('cb1').checked = true
form.click()
this.server.respond()
values.should.deep.equal({ c1: 'cb1' })
byId('cb1').checked = true
byId('cb2').checked = true
form.click()
this.server.respond()
values.should.deep.equal({ c1: ['cb1', 'cb2'] })
byId('cb1').checked = true
byId('cb2').checked = true
byId('cb3').checked = true
form.click()
this.server.respond()
values.should.deep.equal({ c1: ['cb1', 'cb2', 'cb3'] })
byId('cb1').checked = true
byId('cb2').checked = true
byId('cb3').checked = true
byId('cb4').checked = true
form.click()
this.server.respond()
values.should.deep.equal({ c1: ['cb1', 'cb2', 'cb3'], c2: 'cb4' })
byId('cb1').checked = true
byId('cb2').checked = true
byId('cb3').checked = true
byId('cb4').checked = true
byId('cb5').checked = true
form.click()
this.server.respond()
values.should.deep.equal({ c1: ['cb1', 'cb2', 'cb3'], c2: ['cb4', 'cb5'] })
byId('cb1').checked = true
byId('cb2').checked = true
byId('cb3').checked = true
byId('cb4').checked = true
byId('cb5').checked = true
byId('cb6').checked = true
form.click()
this.server.respond()
values.should.deep.equal({ c1: ['cb1', 'cb2', 'cb3'], c2: ['cb4', 'cb5'], c3: 'cb6' })
byId('cb1').checked = true
byId('cb2').checked = false
byId('cb3').checked = true
byId('cb4').checked = false
byId('cb5').checked = true
byId('cb6').checked = true
form.click()
this.server.respond()
values.should.deep.equal({ c1: ['cb1', 'cb3'], c2: 'cb5', c3: 'cb6' })
this.server.respondWith('GET', '/test', "<div id='d1' hx-trigger='click consume' hx-get='/test2'></div>fooo")
this.server.respondWith('GET', '/test2', 'clicked')
var div = make("<div hx-get='/test'/>")
div.click()
this.server.respond()
byId('d1').click()
this.server.respond()
byId('d1').innerHTML.should.equal('clicked')
var globalWasCalled = false
window.callGlobal = function() {
globalWasCalled = true
}
try {
this.server.respondWith('GET', '/test', "<div></div><script type='text/javascript'>callGlobal()</script>")
var div = make("<div hx-get='/test'></div>")
div.click()
this.server.respond()
globalWasCalled.should.equal(true)
} finally {
delete window.callGlobal
}
var globalWasCalled = false
window.callGlobal = function() {
globalWasCalled = true
}
try {
this.server.respondWith('GET', '/test', "<script type='text/javascript'>callGlobal()</script>")
var div = make("<div hx-get='/test'></div>")
div.click()
this.server.respond()
globalWasCalled.should.equal(true)
} finally {
delete window.callGlobal
}
try {
window.foo = {}
this.server.respondWith('GET', '/test', "<script type='text/javascript'>foo.bar = function() { return 42 }</script>")
var div = make("<div hx-get='/test'></div>")
div.click()
this.server.respond()
foo.bar().should.equal(42)
} finally {
delete window.foo
}
var globalWasCalled = false
window.callGlobal = function() {
globalWasCalled = true
}
try {
this.server.respondWith('GET', '/test', "<div><script type='text/javascript'>callGlobal()</script></div>")
var div = make("<div hx-get='/test'></div>")
div.click()
this.server.respond()
globalWasCalled.should.equal(true)
} finally {
delete window.callGlobal
}
var globalWasCalled = false
window.callGlobal = function() {
globalWasCalled = true
}
try {
this.server.respondWith('GET', '/test', "<script type='text/javascript'>callGlobal()</script><div></div>")
var div = make("<div hx-get='/test'></div>")
div.click()
this.server.respond()
globalWasCalled.should.equal(true)
} finally {
delete window.callGlobal
}
var globalWasCalled = false
window.callGlobal = function() {
globalWasCalled = true
}
try {
this.server.respondWith('GET', '/test', '<div><script>callGlobal()</script></div>')
var div = make("<div hx-get='/test'></div>")
div.click()
this.server.respond()
globalWasCalled.should.equal(true)
} finally {
delete window.callGlobal
}
var globalWasCalled = false
window.callGlobal = function() {
globalWasCalled = true
}
try {
this.server.respondWith('GET', '/test', "<div><script type='text/samplescript'>callGlobal()</script></div>")
var div = make("<div hx-get='/test'></div>")
div.click()
this.server.respond()
globalWasCalled.should.equal(false)
} finally {
delete window.callGlobal
}
window.callGlobal = function() {
console.log('Here...')
window.tempVal = byId('d1').innerText
}
try {
this.server.respondWith('GET', '/test', "<div><script>callGlobal()</script><div id='d1'>After settle...</div> </div>")
var div = make("<div hx-get='/test'></div>")
div.click()
this.server.respond()
window.tempVal.should.equal('After settle...')
} finally {
delete window.callGlobal
delete window.tempVal
}
var path = null
var div = make("<div hx-get=''/>")
htmx.on(div, 'htmx:configRequest', function(evt) {
path = evt.detail.path
return false
})
div.click()
this.server.respond()
path.should.not.be.null
var path = null
var div = make('<div hx-get/>')
htmx.on(div, 'htmx:configRequest', function(evt) {
path = evt.detail.path
return false
})
div.click()
this.server.respond()
path.should.not.be.null
this.server.respondWith('GET', '/test', "<input id='i1' value='bar'/>")
var input = make("<input id='i1' hx-get='/test' value='foo' hx-swap='outerHTML settle:50' hx-trigger='click'/>")
input.click()
this.server.respond()
input = byId('i1')
input.value.should.equal('bar')
this.server.respondWith('GET', '/test', "<input id='i2' value='bar' autofocus/>")
var input = make("<input id='i1' hx-get='/test' value='foo' hx-swap='afterend' hx-trigger='click'/>")
input.focus()
input.click()
getWorkArea().shadowRoot.activeElement.should.equal(input)
this.server.respond()
var input2 = byId('i2')
getWorkArea().shadowRoot.activeElement.should.equal(input2)
this.server.respondWith('GET', '/test', "<div><input id='i2' value='bar' autofocus/></div>")
var input = make("<input id='i1' hx-get='/test' value='foo' hx-swap='afterend' hx-trigger='click'/>")
input.focus()
input.click()
getWorkArea().shadowRoot.activeElement.should.equal(input)
this.server.respond()
var input2 = byId('i2')
getWorkArea().shadowRoot.activeElement.should.equal(input2)
this.server.respondWith('GET', '/test', "<div><input id='i2' value='bar' autofocus='true'/></div>")
var input = make("<input id='i1' hx-get='/test' value='foo' hx-swap='afterend' hx-trigger='click'/>")
input.focus()
input.click()
getWorkArea().shadowRoot.activeElement.should.equal(input)
this.server.respond()
var input2 = byId('i2')
getWorkArea().shadowRoot.activeElement.should.equal(input2)
this.server.respondWith('POST', '/test', function(xhr) {
should.equal(xhr.requestHeaders['Content-Type'], undefined)
if (xhr.requestBody.get) { // IE 11 does not support
xhr.requestBody.get('i1').should.equal('foo')
}
xhr.respond(200, {}, 'body: ' + xhr.requestBody)
})
var form = make("<form hx-post='/test' hx-encoding='multipart/form-data' hx-trigger='click'>" +
"<input name='i1' id='i1' value='foo'/>" +
'</form>')
form.focus()
form.click()
this.server.respond()
var count = 0
this.server.respondWith('GET', '/test', function(xhr) {
count++
xhr.respond(200, {}, '')
})
var btn = make('<button hx-get="/test">Click Me!</button>')
htmx.remove(btn)
btn.click()
this.server.respond()
count.should.equal(0)
this.server.respondWith('GET', '/test', function(xhr) {
xhr.respond(200, {}, "<title class=''>htmx rocks!</title>Clicked!")
})
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerText.should.equal('Clicked!')
window.document.title.should.equal('htmx rocks!')
var originalTitle = window.document.title
this.server.respondWith('GET', '/test', function(xhr) {
xhr.respond(200, {}, "<svg class=''><title>" + originalTitle + 'UPDATE' + '</title></svg>Clicked!')
})
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerText.should.equal('Clicked!')
window.document.title.should.equal(originalTitle)
var originalTitle = window.document.title
var newTitle = originalTitle + '!!!'
this.server.respondWith('GET', '/test', function(xhr) {
xhr.respond(200, {}, "<title class=''>" + newTitle + "</title><svg class=''><title>foo</title></svg>Clicked!<title class=''>x</title>")
})
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerText.should.equal('Clicked!')
window.document.title.should.equal(newTitle)
this.server.respondWith('GET', '/test', function(xhr) {
xhr.respond(200, {}, '<title></> htmx rocks!</title>Clicked!')
})
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerText.should.equal('Clicked!')
window.document.title.should.equal('</> htmx rocks!')
this.server.respondWith('GET', '/test', function(xhr) {
xhr.respond(400, {}, 'Clicked!')
})
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerText.should.equal('Click Me!')
var handler = htmx.on('htmx:beforeSwap', function(event) {
if (event.detail.xhr.status === 400) {
event.detail.shouldSwap = true
}
})
this.server.respondWith('GET', '/test', function(xhr) {
xhr.respond(400, {}, 'Clicked!')
})
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerText.should.equal('Clicked!')
htmx.off('htmx:beforeSwap', handler)
var handler = htmx.on('htmx:beforeSwap', function(event) {
if (event.detail.xhr.status === 400) {
event.detail.shouldSwap = true
event.detail.target = byId('d1')
}
})
this.server.respondWith('GET', '/test', function(xhr) {
xhr.respond(400, {}, 'Clicked!')
})
var btn = make('<button hx-get="/test">Click Me!</button>')
var div = make('<div id="d1"></div>')
btn.click()
this.server.respond()
div.innerText.should.equal('Clicked!')
htmx.off('htmx:beforeSwap', handler)
var errors = 0
var handler = htmx.on('htmx:responseError', function() {
errors++
})
this.server.respondWith('GET', '/test1', function(xhr) {
xhr.respond(204, {}, 'Clicked!')
})
this.server.respondWith('GET', '/test2', function(xhr) {
xhr.respond(400, {}, 'Clicked!')
})
var btn1 = make('<button hx-get="/test1">Click Me!</button>')
var btn2 = make('<button hx-get="/test2">Click Me!</button>')
btn1.click()
btn2.click()
this.server.respond()
this.server.respond()
errors.should.equal(1)
htmx.off('htmx:responseError', handler)
var handler = htmx.on('htmx:beforeSwap', function(event) {
if (event.detail.xhr.status === 400) {
event.detail.shouldSwap = true
event.detail.serverResponse = event.detail.serverResponse + '!!'
}
})
this.server.respondWith('GET', '/test', function(xhr) {
xhr.respond(400, {}, 'Clicked!')
})
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerText.should.equal('Clicked!!!')
htmx.off('htmx:beforeSwap', handler)
this.server.respondWith('GET', '/test', '<with:colon id="foobar">Foobar</with:colon>')
var btn = make('<button hx-get="/test">Give me colons!</button>')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('<with:colon id="foobar">Foobar</with:colon>')
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
make('<form hx-post="/test">' +
'<input type="text" name="t1" value="textValue">' +
'<button id="submit" type="submit" name="b1" value="buttonValue">button</button>' +
'</form>')
byId('submit').click()
this.server.respond()
values.should.deep.equal({ t1: 'textValue', b1: 'buttonValue' })
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
make('<form hx-post="/test">' +
'<input type="text" name="t1" value="textValue">' +
'<input id="submit" type="submit" name="b1" value="buttonValue">' +
'</form>')
byId('submit').click()
this.server.respond()
values.should.deep.equal({ t1: 'textValue', b1: 'buttonValue' })
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
make('<form>' +
'<input type="text" name="t1" value="textValue">' +
'<button id="submit" type="submit" name="b1" value="buttonValue" hx-post="/test">button</button>' +
'</form>')
byId('submit').click()
this.server.respond()
values.should.deep.equal({ t1: 'textValue', b1: 'buttonValue' })
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
make('<form>' +
'<input type="text" name="t1" value="textValue">' +
'<input id="submit" type="submit" name="b1" value="buttonValue" hx-post="/test">' +
'</form>')
byId('submit').click()
this.server.respond()
values.should.deep.equal({ t1: 'textValue', b1: 'buttonValue' })
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
make('<form id="externalForm" hx-post="/test">' +
'<input type="text" name="t1" value="textValue">' +
'</form>' +
'<button id="submit" form="externalForm" type="submit" name="b1" value="buttonValue">button</button>')
byId('submit').click()
this.server.respond()
values.should.deep.equal({ t1: 'textValue', b1: 'buttonValue' })
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
make('<form id="externalForm" hx-post="/test">' +
'<input type="text" name="t1" value="textValue">' +
'</form>' +
'<input id="submit" form="externalForm" type="submit" name="b1" value="buttonValue">')
byId('submit').click()
this.server.respond()
values.should.deep.equal({ t1: 'textValue', b1: 'buttonValue' })
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
make('<form hx-post="/test">' +
'<input type="hidden" name="action" value="A">' +
'<button id="btnA" type="submit">A</button>' +
'<button id="btnB" type="submit" name="action" value="B">B</button>' +
'<button id="btnC" type="submit" name="action" value="C">C</button>' +
'</form>')
byId('btnA').click()
this.server.respond()
values.should.deep.equal({ action: 'A' })
byId('btnB').click()
this.server.respond()
values.should.deep.equal({ action: ['A', 'B'] })
byId('btnC').click()
this.server.respond()
values.should.deep.equal({ action: ['A', 'C'] })
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
make('<form hx-post="/test">' +
'<input type="hidden" name="action" value="A">' +
'<input id="btnA" type="submit">A</input>' +
'<input id="btnB" type="submit" name="action" value="B">B</input>' +
'<input id="btnC" type="submit" name="action" value="C">C</input>' +
'</form>')
byId('btnA').click()
this.server.respond()
values.should.deep.equal({ action: 'A' })
byId('btnB').click()
this.server.respond()
values.should.deep.equal({ action: ['A', 'B'] })
byId('btnC').click()
this.server.respond()
values.should.deep.equal({ action: ['A', 'C'] })
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
make('<form id="externalForm" hx-post="/test">' +
'<input type="text" name="t1" value="textValue">' +
'<input type="hidden" name="b1" value="inputValue">' +
'</form>' +
'<form hx-post="/test2">' +
'<button id="submit" form="externalForm" type="submit" name="b1" value="buttonValue">button</button>' +
'</form>')
byId('submit').click()
this.server.respond()
values.should.deep.equal({ t1: 'textValue', b1: ['inputValue', 'buttonValue'] })
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
make('<form id="externalForm" hx-post="/test">' +
'<input type="text" name="t1" value="textValue">' +
'<input type="hidden" name="b1" value="inputValue">' +
'</form>' +
'<form hx-post="/test2">' +
'<input id="submit" form="externalForm" type="submit" name="b1" value="buttonValue">' +
'</form>')
byId('submit').click()
this.server.respond()
values.should.deep.equal({ t1: 'textValue', b1: ['inputValue', 'buttonValue'] })
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
make('<form id="externalForm" hx-post="/test">' +
' <input type="hidden" name="b1" value="inputValue">' +
'</form>' +
'<input type="text" name="t1" value="textValue" form="externalForm">' +
'<select name="s1" form="externalForm">' +
' <option value="someValue"></option>' +
' <option value="selectValue" selected></option>' +
'</select>' +
'<button id="submit" form="externalForm" type="submit" name="b1" value="buttonValue">button</button>')
byId('submit').click()
this.server.respond()
values.should.deep.equal({ t1: 'textValue', b1: ['inputValue', 'buttonValue'], s1: 'selectValue' })
var values
this.server.respondWith('POST', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(200, {}, '')
})
make('<dialog><form hx-post="/test"><button id="submit" formmethod="dialog" name="foo" value="bar">submit</button></form></dialog>')
byId('submit').click()
this.server.respond()
values.should.deep.equal({ foo: 'bar' })
var responded = false
this.server.respondWith('GET', '/test', function(xhr) {
responded = true
xhr.respond(200, {}, '')
})
make('<dialog><form hx-get="/test"><button id="submit" formmethod="dialog">submit</button></form></dialog>')
byId('submit').click()
this.server.respond()
responded.should.equal(true)
const template = '<form ' +
'id="hello" ' +
'hx-target="#hello" ' +
'hx-select="#hello" ' +
'hx-swap="outerHTML" ' +
'hx-post="/test">\n' +
'<input id="input" type="text" name="name" />\n' +
'<button name="value" type="submit">Submit</button>\n' +
'</form>\n' +
'<button id="outside" name="outside" form="hello" type="submit">Outside</button>'
var values
this.server.respondWith('/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(200, {}, template)
})
make(template)
const button = byId('outside')
button.focus()
button.click()
this.server.respond()
values.should.deep.equal({ name: '', outside: '' })
button.focus()
button.click()
this.server.respond()
values.should.deep.equal({ name: '', outside: '' })
var btn = make("<button hx-on:click='window.foo = true'>Foo</button>")
btn.click()
window.foo.should.equal(true)
delete window.foo
var div = make("<div><button id='b1' hx-on:click='window.foo = true'>Foo</button></div>")
var btn = div.querySelector('#b1')
btn.click()
window.foo.should.equal(true)
delete window.foo
this.server.respondWith('GET', '/test', '<div id="r1">Clicked!</div>')
var btn = make('<button hx-get="/test" hx-target="host" hx-swap="afterend">Click Me!</button>')
btn.click()
this.server.respond()
var r1 = document.getElementById('r1')
r1.innerHTML.should.equal('Clicked!')
r1.remove()
this.server.respondWith('GET', '/test', '<div id="r2">Clicked!</div>')
var btn = make('<button hx-get="/test" hx-target="global #work-area" hx-swap="beforebegin">Click Me!</button>')
btn.click()
this.server.respond()
var r2 = document.getElementById('r2')
r2.innerHTML.should.equal('Clicked!')
r2.remove()
this.server.respondWith('GET', '/test', '<div id="work-area" hx-history-elt>Clicked!</div>')
var btn = make('<button hx-get="/test" hx-target="host" hx-swap="outerHTML">Click Me!</button>')
btn.click()
chai.expect(getWorkArea().shadowRoot).to.not.be.a('null')
this.server.respond()
getWorkArea().innerHTML.should.equal('Clicked!')
chai.expect(getWorkArea().shadowRoot).to.be.a('null')
// create an entry with a large content string (256k) and see how fast we can write and read it
// to local storage as a single entry
var entry = { url: stringRepeat('x', 32), content: stringRepeat('x', 256 * 1024) }
var array = []
for (var i = 0; i < 10; i++) {
array.push(entry)
}
var start = performance.now()
var string = JSON.stringify(array)
localStorage.setItem(HTMX_HISTORY_CACHE_NAME, string)
var reReadString = localStorage.getItem(HTMX_HISTORY_CACHE_NAME)
var finalJson = JSON.parse(reReadString)
var end = performance.now()
var timeInMs = end - start
chai.assert(timeInMs < 300, 'Should take less than 300ms on most platforms')
var size = 5 * 1024 // ~350K in size, about the size of CNN's body tag :p
var workArea = getWorkArea()
var html = "<div class='foo bar'>Yay, really large HTML documents are fun!</div>\n"
html = stringRepeat(html, size)
workArea.insertAdjacentHTML('beforeend', html)
var start = performance.now()
htmx._('cleanInnerHtmlForHistory')(workArea)
var end = performance.now()
var timeInMs = end - start
chai.assert(timeInMs < 50, 'Should take less than 50ms on most platforms')
this.server.respondWith('POST', '/test', 'Clicked!')
var form = make('<form hx-post="/test" hx-trigger="click">' +
'No Request' +
'<input id="i1" name="i1" required>' +
'</form>')
form.textContent.should.equal('No Request')
form.click()
this.server.respond()
form.textContent.should.equal('No Request')
byId('i1').value = 'foo'
form.click()
this.server.respond()
form.textContent.should.equal('Clicked!')
this.server.respondWith('POST', '/test', 'Clicked!')
var form = make('<form hx-post="/test" hx-trigger="click" novalidate>' +
'No Request' +
'<input id="i1" name="i1" required>' +
'</form>')
form.textContent.should.equal('No Request')
form.click()
this.server.respond()
form.textContent.should.equal('Clicked!')
this.server.respondWith('POST', '/test', 'Clicked!')
var form = make('<form hx-post="/test" hx-trigger="click">' +
'No Request' +
'<input id="i1" name="i1" required>' +
'<button id="button" hx-post="/test" hx-target="form"></button>' +
'</form>')
form.textContent.should.equal('No Request')
byId('button').click()
this.server.respond()
form.textContent.should.equal('Clicked!')
this.server.respondWith('POST', '/test', 'Clicked!')
var form = make('<form hx-post="/test">' +
'No Request' +
'<input id="i1" name="i1" required>' +
'<button id="button" type="submit" formnovalidate></button>' +
'</form>')
form.textContent.should.equal('No Request')
byId('button').click()
this.server.respond()
form.textContent.should.equal('Clicked!')
this.server.respondWith('POST', '/test', 'Clicked!')
var form = make('<form hx-post="/test" hx-trigger="click">' +
'No Request' +
'<input id="i1" name="i1" pattern="abc" value="xyz">' +
'</form>')
byId('i1').value = 'xyz'
form.textContent.should.equal('No Request')
form.click()
this.server.respond()
form.textContent.should.equal('No Request')
byId('i1').value = 'abc'
form.click()
this.server.respond()
form.textContent.should.equal('Clicked!')
this.server.respondWith('POST', '/test', 'Clicked!')
var form = make('<form hx-post="/test" hx-trigger="click">' +
'No Request' +
'<input id="i1" name="i1">' +
'</form>')
byId('i1').setCustomValidity('Nope')
form.textContent.should.equal('No Request')
form.click()
this.server.respond()
form.textContent.should.equal('No Request')
byId('i1').setCustomValidity('')
form.click()
this.server.respond()
form.textContent.should.equal('Clicked!')
this.server.respondWith('POST', '/test', 'Clicked!')
var form = make('<form hx-post="/test" hx-trigger="click">' +
'No Request' +
'<input id="i1" name="i1" type="checkbox">' +
'</form>')
byId('i1').setCustomValidity('Nope')
form.textContent.should.equal('No Request')
form.click()
this.server.respond()
form.textContent.should.equal('No Request')
byId('i1').setCustomValidity('')
form.click()
this.server.respond()
form.textContent.should.equal('Clicked!')
this.server.respondWith('POST', '/test', 'Clicked!')
var form = make('<form hx-post="/test" hx-trigger="click">' +
'No Request' +
'<input id="i1" name="i1" type="radio">' +
'</form>')
byId('i1').setCustomValidity('Nope')
form.textContent.should.equal('No Request')
form.click()
this.server.respond()
form.textContent.should.equal('No Request')
byId('i1').setCustomValidity('')
form.click()
this.server.respond()
form.textContent.should.equal('Clicked!')
this.server.respondWith('POST', '/test', 'Clicked!')
var form = make('<form hx-post="/test" hx-trigger="click">' +
'No Request' +
'<input _="on htmx:validation:validate if my.value != \'foo\' call me.setCustomValidity(\'Nope\') ' +
' else call me.setCustomValidity(\'\')" id="i1" name="i1">' +
'</form>')
htmx.trigger(form, 'htmx:load')
byId('i1').value = 'boo'
form.textContent.should.equal('No Request')
form.click()
this.server.respond()
form.textContent.should.equal('No Request')
byId('i1').value = 'foo'
form.click()
this.server.respond()
form.textContent.should.equal('Clicked!')
var form = make('<form hx-post="/test" hx-trigger="click">' +
'No Request' +
'<input id="i1" name="i1" required>' +
'</form>')
var calledEvent = false
var handler = htmx.on(form, 'htmx:validation:failed', function() {
calledEvent = true
})
try {
form.click()
this.server.respond()
} finally {
htmx.off(form, handler)
}
calledEvent.should.equal(true)
var form = make('<form hx-post="/test" hx-trigger="click">' +
'No Request' +
'<input id="i1" name="i1" required>' +
'</form>')
var errors = null
var handler = htmx.on(form, 'htmx:validation:halted', function(evt) {
errors = evt.detail.errors
})
try {
form.click()
this.server.respond()
} finally {
htmx.off(form, handler)
}
errors.length.should.equal(1)
byId('i1').should.equal(errors[0].elt)
errors[0].validity.valueMissing.should.equal(true)
this.server.respondWith('POST', '/test', 'Clicked!')
var div = make("<div id='d1'>No Request</div>")
var form = make('<form><input type="text" hx-target="#d1" hx-post="/test" hx-trigger="click" id="i1" name="i1" pattern="[0-9]+" hx-validate="true"/></form>')
var input = byId('i1')
div.textContent.should.equal('No Request')
input.value = 'abc'
input.click()
this.server.respond()
div.textContent.should.equal('No Request')
input.value = '1bc'
input.click()
this.server.respond()
div.textContent.should.equal('No Request')
input.value = '123'
input.click()
this.server.respond()
div.textContent.should.equal('Clicked!')
tokenizeTest('', [])
tokenizeTest(' ', [' ', ' '])
tokenizeTest('(', ['('])
tokenizeTest('()', ['(', ')'])
tokenizeTest('(,)', ['(', ',', ')'])
tokenizeTest(' ( ) ', [' ', '(', ' ', ')', ' '])
tokenizeTest(' && ) ', [' ', '&', '&', ' ', ')', ' '])
tokenizeTest(" && ) 'asdf'", [' ', '&', '&', ' ', ')', ' ', "'asdf'"])
tokenizeTest(" && ) ',asdf'", [' ', '&', '&', ' ', ')', ' ', "',asdf'"])
tokenizeTest('",asdf"', ['",asdf"'])
tokenizeTest('&& ) ",asdf"', ['&', '&', ' ', ')', ' ', '",asdf"'])
var tokens = tokenize('[code==4||(code==5&&foo==true)]')
var conditional = htmx._('maybeGenerateConditional')(null, tokens)
var func = eval(conditional)
func({ code: 5, foo: true }).should.equal(true)
func({ code: 5, foo: false }).should.equal(false)
func({ code: 4, foo: false }).should.equal(true)
func({ code: 3, foo: true }).should.equal(false)
htmx.defineExtension('ext-prevent-request', {
onEvent: function(name, evt) {
if (name === 'htmx:beforeRequest') {
return false
}
}
})
this.server.respondWith('GET', '/test', 'clicked!')
var div = make('<div hx-get="/test" hx-ext="ext-prevent-request">Click Me!</div>')
div.click()
this.server.respond()
div.innerHTML.should.equal('Click Me!')
htmx.defineExtension('ext-prevent-request', {
onEvent: function(name, evt) {
if (name === 'htmx:beforeRequest') {
evt.preventDefault()
}
}
})
this.server.respondWith('GET', '/test', 'clicked!')
var div = make('<div hx-get="/test" hx-ext="ext-prevent-request">Click Me!</div>')
div.click()
this.server.respond()
div.innerHTML.should.equal('Click Me!')
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()
loadCalls.length.should.equal(1)
loadCalls[0].textContent.should.equal('Clicked!') // the new button is loaded
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!')
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!')
loadCalls.length.should.equal(1) // text should not trigger event
this.server.respondWith('GET', '/test', 'Boosted')
var div = make('<div hx-target="this" hx-boost="true"><a id="a1" href="/test">Foo</a></div>')
var a = byId('a1')
a.click()
this.server.respond()
div.innerHTML.should.equal('Boosted')
this.server.respondWith('POST', '/test', 'Boosted')
var div = make('<div hx-target="this" hx-boost="true"><form id="f1" action="/test" method="post"><button id="b1">Submit</button></form></div>')
var btn = byId('b1')
btn.click()
this.server.respond()
div.innerHTML.should.equal('Boosted')
this.server.respondWith('POST', '/test', 'Boosted')
var div = make('<div hx-target="this" hx-boost="true"><form id="f1" method="post"><button id="b1" formaction="/test">Submit</button></form></div>')
var btn = byId('b1')
btn.click()
this.server.respond()
div.innerHTML.should.equal('Boosted')
this.server.respondWith('POST', '/test', 'Boosted')
var div = make('<div hx-target="this" hx-boost="true"><form id="f1" action="/test"><button id="b1" formmethod="post">Submit</button></form></div>')
var btn = byId('b1')
btn.click()
this.server.respond()
div.innerHTML.should.equal('Boosted')
this.server.respondWith('POST', '/test', 'Boosted')
var div = make('<div hx-target="this"><form id="f1" action="/test" method="post" hx-trigger="click" hx-boost="true"></form></div>')
var form = byId('f1')
form.click()
this.server.respond()
div.innerHTML.should.equal('Boosted')
this.server.respondWith('GET', '/test', 'Boosted')
var div = make('<div hx-target="this" hx-boost="true"><form id="f1" action="/test" method="get"><button id="b1">Submit</button></form></div>')
var btn = byId('b1')
btn.click()
this.server.respond()
div.innerHTML.should.equal('Boosted')
this.server.respondWith('GET', '/test', 'Boosted')
var div = make('<div hx-target="this" hx-boost="true"><form id="f1" action="/test"><button id="b1">Submit</button></form></div>')
var btn = byId('b1')
btn.click()
this.server.respond()
div.innerHTML.should.equal('Boosted')
make('<div hx-boost="true"><form id="f1" action="/test" method="dialog"><button id="b1">close</button></form></div>')
var form = byId('f1')
var internalData = htmx._('getInternalData')(form)
should.equal(undefined, internalData.boosted)
this.server.respondWith('GET', '/test', 'Boosted')
var div = make('<div data-hx-target="this" data-hx-boost="true"><a id="a1" href="/test">Foo</a></div>')
var a = byId('a1')
a.click()
this.server.respond()
div.innerHTML.should.equal('Boosted')
htmx.config.defaultSwapStyle = 'afterend'
try {
this.server.respondWith('GET', '/test', 'Boosted')
var a = make('<a hx-target="this" hx-boost="true" id="a1" href="/test">Foo</a>')
a.click()
this.server.respond()
a.innerHTML.should.equal('Boosted')
} finally {
htmx.config.defaultSwapStyle = 'innerHTML'
}
var a = make('<a hx-target="this" hx-boost="true" id="a1" href="/test" target="_blank">Foo</a>')
var internalData = htmx._('getInternalData')(a)
should.equal(undefined, internalData.boosted)
this.server.respondWith('GET', '/test', function(xhr) {
should.equal(xhr.requestHeaders['HX-Boosted'], 'true')
xhr.respond(200, {}, 'Boosted!')
})
var btn = make('<a hx-boost="true" hx-target="this" href="/test">Click Me!</a>')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('Boosted!')
this.server.respondWith('GET', /\/test.*/, function(xhr) {
should.equal(undefined, getParameters(xhr).foo)
xhr.respond(200, {}, 'Boosted!')
})
var div = make('<div hx-target="this" hx-boost="true"><form id="f1" action="/test?foo=bar" method="get"><button id="b1">Submit</button></form></div>')
var btn = byId('b1')
btn.click()
this.server.respond()
div.innerHTML.should.equal('Boosted!')
this.server.respondWith('POST', /\/test.*/, function(xhr) {
should.equal(undefined, getParameters(xhr).foo)
xhr.respond(200, {}, 'Boosted!')
})
var div = make('<div hx-target="this" hx-boost="true"><form id="f1" action="/test?foo=bar" method="post"><button id="b1">Submit</button></form></div>')
var btn = byId('b1')
btn.click()
this.server.respond()
div.innerHTML.should.equal('Boosted!')
this.server.respondWith('GET', /\/*/, function(xhr) {
xhr.respond(200, {}, 'Boosted!')
})
var div = make('<div hx-target="this" hx-boost="true"><form id="f1" method="get"><button id="b1">Submit</button></form></div>')
var btn = byId('b1')
btn.click()
this.server.respond()
div.innerHTML.should.equal('Boosted!')
/// add a foo=bar to the current url
var path = location.href
if (!path.includes('foo=bar')) {
if (!path.includes('?')) {
path += '?foo=bar'
} else {
path += '&foo=bar'
}
}
history.replaceState({ htmx: true }, '', path)
this.server.respondWith('GET', /\/*/, function(xhr) {
// foo should not be present because the form is a get with no action
should.equal(undefined, getParameters(xhr).foo)
xhr.respond(200, {}, 'Boosted!')
})
var div = make('<div hx-target="this" hx-boost="true"><form id="f1" method="get"><button id="b1">Submit</button></form></div>')
var btn = byId('b1')
btn.click()
this.server.respond()
div.innerHTML.should.equal('Boosted!')
/// add a foo=bar to the current url
var path = location.href
if (!path.includes('foo=bar')) {
if (!path.includes('?')) {
path += '?foo=bar'
} else {
path += '&foo=bar'
}
}
history.replaceState({ htmx: true }, '', path)
this.server.respondWith('GET', /\/*/, function(xhr) {
// foo should not be present because the form is a get with no action
should.equal(undefined, getParameters(xhr).foo)
xhr.respond(200, {}, 'Boosted!')
})
var div = make('<div hx-target="this" hx-boost="true"><form id="f1" action="" method="get"><button id="b1">Submit</button></form></div>')
var btn = byId('b1')
btn.click()
this.server.respond()
div.innerHTML.should.equal('Boosted!')
this.server.respondWith('GET', '/test', 'Clicked!')
confirm.returns(true)
var btn = make('<button hx-get="/test" hx-confirm="Sure?">Click Me!</button>')
btn.click()
confirm.calledOnce.should.equal(true)
this.server.respond()
btn.innerHTML.should.equal('Clicked!')
this.server.respondWith('GET', '/test', 'Clicked!')
confirm.returns(false)
var btn = make('<button hx-get="/test" hx-confirm="Sure?">Click Me!</button>')
btn.click()
confirm.calledOnce.should.equal(true)
this.server.respond()
btn.innerHTML.should.equal('Click Me!')
this.server.respondWith('GET', '/test', 'Clicked!')
confirm.returns(false)
var btn = make('<button hx-get="/test" hx-confirm="Sure?">Click Me!</button>')
btn.click()
confirm.firstCall.args[0].should.equal('Sure?')
this.server.respond()
btn.innerHTML.should.equal('Click Me!')
try {
var btn = make('<button hx-get="/test" hx-confirm="Surely?">Click Me!</button>')
var handler = htmx.on('htmx:confirm', function(evt) {
evt.preventDefault()
evt.detail.issueRequest()
})
btn.click()
confirm.calledOnce.should.equal(true)
} finally {
htmx.off('htmx:confirm', handler)
}
var stub = sinon.stub()
try {
var btn = make('<button hx-get="/test" hx-confirm="Surely?">Click Me!</button>')
var handler = htmx.on('htmx:confirm', stub)
btn.click()
stub.calledOnce.should.equal(true)
stub.firstCall.args[0].detail.should.have.property('question', 'Surely?')
} finally {
htmx.off('htmx:confirm', handler)
}
this.server.respondWith('GET', '/test', 'Clicked!')
try {
var btn = make('<button hx-get="/test" hx-confirm="Sure?">Click Me!</button>')
var handler = htmx.on('htmx:confirm', function(evt) {
evt.detail.question.should.equal('Sure?')
evt.preventDefault()
evt.detail.issueRequest(true)
})
btn.click()
confirm.called.should.equal(false)
this.server.respond()
btn.innerHTML.should.equal('Clicked!')
} finally {
htmx.off('htmx:confirm', handler)
}
this.server.respondWith('GET', '/test', 'Clicked!')
try {
var btn = make('<button hx-get="/test" hx-confirm="Sure?">Click Me!</button>')
var handler = htmx.on('htmx:confirm', function(evt) {
evt.detail.question.should.equal('Sure?')
evt.preventDefault()
evt.detail.issueRequest(true)
})
btn.click()
confirm.called.should.equal(false)
this.server.respond()
btn.innerHTML.should.equal('Clicked!')
} finally {
htmx.off('htmx:confirm', handler)
}
this.server.respondWith('GET', '/test', 'Clicked!')
try {
var btn = make('<button hx-get="/test">Click Me!</button>')
var handler = htmx.on('htmx:confirm', function(evt) {
evt.detail.should.have.property('question', null)
evt.preventDefault()
evt.detail.issueRequest()
})
btn.click()
confirm.called.should.equal(false) // no hx-confirm means no window.confirm
this.server.respond()
btn.innerHTML.should.equal('Clicked!')
} finally {
htmx.off('htmx:confirm', handler)
}
this.server.respondWith('DELETE', '/test', function(xhr) {
xhr.respond(200, {}, 'Deleted!')
})
var btn = make('<button hx-delete="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('Deleted!')
this.server.respondWith('DELETE', '/test', function(xhr) {
xhr.respond(200, {}, 'Deleted!')
})
var btn = make('<button data-hx-delete="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('Deleted!')
this.server.respondWith('GET', '/test', 'Clicked!')
var btn = make('<button hx-get="/test" hx-ext="ext-1">Click Me!</button>')
btn.click()
this.server.respond()
ext1Calls.should.equal(1)
ext2Calls.should.equal(0)
ext3Calls.should.equal(0)
this.server.respondWith('GET', '/test', 'Clicked!')
make('<div hx-ext="ext-1"><button id="btn-1" hx-get="/test" hx-ext="ext-2">Click Me!</button>' +
'<button id="btn-2" hx-get="/test" hx-ext="ext-3">Click Me!</button></div>')
var btn1 = byId('btn-1')
var btn2 = byId('btn-2')
btn1.click()
this.server.respond()
ext1Calls.should.equal(1)
ext2Calls.should.equal(1)
ext3Calls.should.equal(0)
btn2.click()
this.server.respond()
ext1Calls.should.equal(2)
ext2Calls.should.equal(1)
ext3Calls.should.equal(1)
this.server.respondWith('GET', '/test', 'Clicked!')
make('<div hx-ext="ext-1"><button id="btn-1" hx-get="/test" hx-ext="ext-2, ext-3 ">Click Me!</button></div>')
var btn1 = byId('btn-1')
var btn2 = byId('btn-2')
btn1.click()
this.server.respond()
ext1Calls.should.equal(1)
ext2Calls.should.equal(1)
ext3Calls.should.equal(1)
this.server.respondWith('GET', '/test', 'Clicked!')
var btn = make('<button data-hx-get="/test" data-hx-ext="ext-1">Click Me!</button>')
btn.click()
this.server.respond()
ext1Calls.should.equal(1)
ext2Calls.should.equal(0)
ext3Calls.should.equal(0)
this.server.respondWith('GET', '/test', [200, { 'HX-Trigger': 'namespace:example' }, ''])
var btn = make('<button data-hx-get="/test" data-hx-ext="ext-4">Click Me!</button>')
btn.click()
this.server.respond()
ext1Calls.should.equal(0)
ext2Calls.should.equal(0)
ext3Calls.should.equal(0)
ext4Calls.should.equal(1)
this.server.respondWith('GET', '/test', [200, { 'HX-Trigger': 'namespace:example' }, ''])
var btn = make('<div data-hx-ext="ext-5"><div foo="bar">test</div></div>')
btn.click()
this.server.respond()
ext1Calls.should.equal(0)
ext2Calls.should.equal(0)
ext3Calls.should.equal(0)
ext4Calls.should.equal(0)
ext5Calls.should.equal(1)
this.server.respondWith('GET', '/test', 'Clicked!')
make('<div id="div-AA" hx-ext="ext-1,ext-2,ext-5"><button id="btn-AA" hx-get="/test" foo="foo">Click Me!</button>' +
'<div id="div-BB" hx-ext="ignore:ext-1,ignore:ext-5"><button id="btn-BB" hx-get="/test" foo="foo"></button></div></div>')
var btn1 = byId('btn-AA')
var btn2 = byId('btn-BB')
btn1.click()
this.server.respond()
ext1Calls.should.equal(1)
ext2Calls.should.equal(1)
ext3Calls.should.equal(0)
btn2.click()
this.server.respond()
ext1Calls.should.equal(1)
ext2Calls.should.equal(2)
ext3Calls.should.equal(0)
ext5Calls.should.equal(1)
this.server.respondWith('GET', '/test', 'Clicked!')
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('Clicked!')
this.server.respondWith('GET', '/test', function(xhr) {
should.equal(getParameters(xhr).i1, undefined)
xhr.respond(200, {}, 'Clicked!')
})
make('<form><input name="i1" value="value"/><button id="b1" hx-get="/test">Click Me!</button></form>')
var btn = byId('b1')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('Clicked!')
this.server.respondWith('GET', /\/test.*/, function(xhr) {
getParameters(xhr).i1.should.equal('value')
xhr.respond(200, {}, 'Clicked!')
})
var form = make('<form hx-trigger="click" hx-get="/test"><input name="i1" value="value"/><button id="b1">Click Me!</button></form>')
form.click()
this.server.respond()
form.innerHTML.should.equal('Clicked!')
this.server.respondWith('GET', /\/test.*/, function(xhr) {
getParameters(xhr).foo.should.equal('bar')
getParameters(xhr).i1.should.equal('value')
xhr.respond(200, {}, 'Clicked!')
})
var form = make('<form hx-trigger="click" hx-get="/test?foo=bar"><input name="i1" value="value"/><button id="b1">Click Me!</button></form>')
form.click()
this.server.respond()
form.innerHTML.should.equal('Clicked!')
this.server.respondWith('GET', /\/test.*/, function(xhr) {
getParameters(xhr).foo.should.equal('bar')
getParameters(xhr).i1.should.equal('value')
xhr.respond(200, {}, 'Clicked!')
})
var form = make('<form hx-trigger="click" hx-get="/test?foo=bar#foo"><input name="i1" value="value"/><button id="b1">Click Me!</button></form>')
form.click()
this.server.respond()
form.innerHTML.should.equal('Clicked!')
this.server.respondWith('GET', '/test', 'Clicked!')
var btn = make('<button data-hx-get="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('Clicked!')
this.server.respondWith('GET', /\/test.*/, function(xhr) {
should.not.exist(getParameters(xhr)['org.htmx.cache-buster'])
xhr.respond(200, {}, 'Clicked!')
})
try {
htmx.config.getCacheBusterParam = false
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('Clicked!')
} finally {
htmx.config.getCacheBusterParam = false
}
this.server.respondWith('GET', /\/test.*/, function(xhr) {
getParameters(xhr)['org.htmx.cache-buster'].should.equal('true')
xhr.respond(200, {}, 'Clicked!')
})
try {
htmx.config.getCacheBusterParam = true
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('Clicked!')
} finally {
htmx.config.getCacheBusterParam = false
}
this.server.respondWith('GET', /\/test.*/, function(xhr) {
getParameters(xhr)['org.htmx.cache-buster'].should.equal('foo')
xhr.respond(200, {}, 'Clicked!')
})
try {
htmx.config.getCacheBusterParam = true
var btn = make('<button hx-get="/test" id="foo">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('Clicked!')
} finally {
htmx.config.getCacheBusterParam = false
}
this.server.respondWith('POST', '/vars', function(xhr) {
xhr.requestHeaders.i1.should.equal('test')
xhr.respond(200, {}, 'Clicked!')
})
var div = make("<div hx-post='/vars' hx-headers='\"i1\":\"test\"'></div>")
div.click()
this.server.respond()
div.innerHTML.should.equal('Clicked!')
this.server.respondWith('POST', '/vars', function(xhr) {
xhr.requestHeaders.i1.should.equal('test')
xhr.respond(200, {}, 'Clicked!')
})
var div = make("<div hx-post='/vars' hx-headers='{\"i1\":\"test\"}'></div>")
div.click()
this.server.respond()
div.innerHTML.should.equal('Clicked!')
this.server.respondWith('POST', '/vars', function(xhr) {
xhr.requestHeaders.v1.should.equal('test')
xhr.requestHeaders.v2.should.equal('42')
xhr.respond(200, {}, 'Clicked!')
})
var div = make("<div hx-post='/vars' hx-headers='\"v1\":\"test\", \"v2\":42'></div>")
div.click()
this.server.respond()
div.innerHTML.should.equal('Clicked!')
this.server.respondWith('POST', '/vars', function(xhr) {
xhr.requestHeaders.i1.should.equal('test')
xhr.respond(200, {}, 'Clicked!')
})
make("<div hx-headers='\"i1\":\"test\"'><div id='d1' hx-post='/vars'></div></div>")
var div = byId('d1')
div.click()
this.server.respond()
div.innerHTML.should.equal('Clicked!')
this.server.respondWith('POST', '/vars', function(xhr) {
xhr.requestHeaders.i1.should.equal('best')
xhr.respond(200, {}, 'Clicked!')
})
make("<div hx-headers='\"i1\":\"test\"'><div id='d1' hx-headers='\"i1\":\"best\"' hx-post='/vars'></div></div>")
var div = byId('d1')
div.click()
this.server.respond()
div.innerHTML.should.equal('Clicked!')
this.server.respondWith('POST', '/include', function(xhr) {
xhr.requestHeaders.i1.should.equal('best')
xhr.respond(200, {}, 'Clicked!')
})
var div = make("<div hx-target='this'><input hx-post='/include' hx-headers='\"i1\":\"best\"' hx-trigger='click' id='i1' name='i1' value='test'/></div>")
var input = byId('i1')
input.click()
this.server.respond()
div.innerHTML.should.equal('Clicked!')
this.server.respondWith('POST', '/vars', function(xhr) {
xhr.requestHeaders.i1.should.equal('test')
xhr.respond(200, {}, 'Clicked!')
})
var div = make('<div hx-post="/vars" hx-headers="javascript:i1:\'test\'"></div>')
div.click()
this.server.respond()
div.innerHTML.should.equal('Clicked!')
this.server.respondWith('POST', '/vars', function(xhr) {
xhr.requestHeaders.i1.should.equal('test')
xhr.respond(200, {}, 'Clicked!')
})
var div = make('<div hx-post="/vars" hx-headers="javascript:{i1:\'test\'}"></div>')
div.click()
this.server.respond()
div.innerHTML.should.equal('Clicked!')
this.server.respondWith('POST', '/vars', function(xhr) {
xhr.requestHeaders.v1.should.equal('test')
xhr.requestHeaders.v2.should.equal('42')
xhr.respond(200, {}, 'Clicked!')
})
var div = make('<div hx-post="/vars" hx-headers="javascript:v1:\'test\', v2:42"></div>')
div.click()
this.server.respond()
div.innerHTML.should.equal('Clicked!')
this.server.respondWith('POST', '/vars', function(xhr) {
xhr.requestHeaders.i1.should.equal('test')
xhr.respond(200, {}, 'Clicked!')
})
make('<div hx-headers="javascript:i1:\'test\'"><div id="d1" hx-post="/vars"></div></div>')
var div = byId('d1')
div.click()
this.server.respond()
div.innerHTML.should.equal('Clicked!')
this.server.respondWith('POST', '/vars', function(xhr) {
xhr.requestHeaders.i1.should.equal('best')
xhr.respond(200, {}, 'Clicked!')
})
make('<div hx-headers="javascript:i1:\'test\'"><div id="d1" hx-headers="javascript:i1:\'best\'" hx-post="/vars"></div></div>')
var div = byId('d1')
div.click()
this.server.respond()
div.innerHTML.should.equal('Clicked!')
this.server.respondWith('POST', '/include', function(xhr) {
xhr.requestHeaders.i1.should.equal('best')
xhr.respond(200, {}, 'Clicked!')
})
var div = make('<div hx-target="this"><input hx-post="/include" hx-headers="javascript:i1:\'best\'" hx-trigger="click" id="i1" name="i1" value="test"/></div>')
var input = byId('i1')
input.click()
this.server.respond()
div.innerHTML.should.equal('Clicked!')
this.server.respondWith('GET', '/test1', '<div id="d2" hx-push-url="true" hx-get="/test2" hx-swap="outerHTML settle:0" hx-history="true">test1</div>')
this.server.respondWith('GET', '/test2', '<div id="d3" hx-push-url="true" hx-get="/test3" hx-swap="outerHTML settle:0" hx-history="false">test2</div>')
this.server.respondWith('GET', '/test3', '<div id="d4" hx-push-url="true" hx-get="/test3" hx-swap="outerHTML settle:0" hx-history="true">test3</div>')
make('<div id="d1" hx-push-url="true" hx-get="/test1" hx-swap="outerHTML settle:0">init</div>')
byId('d1').click()
this.server.respond()
var workArea = getWorkArea()
workArea.textContent.should.equal('test1')
byId('d2').click()
this.server.respond()
workArea.textContent.should.equal('test2')
byId('d3').click()
this.server.respond()
workArea.textContent.should.equal('test3')
// embargoed content should NOT be in the localStorage cache
var cache = JSON.parse(localStorage.getItem(HTMX_HISTORY_CACHE_NAME))
cache.length.should.equal(2)
// on history navigation, embargoed content is retrieved from server
htmx._('restoreHistory')('/test2')
this.server.respond()
getWorkArea().textContent.should.equal('test2')
this.server.respondWith('POST', '/include', function(xhr) {
var params = getParameters(xhr)
params.i1.should.equal('test')
xhr.respond(200, {}, 'Clicked!')
})
var div = make('<div hx-target="this"><input hx-post="/include" hx-trigger="click" id="i1" name="i1" value="test"/></div>')
var input = byId('i1')
input.click()
this.server.respond()
div.innerHTML.should.equal('Clicked!')
this.server.respondWith('POST', '/include', function(xhr) {
var params = getParameters(xhr)
params.i1.should.equal('test')
xhr.respond(200, {}, 'Clicked!')
})
var div = make('<form hx-target="this"><div id="d1" hx-post="/include"></div><input name="i1" value="test"/></form>')
var input = byId('d1')
input.click()
this.server.respond()
div.innerHTML.should.equal('Clicked!')
this.server.respondWith('POST', '/include', function(xhr) {
var params = getParameters(xhr)
params.i1.should.equal('test')
xhr.respond(200, {}, 'Clicked!')
})
var div = make('<div hx-include="*" hx-target="this">' +
'<input name="i1" value="before"/>' +
'<form><div id="d1" hx-post="/include"></div><input name="i1" value="test"/></form>' +
'<input name="i1" value="after"/>')
var input = byId('d1')
input.click()
this.server.respond()
div.innerHTML.should.equal('Clicked!')
this.server.respondWith('GET', '/include', function(xhr) {
var params = getParameters(xhr)
should.equal(params.i1, undefined)
xhr.respond(200, {}, 'Clicked!')
})
var div = make('<form hx-target="this"><div id="d1" hx-get="/include"></div><input name="i1" value="test"/></form>')
var input = byId('d1')
input.click()
this.server.respond()
div.innerHTML.should.equal('Clicked!')
this.server.respondWith('POST', '/include', function(xhr) {
var params = getParameters(xhr)
params.i1.should.equal('test')
xhr.respond(200, {}, 'Clicked!')
})
var div = make('<form hx-target="this"><input hx-post="/include" hx-trigger="click" id="i1" name="i1" value="test"/></form>')
var input = byId('i1')
input.click()
this.server.respond()
div.innerHTML.should.equal('Clicked!')
this.server.respondWith('POST', '/include', function(xhr) {
var params = getParameters(xhr)
params.i1.should.deep.equal(['test', 'test2'])
xhr.respond(200, {}, 'Clicked!')
})
var div = make('<div hx-include="*" hx-target="this">' +
'<input hx-post="/include" hx-trigger="click" id="i1" name="i1" value="test"/>' +
'<input name="i1" value="test2"/>' +
'</div>')
var input = byId('i1')
input.click()
this.server.respond()
div.innerHTML.should.equal('Clicked!')
this.server.respondWith('POST', '/include', function(xhr) {
var params = getParameters(xhr)
params.i1.should.deep.equal(['test', 'test2'])
xhr.respond(200, {}, 'Clicked!')
})
var div = make('<form hx-target="this">' +
'<input hx-post="/include" hx-trigger="click" id="i1" name="i1" value="test"/>' +
'<input name="i1" value="test2"/>' +
'</form>')
var input = byId('i1')
input.click()
this.server.respond()
div.innerHTML.should.equal('Clicked!')
this.server.respondWith('POST', '/include', function(xhr) {
var params = getParameters(xhr)
params.i1.should.equal('test')
xhr.respond(200, {}, 'Clicked!')
})
var div = make('<form id="f1" hx-target="this">' +
'<input hx-include="#f1" hx-post="/include" hx-trigger="click" id="i1" name="i1" value="test"/>' +
'</form>')
var input = byId('i1')
input.click()
this.server.respond()
div.innerHTML.should.equal('Clicked!')
this.server.respondWith('POST', '/include', function(xhr) {
var params = getParameters(xhr)
params.i1.should.equal('test')
xhr.respond(200, {}, 'Clicked!')
})
make('<input id="i1" name="i1" value="test"/>')
var div = make('<div hx-post="/include" hx-include="#i1"></div>')
div.click()
this.server.respond()
div.innerHTML.should.equal('Clicked!')
this.server.respondWith('POST', '/include', function(xhr) {
var params = getParameters(xhr)
params.i1.should.equal('test')
params.i2.should.equal('test')
xhr.respond(200, {}, 'Clicked!')
})
make('<input id="i1" name="i1" value="test"/>')
make('<input id="i2" name="i2" value="test"/>')
var div = make('<div hx-post="/include" hx-include="#i1, #i2"></div>')
div.click()
this.server.respond()
div.innerHTML.should.equal('Clicked!')
this.server.respondWith('POST', '/include', function(xhr) {
var params = getParameters(xhr)
params.i1.should.equal('test')
params.i2.should.equal('test')
xhr.respond(200, {}, 'Clicked!')
})
make('<form id="f1">' +
'<input name="i1" value="test"/>' +
'<input name="i2" value="test"/>' +
'</form> ')
var div = make('<div hx-post="/include" hx-include="#f1"></div>')
div.click()
this.server.respond()
div.innerHTML.should.equal('Clicked!')
this.server.respondWith('POST', '/include', function(xhr) {
var params = getParameters(xhr)
params.i1.should.equal('test')
xhr.respond(200, {}, 'Clicked!')
})
var div = make('<div data-hx-target="this"><input data-hx-post="/include" data-hx-trigger="click" id="i1" name="i1" value="test"/></div>')
var input = byId('i1')
input.click()
this.server.respond()
div.innerHTML.should.equal('Clicked!')
this.server.respondWith('POST', '/include', function(xhr) {
var params = getParameters(xhr)
params.i1.should.equal('test')
params.i2.should.equal('test')
xhr.respond(200, {}, 'Clicked!')
})
make('<div id="i"><input name="i1" value="test"/><input name="i2" value="test"/></div>')
var div = make('<div hx-post="/include" hx-include="#i"></div>')
div.click()
this.server.respond()
div.innerHTML.should.equal('Clicked!')
this.server.respondWith('POST', '/include', function(xhr) {
var params = getParameters(xhr)
params.i1.should.equal('test')
params.i2.should.equal('test')
xhr.respond(200, {}, 'Clicked!')
})
make('<div id="i"><input name="i1" value="test"/><input name="i2" value="test"/>' +
'<button id="btn" hx-post="/include" hx-include="closest div"></button></div>')
var btn = byId('btn')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('Clicked!')
this.server.respondWith('POST', '/include', function(xhr) {
var params = getParameters(xhr)
params.i1.should.equal('test')
params.i2.should.equal('test')
xhr.respond(200, {}, 'Clicked!')
})
make('<div id="i" hx-include="this"><input name="i1" value="test"/><input name="i2" value="test"/>' +
'<button id="btn" hx-post="/include"></button></div>')
var btn = byId('btn')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('Clicked!')
this.server.respondWith('POST', '/include', function(xhr) {
var params = getParameters(xhr)
params.i1.should.equal('test')
params.i2.should.equal('foo')
params.i3.should.equal('bar')
params.i4.should.equal('test2')
xhr.respond(200, {}, 'Clicked!')
})
make('<input name="i4" value="test2" id="i4"/>' +
'<div id="i">' +
'<input name="i1" value="test"/>' +
'<input name="i2" value="foo"/>' +
'<button id="btn" hx-post="/include" hx-include="closest div, next input, #i4"></button>' +
'</div>' +
'<input name="i3" value="bar"/>')
var btn = byId('btn')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('Clicked!')
this.server.respondWith('POST', '/include', function(xhr) {
var params = getParameters(xhr)
params.i1.should.equal('test')
should.equal(params.i2, undefined)
params.i3.should.equal('bar')
params.i4.should.equal('test2')
xhr.respond(200, {}, 'Clicked!')
})
make('<input name="i4" value="test2" id="i4"/>' +
'<div id="i">' +
'<input name="i1" value="test" id="i1"/>' +
'<input name="i2" value="foo"/>' +
'<button id="btn" hx-post="/include" hx-include="#i1, next input, #i4"></button>' +
'</div>' +
'<input name="i3" value="bar"/>')
var btn = byId('btn')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('Clicked!')
this.server.respondWith('POST', '/include', function(xhr) {
var params = getParameters(xhr)
params.i1.should.equal('test')
params.i2.should.equal('foo')
params.i3.should.equal('bar')
should.equal(params.i4, undefined)
should.equal(params.i5, undefined)
xhr.respond(200, {}, 'Clicked!')
})
make('<input name="i4" value="test2" id="i4"/>' +
'<div id="i">' +
'<input name="i1" value="test" id="i1"/>' +
'<input name="i2" value="foo"/>' +
'<input name="i5" value="test"/>' +
'<button id="btn" hx-post="/include" hx-include="next input, #i > :is([name=\'i1\'], [name=\'i2\'])"></button>' +
'</div>' +
'<input name="i3" value="bar"/>')
var btn = byId('btn')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('Clicked!')
this.server.respondWith('POST', '/include', function(xhr) {
var params = getParameters(xhr)
should.equal(params.i1, undefined)
params.i2.should.equal('foo')
params.i3.should.equal('bar')
should.equal(params.i4, undefined)
should.equal(params.i5, undefined)
xhr.respond(200, {}, 'Clicked!')
})
make('<input name="i4" value="test2" id="i4"/>' +
'<div id="i">' +
'<input name="i1" value="test" id="i1"/>' +
'<input name="i2" value="foo"/>' +
'<button id="btn" hx-post="/include" hx-include="next <#nonexistent, input/>, previous <#i5, [name=\'i2\'], #i4/>"></button>' +
'</div>' +
'<input name="i3" value="bar"/>' +
'<input name="i5" value="test"/>')
var btn = byId('btn')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('Clicked!')
this.server.respondWith('POST', '/include', function(xhr) {
var params = getParameters(xhr)
should.equal(params.i1, undefined)
params.i2.should.equal('bar')
xhr.respond(200, {}, 'Clicked!')
})
make('<section>' +
'<input name="i1" value="foo"/>' +
'<div>' +
'<input name="i2" value="bar"/>' +
'<button id="btn" hx-post="/include" hx-include="closest <section, div/>"></button>' +
'</div>' +
'</section>')
var btn = byId('btn')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('Clicked!')
this.server.respondWith('GET', '/test', 'Clicked!')
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
btn.classList.contains('htmx-request').should.equal(true)
this.server.respond()
btn.classList.contains('htmx-request').should.equal(false)
this.server.respondWith('GET', '/test', 'Clicked!')
var btn = make('<button hx-get="/test" hx-indicator="#a1, #a2">Click Me!</button>')
var a1 = make('<a id="a1"></a>')
var a2 = make('<a id="a2"></a>')
btn.click()
btn.classList.contains('htmx-request').should.equal(false)
a1.classList.contains('htmx-request').should.equal(true)
a2.classList.contains('htmx-request').should.equal(true)
this.server.respond()
btn.classList.contains('htmx-request').should.equal(false)
a1.classList.contains('htmx-request').should.equal(false)
a2.classList.contains('htmx-request').should.equal(false)
this.server.respondWith('GET', '/test', 'Clicked!')
var btn = make('<button hx-get="/test" hx-indicator="next a">Click Me!</button>')
var a1 = make('<a id="a1"></a>')
btn.click()
btn.classList.contains('htmx-request').should.equal(false)
a1.classList.contains('htmx-request').should.equal(true)
this.server.respond()
btn.classList.contains('htmx-request').should.equal(false)
a1.classList.contains('htmx-request').should.equal(false)
this.server.respondWith('GET', '/test', 'Clicked!')
var btn = make('<button hx-get="/test" data-hx-indicator="#a1, #a2">Click Me!</button>')
var a1 = make('<a id="a1"></a>')
var a2 = make('<a id="a2"></a>')
btn.click()
btn.classList.contains('htmx-request').should.equal(false)
a1.classList.contains('htmx-request').should.equal(true)
a2.classList.contains('htmx-request').should.equal(true)
this.server.respond()
btn.classList.contains('htmx-request').should.equal(false)
a1.classList.contains('htmx-request').should.equal(false)
a2.classList.contains('htmx-request').should.equal(false)
this.server.respondWith('GET', '/test', 'Clicked!')
var div = make('<div id="d1"><button id="b1" hx-get="/test" hx-indicator="closest div">Click Me!</button></div>')
var btn = byId('b1')
btn.click()
btn.classList.contains('htmx-request').should.equal(false)
div.classList.contains('htmx-request').should.equal(true)
this.server.respond()
btn.classList.contains('htmx-request').should.equal(false)
div.classList.contains('htmx-request').should.equal(false)
this.server.respondWith('GET', '/test', 'Clicked!')
var indicator = make('<div id="ind1">Indicator</div>')
var div = make('<div id="d1" hx-target="this" hx-indicator="#ind1"><button id="b1" hx-get="/test">Click Me!</button></div>')
var btn = byId('b1')
btn.click()
indicator.classList.contains('htmx-request').should.equal(true)
this.server.respond()
indicator.classList.contains('htmx-request').should.equal(false)
this.server.respondWith('GET', '/test', 'Clicked!')
var div = make('<div id="d1" hx-indicator="this"><button id="b1" hx-get="/test">Click Me!</button></div>')
var btn = byId('b1')
btn.click()
btn.classList.contains('htmx-request').should.equal(false)
div.classList.contains('htmx-request').should.equal(true)
this.server.respond()
btn.classList.contains('htmx-request').should.equal(false)
div.classList.contains('htmx-request').should.equal(false)
this.server.respondWith('GET', '/test', 'Clicked!')
var b1 = make('<button hx-get="/test" hx-indicator=".a1">Click Me!</button>')
var b2 = make('<button hx-get="/test" hx-indicator=".a1">Click Me!</button>')
var a1 = make('<a class="a1"></a>')
b1.click()
b1.classList.contains('htmx-request').should.equal(false)
b2.classList.contains('htmx-request').should.equal(false)
a1.classList.contains('htmx-request').should.equal(true)
b2.click()
b1.classList.contains('htmx-request').should.equal(false)
b2.classList.contains('htmx-request').should.equal(false)
a1.classList.contains('htmx-request').should.equal(true)
// hack to make sinon process only one response
this.server.processRequest(this.server.queue.shift())
b1.classList.contains('htmx-request').should.equal(false)
b2.classList.contains('htmx-request').should.equal(false)
a1.classList.contains('htmx-request').should.equal(true)
this.server.respond()
b1.classList.contains('htmx-request').should.equal(false)
b2.classList.contains('htmx-request').should.equal(false)
a1.classList.contains('htmx-request').should.equal(false)
this.server.respondWith('GET', '/test', 'Clicked!')
var btn = make('<button hx-get="/test" hx-disabled-elt="this">Click Me!</button>')
btn.hasAttribute('disabled').should.equal(false)
btn.click()
btn.hasAttribute('disabled').should.equal(true)
this.server.respond()
btn.hasAttribute('disabled').should.equal(false)
this.server.respondWith('GET', '/test', 'Clicked!')
var btn = make('<button hx-get="/test" data-hx-disabled-elt="this">Click Me!</button>')
btn.hasAttribute('disabled').should.equal(false)
btn.click()
btn.hasAttribute('disabled').should.equal(true)
this.server.respond()
btn.hasAttribute('disabled').should.equal(false)
this.server.respondWith('GET', '/test', 'Clicked!')
var fieldset = make('<fieldset><button id="b1" hx-get="/test" hx-disabled-elt="closest fieldset">Click Me!</button></fieldset>')
var btn = byId('b1')
fieldset.hasAttribute('disabled').should.equal(false)
btn.click()
fieldset.hasAttribute('disabled').should.equal(true)
this.server.respond()
fieldset.hasAttribute('disabled').should.equal(false)
this.server.respondWith('GET', '/test', 'Clicked!')
var b1 = make('<button hx-get="/test" hx-disabled-elt="#b3">Click Me!</button>')
var b2 = make('<button hx-get="/test" hx-disabled-elt="#b3">Click Me!</button>')
var b3 = make('<button id="b3">Demo</button>')
b3.hasAttribute('disabled').should.equal(false)
b1.click()
b3.hasAttribute('disabled').should.equal(true)
b2.click()
b3.hasAttribute('disabled').should.equal(true)
// hack to make sinon process only one response
this.server.processRequest(this.server.queue.shift())
b3.hasAttribute('disabled').should.equal(true)
this.server.respond()
b3.hasAttribute('disabled').should.equal(false)
this.server.respondWith('GET', '/test', 'Clicked!')
var b1 = make('<button hx-get="/test" hx-disabled-elt="#b2, #b3">Click Me!</button>')
var b2 = make('<button id="b2">Click Me!</button>')
var b3 = make('<button id="b3">Demo</button>')
b2.hasAttribute('disabled').should.equal(false)
b3.hasAttribute('disabled').should.equal(false)
b1.click()
b2.hasAttribute('disabled').should.equal(true)
b3.hasAttribute('disabled').should.equal(true)
this.server.respond()
b2.hasAttribute('disabled').should.equal(false)
b3.hasAttribute('disabled').should.equal(false)
this.server.respondWith('GET', '/test', 'Loaded!')
var div1 = make('<div id="d1" hx-get="/test" hx-disabled-elt="#b1" hx-trigger="load">Load Me!</div><button id="b1">Demo</button>')
var div = byId('d1')
var btn = byId('b1')
div.innerHTML.should.equal('Load Me!')
btn.hasAttribute('disabled').should.equal(true)
this.server.respond()
div.innerHTML.should.equal('Loaded!')
btn.hasAttribute('disabled').should.equal(false)
this.server.respondWith('GET', '/test', 'Clicked!')
var form = make('<form hx-get="/test" hx-disabled-elt="find input[type=\'text\'], find button" hx-swap="none"><input id="i1" type="text" placeholder="Type here..."><button id="b2" type="submit">Send</button></form>')
var i1 = byId('i1')
var b2 = byId('b2')
i1.hasAttribute('disabled').should.equal(false)
b2.hasAttribute('disabled').should.equal(false)
b2.click()
i1.hasAttribute('disabled').should.equal(true)
b2.hasAttribute('disabled').should.equal(true)
this.server.respond()
i1.hasAttribute('disabled').should.equal(false)
b2.hasAttribute('disabled').should.equal(false)
this.server.respondWith('GET', '/test', 'Clicked!')
var btn1 = make('<button hx-get="/test" hx-disabled-elt="closest input">Click Me!</button>')
var btn2 = make('<button hx-get="/test" hx-disabled-elt="find input">Click Me!</button>')
var btn3 = make('<button hx-get="/test" hx-disabled-elt="next input">Click Me!</button>')
var btn4 = make('<button hx-get="/test" hx-disabled-elt="previous input">Click Me!</button>')
btn1.click()
btn1.hasAttribute('disabled').should.equal(false)
this.server.respond()
btn2.click()
btn2.hasAttribute('disabled').should.equal(false)
this.server.respond()
btn3.click()
btn3.hasAttribute('disabled').should.equal(false)
this.server.respond()
btn4.click()
btn4.hasAttribute('disabled').should.equal(false)
this.server.respond()
this.server.respondWith('GET', '/test', 'Test')
var div = make('<div hx-target="#cta">' +
'<button id="btn1" hx-get="/test"></button>' +
'<span id="cta">Click Me!</span>' +
'</div>')
var btn = byId('btn1')
btn.click()
this.server.respond()
btn.innerText.should.equal('Test')
this.server.respondWith('GET', '/test', 'Test')
var div = make('<div hx-target="#cta" hx-inherit="*">' +
'<button id="btn1" hx-get="/test"></button>' +
'<span id="cta">Click Me!</span>' +
'</div>')
var btn = byId('btn1')
var span = byId('cta')
btn.click()
this.server.respond()
btn.innerText.should.equal('')
span.innerText.should.equal('Test')
this.server.respondWith('GET', '/test', 'Test')
var div = make('<div hx-target="#cta" hx-inherit="hx-target">' +
'<button id="btn1" hx-get="/test"></button>' +
'<span id="cta">Click Me!</span>' +
'</div>')
var btn = byId('btn1')
var span = byId('cta')
btn.click()
this.server.respond()
btn.innerText.should.equal('')
span.innerText.should.equal('Test')
this.server.respondWith('GET', '/test', 'Test')
var div = make('<div hx-target="#cta" hx-inherit="hx-swap">' +
'<button id="btn1" hx-get="/test"></button>' +
'<span id="cta">Click Me!</span>' +
'</div>')
var btn = byId('btn1')
var span = byId('cta')
btn.click()
this.server.respond()
btn.innerText.should.equal('Test')
span.innerText.should.equal('Click Me!')
this.server.respondWith('GET', '/test', 'Test')
var div = make('<div hx-target="#cta" hx-swap="outerHTML" hx-inherit="hx-target hx-swap">' +
'<button id="btn1" hx-get="/test"></button>' +
'<div id="d2"><span id="cta">Click Me!</span></div>' +
'</div>')
var btn = byId('btn1')
var div = byId('d2')
btn.click()
this.server.respond()
div.innerHTML.should.equal('Test')
var response_inner = '<div id="snowflake" class="">Hello world</div>'
var response = '<div id="unique" class="">' + response_inner + '</div>'
this.server.respondWith('GET', '/test', response)
var div = make('<div hx-select="#snowflake" hx-target="#cta" hx-swap="outerHTML"><button id="bx1" hx-get="/test"><span id="cta">Click Me!</span></button></div>')
var btn = byId('bx1')
btn.click()
this.server.respond()
btn.firstChild.id.should.equal('snowflake')
btn.innerText.should.equal('Hello world')
var response_inner = '<div id="snowflake">Hello world</div>'
var response = '<div id="unique">' + response_inner + '</div>'
this.server.respondWith('GET', '/test', response)
var div = make('<div hx-select="#snowflake" hx-target="#cta" hx-swap="beforebegin" hx-disinherit="hx-select"><button id="bx1" hx-get="/test"><span id="cta">Click Me!</span></button></div>')
var btn = byId('bx1')
btn.click()
this.server.respond()
btn.firstChild.id.should.equal('unique')
btn.firstChild.firstChild.id.should.equal('snowflake')
btn.childNodes[1].innerText.should.equal('Click Me!')
var response_inner = '<div id="snowflake">Hello world</div>'
var response = '<div id="unique">' + response_inner + '</div>'
this.server.respondWith('GET', '/test', response)
var div = make('<div hx-select="#snowflake" hx-target="#cta" hx-swap="beforebegin" hx-disinherit="hx-select hx-swap">' +
' <button id="bx1" hx-get="/test"><span id="cta">Click Me!</span></button>' +
'</div>')
var btn = byId('bx1')
btn.click()
this.server.respond()
console.log(btn.innerHTML)
console.log(response)
btn.firstChild.id.should.equal('cta')
btn.firstChild.firstChild.id.should.equal('unique')
btn.firstChild.firstChild.firstChild.id.should.equal('snowflake')
var response_inner = '<div id="snowflake">Hello world</div>'
var response = '<div id="unique">' + response_inner + '</div>'
this.server.respondWith('GET', '/test', response)
var div = make('<div hx-select="#snowflake" hx-target="#cta" hx-swap="beforebegin" hx-disinherit="*">' +
' <button id="bx1" hx-get="/test">' +
' <span id="cta">Click Me!</span>' +
' </button>' +
'</div>')
var btn = byId('bx1')
btn.click()
this.server.respond()
btn.firstChild.id.should.equal('unique')
btn.firstChild.firstChild.id.should.equal('snowflake')
var response_inner = '<div id="snowflake" class="">Hello world</div>'
var response = '<div id="unique">' + response_inner + '</div>'
this.server.respondWith('GET', '/test', response)
var btn = make('<button hx-select="#snowflake" hx-target="#container" hx-trigger="click" hx-get="/test" hx-swap="outerHTML" hx-disinherit="*"><div id="container"></div></button>')
btn.click()
this.server.respond()
btn.firstChild.id.should.equal('snowflake')
btn.firstChild.innerText.should.equal('Hello world')