diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/attributes/hx-ext.js | 6 | ||||
-rw-r--r-- | test/attributes/hx-push-url.js | 8 | ||||
-rw-r--r-- | test/core/ajax.js | 4 | ||||
-rw-r--r-- | test/core/api.js | 2 | ||||
-rw-r--r-- | test/core/events.js | 24 | ||||
-rw-r--r-- | test/ext/extension-swap.js | 2 | ||||
-rw-r--r-- | test/ext/hyperscript.js | 4 | ||||
-rw-r--r-- | test/lib/_hyperscript.js | 144 |
8 files changed, 139 insertions, 55 deletions
diff --git a/test/attributes/hx-ext.js b/test/attributes/hx-ext.js index cead2f51..1211e722 100644 --- a/test/attributes/hx-ext.js +++ b/test/attributes/hx-ext.js @@ -8,21 +8,21 @@ describe("hx-ext attribute", function() { clearWorkArea(); htmx.defineExtension("ext-1", { onEvent : function(name, evt) { - if(name === "afterRequest.htmx"){ + if(name === "htmx:afterRequest"){ ext1Calls++; } } }); htmx.defineExtension("ext-2", { onEvent : function(name, evt) { - if(name === "afterRequest.htmx"){ + if(name === "htmx:afterRequest"){ ext2Calls++; } } }); htmx.defineExtension("ext-3", { onEvent : function(name, evt) { - if(name === "afterRequest.htmx"){ + if(name === "htmx:afterRequest"){ ext3Calls++; } } diff --git a/test/attributes/hx-push-url.js b/test/attributes/hx-push-url.js index 81983f80..e137d4a0 100644 --- a/test/attributes/hx-push-url.js +++ b/test/attributes/hx-push-url.js @@ -114,7 +114,7 @@ describe("hx-push-url attribute", function() { it("afterSettle.htmx is called when replacing outerHTML", function () { var called = false; - var handler = htmx.on("afterSettle.htmx", function (evt) { + var handler = htmx.on("htmx:afterSettle", function (evt) { called = true; }); try { @@ -126,13 +126,13 @@ describe("hx-push-url attribute", function() { this.server.respond(); should.equal(called, true); } finally { - htmx.off("afterSettle.htmx", handler); + htmx.off("htmx:afterSettle", handler); } }); it("should include parameters on a get", function () { var path = ""; - var handler = htmx.on("pushedIntoHistory.htmx", function (evt) { + var handler = htmx.on("htmx:pushedIntoHistory", function (evt) { path = evt.detail.path; }); try { @@ -145,7 +145,7 @@ describe("hx-push-url attribute", function() { form.textContent.should.equal("second") path.should.equal("/test?foo=bar") } finally { - htmx.off("pushedIntoHistory.htmx", handler); + htmx.off("htmx:pushedIntoHistory", handler); } }); diff --git a/test/core/ajax.js b/test/core/ajax.js index 8d51dc56..efdb738c 100644 --- a/test/core/ajax.js +++ b/test/core/ajax.js @@ -439,7 +439,7 @@ describe("Core htmx AJAX Tests", function(){ { var path = null; var div = make("<div hx-get=''/>"); - htmx.on(div, "configRequest.htmx", function (evt) { + htmx.on(div, "htmx:configRequest", function (evt) { path = evt.detail.path; return false; }); @@ -452,7 +452,7 @@ describe("Core htmx AJAX Tests", function(){ { var path = null; var div = make("<div hx-get/>"); - htmx.on(div, "configRequest.htmx", function (evt) { + htmx.on(div, "htmx:configRequest", function (evt) { path = evt.detail.path; return false; }); diff --git a/test/core/api.js b/test/core/api.js index 63b248ec..10c84ad2 100644 --- a/test/core/api.js +++ b/test/core/api.js @@ -20,7 +20,7 @@ describe("Core htmx API test", function(){ this.server.respond(); byId("d1").getAttribute("foo").should.equal("bar"); } finally { - htmx.off("load.htmx", helper); + htmx.off("htmx:load", helper); } }); diff --git a/test/core/events.js b/test/core/events.js index dfe5705b..c7db8fa1 100644 --- a/test/core/events.js +++ b/test/core/events.js @@ -10,7 +10,7 @@ describe("Core htmx Events", function() { it("load.htmx fires properly", function () { var called = false; - var handler = htmx.on("load.htmx", function (evt) { + var handler = htmx.on("htmx:load", function (evt) { called = true; }); try { @@ -21,12 +21,12 @@ describe("Core htmx Events", function() { this.server.respond(); should.equal(called, true); } finally { - htmx.off("load.htmx", handler); + htmx.off("htmx:load", handler); } }); it("configRequest.htmx allows attribute addition", function () { - var handler = htmx.on("configRequest.htmx", function (evt) { + var handler = htmx.on("htmx:configRequest", function (evt) { evt.detail.parameters['param'] = "true"; }); try { @@ -40,13 +40,13 @@ describe("Core htmx Events", function() { this.server.respond(); param.should.equal("true"); } finally { - htmx.off("configRequest.htmx", handler); + htmx.off("htmx:configRequest", handler); } }); it("configRequest.htmx allows attribute removal", function () { var param = "foo"; - var handler = htmx.on("configRequest.htmx", function (evt) { + var handler = htmx.on("htmx:configRequest", function (evt) { delete evt.detail.parameters['param']; }); try { @@ -59,13 +59,13 @@ describe("Core htmx Events", function() { this.server.respond(); should.equal(param, undefined); } finally { - htmx.off("configRequest.htmx", handler); + htmx.off("htmx:configRequest", handler); } }); it("configRequest.htmx allows header tweaking", function () { var header = "foo"; - var handler = htmx.on("configRequest.htmx", function (evt) { + var handler = htmx.on("htmx:configRequest", function (evt) { evt.detail.headers['X-My-Header'] = "bar"; }); try { @@ -78,13 +78,13 @@ describe("Core htmx Events", function() { this.server.respond(); should.equal(header, "bar"); } finally { - htmx.off("configRequest.htmx", handler); + htmx.off("htmx:configRequest", handler); } }); it("afterSwap.htmx is called when replacing outerHTML", function () { var called = false; - var handler = htmx.on("afterSwap.htmx", function (evt) { + var handler = htmx.on("htmx:afterSwap", function (evt) { called = true; }); try { @@ -96,13 +96,13 @@ describe("Core htmx Events", function() { this.server.respond(); should.equal(called, true); } finally { - htmx.off("afterSwap.htmx", handler); + htmx.off("htmx:afterSwap", handler); } }); it("afterSettle.htmx is called when replacing outerHTML", function () { var called = false; - var handler = htmx.on("afterSettle.htmx", function (evt) { + var handler = htmx.on("htmx:afterSettle", function (evt) { called = true; }); try { @@ -114,7 +114,7 @@ describe("Core htmx Events", function() { this.server.respond(); should.equal(called, true); } finally { - htmx.off("afterSettle.htmx", handler); + htmx.off("htmx:afterSettle", handler); } }); diff --git a/test/ext/extension-swap.js b/test/ext/extension-swap.js index cda42f16..0186b525 100644 --- a/test/ext/extension-swap.js +++ b/test/ext/extension-swap.js @@ -9,7 +9,7 @@ describe("default extensions behavior", function() { htmx.defineExtension("ext-testswap", { onEvent : function(name, evt) { - if (name === "load.htmx") { + if (name === "htmx:load") { loadCalls.push(evt.detail.elt); } }, diff --git a/test/ext/hyperscript.js b/test/ext/hyperscript.js index 4c7f8674..07b93bfd 100644 --- a/test/ext/hyperscript.js +++ b/test/ext/hyperscript.js @@ -18,7 +18,7 @@ describe("hyperscript integration", function() { it('can handle htmx driven events', function () { this.server.respondWith("GET", "/test", "Clicked!"); - var btn = make('<button _="on afterSettle.htmx add .afterSettle" hx-get="/test">Click Me!</button>') + var btn = make('<button _="on htmx:afterSettle add .afterSettle" hx-get="/test">Click Me!</button>') btn.classList.contains("afterSettle").should.equal(false); btn.click(); this.server.respond(); @@ -28,7 +28,7 @@ describe("hyperscript integration", function() { it('can handle htmx error events', function () { this.server.respondWith("GET", "/test", [404, {}, "Bad request"]); var div = make('<div id="d1"></div>') - var btn = make('<button _="on error.htmx(errorInfo) put errorInfo.error into #d1.innerHTML" hx-get="/test">Click Me!</button>') + var btn = make('<button _="on htmx:error(errorInfo) put errorInfo.error into #d1.innerHTML" hx-get="/test">Click Me!</button>') btn.click(); this.server.respond(); div.innerHTML.should.equal("Response Status Error Code 404 from /test"); diff --git a/test/lib/_hyperscript.js b/test/lib/_hyperscript.js index bf6a5495..ebe8da67 100644 --- a/test/lib/_hyperscript.js +++ b/test/lib/_hyperscript.js @@ -554,13 +554,9 @@ ctx = ctx || {}; var compiled = _parser.parseElement(type, _lexer.tokenize(src) ).transpile(); var evalString = "(function(" + Object.keys(ctx).join(",") + "){return " + compiled + "})"; - // TODO parser debugging - if(false) console.log("transpile: " + compiled); - if(false) console.log("evalString: " + evalString); var args = Object.keys(ctx).map(function (key) { return ctx[key] }); - if(false) console.log("args", args); return eval(evalString).apply(null, args); } @@ -570,7 +566,9 @@ var tokens = _lexer.tokenize(src); var hyperScript = _parser.parseHyperScript(tokens); var transpiled = _parser.transpile(hyperScript); - if(true) console.log(transpiled); + if (elt.getAttribute('debug') === "true") { + console.log(transpiled); + } var hyperscriptObj = eval(transpiled); hyperscriptObj.applyEventListenersTo(elt); } @@ -579,7 +577,7 @@ function ajax(method, url, callback, data) { var xhr = new XMLHttpRequest(); xhr.onload = function() { - callback(this.response) + callback(this.response, xhr); }; xhr.open(method, url); xhr.send(JSON.stringify(data)); @@ -657,7 +655,7 @@ type: "nakedString", tokens: tokenArr, transpile: function () { - return "'" + tokenArr.map(function(t){return t.value}).join("") + "'"; + return "'" + tokenArr.map(function(t){return t.value}).join("") + "'"; } } } @@ -757,6 +755,32 @@ }) + _parser.addGrammarElement("namedArgumentList", function (parser, tokens) { + if (tokens.matchOpToken("(")) { + var fields = [] + if (!tokens.matchOpToken(")")) { + do { + var name = tokens.requireTokenType("IDENTIFIER"); + tokens.requireOpToken(":"); + var value = parser.parseElement("expression", tokens); + fields.push({name: name, value: value}); + } while (tokens.matchOpToken(",")) + tokens.requireOpToken(")"); + } + return { + type: "namedArgumentList", + fields: fields, + transpile: function () { + return "({_namedArgList_:true, " + fields.map(function (field) { + return field.name.value + ":" + parser.transpile(field.value) + }).join(", ") + "})"; + } + } + } + + + }) + _parser.addGrammarElement("symbol", function (parser, tokens) { var identifier = tokens.matchTokenType('IDENTIFIER'); if (identifier) { @@ -1106,8 +1130,8 @@ }); _parser.addGrammarElement("command", function (parser, tokens) { - return parser.parseAnyOf(["onCmd", "addCmd", "removeCmd", "toggleCmd", "waitCmd", "sendCmd", - "takeCmd", "logCmd", "callCmd", "putCmd", "ifCmd", "ajaxCmd"], tokens); + return parser.parseAnyOf(["onCmd", "addCmd", "removeCmd", "toggleCmd", "waitCmd", "sendCmd", "triggerCmd", + "takeCmd", "logCmd", "callCmd", "putCmd", "setCmd", "ifCmd", "ajaxCmd"], tokens); }) _parser.addGrammarElement("commandList", function (parser, tokens) { @@ -1134,9 +1158,9 @@ return "(function(){\n" + "var eventListeners = []\n" + eventListeners.map(function (el) { - return "eventListeners.push(" + parser.transpile(el) + ");\n" - }) + - " function applyEventListenersTo(elt) { _hyperscript.runtime.applyEventListeners(this, elt) }" + + return " eventListeners.push(" + parser.transpile(el) + ");\n" + }).join("") + + " function applyEventListenersTo(elt) { _hyperscript.runtime.applyEventListeners(this, elt) }\n" + " return {eventListeners:eventListeners, applyEventListenersTo:applyEventListenersTo}\n" + "})()" } @@ -1146,7 +1170,7 @@ _parser.addGrammarElement("eventListener", function (parser, tokens) { tokens.requireToken("on"); - var on = parser.parseElement("dotPath", tokens); + var on = parser.parseElement("dotOrColonPath", tokens); if (on == null) { parser.raiseParseError(tokens, "Expected event name") } @@ -1326,18 +1350,24 @@ } }) - _parser.addGrammarElement("dotPath", function (parser, tokens) { + // TODO - colon path needs to eventually become part of ruby-style symbols + _parser.addGrammarElement("dotOrColonPath", function (parser, tokens) { var root = tokens.matchTokenType("IDENTIFIER"); if (root) { var path = [root.value]; - while (tokens.matchOpToken(".")) { - path.push(tokens.requireTokenType("IDENTIFIER").value); + + var separator = tokens.matchOpToken(".") || tokens.matchOpToken(":"); + if (separator) { + do { + path.push(tokens.requireTokenType("IDENTIFIER").value); + } while (tokens.matchOpToken(separator.value)) } + return { - type: "dotPath", + type: "dotOrColonPath", path: path, transpile: function () { - return path.join("."); + return path.join(separator ? separator.value : ""); } } } @@ -1346,9 +1376,9 @@ _parser.addGrammarElement("sendCmd", function (parser, tokens) { if (tokens.matchToken("send")) { - var eventName = parser.parseElement("dotPath", tokens); + var eventName = parser.parseElement("dotOrColonPath", tokens); - var details = parser.parseElement("objectLiteral", tokens); + var details = parser.parseElement("namedArgumentList", tokens); if (tokens.matchToken("to")) { var to = parser.parseElement("target", tokens); } else { @@ -1369,6 +1399,23 @@ } }) + _parser.addGrammarElement("triggerCmd", function (parser, tokens) { + if (tokens.matchToken("trigger")) { + + var eventName = parser.parseElement("dotOrColonPath", tokens); + var details = parser.parseElement("namedArgumentList", tokens); + + return { + type: "triggerCmd", + eventName: eventName, + details: details, + transpile: function () { + return "_hyperscript.runtime.triggerEvent(me, '" + parser.transpile(eventName) + "'," + parser.transpile(details, "{}") + ");"; + } + } + } + }) + _parser.addGrammarElement("takeCmd", function (parser, tokens) { if (tokens.matchToken("take")) { var classRef = tokens.requireTokenType(tokens, "CLASS_REF"); @@ -1430,7 +1477,7 @@ }) _parser.addGrammarElement("callCmd", function (parser, tokens) { - if (tokens.matchToken("call")) { + if (tokens.matchToken("call") || tokens.matchToken("get")) { return { type: "callCmd", expr: parser.parseElement("expression", tokens), @@ -1448,12 +1495,16 @@ var operation = tokens.matchToken("into") || tokens.matchToken("before") || - tokens.matchToken("afterbegin") || - tokens.matchToken("beforeend") || tokens.matchToken("after"); + if (operation == null && tokens.matchToken("at")) { + operation = tokens.matchToken("start") || + tokens.matchToken("end"); + tokens.requireToken("of"); + } + if (operation == null) { - parser.raiseParseError(tokens, "Expected one of 'into', 'before', 'afterbegin', 'beforeend', 'after'") + parser.raiseParseError(tokens, "Expected one of 'into', 'before', 'at start of', 'at end of', 'after'"); } var target = parser.parseElement("target", tokens); @@ -1482,11 +1533,11 @@ return "_hyperscript.runtime.forEach( " + parser.transpile(target) + ", function (target) {" + " target.insertAdjacentHTML('beforebegin', " + parser.transpile(value) + ")" + "})"; - } else if (this.op === "afterbegin") { + } else if (this.op === "start") { return "_hyperscript.runtime.forEach( " + parser.transpile(target) + ", function (target) {" + " target.insertAdjacentHTML('afterbegin', " + parser.transpile(value) + ")" + "})"; - } else if (this.op === "beforeend") { + } else if (this.op === "end") { return "_hyperscript.runtime.forEach( " + parser.transpile(target) + ", function (target) {" + " target.insertAdjacentHTML('beforeend', " + parser.transpile(value) + ")" + "})"; @@ -1501,9 +1552,44 @@ } }) + _parser.addGrammarElement("setCmd", function (parser, tokens) { + if (tokens.matchToken("set")) { + + var target = parser.parseElement("target", tokens); + + tokens.requireToken("to"); + + var value = parser.parseElement("expression", tokens); + + var directWrite = target.propPath.length === 0; + var symbolWrite = directWrite && target.root.type === "symbol"; + if (directWrite && !symbolWrite) { + parser.raiseParseError(tokens, "Can only put directly into symbols, not references") + } + + return { + type: "setCmd", + target: target, + symbolWrite: symbolWrite, + value: value, + transpile: function () { + if (this.symbolWrite) { + return "var " + target.root.name + " = " + parser.transpile(value); + } else { + var lastProperty = target.propPath.pop(); // steal last property for assignment + return "_hyperscript.runtime.forEach( " + parser.transpile(target) + ", function (target) {" + + " target." + lastProperty + "=" + parser.transpile(value) + + "})"; + } + } + } + } + }) + _parser.addGrammarElement("ifCmd", function (parser, tokens) { if (tokens.matchToken("if")) { var expr = parser.parseElement("expression", tokens); + tokens.matchToken("then"); // optional 'then' var trueBranch = parser.parseElement("commandList", tokens); if (tokens.matchToken("else")) { var falseBranch = parser.parseElement("commandList", tokens); @@ -1531,9 +1617,7 @@ if (method == null) { parser.raiseParseError(tokens, "Requires either GET or POST"); } - if (method.value === "GET") { - tokens.requireToken("from"); - } else { + if (method.value !== "GET") { if (!tokens.matchToken("to")) { var data = parser.parseElement("expression", tokens); tokens.requireToken("to"); @@ -1553,7 +1637,7 @@ delete this.next; return "_hyperscript.runtime.ajax('" + method.value + "', " + parser.transpile(url) + ", " + - "function(response){ " + parser.transpile(capturedNext) + " }," + + "function(response, xhr){ " + parser.transpile(capturedNext) + " }," + parser.transpile(data, "null") + ")"; } }; |