diff options
author | carson <carson@leaddyno.com> | 2020-05-23 04:52:52 -0700 |
---|---|---|
committer | carson <carson@leaddyno.com> | 2020-05-23 04:52:52 -0700 |
commit | ba6d38e9dd0f61cca373e2e660c99b5e23f73a6b (patch) | |
tree | b90aebcc597706a3e5cb4509924c13b1e5ad3d0e | |
parent | 8b6aec296013588e7acc64eab5878f1cef818f1b (diff) | |
download | htmx-ba6d38e9dd0f61cca373e2e660c99b5e23f73a6b.tar.gz htmx-ba6d38e9dd0f61cca373e2e660c99b5e23f73a6b.zip |
Fix https://github.com/bigskysoftware/htmx/issues/19
clean up uses of getRawAttribute() and add a `data-*` test for all attribute tests.
-rw-r--r-- | src/htmx.js | 18 | ||||
-rw-r--r-- | test/attributes/hx-boost.js | 9 | ||||
-rw-r--r-- | test/attributes/hx-classes.js | 12 | ||||
-rw-r--r-- | test/attributes/hx-delete.js | 13 | ||||
-rw-r--r-- | test/attributes/hx-error-url.js | 11 | ||||
-rw-r--r-- | test/attributes/hx-ext.js | 12 | ||||
-rw-r--r-- | test/attributes/hx-get.js | 8 | ||||
-rw-r--r-- | test/attributes/hx-include.js | 14 | ||||
-rw-r--r-- | test/attributes/hx-indicator.js | 16 | ||||
-rw-r--r-- | test/attributes/hx-params.js | 18 | ||||
-rw-r--r-- | test/attributes/hx-patch.js | 13 | ||||
-rw-r--r-- | test/attributes/hx-post.js | 13 | ||||
-rw-r--r-- | test/attributes/hx-push-url.js | 11 | ||||
-rw-r--r-- | test/attributes/hx-put.js | 13 | ||||
-rw-r--r-- | test/attributes/hx-select.js | 10 | ||||
-rw-r--r-- | test/attributes/hx-swap-oob.js | 10 | ||||
-rw-r--r-- | test/attributes/hx-swap.js | 17 | ||||
-rw-r--r-- | test/attributes/hx-target.js | 12 | ||||
-rw-r--r-- | test/attributes/hx-trigger.js | 11 |
19 files changed, 232 insertions, 9 deletions
diff --git a/src/htmx.js b/src/htmx.js index 113da9ee..156d7254 100644 --- a/src/htmx.js +++ b/src/htmx.js @@ -24,7 +24,7 @@ var htmx = htmx || (function () { return elt.getAttribute && elt.getAttribute(name); } - // resolve with both kt and data-kt prefixes + // resolve with both hx and data-hx prefixes function getAttributeValue(elt, qualifiedName) { return getRawAttribute(elt, qualifiedName) || getRawAttribute(elt, "data-" + qualifiedName); } @@ -50,7 +50,7 @@ var htmx = htmx || (function () { function getClosestAttributeValue(elt, attributeName) { var closestAttr = null; getClosestMatch(elt, function (e) { - return closestAttr = getRawAttribute(e, attributeName); + return closestAttr = getAttributeValue(e, attributeName); }); return closestAttr; } @@ -290,9 +290,9 @@ var htmx = htmx || (function () { //==================================================================== function getTarget(elt) { - var explicitTarget = getClosestMatch(elt, function(e){return getRawAttribute(e,"hx-target") !== null}); + var explicitTarget = getClosestMatch(elt, function(e){return getAttributeValue(e,"hx-target") !== null}); if (explicitTarget) { - var targetStr = getRawAttribute(explicitTarget, "hx-target"); + var targetStr = getAttributeValue(explicitTarget, "hx-target"); if (targetStr === "this") { return explicitTarget; } else if (targetStr.indexOf("closest ") === 0) { @@ -652,7 +652,7 @@ var htmx = htmx || (function () { function initScrollHandler() { if (!window['htmxScrollHandler']) { var scrollHandler = function() { - forEach(getDocument().querySelectorAll("[hx-trigger='revealed']"), function (elt) { + forEach(getDocument().querySelectorAll("[hx-trigger='revealed'],[data-hx-trigger='revealed']"), function (elt) { maybeReveal(elt); }); }; @@ -825,7 +825,7 @@ var htmx = htmx || (function () { var currentPathForHistory = null; function getHistoryElement() { - var historyElt = getDocument().querySelector('[hx-history-elt]'); + var historyElt = getDocument().querySelector('[hx-history-elt],[data-hx-history-elt]'); return historyElt || getDocument().body; } @@ -882,7 +882,7 @@ var htmx = htmx || (function () { if (this.status >= 200 && this.status < 400) { triggerEvent(getDocument().body, "historyCacheMissLoad.htmx", details); var fragment = makeFragment(this.response); - fragment = fragment.querySelector('[hx-history-elt]') || fragment; + fragment = fragment.querySelector('[hx-history-elt],[data-hx-history-elt]') || fragment; settleImmediately(swapInnerHTML(getHistoryElement(), fragment)); currentPathForHistory = path; } else { @@ -1049,7 +1049,7 @@ var htmx = htmx || (function () { "X-HX-Request" : "true", "X-HX-Trigger" : getRawAttribute(elt, "id"), "X-HX-Trigger-Name" : getRawAttribute(elt, "name"), - "X-HX-Target" : getRawAttribute(target, "id"), + "X-HX-Target" : getAttributeValue(target, "id"), "Current-URL" : getDocument().location.href, } if (prompt !== undefined) { @@ -1136,7 +1136,7 @@ var htmx = htmx || (function () { function issueAjaxRequest(elt, verb, path, eventTarget) { var target = getTarget(elt); if (target == null) { - triggerErrorEvent(elt, 'targetError.htmx', {target: getRawAttribute(elt, "hx-target")}); + triggerErrorEvent(elt, 'targetError.htmx', {target: getAttributeValue(elt, "hx-target")}); return; } var eltData = getInternalData(elt); diff --git a/test/attributes/hx-boost.js b/test/attributes/hx-boost.js index 41dfb29e..49483b3c 100644 --- a/test/attributes/hx-boost.js +++ b/test/attributes/hx-boost.js @@ -47,6 +47,15 @@ describe("hx-boost attribute", function() { div.innerHTML.should.equal("Boosted"); }) + it('handles basic anchor properly w/ data-* prefix', function () { + 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"); + }) + }); diff --git a/test/attributes/hx-classes.js b/test/attributes/hx-classes.js index a138976e..00dc5cfb 100644 --- a/test/attributes/hx-classes.js +++ b/test/attributes/hx-classes.js @@ -29,4 +29,16 @@ describe("hx-classes attribute", function(){ done(); }, 100); }); + + it('adds classes properly w/ data-* prefix', function(done) + { + var div = make('<div data-hx-classes="add c1">Click Me!</div>') + should.equal(div.classList.length, 0); + setTimeout(function(){ + should.equal(div.classList.contains("c1"), true); + done(); + }, 100); + }); + + }) diff --git a/test/attributes/hx-delete.js b/test/attributes/hx-delete.js index 42892e31..3a166aaf 100644 --- a/test/attributes/hx-delete.js +++ b/test/attributes/hx-delete.js @@ -20,4 +20,17 @@ describe("hx-delete attribute", function(){ this.server.respond(); btn.innerHTML.should.equal("Deleted!"); }); + + it('issues a DELETE request with proper headers w/ data-* prefix', function() + { + this.server.respondWith("DELETE", "/test", function(xhr){ + xhr.requestHeaders['X-HTTP-Method-Override'].should.equal('DELETE'); + 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!"); + }); }) diff --git a/test/attributes/hx-error-url.js b/test/attributes/hx-error-url.js index 1984edcc..3ee46aa7 100644 --- a/test/attributes/hx-error-url.js +++ b/test/attributes/hx-error-url.js @@ -18,4 +18,15 @@ describe("hx-error-url attribute", function(){ this.server.respond(); this.server.respond(); }); + + it('Submits a POST with error content on bad request w/ data-* prefix', function() + { + this.server.respondWith("POST", "/error", function(xhr){ + should.equal(JSON.parse(xhr.requestBody).detail.xhr.status, 404); + }); + var btn = make('<button data-hx-error-url="/error" hx-get="/bad">Click Me!</button>') + btn.click(); + this.server.respond(); + this.server.respond(); + }); }) diff --git a/test/attributes/hx-ext.js b/test/attributes/hx-ext.js index 3e2170ab..cead2f51 100644 --- a/test/attributes/hx-ext.js +++ b/test/attributes/hx-ext.js @@ -83,4 +83,16 @@ describe("hx-ext attribute", function() { ext3Calls.should.equal(1); }); + it('A simple extension is invoked properly w/ data-* prefix', function () { + 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); + }); + + });
\ No newline at end of file diff --git a/test/attributes/hx-get.js b/test/attributes/hx-get.js index d9d3dddd..7326c39e 100644 --- a/test/attributes/hx-get.js +++ b/test/attributes/hx-get.js @@ -65,4 +65,12 @@ describe("hx-get attribute", function() { }); + it('issues a GET request on click and swaps content w/ data-* prefix', function () { + 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!"); + }); });
\ No newline at end of file diff --git a/test/attributes/hx-include.js b/test/attributes/hx-include.js index 7a75684f..1d00f25d 100644 --- a/test/attributes/hx-include.js +++ b/test/attributes/hx-include.js @@ -136,4 +136,18 @@ describe("hx-include attribute", function() { div.innerHTML.should.equal("Clicked!"); }); + it('By default an input includes itself w/ data-* prefix', function () { + 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!"); + }); + + });
\ No newline at end of file diff --git a/test/attributes/hx-indicator.js b/test/attributes/hx-indicator.js index 7b1503bf..1385eb42 100644 --- a/test/attributes/hx-indicator.js +++ b/test/attributes/hx-indicator.js @@ -33,4 +33,20 @@ describe("hx-indicator attribute", function(){ a1.classList.contains("htmx-request").should.equal(false); a2.classList.contains("htmx-request").should.equal(false); }); + + it('Indicator classes are properly put on element with explicit indicator w/ data-* prefix', function() + { + 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); + }); }) diff --git a/test/attributes/hx-params.js b/test/attributes/hx-params.js index cac80bd9..b2b19ca2 100644 --- a/test/attributes/hx-params.js +++ b/test/attributes/hx-params.js @@ -80,4 +80,22 @@ describe("hx-params attribute", function() { form.innerHTML.should.equal("Clicked!"); }); + it('named exclude works w/ data-* prefix', function () { + this.server.respondWith("POST", "/params", function (xhr) { + var params = getParameters(xhr); + should.equal(params['i1'], undefined); + should.equal(params['i2'], "test"); + should.equal(params['i3'], undefined); + xhr.respond(200, {}, "Clicked!") + }); + var form = make('<form data-hx-trigger="click" data-hx-post="/params" data-hx-params="not i1, i3">' + + '<input name="i1" value="test"/>' + + '<input name="i2" value="test"/>' + + '<input name="i3" value="test"/>' + + '</form> '); + form.click(); + this.server.respond(); + form.innerHTML.should.equal("Clicked!"); + }); + });
\ No newline at end of file diff --git a/test/attributes/hx-patch.js b/test/attributes/hx-patch.js index 5f4abd63..6f7a5e9d 100644 --- a/test/attributes/hx-patch.js +++ b/test/attributes/hx-patch.js @@ -20,4 +20,17 @@ describe("hx-patch attribute", function(){ this.server.respond(); btn.innerHTML.should.equal("Patched!"); }); + + it('issues a PATCH request with proper headers w/ data-* prefix', function() + { + this.server.respondWith("PATCH", "/test", function(xhr){ + xhr.requestHeaders['X-HTTP-Method-Override'].should.equal('PATCH'); + xhr.respond(200, {}, "Patched!"); + }); + + var btn = make('<button data-hx-patch="/test">Click Me!</button>') + btn.click(); + this.server.respond(); + btn.innerHTML.should.equal("Patched!"); + }); }) diff --git a/test/attributes/hx-post.js b/test/attributes/hx-post.js index 4b548018..6734e30d 100644 --- a/test/attributes/hx-post.js +++ b/test/attributes/hx-post.js @@ -20,4 +20,17 @@ describe("hx-post attribute", function(){ this.server.respond(); btn.innerHTML.should.equal("Posted!"); }); + + it('issues a POST request with proper headers w/ data-* prefix', function() + { + this.server.respondWith("POST", "/test", function(xhr){ + should.equal(xhr.requestHeaders['X-HTTP-Method-Override'], undefined); + xhr.respond(200, {}, "Posted!"); + }); + + var btn = make('<button data-hx-post="/test">Click Me!</button>') + btn.click(); + this.server.respond(); + btn.innerHTML.should.equal("Posted!"); + }); }) diff --git a/test/attributes/hx-push-url.js b/test/attributes/hx-push-url.js index c76d6aa4..4559d57a 100644 --- a/test/attributes/hx-push-url.js +++ b/test/attributes/hx-push-url.js @@ -120,4 +120,15 @@ describe("hx-push-url attribute", function() { chai.assert(timeInMs < 300, "Should take less than 300ms on most platforms"); }) + it("navigation should push an element into the cache w/ data-* prefix", function () { + this.server.respondWith("GET", "/test", "second"); + getWorkArea().innerHTML.should.be.equal(""); + var div = make('<div data-hx-push-url="true" data-hx-get="/test">first</div>'); + div.click(); + this.server.respond(); + getWorkArea().textContent.should.equal("second") + var cache = JSON.parse(localStorage.getItem(KUTTY_HISTORY_CACHE)); + cache.length.should.equal(1); + }); + });
\ No newline at end of file diff --git a/test/attributes/hx-put.js b/test/attributes/hx-put.js index ad347da6..a1d47bcc 100644 --- a/test/attributes/hx-put.js +++ b/test/attributes/hx-put.js @@ -20,4 +20,17 @@ describe("hx-put attribute", function(){ this.server.respond(); btn.innerHTML.should.equal("Putted!"); }); + + it('issues a PUT request with proper headers', function() + { + this.server.respondWith("PUT", "/test", function(xhr){ + xhr.requestHeaders['X-HTTP-Method-Override'].should.equal('PUT'); + xhr.respond(200, {}, "Putted!"); + }); + + var btn = make('<button data-hx-put="/test">Click Me!</button>') + btn.click(); + this.server.respond(); + btn.innerHTML.should.equal("Putted!"); + }); }) diff --git a/test/attributes/hx-select.js b/test/attributes/hx-select.js index 916571c1..c5868430 100644 --- a/test/attributes/hx-select.js +++ b/test/attributes/hx-select.js @@ -27,4 +27,14 @@ describe("BOOTSTRAP - htmx AJAX Tests", function(){ this.server.respond(); div.innerHTML.should.equal("<div id=\"d1\">foo</div>"); }); + + it('properly handles a full HTML document w/ data-* prefix', function() + { + var i = 1; + 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" data-hx-select="#d1"></div>'); + div.click(); + this.server.respond(); + div.innerHTML.should.equal("<div id=\"d1\">foo</div>"); + }); }) diff --git a/test/attributes/hx-swap-oob.js b/test/attributes/hx-swap-oob.js index b6b2afb8..2d84daa5 100644 --- a/test/attributes/hx-swap-oob.js +++ b/test/attributes/hx-swap-oob.js @@ -38,5 +38,15 @@ describe("hx-swap-oob attribute", function () { div.innerText.should.equal("Clicked"); }) + it('handles basic response properly w/ data-* prefix', function () { + this.server.respondWith("GET", "/test", "Clicked<div id='d1' data-hx-swap-oob='true'>Swapped</div>"); + var div = make('<div data-hx-get="/test">click me</div>'); + make('<div id="d1"></div>'); + div.click(); + this.server.respond(); + div.innerHTML.should.equal("Clicked"); + byId("d1").innerHTML.should.equal("Swapped"); + }) + }); diff --git a/test/attributes/hx-swap.js b/test/attributes/hx-swap.js index ee5307ec..39b04edb 100644 --- a/test/attributes/hx-swap.js +++ b/test/attributes/hx-swap.js @@ -246,4 +246,21 @@ describe("hx-swap attribute", function(){ }, 30); }); + + it('swap outerHTML properly w/ data-* prefix', function() + { + this.server.respondWith("GET", "/test", '<a id="a1" data-hx-get="/test2">Click Me</a>'); + this.server.respondWith("GET", "/test2", "Clicked!"); + + var div = make('<div id="d1" data-hx-get="/test" data-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!'); + }); + + }) diff --git a/test/attributes/hx-target.js b/test/attributes/hx-target.js index c28fcc9d..d90c2db3 100644 --- a/test/attributes/hx-target.js +++ b/test/attributes/hx-target.js @@ -68,4 +68,16 @@ describe("hx-target attribute", function(){ btn.innerHTML.should.equal("Click Me!"); }); + + it('targets an adjacent element properly w/ data-* prefix', function() + { + this.server.respondWith("GET", "/test", "Clicked!"); + var btn = make('<button data-hx-target="#d1" data-hx-get="/test">Click Me!</button>') + var div1 = make('<div id="d1"></div>') + btn.click(); + this.server.respond(); + div1.innerHTML.should.equal("Clicked!"); + }); + + }) diff --git a/test/attributes/hx-trigger.js b/test/attributes/hx-trigger.js index 62052500..38cd3db6 100644 --- a/test/attributes/hx-trigger.js +++ b/test/attributes/hx-trigger.js @@ -86,4 +86,15 @@ describe("hx-trigger attribute", function(){ }); + it('non-default value works w/ data-* prefix', function() + { + this.server.respondWith("GET", "/test", "Clicked!"); + + var form = make('<form data-hx-get="/test" data-hx-trigger="click">Click Me!</form>'); + form.click(); + form.innerHTML.should.equal("Click Me!"); + this.server.respond(); + form.innerHTML.should.equal("Clicked!"); + }); + }) |