diff --git a/src/ext/path-deps.js b/src/ext/path-deps.js new file mode 100644 index 000000000..5eedced1c --- /dev/null +++ b/src/ext/path-deps.js @@ -0,0 +1,36 @@ +(function(){ + function dependsOn(pathSpec, url) { + var dependencyPath = pathSpec.split("/"); + var urlPath = url.split("/"); + for (var i = 0; i < urlPath.length; i++) { + var dependencyElement = dependencyPath.shift(); + var pathElement = urlPath[i]; + if (dependencyElement !== pathElement && dependencyElement !== "*") { + return false; + } + if (dependencyPath.length === 0 || (dependencyPath.length === 1 && dependencyPath[0] === "")) { + return true; + } + } + return false; + } + + htmx.defineExtension('path-deps', { + onEvent: function (name, evt) { + if (name === "afterRequest.htmx") { + var xhr = evt.detail.xhr; + console.log(xhr); + // mutating call + if (xhr.method !== "GET") { + var eltsWithDeps = htmx.findAll("[path-deps]"); + for (var i = 0; i < eltsWithDeps.length; i++) { + var elt = eltsWithDeps[i]; + if (dependsOn(elt.getAttribute('path-deps'), xhr.url)) { + htmx.trigger(elt, "path-deps"); + } + } + } + } + } + }); +})(); diff --git a/src/htmx.js b/src/htmx.js index 9550c51a8..0e7892a1a 100644 --- a/src/htmx.js +++ b/src/htmx.js @@ -804,6 +804,9 @@ var htmx = htmx || (function () { } function triggerEvent(elt, eventName, detail) { + if (detail == null) { + detail = {}; + } detail["elt"] = elt; var event = makeEvent(eventName, detail); if (htmx.logger) { diff --git a/test/core/api.js b/test/core/api.js index 11cf58420..63b248ec5 100644 --- a/test/core/api.js +++ b/test/core/api.js @@ -38,6 +38,16 @@ describe("Core htmx API test", function(){ detailStr.should.equal("foo"); }); + it('triggers with no details properly', function () { + var div = make("
"); + var myEventCalled = false; + htmx.on("myEvent", function(evt){ + myEventCalled = true; + }) + htmx.trigger(div, "myEvent") + myEventCalled.should.equal(true); + }); + it('should find properly', function(){ var div = make("
"); div.should.equal(htmx.find("#d1")); diff --git a/test/ext/path-deps.js b/test/ext/path-deps.js new file mode 100644 index 000000000..8dea9f70f --- /dev/null +++ b/test/ext/path-deps.js @@ -0,0 +1,142 @@ +describe("path-deps extension", function() { + beforeEach(function () { + this.server = makeServer(); + clearWorkArea(); + }); + afterEach(function () { + this.server.restore(); + clearWorkArea(); + }); + + it('path-deps basic case works', function () { + this.server.respondWith("POST", "/test", "Clicked!"); + this.server.respondWith("GET", "/test2", "Deps fired!"); + var btn = make('') + var div = make('
FOO
') + btn.click(); + this.server.respond(); + btn.innerHTML.should.equal("Clicked!"); + div.innerHTML.should.equal("FOO"); + this.server.respond(); + div.innerHTML.should.equal("Deps fired!"); + }); + + it('path-deps works with trailing slash', function () { + this.server.respondWith("POST", "/test", "Clicked!"); + this.server.respondWith("GET", "/test2", "Deps fired!"); + var btn = make('') + var div = make('
FOO
') + btn.click(); + this.server.respond(); + btn.innerHTML.should.equal("Clicked!"); + div.innerHTML.should.equal("FOO"); + this.server.respond(); + div.innerHTML.should.equal("Deps fired!"); + }); + + it('path-deps GET does not trigger', function () { + this.server.respondWith("GET", "/test", "Clicked!"); + this.server.respondWith("GET", "/test2", "Deps fired!"); + var btn = make('') + var div = make('
FOO
') + btn.click(); + this.server.respond(); + btn.innerHTML.should.equal("Clicked!"); + div.innerHTML.should.equal("FOO"); + this.server.respond(); + div.innerHTML.should.equal("FOO"); + }); + + it('path-deps dont trigger on path mismatch', function () { + this.server.respondWith("POST", "/test", "Clicked!"); + this.server.respondWith("GET", "/test2", "Deps fired!"); + var btn = make('') + var div = make('
FOO
') + btn.click(); + this.server.respond(); + btn.innerHTML.should.equal("Clicked!"); + div.innerHTML.should.equal("FOO"); + this.server.respond(); + div.innerHTML.should.equal("FOO"); + }); + + it('path-deps dont trigger on path longer than request', function () { + this.server.respondWith("POST", "/test", "Clicked!"); + this.server.respondWith("GET", "/test2", "Deps fired!"); + var btn = make('') + var div = make('
FOO
') + btn.click(); + this.server.respond(); + btn.innerHTML.should.equal("Clicked!"); + div.innerHTML.should.equal("FOO"); + this.server.respond(); + div.innerHTML.should.equal("FOO"); + }); + + it('path-deps trigger on path shorter than request', function () { + this.server.respondWith("POST", "/test/child", "Clicked!"); + this.server.respondWith("GET", "/test2", "Deps fired!"); + var btn = make('') + var div = make('
FOO
') + btn.click(); + this.server.respond(); + btn.innerHTML.should.equal("Clicked!"); + div.innerHTML.should.equal("FOO"); + this.server.respond(); + div.innerHTML.should.equal("Deps fired!"); + }); + + it('path-deps trigger on *-at-start path', function () { + this.server.respondWith("POST", "/test/child/test", "Clicked!"); + this.server.respondWith("GET", "/test2", "Deps fired!"); + var btn = make('') + var div = make('
FOO
') + btn.click(); + this.server.respond(); + btn.innerHTML.should.equal("Clicked!"); + div.innerHTML.should.equal("FOO"); + this.server.respond(); + div.innerHTML.should.equal("Deps fired!"); + }); + + it('path-deps trigger on *-in-middle path', function () { + this.server.respondWith("POST", "/test/child/test", "Clicked!"); + this.server.respondWith("GET", "/test2", "Deps fired!"); + var btn = make('') + var div = make('
FOO
') + btn.click(); + this.server.respond(); + btn.innerHTML.should.equal("Clicked!"); + div.innerHTML.should.equal("FOO"); + this.server.respond(); + div.innerHTML.should.equal("Deps fired!"); + }); + + it('path-deps trigger on *-at-end path', function () { + this.server.respondWith("POST", "/test/child/test", "Clicked!"); + this.server.respondWith("GET", "/test2", "Deps fired!"); + var btn = make('') + var div = make('
FOO
') + btn.click(); + this.server.respond(); + btn.innerHTML.should.equal("Clicked!"); + div.innerHTML.should.equal("FOO"); + this.server.respond(); + div.innerHTML.should.equal("Deps fired!"); + }); + + it('path-deps trigger all *s path', function () { + this.server.respondWith("POST", "/test/child/test", "Clicked!"); + this.server.respondWith("GET", "/test2", "Deps fired!"); + var btn = make('') + var div = make('
FOO
') + btn.click(); + this.server.respond(); + btn.innerHTML.should.equal("Clicked!"); + div.innerHTML.should.equal("FOO"); + this.server.respond(); + div.innerHTML.should.equal("Deps fired!"); + }); + + +}); \ No newline at end of file diff --git a/test/index.html b/test/index.html index 1f3e5bcfd..fd68e36e3 100644 --- a/test/index.html +++ b/test/index.html @@ -13,7 +13,7 @@ -

htmx.js test suite

+

htmx.js test suite

Scratch Page