diff options
author | Vincent <vichenzo-thebaud@hotmail.com> | 2024-12-12 19:12:01 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-12-12 11:12:01 -0700 |
commit | a3312449237c455243aff5137c988b926a260edf (patch) | |
tree | a77e67d8d98dcfc1cd70f6637680287cbff1423c /test | |
parent | 232667d2c683a57ba52665ffaf8379ae8f432cfd (diff) | |
download | htmx-a3312449237c455243aff5137c988b926a260edf.tar.gz htmx-a3312449237c455243aff5137c988b926a260edf.zip |
Support multiple extended selectors for hx-include, hx-trigger from, and hx-disabled-elt (#2902)
* Initial suggestion (squashed)
Support multiple extended selectors for hx-include
Additional test for nested standard selector
Add @MichaelWest22 hx-disabled-elt multiple selector test
Add hx-trigger `from` test with multiple extended selectors
Simplify
Include #2915 fix
Update htmx.js
Split for readability
Don't apply global to previous selectors
Rewrite loop, restore global recursive call, minimize diff
Use break for better readability
Co-Authored-By: MichaelWest22 <12867972+MichaelWest22@users.noreply.github.com>
* Keep global as a first-position-only keyword
* Wrapped selector syntax
* Replace substring check by individual chars check
* Fix format
---------
Co-authored-by: MichaelWest22 <12867972+MichaelWest22@users.noreply.github.com>
Diffstat (limited to 'test')
-rw-r--r-- | test/attributes/hx-boost.js | 26 | ||||
-rw-r--r-- | test/attributes/hx-disabled-elt.js | 39 | ||||
-rw-r--r-- | test/attributes/hx-include.js | 112 | ||||
-rw-r--r-- | test/attributes/hx-trigger.js | 20 |
4 files changed, 183 insertions, 14 deletions
diff --git a/test/attributes/hx-boost.js b/test/attributes/hx-boost.js index 8f23c741..e788dfa0 100644 --- a/test/attributes/hx-boost.js +++ b/test/attributes/hx-boost.js @@ -157,17 +157,16 @@ describe('hx-boost attribute', function() { }) it('form get with no action properly clears existing parameters on submit', function() { - /// add a foo=bar to the current url - var path = location.href; - if (!path.includes("foo=bar")) { - if (!path.includes("?")) { - path += "?foo=bar"; + var path = location.href + if (!path.includes('foo=bar')) { + if (!path.includes('?')) { + path += '?foo=bar' } else { - path += "&foo=bar"; + path += '&foo=bar' } } - history.replaceState({ htmx: true }, '', path); + history.replaceState({ htmx: true }, '', path) this.server.respondWith('GET', /\/*/, function(xhr) { // foo should not be present because the form is a get with no action @@ -183,17 +182,16 @@ describe('hx-boost attribute', function() { }) it('form get with an empty action properly clears existing parameters on submit', function() { - /// add a foo=bar to the current url - var path = location.href; - if (!path.includes("foo=bar")) { - if (!path.includes("?")) { - path += "?foo=bar"; + var path = location.href + if (!path.includes('foo=bar')) { + if (!path.includes('?')) { + path += '?foo=bar' } else { - path += "&foo=bar"; + path += '&foo=bar' } } - history.replaceState({ htmx: true }, '', path); + history.replaceState({ htmx: true }, '', path) this.server.respondWith('GET', /\/*/, function(xhr) { // foo should not be present because the form is a get with no action diff --git a/test/attributes/hx-disabled-elt.js b/test/attributes/hx-disabled-elt.js index 66d8386b..abdfa306 100644 --- a/test/attributes/hx-disabled-elt.js +++ b/test/attributes/hx-disabled-elt.js @@ -92,4 +92,43 @@ describe('hx-disabled-elt attribute', function() { div.innerHTML.should.equal('Loaded!') btn.hasAttribute('disabled').should.equal(false) }) + + it('hx-disabled-elt supports multiple extended selectors', function() { + this.server.respondWith('GET', '/test', 'Clicked!') + var form = make('<form hx-get="/test" hx-disabled-elt="find input[type=\'text\'], find button" hx-swap="none"><input id="i1" type="text" placeholder="Type here..."><button id="b2" type="submit">Send</button></form>') + var i1 = byId('i1') + var b2 = byId('b2') + + i1.hasAttribute('disabled').should.equal(false) + b2.hasAttribute('disabled').should.equal(false) + + b2.click() + i1.hasAttribute('disabled').should.equal(true) + b2.hasAttribute('disabled').should.equal(true) + + this.server.respond() + + i1.hasAttribute('disabled').should.equal(false) + b2.hasAttribute('disabled').should.equal(false) + }) + + it('closest/find/next/previous handle nothing to find without exception', function() { + this.server.respondWith('GET', '/test', 'Clicked!') + var btn1 = make('<button hx-get="/test" hx-disabled-elt="closest input">Click Me!</button>') + var btn2 = make('<button hx-get="/test" hx-disabled-elt="find input">Click Me!</button>') + var btn3 = make('<button hx-get="/test" hx-disabled-elt="next input">Click Me!</button>') + var btn4 = make('<button hx-get="/test" hx-disabled-elt="previous input">Click Me!</button>') + btn1.click() + btn1.hasAttribute('disabled').should.equal(false) + this.server.respond() + btn2.click() + btn2.hasAttribute('disabled').should.equal(false) + this.server.respond() + btn3.click() + btn3.hasAttribute('disabled').should.equal(false) + this.server.respond() + btn4.click() + btn4.hasAttribute('disabled').should.equal(false) + this.server.respond() + }) }) diff --git a/test/attributes/hx-include.js b/test/attributes/hx-include.js index 299810ad..502e78a1 100644 --- a/test/attributes/hx-include.js +++ b/test/attributes/hx-include.js @@ -224,4 +224,116 @@ describe('hx-include attribute', function() { this.server.respond() btn.innerHTML.should.equal('Clicked!') }) + + it('Multiple extended selectors can be used in hx-include', function() { + this.server.respondWith('POST', '/include', function(xhr) { + var params = getParameters(xhr) + params.i1.should.equal('test') + params.i2.should.equal('foo') + params.i3.should.equal('bar') + params.i4.should.equal('test2') + xhr.respond(200, {}, 'Clicked!') + }) + make('<input name="i4" value="test2" id="i4"/>' + + '<div id="i">' + + '<input name="i1" value="test"/>' + + '<input name="i2" value="foo"/>' + + '<button id="btn" hx-post="/include" hx-include="closest div, next input, #i4"></button>' + + '</div>' + + '<input name="i3" value="bar"/>') + var btn = byId('btn') + btn.click() + this.server.respond() + btn.innerHTML.should.equal('Clicked!') + }) + + it('hx-include processes extended selector in between standard selectors', function() { + this.server.respondWith('POST', '/include', function(xhr) { + var params = getParameters(xhr) + params.i1.should.equal('test') + should.equal(params.i2, undefined) + params.i3.should.equal('bar') + params.i4.should.equal('test2') + xhr.respond(200, {}, 'Clicked!') + }) + make('<input name="i4" value="test2" id="i4"/>' + + '<div id="i">' + + '<input name="i1" value="test" id="i1"/>' + + '<input name="i2" value="foo"/>' + + '<button id="btn" hx-post="/include" hx-include="#i1, next input, #i4"></button>' + + '</div>' + + '<input name="i3" value="bar"/>') + var btn = byId('btn') + btn.click() + this.server.respond() + btn.innerHTML.should.equal('Clicked!') + }) + + it('hx-include processes nested standard selectors correctly', function() { + this.server.respondWith('POST', '/include', function(xhr) { + var params = getParameters(xhr) + params.i1.should.equal('test') + params.i2.should.equal('foo') + params.i3.should.equal('bar') + should.equal(params.i4, undefined) + should.equal(params.i5, undefined) + xhr.respond(200, {}, 'Clicked!') + }) + make('<input name="i4" value="test2" id="i4"/>' + + '<div id="i">' + + '<input name="i1" value="test" id="i1"/>' + + '<input name="i2" value="foo"/>' + + '<input name="i5" value="test"/>' + + '<button id="btn" hx-post="/include" hx-include="next input, #i > :is([name=\'i1\'], [name=\'i2\'])"></button>' + + '</div>' + + '<input name="i3" value="bar"/>') + var btn = byId('btn') + btn.click() + this.server.respond() + btn.innerHTML.should.equal('Clicked!') + }) + + it('hx-include processes wrapped next/previous selectors correctly', function() { + this.server.respondWith('POST', '/include', function(xhr) { + var params = getParameters(xhr) + should.equal(params.i1, undefined) + params.i2.should.equal('foo') + params.i3.should.equal('bar') + should.equal(params.i4, undefined) + should.equal(params.i5, undefined) + xhr.respond(200, {}, 'Clicked!') + }) + make('<input name="i4" value="test2" id="i4"/>' + + '<div id="i">' + + '<input name="i1" value="test" id="i1"/>' + + '<input name="i2" value="foo"/>' + + '<button id="btn" hx-post="/include" hx-include="next <#nonexistent, input/>, previous <#i5, [name=\'i2\'], #i4/>"></button>' + + '</div>' + + '<input name="i3" value="bar"/>' + + '<input name="i5" value="test"/>') + var btn = byId('btn') + btn.click() + this.server.respond() + btn.innerHTML.should.equal('Clicked!') + }) + + it('hx-include processes wrapped closest selector correctly', function() { + this.server.respondWith('POST', '/include', function(xhr) { + var params = getParameters(xhr) + should.equal(params.i1, undefined) + params.i2.should.equal('bar') + xhr.respond(200, {}, 'Clicked!') + }) + make('<section>' + + '<input name="i1" value="foo"/>' + + '<div>' + + '<input name="i2" value="bar"/>' + + '<button id="btn" hx-post="/include" hx-include="closest <section, div/>"></button>' + + '</div>' + + '</section>') + var btn = byId('btn') + btn.click() + this.server.respond() + btn.innerHTML.should.equal('Clicked!') + }) }) diff --git a/test/attributes/hx-trigger.js b/test/attributes/hx-trigger.js index 704e9ec9..b673a8a5 100644 --- a/test/attributes/hx-trigger.js +++ b/test/attributes/hx-trigger.js @@ -657,6 +657,26 @@ describe('hx-trigger attribute', function() { div1.innerHTML.should.equal('Requests: 2') }) + it('from clause works with multiple extended selectors', function() { + var requests = 0 + this.server.respondWith('GET', '/test', function(xhr) { + requests++ + xhr.respond(200, {}, 'Requests: ' + requests) + }) + make('<button id="btn" type="button">Click me</button>' + + '<div hx-trigger="click from:(previous button, next a)" hx-target="#a1" hx-get="/test"></div>' + + '<a id="a1">Requests: 0</a>') + var btn = byId('btn') + var a1 = byId('a1') + a1.innerHTML.should.equal('Requests: 0') + btn.click() + this.server.respond() + a1.innerHTML.should.equal('Requests: 1') + a1.click() + this.server.respond() + a1.innerHTML.should.equal('Requests: 2') + }) + it('event listeners can filter on target', function() { var requests = 0 this.server.respondWith('GET', '/test', function(xhr) { |