From 9058f3647927f7002aabc5803922b959f30a364c Mon Sep 17 00:00:00 2001 From: MichaelWest22 Date: Thu, 14 Nov 2024 14:47:33 +1300 Subject: [PATCH 1/7] Rewrite getExtensions with local: support --- src/htmx.js | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/htmx.js b/src/htmx.js index 7792941d3..88412af06 100644 --- a/src/htmx.js +++ b/src/htmx.js @@ -4910,23 +4910,28 @@ var htmx = (function() { * @returns {HtmxExtension[]} */ function getExtensions(elt, extensionsToReturn, extensionsToIgnore) { - if (extensionsToReturn == undefined) { + const isParentScan = !!extensionsToReturn + if (!extensionsToReturn) { extensionsToReturn = [] } - if (elt == undefined) { + if (!elt) { return extensionsToReturn } - if (extensionsToIgnore == undefined) { + if (!extensionsToIgnore) { extensionsToIgnore = [] } const extensionsForElement = getAttributeValue(elt, 'hx-ext') if (extensionsForElement) { forEach(extensionsForElement.split(','), function(extensionName) { - extensionName = extensionName.replace(/ /g, '') - if (extensionName.slice(0, 7) == 'ignore:') { + extensionName = extensionName.trim() + if (extensionName.indexOf('ignore:') === 0) { extensionsToIgnore.push(extensionName.slice(7)) return } + if (extensionName.indexOf('local:') === 0) { + if (isParentScan) return + extensionName = extensionName.slice(6) + } if (extensionsToIgnore.indexOf(extensionName) < 0) { const extension = extensions[extensionName] if (extension && extensionsToReturn.indexOf(extension) < 0) { From 0cb48a5fb5dc47a926420176f5717ae0dfb4430d Mon Sep 17 00:00:00 2001 From: MichaelWest22 Date: Thu, 14 Nov 2024 15:29:15 +1300 Subject: [PATCH 2/7] update doco --- www/content/attributes/hx-ext.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/www/content/attributes/hx-ext.md b/www/content/attributes/hx-ext.md index 65dcbb6b7..0741a8baa 100644 --- a/www/content/attributes/hx-ext.md +++ b/www/content/attributes/hx-ext.md @@ -14,8 +14,7 @@ and on the `body` tag for it to apply to all htmx requests. * `hx-ext` is both inherited and merged with parent elements, so you can specify extensions on any element in the DOM hierarchy and it will apply to all child elements. -* You can ignore an extension that is defined by a parent node using `hx-ext="ignore:extensionName"` - +* You can ignore an extension that is defined by a parent element using `hx-ext="ignore:extensionName"` ```html
@@ -26,3 +25,12 @@ hierarchy and it will apply to all child elements.
``` +* If an extension needs to apply only to a single element you can override inheritance on an element using `hx-ext="local:extensionName"` + +```html +
+
+ ... but it will not be used in this part. +
+
+``` From 8ff4dba359ae9e69ee1a41e8705748d3da74f885 Mon Sep 17 00:00:00 2001 From: MichaelWest22 Date: Thu, 14 Nov 2024 16:09:37 +1300 Subject: [PATCH 3/7] Add Test --- test/attributes/hx-ext.js | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/test/attributes/hx-ext.js b/test/attributes/hx-ext.js index b573c4ddf..a90f9aebf 100644 --- a/test/attributes/hx-ext.js +++ b/test/attributes/hx-ext.js @@ -156,4 +156,28 @@ describe('hx-ext attribute', function() { ext5Calls.should.equal(1) }) + + it('Extensions can be local properly', function() { + this.server.respondWith('GET', '/test', 'Clicked!') + + make('
Click Me!' + + '
') + + var div1 = byId('div-AA') + var btn2 = byId('btn-BB') + + btn2.click() + this.server.respond() + ext1Calls.should.equal(0) + ext2Calls.should.equal(1) + ext3Calls.should.equal(0) + + div1.click() + this.server.respond() + ext1Calls.should.equal(1) + ext2Calls.should.equal(2) + ext3Calls.should.equal(0) + + ext5Calls.should.equal(1) + }) }) From 41e6011fd5f71a765025c21a6048ad8e7089d05b Mon Sep 17 00:00:00 2001 From: MichaelWest22 Date: Thu, 14 Nov 2024 16:14:13 +1300 Subject: [PATCH 4/7] test no local --- test/attributes/hx-ext.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/attributes/hx-ext.js b/test/attributes/hx-ext.js index a90f9aebf..4f3ec0a0d 100644 --- a/test/attributes/hx-ext.js +++ b/test/attributes/hx-ext.js @@ -160,21 +160,21 @@ describe('hx-ext attribute', function() { it('Extensions can be local properly', function() { this.server.respondWith('GET', '/test', 'Clicked!') - make('
Click Me!' + - '
') + make('
Click Me!' + + '
') var div1 = byId('div-AA') var btn2 = byId('btn-BB') btn2.click() this.server.respond() - ext1Calls.should.equal(0) + ext1Calls.should.equal(1) ext2Calls.should.equal(1) ext3Calls.should.equal(0) div1.click() this.server.respond() - ext1Calls.should.equal(1) + ext1Calls.should.equal(2) ext2Calls.should.equal(2) ext3Calls.should.equal(0) From a486cd77675500bf550fe8c8c5320ccb874975ef Mon Sep 17 00:00:00 2001 From: MichaelWest22 Date: Thu, 14 Nov 2024 16:17:59 +1300 Subject: [PATCH 5/7] add back local test --- test/attributes/hx-ext.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/attributes/hx-ext.js b/test/attributes/hx-ext.js index 4f3ec0a0d..13e90fb49 100644 --- a/test/attributes/hx-ext.js +++ b/test/attributes/hx-ext.js @@ -160,7 +160,7 @@ describe('hx-ext attribute', function() { it('Extensions can be local properly', function() { this.server.respondWith('GET', '/test', 'Clicked!') - make('
Click Me!' + + make('
Click Me!' + '
') var div1 = byId('div-AA') @@ -168,13 +168,13 @@ describe('hx-ext attribute', function() { btn2.click() this.server.respond() - ext1Calls.should.equal(1) + ext1Calls.should.equal(0) ext2Calls.should.equal(1) ext3Calls.should.equal(0) div1.click() this.server.respond() - ext1Calls.should.equal(2) + ext1Calls.should.equal(1) ext2Calls.should.equal(2) ext3Calls.should.equal(0) From 3834d2687fd1bbb43280709668c14ba384ef3954 Mon Sep 17 00:00:00 2001 From: MichaelWest22 Date: Fri, 6 Dec 2024 10:28:40 +1300 Subject: [PATCH 6/7] Change to use this-only instead of local --- src/htmx.js | 4 ++-- test/attributes/hx-ext.js | 4 ++-- www/content/attributes/hx-ext.md | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/htmx.js b/src/htmx.js index 88412af06..aad5724e5 100644 --- a/src/htmx.js +++ b/src/htmx.js @@ -4928,9 +4928,9 @@ var htmx = (function() { extensionsToIgnore.push(extensionName.slice(7)) return } - if (extensionName.indexOf('local:') === 0) { + if (extensionName.indexOf('this-only:') === 0) { if (isParentScan) return - extensionName = extensionName.slice(6) + extensionName = extensionName.slice(10) } if (extensionsToIgnore.indexOf(extensionName) < 0) { const extension = extensions[extensionName] diff --git a/test/attributes/hx-ext.js b/test/attributes/hx-ext.js index 13e90fb49..c00592e65 100644 --- a/test/attributes/hx-ext.js +++ b/test/attributes/hx-ext.js @@ -157,10 +157,10 @@ describe('hx-ext attribute', function() { ext5Calls.should.equal(1) }) - it('Extensions can be local properly', function() { + it('Extensions can be applied to this element only properly', function() { this.server.respondWith('GET', '/test', 'Clicked!') - make('
Click Me!' + + make('
Click Me!' + '
') var div1 = byId('div-AA') diff --git a/www/content/attributes/hx-ext.md b/www/content/attributes/hx-ext.md index 0741a8baa..35abaed49 100644 --- a/www/content/attributes/hx-ext.md +++ b/www/content/attributes/hx-ext.md @@ -25,10 +25,10 @@ hierarchy and it will apply to all child elements.
``` -* If an extension needs to apply only to a single element you can override inheritance on an element using `hx-ext="local:extensionName"` +* If an extension needs to apply only to a single element you can override inheritance on an element using `hx-ext="this-only:extensionName"` ```html -
+
... but it will not be used in this part.
From a58230e8971f6ead1d6d0f7b476e64eb18ae5dad Mon Sep 17 00:00:00 2001 From: MichaelWest22 Date: Thu, 12 Dec 2024 11:04:52 +1300 Subject: [PATCH 7/7] if should use {} --- src/htmx.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/htmx.js b/src/htmx.js index aad5724e5..e71e1445c 100644 --- a/src/htmx.js +++ b/src/htmx.js @@ -4929,7 +4929,9 @@ var htmx = (function() { return } if (extensionName.indexOf('this-only:') === 0) { - if (isParentScan) return + if (isParentScan) { + return + } extensionName = extensionName.slice(10) } if (extensionsToIgnore.indexOf(extensionName) < 0) {