diff --git a/src/ext/ws.js b/src/ext/ws.js index 39607139b..afd829954 100644 --- a/src/ext/ws.js +++ b/src/ext/ws.js @@ -341,7 +341,7 @@ This extension adds support for WebSockets to htmx. See /www/extensions/ws.md f /** @type {WebSocketWrapper} */ var socketWrapper = api.getInternalData(socketElt).webSocket; - var headers = api.getHeaders(sendElt, socketElt); + var headers = api.getHeaders(sendElt, api.getTarget(sendElt)); var results = api.getInputValues(sendElt, 'post'); var errors = results.errors; var rawParameters = results.values; diff --git a/src/htmx.js b/src/htmx.js index 26cc929e6..d0bbffa9a 100644 --- a/src/htmx.js +++ b/src/htmx.js @@ -1929,18 +1929,22 @@ return (function () { function addHxOnEventHandler(elt, eventName, code) { var nodeData = getInternalData(elt); nodeData.onHandlers = []; - var func = new Function("event", code + "; return;"); + var func; var listener = function (e) { - return func.call(elt, e); + return maybeEval(elt, function() { + if (!func) { + func = new Function("event", code); + } + func.call(elt, e); + }); }; elt.addEventListener(eventName, listener); nodeData.onHandlers.push({event:eventName, listener:listener}); - return {nodeData:nodeData, code:code, func:func, listener:listener}; } function processHxOn(elt) { var hxOnValue = getAttributeValue(elt, 'hx-on'); - if (hxOnValue && htmx.config.allowEval) { + if (hxOnValue) { var handlers = {} var lines = hxOnValue.split("\n"); var currentEvent = null; diff --git a/test/attributes/hx-on-wildcard.js b/test/attributes/hx-on-wildcard.js index 920214727..1bde519af 100644 --- a/test/attributes/hx-on-wildcard.js +++ b/test/attributes/hx-on-wildcard.js @@ -130,4 +130,21 @@ describe("hx-on:* attribute", function() { 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(""); + btn.click(); + should.not.exist(window.foo); + } finally { + htmx.config.allowEval = true; + htmx.off("htmx:evalDisallowedError", handler); + delete window.foo; + } + calledEvent.should.equal(true); + }); }); diff --git a/test/attributes/hx-on.js b/test/attributes/hx-on.js index 9a2005b11..5bb5ac22d 100644 --- a/test/attributes/hx-on.js +++ b/test/attributes/hx-on.js @@ -119,4 +119,21 @@ describe("hx-on attribute", function() { 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(""); + btn.click(); + should.not.exist(window.foo); + } finally { + htmx.config.allowEval = true; + htmx.off("htmx:evalDisallowedError", handler); + delete window.foo; + } + calledEvent.should.equal(true); + }); }); diff --git a/test/attributes/hx-vals.js b/test/attributes/hx-vals.js index e2728e2c4..4c7e2d335 100644 --- a/test/attributes/hx-vals.js +++ b/test/attributes/hx-vals.js @@ -252,4 +252,49 @@ describe("hx-vals attribute", function() { div.innerHTML.should.equal("Clicked!"); }); + it('javascript: is not evaluated when allowEval is false', function () { + var calledEvent = false; + var handler = htmx.on("htmx:evalDisallowedError", function(){ + calledEvent = true; + }); + try { + htmx.config.allowEval = false; + this.server.respondWith("POST", "/vars", function (xhr) { + var params = getParameters(xhr); + should.not.exist(params['i1']); + xhr.respond(200, {}, "Clicked!") + }); + var div = make('
') + div.click(); + this.server.respond(); + div.innerHTML.should.equal("Clicked!"); + } finally { + htmx.config.allowEval = true; + htmx.off("htmx:evalDisallowedError", handler); + } + calledEvent.should.equal(true); + }); + + it('js: is not evaluated when allowEval is false', function () { + var calledEvent = false; + var handler = htmx.on("htmx:evalDisallowedError", function(){ + calledEvent = true; + }); + try { + htmx.config.allowEval = false; + this.server.respondWith("POST", "/vars", function (xhr) { + var params = getParameters(xhr); + should.not.exist(params['i1']); + xhr.respond(200, {}, "Clicked!") + }); + var div = make('
') + div.click(); + this.server.respond(); + div.innerHTML.should.equal("Clicked!"); + } finally { + htmx.config.allowEval = true; + htmx.off("htmx:evalDisallowedError", handler); + } + calledEvent.should.equal(true); + }); }); diff --git a/test/attributes/hx-vars.js b/test/attributes/hx-vars.js index be20caf43..f9647c0a5 100644 --- a/test/attributes/hx-vars.js +++ b/test/attributes/hx-vars.js @@ -152,4 +152,26 @@ describe("hx-vars attribute", function() { div.innerHTML.should.equal("Clicked!"); }); + it('is not evaluated when allowEval is false', function () { + var calledEvent = false; + var handler = htmx.on("htmx:evalDisallowedError", function(){ + calledEvent = true; + }); + try { + htmx.config.allowEval = false; + this.server.respondWith("POST", "/vars", function (xhr) { + var params = getParameters(xhr); + should.not.exist(params['i1']); + xhr.respond(200, {}, "Clicked!") + }); + var div = make('
') + div.click(); + this.server.respond(); + div.innerHTML.should.equal("Clicked!"); + } finally { + htmx.config.allowEval = true; + htmx.off("htmx:evalDisallowedError", handler); + } + calledEvent.should.equal(true); + }); }); diff --git a/test/ext/ws.js b/test/ext/ws.js index 442872d8b..5a887b6d6 100644 --- a/test/ext/ws.js +++ b/test/ext/ws.js @@ -88,6 +88,27 @@ describe("web-sockets extension", function () { this.messages.length.should.equal(1); }) + it('sends expected headers to the server', function () { + var div = make('
'); + this.tickMock(); + + byId("d1").click(); + + this.tickMock(); + + this.messages.length.should.equal(1); + var message = JSON.parse(this.messages[0]); + var headers = message.HEADERS; + + console.log(headers); + + headers['HX-Request'].should.be.equal('true'); + headers['HX-Current-URL'].should.be.equal(document.location.href) + headers['HX-Trigger'].should.be.equal('d1'); + headers['HX-Trigger-Name'].should.be.equal('d1-name'); + headers['HX-Target'].should.be.equal('target'); + }) + it('handles message from the server', function () { var div = make('
div1
div2
'); this.tickMock();