Skip to content

Commit 6db81a2

Browse files
committed
AG-52680 Fix 'trusted-click-element' — throws error when trying to set 'cancelBubble'. #555
Squashed commit of the following: commit 4b6fd24 Merge: d72139c 0330774 Author: Adam Wróblewski <adam@adguard.com> Date: Thu Apr 2 16:43:29 2026 +0200 Merge branch 'master' into fix/AG-52680 commit d72139c Author: Adam Wróblewski <adam@adguard.com> Date: Thu Apr 2 12:28:37 2026 +0200 Fix `trusted-click-element` to allow setting `cancelBubble` without errors in spoofed events
1 parent 0330774 commit 6db81a2

3 files changed

Lines changed: 49 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,14 @@ The format is based on [Keep a Changelog], and this project adheres to [Semantic
2121
- Support for `JSONPath` in `json-prune`, `json-prune-fetch-response`, `json-prune-xhr-response`,
2222
`trusted-json-set`, `trusted-json-set-fetch-response` and `trusted-json-set-xhr-response` scriptlets [#522].
2323

24+
### Fixed
25+
26+
- `trusted-click-element` no longer throws when event handlers set `cancelBubble`
27+
on spoofed events [#555].
28+
2429
[Unreleased]: https://github.com/AdguardTeam/Scriptlets/compare/v2.3.1...HEAD
2530
[#522]: https://github.com/AdguardTeam/Scriptlets/issues/522
31+
[#555]: https://github.com/AdguardTeam/Scriptlets/issues/555
2632

2733
## [v2.3.1] - 2026-03-24
2834

src/helpers/click-utils.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,11 @@ export const spoofClickEventsIsTrusted = (): void => {
9191
}
9292
return val;
9393
},
94+
// Required for setting properties like "cancelBubble" in event handlers
95+
// https://github.com/AdguardTeam/Scriptlets/issues/555
96+
set(target, prop, value) {
97+
return Reflect.set(target, prop, value);
98+
},
9499
});
95100
if (isFn) {
96101
return (listener as EventListener).call(this, proxied);

tests/scriptlets/trusted-click-element.test.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1227,6 +1227,44 @@ test('isTrusted spoofing - removeEventListener works with EventListenerObject',
12271227
}, 150);
12281228
});
12291229

1230+
test('cancelBubble can be set without error in spoofed event', (assert) => {
1231+
const ASSERTIONS = 4;
1232+
assert.expect(ASSERTIONS);
1233+
const done = assert.async();
1234+
1235+
const selectorsString = `#${PANEL_ID} > #${CLICKABLE_NAME}1`;
1236+
1237+
// Run scriptlet before adding event listener to ensure isTrusted is spoofed
1238+
// and before creating the panel and clickable to ensure they are tracked by the scriptlet
1239+
runScriptlet(name, [selectorsString]);
1240+
1241+
const panel = createPanel();
1242+
1243+
const clickable = createClickable(1);
1244+
panel.appendChild(clickable);
1245+
1246+
let receivedIsTrusted = null;
1247+
let cancelBubbleIsSet = null;
1248+
clickable.addEventListener('click', (e) => {
1249+
try {
1250+
receivedIsTrusted = e.isTrusted;
1251+
e.cancelBubble = true;
1252+
cancelBubbleIsSet = e.cancelBubble;
1253+
} catch (error) {
1254+
console.error('Error in click event listener:', error);
1255+
cancelBubbleIsSet = false;
1256+
}
1257+
});
1258+
1259+
setTimeout(() => {
1260+
assert.ok(clickable.getAttribute('clicked'), 'Element should be clicked');
1261+
assert.strictEqual(receivedIsTrusted, true, 'isTrusted should be spoofed to true');
1262+
assert.strictEqual(cancelBubbleIsSet, true, 'cancelBubble should be settable to true');
1263+
assert.strictEqual(window.hit, 'FIRED', 'hit func executed');
1264+
done();
1265+
}, 150);
1266+
});
1267+
12301268
test('isTrusted is spoofed for onclick events', (assert) => {
12311269
const ASSERTIONS = 3;
12321270
assert.expect(ASSERTIONS);

0 commit comments

Comments
 (0)