summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
authorJoerg Sonnenberger <joerg@bec.de>2024-10-03 03:17:25 +0200
committerGitHub <noreply@github.com>2024-10-02 19:17:25 -0600
commitdf92b295d6b91291ecef97733ba135ac5de565a5 (patch)
tree9b605d8b6baee7f8e4fee53b081468582603a2a5 /src
parent4916ce4d0260072f3ceb2957d75229c88cf59fc2 (diff)
downloadhtmx-df92b295d6b91291ecef97733ba135ac5de565a5.tar.gz
htmx-df92b295d6b91291ecef97733ba135ac5de565a5.zip
Change hx-trigger's changed modifier to work for independent trigger specifications (#2891)
* Adjust hx-trigger's changed modifier for multiple sources The `changed` trigger modifier can see different event targets, either due to the `from` modifier or event bubbling. The existing behavior trigger only for one node (`from` modifier) or inconsistently (bubbling). Use a nested weak map to keep track of the last value per distinguished (trigger specification, event target node) pair. The weak map ensures that Garbage Collection can still recycle the nodes. If a event target was not seen via `from`, it is assumed changed for the first time the trigger is hit. * Add test case for separate triggers with changed modifier
Diffstat (limited to 'src')
-rw-r--r--src/htmx.js26
1 files changed, 13 insertions, 13 deletions
diff --git a/src/htmx.js b/src/htmx.js
index e24dd23a..b51cc165 100644
--- a/src/htmx.js
+++ b/src/htmx.js
@@ -695,7 +695,7 @@ var htmx = (function() {
* @property {boolean} [triggeredOnce]
* @property {number} [delayed]
* @property {number|null} [throttle]
- * @property {string} [lastValue]
+ * @property {WeakMap<HtmxTriggerSpecification,WeakMap<EventTarget,string>>} [lastValue]
* @property {boolean} [loaded]
* @property {string} [path]
* @property {string} [verb]
@@ -2417,10 +2417,15 @@ var htmx = (function() {
}
// store the initial values of the elements, so we can tell if they change
if (triggerSpec.changed) {
+ if (!('lastValue' in elementData)) {
+ elementData.lastValue = new WeakMap()
+ }
eltsToListenOn.forEach(function(eltToListenOn) {
- const eltToListenOnData = getInternalData(eltToListenOn)
+ if (!elementData.lastValue.has(triggerSpec)) {
+ elementData.lastValue.set(triggerSpec, new WeakMap())
+ }
// @ts-ignore value will be undefined for non-input elements, which is fine
- eltToListenOnData.lastValue = eltToListenOn.value
+ elementData.lastValue.get(triggerSpec).set(eltToListenOn, eltToListenOn.value)
})
}
forEach(eltsToListenOn, function(eltToListenOn) {
@@ -2462,13 +2467,14 @@ var htmx = (function() {
}
}
if (triggerSpec.changed) {
- const eltToListenOnData = getInternalData(eltToListenOn)
+ const node = event.target
// @ts-ignore value will be undefined for non-input elements, which is fine
- const value = eltToListenOn.value
- if (eltToListenOnData.lastValue === value) {
+ const value = node.value
+ const lastValue = elementData.lastValue.get(triggerSpec)
+ if (lastValue.has(node) && lastValue.get(node) === value) {
return
}
- eltToListenOnData.lastValue = value
+ lastValue.set(node, value)
}
if (elementData.delayed) {
clearTimeout(elementData.delayed)
@@ -2846,12 +2852,6 @@ var htmx = (function() {
triggerEvent(elt, 'htmx:beforeProcessNode')
- // @ts-ignore value will be undefined for non-input elements, which is fine
- if (elt.value) {
- // @ts-ignore
- nodeData.lastValue = elt.value
- }
-
const triggerSpecs = getTriggerSpecs(elt)
const hasExplicitHttpAction = processVerbs(elt, nodeData, triggerSpecs)