htmx/test/attributes/hx-on-wildcard.js
Mark Gibson 94623d1129
Fix hx-on/hx-on:* to suppress evaluation if allowEval is false (#1682)
* Added more tests for allowEval=false

* Wrap hx-on event handlers in maybeEval

* Create and cache hx-on function on first event trigger.
2023-08-24 12:11:00 -06:00

151 lines
5.4 KiB
JavaScript

describe("hx-on:* attribute", function() {
beforeEach(function () {
this.server = makeServer();
clearWorkArea();
});
afterEach(function () {
this.server.restore();
clearWorkArea();
});
it("can handle basic events w/ no other attributes", function () {
var btn = make("<button hx-on:click='window.foo = true'>Foo</button>");
btn.click();
window.foo.should.equal(true);
delete window.foo;
});
it("can modify a parameter via htmx:configRequest", function () {
this.server.respondWith("POST", "/test", function (xhr) {
var params = parseParams(xhr.requestBody);
xhr.respond(200, {}, params.foo);
});
var btn = make("<button hx-on:htmx:config-request='event.detail.parameters.foo = \"bar\"' hx-post='/test'>Foo</button>");
btn.click();
this.server.respond();
btn.innerText.should.equal("bar");
});
it("expands :: shorthand into htmx:", function () {
this.server.respondWith("POST", "/test", function (xhr) {
var params = parseParams(xhr.requestBody);
xhr.respond(200, {}, params.foo);
});
var btn = make("<button hx-on::config-request='event.detail.parameters.foo = \"bar\"' hx-post='/test'>Foo</button>");
btn.click();
this.server.respond();
btn.innerText.should.equal("bar");
});
it("can cancel an event via preventDefault for htmx:config-request", function () {
this.server.respondWith("POST", "/test", function (xhr) {
xhr.respond(200, {}, "<button>Bar</button>");
});
var btn = make("<button hx-on:htmx:config-request='event.preventDefault()' hx-post='/test' hx-swap='outerHTML'>Foo</button>");
btn.click();
this.server.respond();
btn.innerText.should.equal("Foo");
});
it("can respond to data-hx-on", function () {
this.server.respondWith("POST", "/test", function (xhr) {
var params = parseParams(xhr.requestBody);
xhr.respond(200, {}, params.foo);
});
var btn = make("<button data-hx-on:htmx:config-request='event.detail.parameters.foo = \"bar\"' hx-post='/test'>Foo</button>");
btn.click();
this.server.respond();
btn.innerText.should.equal("bar");
});
it("has the this symbol set to the element", function () {
this.server.respondWith("POST", "/test", function (xhr) {
xhr.respond(200, {}, "foo");
});
var btn = make("<button hx-on:htmx:config-request='window.elt = this' hx-post='/test'>Foo</button>");
btn.click();
this.server.respond();
btn.innerText.should.equal("foo");
btn.should.equal(window.elt);
delete window.elt;
});
it("can handle multi-line JSON", function () {
this.server.respondWith("POST", "/test", function (xhr) {
xhr.respond(200, {}, "foo");
});
var btn = make("<button hx-on:htmx:config-request='window.elt = {foo: true,\n" +
" bar: false}' hx-post='/test'>Foo</button>");
btn.click();
this.server.respond();
btn.innerText.should.equal("foo");
var obj = {foo: true, bar: false};
obj.should.deep.equal(window.elt);
delete window.elt;
});
it("can handle multiple event handlers in the presence of multi-line JSON", function () {
this.server.respondWith("POST", "/test", function (xhr) {
xhr.respond(200, {}, "foo");
});
var btn = make("<button hx-on:htmx:config-request='window.elt = {foo: true,\n" +
" bar: false}\n'" +
" hx-on:htmx:after-request='window.foo = true'" +
" hx-post='/test'>Foo</button>");
btn.click();
this.server.respond();
btn.innerText.should.equal("foo");
var obj = {foo: true, bar: false};
obj.should.deep.equal(window.elt);
delete window.elt;
window.foo.should.equal(true);
delete window.foo;
});
it("de-initializes hx-on-* content properly", function () {
window.tempCount = 0;
this.server.respondWith("POST", "/test", function (xhr) {
xhr.respond(200, {}, "<button id='foo' hx-on:click=\"window.tempCount++;\">increment</button>");
});
var div = make("<div hx-post='/test'>Foo</div>");
// get response
div.click();
this.server.respond();
// click button
byId('foo').click();
window.tempCount.should.equal(1);
// get second response
div.click();
this.server.respond();
// click button again
byId('foo').click();
window.tempCount.should.equal(2);
delete window.tempCount;
});
it("is not evaluated when allowEval is false", function () {
var calledEvent = false;
var handler = htmx.on("htmx:evalDisallowedError", function(){
calledEvent = true;
});
htmx.config.allowEval = false;
try {
var btn = make("<button hx-on:click='window.foo = true'>Foo</button>");
btn.click();
should.not.exist(window.foo);
} finally {
htmx.config.allowEval = true;
htmx.off("htmx:evalDisallowedError", handler);
delete window.foo;
}
calledEvent.should.equal(true);
});
});