forked from WebKit/Speedometer
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhelpers.mjs
More file actions
55 lines (51 loc) · 2.57 KB
/
helpers.mjs
File metadata and controls
55 lines (51 loc) · 2.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
/**
* Recursively queries the DOM for an element, traversing through shadow DOMs.
*
* @param {Element|ShadowRoot} lookupStartNode The node or shadow root to start the lookup from.
* @param {string[]} path An array of CSS selectors representing the path to the target element.
* @returns {Element|null} The target element if found, otherwise null.
*/
export function recursivelyQuerySelector(lookupStartNode, path) {
lookupStartNode = lookupStartNode.shadowRoot ?? lookupStartNode;
const target = path.reduce((root, selector) => {
const node = root.querySelector(selector);
return node.shadowRoot ?? node;
}, lookupStartNode);
return target;
}
/**
* Retrieves a single DOM element, optionally traversing through shadow DOMs to a specified path before the final selection.
*
* @param {string} selector The CSS selector for the desired element.
* @param {string[]} [path=[]] An optional array of CSS selectors to reach the desired shadowRoot or parent element.
* @param {Element|ShadowRoot} [lookupStartNode=document] The starting node for the lookup.
* @returns {Element|null} The found element, or null if not found.
*/
export function getElement(selector, path = [], lookupStartNode = document) {
const element = recursivelyQuerySelector(lookupStartNode, path).querySelector(selector);
return element;
}
/**
* Retrieves all DOM elements matching a selector, optionally traversing through shadow DOMs to a specified path before the final selection.
*
* @param {string} selector The CSS selector for the desired elements.
* @param {string[]} [path=[]] An optional array of CSS selectors to reach the desired shadowRoot or parent element.
* @param {Element|ShadowRoot} [lookupStartNode=document] The starting node for the lookup.
* @returns {Element[]} An array of found elements.
*/
export function getAllElements(selector, path = [], lookupStartNode = document) {
const elements = Array.from(recursivelyQuerySelector(lookupStartNode, path).querySelectorAll(selector));
return elements;
}
/**
* Forces a reflow/layout of the document by requesting a DOM property that triggers it.
* This can be useful for ensuring that styles and positions are up-to-date before
* performing measurements or animations. It also returns an element from the center of the viewport.
*
* @returns {Element|null} An element at the center of the viewport, or null if no element is there.
*/
export function forceLayout() {
const rect = document.body.getBoundingClientRect();
const e = document.elementFromPoint((rect.width / 2) | 0, (rect.height / 2) | 0);
return e;
}