Skip to content

Commit d39d5ea

Browse files
authored
Merge pull request #1269 from Patternslib/thet/4321--inject-scroll
Thet/4321 inject scroll
2 parents 0549076 + c20c58a commit d39d5ea

File tree

5 files changed

+343
-38
lines changed

5 files changed

+343
-38
lines changed

src/core/dom.js

Lines changed: 50 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -37,36 +37,61 @@ const document_ready = (fn) => {
3737
/**
3838
* Return an array of DOM nodes.
3939
*
40-
* @param {Node|NodeList|jQuery} nodes - The DOM node to start the search from.
40+
* @param {Node|NodeList|jQuery} nodes - The object which should be returned as array.
4141
*
4242
* @returns {Array} - An array of DOM nodes.
4343
*/
44-
const toNodeArray = (nodes) => {
45-
if (nodes.jquery || nodes instanceof NodeList) {
46-
// jQuery or document.querySelectorAll
44+
const to_node_array = (nodes) => {
45+
if (nodes?.jquery || nodes instanceof NodeList) {
4746
nodes = [...nodes];
4847
} else if (nodes instanceof Array === false) {
4948
nodes = [nodes];
5049
}
50+
// Filter for DOM nodes only.
51+
nodes = nodes.filter((node) => node instanceof Node);
52+
return nodes;
53+
};
54+
55+
/**
56+
* Return an array of DOM elements.
57+
*
58+
* @param {Node|NodeList|jQuery} nodes - The object which should be returned as array.
59+
*
60+
* @returns {Array} - An array of DOM elements.
61+
*/
62+
const to_element_array = (nodes) => {
63+
nodes = to_node_array(nodes);
64+
// Filter for DOM elements only.
65+
nodes = nodes.filter((node) => node instanceof Element);
5166
return nodes;
5267
};
5368

5469
/**
5570
* Like querySelectorAll but including the element where it starts from.
5671
* Returns an Array, not a NodeList
5772
*
58-
* @param {Node} el - The DOM node to start the search from.
73+
* @param {Element|NodeList|Array} el - The DOM element, NodeList or array of elements to start the search from.
74+
* @param {string} selector - The CSS selector to search for.
5975
*
60-
* @returns {Array} - The DOM nodes found.
76+
* @returns {Array} - The DOM elements found.
6177
*/
6278
const querySelectorAllAndMe = (el, selector) => {
63-
if (!el || !el.querySelectorAll) {
64-
return [];
65-
}
66-
67-
const all = [...el.querySelectorAll(selector)];
68-
if (el.matches(selector)) {
69-
all.unshift(el); // start element should be first.
79+
// Ensure we have a list of DOM elements.
80+
const roots = to_element_array(el);
81+
const seen = new WeakSet();
82+
const all = [];
83+
84+
for (const root of roots) {
85+
if (root.matches(selector) && !seen.has(root)) {
86+
all.push(root);
87+
seen.add(root);
88+
}
89+
for (const match of root.querySelectorAll(selector)) {
90+
if (!seen.has(match)) {
91+
all.push(match);
92+
seen.add(match);
93+
}
94+
}
7095
}
7196
return all;
7297
};
@@ -157,8 +182,6 @@ const is_button = (el) => {
157182
`);
158183
};
159184

160-
161-
162185
/**
163186
* Return all direct parents of ``el`` matching ``selector``.
164187
* This matches against all parents but not the element itself.
@@ -383,15 +406,15 @@ const get_relative_position = (el, reference_el = document.body) => {
383406
// https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect
384407
const left = Math.abs(
385408
el.getBoundingClientRect().left +
386-
reference_el.scrollLeft -
387-
reference_el.getBoundingClientRect().left -
388-
dom.get_css_value(reference_el, "border-left-width", true)
409+
reference_el.scrollLeft -
410+
reference_el.getBoundingClientRect().left -
411+
dom.get_css_value(reference_el, "border-left-width", true)
389412
);
390413
const top = Math.abs(
391414
el.getBoundingClientRect().top +
392-
reference_el.scrollTop -
393-
reference_el.getBoundingClientRect().top -
394-
dom.get_css_value(reference_el, "border-top-width", true)
415+
reference_el.scrollTop -
416+
reference_el.getBoundingClientRect().top -
417+
dom.get_css_value(reference_el, "border-top-width", true)
395418
);
396419

397420
return { top, left };
@@ -535,9 +558,9 @@ const get_visible_ratio = (el, container) => {
535558
container !== window
536559
? container.getBoundingClientRect()
537560
: {
538-
top: 0,
539-
bottom: window.innerHeight,
540-
};
561+
top: 0,
562+
bottom: window.innerHeight,
563+
};
541564

542565
let visible_ratio = 0;
543566
if (rect.top < container_rect.bottom && rect.bottom > container_rect.top) {
@@ -619,7 +642,9 @@ const find_inputs = (el) => {
619642

620643
const dom = {
621644
document_ready: document_ready,
622-
toNodeArray: toNodeArray,
645+
to_element_array: to_element_array,
646+
to_node_array: to_node_array,
647+
toNodeArray: to_node_array, // BBB.
623648
querySelectorAllAndMe: querySelectorAllAndMe,
624649
wrap: wrap,
625650
hide: hide,

0 commit comments

Comments
 (0)