summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
authorVincent <vichenzo-thebaud@hotmail.com>2024-12-12 19:12:01 +0100
committerGitHub <noreply@github.com>2024-12-12 11:12:01 -0700
commita3312449237c455243aff5137c988b926a260edf (patch)
treea77e67d8d98dcfc1cd70f6637680287cbff1423c /src
parent232667d2c683a57ba52665ffaf8379ae8f432cfd (diff)
downloadhtmx-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 'src')
-rw-r--r--src/htmx.js97
1 files changed, 70 insertions, 27 deletions
diff --git a/src/htmx.js b/src/htmx.js
index d3411e2c..eaa4d6c6 100644
--- a/src/htmx.js
+++ b/src/htmx.js
@@ -1126,34 +1126,77 @@ var htmx = (function() {
* @returns {(Node|Window)[]}
*/
function querySelectorAllExt(elt, selector, global) {
- elt = resolveTarget(elt)
- if (selector.indexOf('closest ') === 0) {
- return [closest(asElement(elt), normalizeSelector(selector.slice(8)))]
- } else if (selector.indexOf('find ') === 0) {
- return [find(asParentNode(elt), normalizeSelector(selector.slice(5)))]
- } else if (selector === 'next') {
- return [asElement(elt).nextElementSibling]
- } else if (selector.indexOf('next ') === 0) {
- return [scanForwardQuery(elt, normalizeSelector(selector.slice(5)), !!global)]
- } else if (selector === 'previous') {
- return [asElement(elt).previousElementSibling]
- } else if (selector.indexOf('previous ') === 0) {
- return [scanBackwardsQuery(elt, normalizeSelector(selector.slice(9)), !!global)]
- } else if (selector === 'document') {
- return [document]
- } else if (selector === 'window') {
- return [window]
- } else if (selector === 'body') {
- return [document.body]
- } else if (selector === 'root') {
- return [getRootNode(elt, !!global)]
- } else if (selector === 'host') {
- return [(/** @type ShadowRoot */(elt.getRootNode())).host]
- } else if (selector.indexOf('global ') === 0) {
+ if (selector.indexOf('global ') === 0) {
return querySelectorAllExt(elt, selector.slice(7), true)
- } else {
- return toArray(asParentNode(getRootNode(elt, !!global)).querySelectorAll(normalizeSelector(selector)))
}
+
+ elt = resolveTarget(elt)
+
+ const parts = []
+ {
+ let chevronsCount = 0
+ let offset = 0
+ for (let i = 0; i < selector.length; i++) {
+ const char = selector[i]
+ if (char === ',' && chevronsCount === 0) {
+ parts.push(selector.substring(offset, i))
+ offset = i + 1
+ continue
+ }
+ if (char === '<') {
+ chevronsCount++
+ } else if (char === '/' && i < selector.length - 1 && selector[i + 1] === '>') {
+ chevronsCount--
+ }
+ }
+ if (offset < selector.length) {
+ parts.push(selector.substring(offset))
+ }
+ }
+
+ const result = []
+ const unprocessedParts = []
+ while (parts.length > 0) {
+ const selector = normalizeSelector(parts.shift())
+ let item
+ if (selector.indexOf('closest ') === 0) {
+ item = closest(asElement(elt), normalizeSelector(selector.substr(8)))
+ } else if (selector.indexOf('find ') === 0) {
+ item = find(asParentNode(elt), normalizeSelector(selector.substr(5)))
+ } else if (selector === 'next' || selector === 'nextElementSibling') {
+ item = asElement(elt).nextElementSibling
+ } else if (selector.indexOf('next ') === 0) {
+ item = scanForwardQuery(elt, normalizeSelector(selector.substr(5)), !!global)
+ } else if (selector === 'previous' || selector === 'previousElementSibling') {
+ item = asElement(elt).previousElementSibling
+ } else if (selector.indexOf('previous ') === 0) {
+ item = scanBackwardsQuery(elt, normalizeSelector(selector.substr(9)), !!global)
+ } else if (selector === 'document') {
+ item = document
+ } else if (selector === 'window') {
+ item = window
+ } else if (selector === 'body') {
+ item = document.body
+ } else if (selector === 'root') {
+ item = getRootNode(elt, !!global)
+ } else if (selector === 'host') {
+ item = (/** @type ShadowRoot */(elt.getRootNode())).host
+ } else {
+ unprocessedParts.push(selector)
+ }
+
+ if (item) {
+ result.push(item)
+ }
+ }
+
+ if (unprocessedParts.length > 0) {
+ const standardSelector = unprocessedParts.join(',')
+ const rootNode = asParentNode(getRootNode(elt, !!global))
+ result.push(...toArray(rootNode.querySelectorAll(standardSelector)))
+ }
+
+ return result
}
/**
@@ -2327,7 +2370,7 @@ var htmx = (function() {
path = getDocument().location.href
}
if (verb === 'get' && path.includes('?')) {
- path = path.replace(/\?[^#]+/, '');
+ path = path.replace(/\?[^#]+/, '')
}
}
triggerSpecs.forEach(function(triggerSpec) {