Skip to content

Commit

Permalink
AG-32271 Add ability to click element in closed shadow root in `trust…
Browse files Browse the repository at this point in the history
…ed-click-element` scriptlet. #423

Squashed commit of the following:

commit 4b2e958
Author: Adam Wróblewski <adam@adguard.com>
Date:   Mon May 27 14:11:34 2024 +0200

    Add ability to click element in closed shadow root in `trusted-click-element` scriptlet
  • Loading branch information
AdamWr committed May 29, 2024
1 parent c0836cd commit 2d333ab
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ The format is based on [Keep a Changelog], and this project adheres to [Semantic

### Added

- ability to click element in closed shadow root in `trusted-click-element` scriptlet [#423]
- `isRedirectResourceCompatibleWithAdg()` method to check compatibility of redirect resources with AdGuard
without needing the full rule text [#420]
- `trusted-replace-outbound-text` scriptlet [#410]
Expand All @@ -27,6 +28,7 @@ The format is based on [Keep a Changelog], and this project adheres to [Semantic

[Unreleased]: https://github.com/AdguardTeam/Scriptlets/compare/v1.10.25...HEAD
[#425]: https://github.com/AdguardTeam/Scriptlets/issues/425
[#423]: https://github.com/AdguardTeam/Scriptlets/issues/423
[#420]: https://github.com/AdguardTeam/Scriptlets/issues/420
[#410]: https://github.com/AdguardTeam/Scriptlets/issues/410
[#409]: https://github.com/AdguardTeam/Scriptlets/issues/409
Expand Down
22 changes: 22 additions & 0 deletions src/scriptlets/trusted-click-element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ export function trustedClickElement(
return;
}

const SHADOW_COMBINATOR = ' >>> ';
const OBSERVER_TIMEOUT_MS = 10000;
const THROTTLE_DELAY_MS = 20;
const STATIC_CLICK_DELAY_MS = 150;
Expand All @@ -136,6 +137,27 @@ export function trustedClickElement(

const sleep = (delayMs: number) => new Promise((resolve) => setTimeout(resolve, delayMs));

// If shadow combinator is present in selector, then override attachShadow and set mode to 'open'
if (selectors.includes(SHADOW_COMBINATOR)) {
const attachShadowWrapper = (
target: typeof Element.prototype.attachShadow,
thisArg: Element,
argumentsList: any[],
) => {
const mode = argumentsList[0]?.mode;
if (mode === 'closed') {
argumentsList[0].mode = 'open';
}
return Reflect.apply(target, thisArg, argumentsList);
};

const attachShadowHandler = {
apply: attachShadowWrapper,
};

window.Element.prototype.attachShadow = new Proxy(window.Element.prototype.attachShadow, attachShadowHandler);
}

let parsedDelay;
if (delay) {
parsedDelay = parseInt(String(delay), 10);
Expand Down
25 changes: 25 additions & 0 deletions tests/scriptlets/trusted-click-element.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -807,3 +807,28 @@ test('Open shadow dom element clicked', (assert) => {
done();
}, 150);
});

test('Closed shadow dom element clicked', (assert) => {
const ELEM_COUNT = 1;
// Check elements for being clicked and hit func execution
const ASSERTIONS = ELEM_COUNT + 1;
assert.expect(ASSERTIONS);
const done = assert.async();

const selectorsString = `#${PANEL_ID} >>> div > #${CLICKABLE_NAME}${ELEM_COUNT}`;

runScriptlet(name, [selectorsString]);

const panel = createPanel();
const shadowRoot = panel.attachShadow({ mode: 'closed' });
const div = document.createElement('div');
const clickable = createClickable(1);
div.appendChild(clickable);
shadowRoot.appendChild(div);

setTimeout(() => {
assert.ok(clickable.getAttribute('clicked'), 'Element should be clicked');
assert.strictEqual(window.hit, 'FIRED', 'hit func executed');
done();
}, 150);
});

0 comments on commit 2d333ab

Please sign in to comment.