')
var div = make("")
div.click()
this.server.respond()
should.equal(called, true)
} finally {
htmx.off('htmx:load', handler)
}
})
it('htmx:configRequest allows attribute addition', function() {
var handler = htmx.on('htmx:configRequest', function(evt) {
evt.detail.parameters.param = 'true'
})
try {
var param = null
this.server.respondWith('POST', '/test', function(xhr) {
param = getParameters(xhr).param
xhr.respond(200, {}, '')
})
var div = make("")
div.click()
this.server.respond()
param.should.equal('true')
} finally {
htmx.off('htmx:configRequest', handler)
}
})
it('htmx:configRequest is also dispatched in kebab-case', function() {
var handler = htmx.on('htmx:config-request', function(evt) {
evt.detail.parameters.param = 'true'
})
try {
var param = null
this.server.respondWith('POST', '/test', function(xhr) {
param = getParameters(xhr).param
xhr.respond(200, {}, '')
})
var div = make("")
div.click()
this.server.respond()
param.should.equal('true')
} finally {
htmx.off('htmx:config-request', handler)
}
})
it('events are only dispatched once if kebab and camel case match', function() {
var invoked = 0
var handler = htmx.on('custom', function() {
invoked = invoked + 1
})
try {
var div = make("")
htmx.trigger(div, 'custom')
invoked.should.equal(1)
} finally {
htmx.off('custom', handler)
}
})
it('events accept an options argument and the result works as expected', function() {
var invoked = 0
var handler = htmx.on('custom', function() {
invoked = invoked + 1
}, { once: true })
try {
var div = make("")
htmx.trigger(div, 'custom')
htmx.trigger(div, 'custom')
invoked.should.equal(1)
} finally {
htmx.off('custom', handler)
}
})
it('htmx:configRequest allows attribute removal', function() {
var param = 'foo'
var handler = htmx.on('htmx:configRequest', function(evt) {
delete evt.detail.parameters.param
})
try {
this.server.respondWith('POST', '/test', function(xhr) {
param = getParameters(xhr).param
xhr.respond(200, {}, '')
})
var div = make("")
div.click()
this.server.respond()
should.equal(param, undefined)
} finally {
htmx.off('htmx:configRequest', handler)
}
})
it('htmx:configRequest allows header tweaking', function() {
var header = 'foo'
var handler = htmx.on('htmx:configRequest', function(evt) {
evt.detail.headers['X-My-Header'] = 'bar'
})
try {
this.server.respondWith('POST', '/test', function(xhr) {
header = xhr.requestHeaders['X-My-Header']
xhr.respond(200, {}, '')
})
var div = make("")
div.click()
this.server.respond()
should.equal(header, 'bar')
} finally {
htmx.off('htmx:configRequest', handler)
}
})
it('htmx:configRequest on form gives access to submit event', function() {
var skip = false
var submitterId
var handler = htmx.on('htmx:configRequest', function(evt) {
// submitter may be null, but undefined means the browser doesn't support it
if (typeof evt.detail.triggeringEvent.submitter === 'undefined') {
skip = true
return
}
evt.detail.headers['X-Submitter-Id'] = evt.detail.triggeringEvent.submitter.id
})
try {
this.server.respondWith('POST', '/test', function(xhr) {
submitterId = xhr.requestHeaders['X-Submitter-Id']
xhr.respond(200, {}, '')
})
make('')
var btn = byId('b1')
btn.click()
this.server.respond()
if (skip) {
this._runnable.title += " - Skipped as IE11 doesn't support submitter"
this.skip()
}
should.equal(submitterId, 'b1')
} finally {
htmx.off('htmx:configRequest', handler)
}
})
it('htmx:afterSwap is called when replacing outerHTML', function() {
var called = false
var handler = htmx.on('htmx:afterSwap', function(evt) {
called = true
})
try {
this.server.respondWith('POST', '/test', function(xhr) {
xhr.respond(200, {}, '')
})
var div = make("")
div.click()
this.server.respond()
should.equal(called, true)
} finally {
htmx.off('htmx:afterSwap', handler)
}
})
it('htmx:afterSwap is called when replacing outerHTML, new line content', function() {
var called = false
var handler = htmx.on('htmx:afterSwap', function(evt) {
called = true
})
try {
this.server.respondWith('POST', '/test', function(xhr) {
xhr.respond(200, {}, '\n')
})
var div = make("")
div.click()
this.server.respond()
should.equal(called, true)
} finally {
htmx.off('htmx:afterSwap', handler)
}
})
it('htmx:oobBeforeSwap is called before swap', function() {
var called = false
var handler = htmx.on('htmx:oobBeforeSwap', function(evt) {
called = true
})
try {
this.server.respondWith('POST', '/test', function(xhr) {
xhr.respond(200, {}, "
Baz
")
})
var oob = make('
Blip
')
var div = make("")
div.click()
this.server.respond()
byId('d1').innerHTML.should.equal('Baz')
should.equal(called, true)
} finally {
htmx.off('htmx:oobBeforeSwap', handler)
}
})
it('htmx:oobBeforeSwap can abort a swap', function() {
var called = false
var handler = htmx.on('htmx:oobBeforeSwap', function(evt) {
called = true
evt.preventDefault()
})
try {
this.server.respondWith('POST', '/test', function(xhr) {
xhr.respond(200, {}, "
Baz
")
})
var oob = make('
Blip
')
var div = make("")
div.click()
this.server.respond()
byId('d1').innerHTML.should.equal('Blip')
should.equal(called, true)
} finally {
htmx.off('htmx:oobBeforeSwap', handler)
}
})
it('htmx:oobBeforeSwap is not called on an oob miss', function() {
var called = false
var handler = htmx.on('htmx:oobBeforeSwap', function(evt) {
called = true
})
try {
this.server.respondWith('POST', '/test', function(xhr) {
xhr.respond(200, {}, "
Baz
")
})
var div = make("")
div.click()
this.server.respond()
should.equal(called, false)
} finally {
htmx.off('htmx:oobBeforeSwap', handler)
}
})
it('htmx:oobAfterSwap is called after swap', function() {
var called = false
var handler = htmx.on('htmx:oobAfterSwap', function(evt) {
called = true
})
try {
this.server.respondWith('POST', '/test', function(xhr) {
xhr.respond(200, {}, "
Baz
")
})
var oob = make('
Blip
')
var div = make("")
div.click()
this.server.respond()
byId('d1').innerHTML.should.equal('Baz')
should.equal(called, true)
} finally {
htmx.off('htmx:oobAfterSwap', handler)
}
})
it('htmx:oobAfterSwap is not called on an oob miss', function() {
var called = false
var handler = htmx.on('htmx:oobAfterSwap', function(evt) {
called = true
})
try {
this.server.respondWith('POST', '/test', function(xhr) {
xhr.respond(200, {}, "
Baz
")
})
var div = make("")
div.click()
this.server.respond()
should.equal(called, false)
} finally {
htmx.off('htmx:oobAfterSwap', handler)
}
})
it('htmx:afterSettle is called once when replacing outerHTML', function() {
var called = 0
var handler = htmx.on('htmx:afterSettle', function(evt) {
called++
})
try {
this.server.respondWith('POST', '/test', function(xhr) {
xhr.respond(200, {}, '')
})
var div = make("")
div.click()
this.server.respond()
should.equal(called, 1)
} finally {
htmx.off('htmx:afterSettle', handler)
}
})
it('htmx:afterSettle is called once when replacing outerHTML with whitespace', function() {
var called = 0
var handler = htmx.on('htmx:afterSettle', function(evt) {
called++
})
try {
this.server.respondWith('POST', '/test', function(xhr) {
xhr.respond(200, {}, '\n')
})
var div = make("")
div.click()
this.server.respond()
should.equal(called, 1)
} finally {
htmx.off('htmx:afterSettle', handler)
}
})
it('htmx:afterSettle is called twice when replacing outerHTML with whitespace separated elements', function() {
var called = 0
var handler = htmx.on('htmx:afterSettle', function(evt) {
called++
})
try {
this.server.respondWith('POST', '/test', function(xhr) {
xhr.respond(200, {}, '\n Foo')
})
var div = make("")
div.click()
this.server.respond()
should.equal(called, 2)
} finally {
htmx.off('htmx:afterSettle', handler)
}
})
it('htmx:afterSettle is called multiple times when doing OOB outerHTML swaps', function() {
var called = 0
var handler = htmx.on('htmx:afterSettle', function(evt) {
called++
})
try {
this.server.respondWith('POST', '/test', function(xhr) {
xhr.respond(200, {}, "\n
t1
t2
")
})
var div = make("")
var button = byId('button')
button.click()
this.server.respond()
should.equal(called, 3)
} finally {
htmx.off('htmx:afterSettle', handler)
}
})
it('htmx:afterRequest is called after a successful request', function() {
var called = false
var handler = htmx.on('htmx:afterRequest', function(evt) {
called = true
})
try {
this.server.respondWith('POST', '/test', function(xhr) {
xhr.respond(200, {}, '')
})
var div = make("")
div.click()
this.server.respond()
should.equal(called, true)
} finally {
htmx.off('htmx:afterRequest', handler)
}
})
it('htmx:afterOnLoad is called after a successful request', function() {
var called = false
var handler = htmx.on('htmx:afterOnLoad', function(evt) {
called = true
})
try {
this.server.respondWith('POST', '/test', function(xhr) {
xhr.respond(200, {}, '')
})
var div = make("")
div.click()
this.server.respond()
should.equal(called, true)
} finally {
htmx.off('htmx:afterOnLoad', handler)
}
})
it('htmx:afterRequest is called after a failed request', function() {
var called = false
var handler = htmx.on('htmx:afterRequest', function(evt) {
called = true
})
try {
this.server.respondWith('POST', '/test', function(xhr) {
xhr.respond(500, {}, '')
})
var div = make("")
div.click()
this.server.respond()
should.equal(called, true)
} finally {
htmx.off('htmx:afterRequest', handler)
}
})
it('htmx:sendError is called after a failed request', function(done) {
htmx.config.selfRequestsOnly = false // turn off self requests only
var called = false
var handler = htmx.on('htmx:sendError', function(evt) {
called = true
})
this.server.restore() // turn off server mock so connection doesn't work
var div = make("")
div.click()
setTimeout(function() {
htmx.off('htmx:sendError', handler)
should.equal(called, true)
htmx.config.selfRequestsOnly = true // restore self requests only
done()
}, 30)
})
it('htmx:afterRequest is called when replacing outerHTML', function() {
var called = false
var handler = htmx.on('htmx:afterRequest', function(evt) {
called = true
})
try {
this.server.respondWith('POST', '/test', function(xhr) {
xhr.respond(200, {}, '')
})
var div = make("")
div.click()
this.server.respond()
should.equal(called, true)
} finally {
htmx.off('htmx:afterRequest', handler)
}
})
it('htmx:afterOnLoad is called when replacing outerHTML', function() {
var called = false
var handler = htmx.on('htmx:afterOnLoad', function(evt) {
called = true
})
try {
this.server.respondWith('POST', '/test', function(xhr) {
xhr.respond(200, {}, '')
})
var div = make("")
div.click()
this.server.respond()
should.equal(called, true)
} finally {
htmx.off('htmx:afterOnLoad', handler)
}
})
it('htmx:beforeProcessNode is called when replacing outerHTML', function() {
var called = false
var handler = htmx.on('htmx:beforeProcessNode', function(evt) {
called = true
})
try {
this.server.respondWith('POST', '/test', function(xhr) {
xhr.respond(200, {}, '')
})
var div = make("")
div.click()
this.server.respond()
should.equal(called, true)
} finally {
htmx.off('htmx:beforeProcessNode', handler)
}
})
it('htmx:beforeProcessNode allows htmx attribute tweaking', function() {
var called = false
var handler = htmx.on('htmx:beforeProcessNode', function(evt) {
evt.target.setAttribute('hx-post', '/success')
called = true
})
try {
this.server.respondWith('POST', '/success', function(xhr) {
xhr.respond(200, {}, '')
})
var div = make("")
div.click()
this.server.respond()
should.equal(called, true)
} finally {
htmx.off('htmx:beforeProcessNode', handler)
}
})
it('htmx:afterProcessNode is called after replacing outerHTML', function() {
var called = false
var handler = htmx.on('htmx:afterProcessNode', function(evt) {
called = true
})
try {
this.server.respondWith('POST', '/test', function(xhr) {
xhr.respond(200, {}, '')
})
var div = make("")
div.click()
this.server.respond()
should.equal(called, true)
} finally {
htmx.off('htmx:afterProcessNode', handler)
}
})
it('htmx:afterRequest is called when targeting a parent div', function() {
var called = false
var handler = htmx.on('htmx:afterRequest', function(evt) {
called = true
})
try {
this.server.respondWith('POST', '/test', function(xhr) {
xhr.respond(200, {}, '')
})
var div = make("")
var button = byId('b1')
button.click()
this.server.respond()
should.equal(called, true)
} finally {
htmx.off('htmx:afterRequest', handler)
}
})
it('adding an error in htmx:configRequest stops the request', function() {
try {
var handler = htmx.on('htmx:configRequest', function(evt) {
evt.detail.errors.push('An error')
})
var request = false
this.server.respondWith('POST', '/test', function(xhr) {
request = true
xhr.respond(200, {}, '')
})
var div = make("")
div.click()
this.server.respond()
should.equal(request, false)
} finally {
htmx.off('htmx:configRequest', handler)
}
})
it('preventDefault() in htmx:configRequest stops the request', function() {
try {
var handler = htmx.on('htmx:configRequest', function(evt) {
evt.preventDefault()
})
var request = false
this.server.respondWith('POST', '/test', function(xhr) {
request = true
xhr.respond(200, {}, '')
})
var div = make("")
div.click()
this.server.respond()
should.equal(request, false)
} finally {
htmx.off('htmx:configRequest', handler)
}
})
it('preventDefault() in the htmx:beforeRequest event cancels the request', function() {
try {
var handler = htmx.on('htmx:beforeRequest', function(evt) {
evt.preventDefault()
})
var request = false
this.server.respondWith('POST', '/test', function(xhr) {
request = true
xhr.respond(200, {}, '')
})
var div = make("")
div.click()
this.server.respond()
should.equal(request, false)
} finally {
htmx.off('htmx:beforeRequest', handler)
}
})
it('preventDefault() in the htmx:beforeOnLoad event cancels the swap', function() {
try {
var handler = htmx.on('htmx:beforeOnLoad', function(evt) {
evt.preventDefault()
})
var request = false
this.server.respondWith('POST', '/test', function(xhr) {
request = true
xhr.respond(200, {}, 'Bar')
})
var div = make("")
div.click()
this.server.respond()
should.equal(request, true)
div.innerText.should.equal('Foo')
} finally {
htmx.off('htmx:beforeOnLoad', handler)
}
})
it("htmx:afterRequest event contains 'successful' and 'failed' properties indicating success after successful request", function() {
var successful = false
var failed = true
var handler = htmx.on('htmx:afterRequest', function(evt) {
successful = evt.detail.successful
failed = evt.detail.failed
})
try {
this.server.respondWith('POST', '/test', function(xhr) {
xhr.respond(200, {}, '')
})
var div = make("")
div.click()
this.server.respond()
should.equal(successful, true)
should.equal(failed, false)
} finally {
htmx.off('htmx:afterRequest', handler)
}
})
it("htmx:afterRequest event contains 'successful' and 'failed' properties indicating failure after failed request", function() {
var successful = true
var failed = false
var handler = htmx.on('htmx:afterRequest', function(evt) {
successful = evt.detail.successful
failed = evt.detail.failed
})
try {
this.server.respondWith('POST', '/test', function(xhr) {
xhr.respond(500, {}, '')
})
var div = make("")
div.click()
this.server.respond()
should.equal(successful, false)
should.equal(failed, true)
} finally {
htmx.off('htmx:afterRequest', handler)
}
})
it('htmx:confirm can cancel request', function() {
var allow = false
var handler = htmx.on('htmx:confirm', function(evt) {
evt.preventDefault()
if (allow) {
evt.detail.issueRequest()
}
})
try {
this.server.respondWith('GET', '/test', 'updated')
var div = make("")
div.click()
this.server.respond()
div.innerHTML.should.equal('')
allow = true
div.click()
this.server.respond()
div.innerHTML.should.equal('updated')
} finally {
htmx.off('htmx:confirm', handler)
}
})
it('has updated target available when target set via htmx:beforeSwap', function() {
var targetWasUpdatedInAfterSwapHandler = false
var beforeSwapHandler = htmx.on('htmx:beforeSwap', function(evt) {
console.log('beforeSwap', evt.detail.target, byId('d2'))
evt.detail.target = byId('d2')
})
var afterSwapHandler = htmx.on('htmx:afterSwap', function(evt) {
console.log('afterSwap', evt.detail.target, byId('d2'))
targetWasUpdatedInAfterSwapHandler = evt.detail.target === byId('d2')
})
try {
this.server.respondWith('GET', '/test', 'updated')
make("")
var div = byId('d0')
div.click()
this.server.respond()
targetWasUpdatedInAfterSwapHandler.should.equal(true)
} finally {
htmx.off('htmx:beforeSwap', beforeSwapHandler)
htmx.off('htmx:afterSwap', afterSwapHandler)
}
})
it('htmx:beforeSwap can override swap style using evt.detail.swapOverride and has final say on it', function() {
var swapWasOverriden = false
var responseBody = 'look at me. iām the innerHTML now.'
var beforeSwapHandler = htmx.on('htmx:beforeSwap', function(evt) {
evt.detail.swapOverride = 'innerHTML'
})
var afterSwapHandler = htmx.on('htmx:afterSwap', function(evt) {
console.log('afterSwap', byId('b').innerHTML)
swapWasOverriden = byId('b') !== null && byId('b').innerHTML === responseBody
})
try {
this.server.respondWith('GET', '/test', [200, { 'HX-Reswap': 'afterbegin' }, responseBody])
make("