Skip to content

Commit 6160980

Browse files
committed
core dom: Add get_parents to return all parent elements from a given DOM node.
1 parent 7c85ee5 commit 6160980

File tree

3 files changed

+55
-1
lines changed

3 files changed

+55
-1
lines changed

CHANGES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
- Allow overriding the public path from outside via the definition of a ``window.__patternslib_public_path__`` global variable.
4949
- Introduce new ``core/dom`` module for DOM manipulation and traversing.
5050
``core/dom`` includes methods which help transition from jQuery to the JavaScript DOM API.
51+
- core dom: Add ``get_parents`` to return all parent elements from a given DOM node.
5152
- core dom: Add ``toNodeArray`` to return an array of DOM nodes if a NodeList, single DOM node or a jQuery object was passed.
5253
- core dom: Add ``querySelectorAllAndMe`` to do a querySelectorAll including the starter element.
5354
- core dom: Add ``wrap`` wrap an element with a wrapper element.

src/core/dom.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,19 @@ const find_scoped = (el, selector) => {
7575
);
7676
};
7777

78+
const get_parents = (el) => {
79+
// Return all HTMLElement parents of el, starting from the direct parent of el.
80+
// The document itself is excluded because it's not a real DOM node.
81+
const parents = [];
82+
let parent = el?.parentNode;
83+
while (parent) {
84+
parents.push(parent);
85+
parent = parent?.parentNode;
86+
parent = parent instanceof HTMLElement ? parent : null;
87+
}
88+
return parents;
89+
};
90+
7891
const is_visible = (el) => {
7992
// Check, if element is visible in DOM.
8093
// https://stackoverflow.com/a/19808107/1337474
@@ -96,6 +109,7 @@ const dom = {
96109
show: show,
97110
find_parents: find_parents,
98111
find_scoped: find_scoped,
112+
get_parents: get_parents,
99113
is_visible: is_visible,
100114
create_from_string: create_from_string,
101115
};

src/core/dom.test.js

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,6 @@ describe("core.dom tests", () => {
184184
it("don't break with DocumentFragment without a parent.", (done) => {
185185
const el = new DocumentFragment();
186186
el.innerHTML = `<div class="starthere"></div>`;
187-
console.log(el.parentNode);
188187
const res = dom.find_parents(
189188
el.querySelector(".starthere"),
190189
".findme"
@@ -242,6 +241,46 @@ describe("core.dom tests", () => {
242241
});
243242
});
244243

244+
describe("get_parents", () => {
245+
it("it finds all parents of an element except document itself.", (done) => {
246+
document.body.innerHTML = `
247+
<div class="level1">
248+
<div class="level2">
249+
<div class="level3">
250+
<div class="level4">
251+
</div>
252+
</div>
253+
</div>
254+
</div>
255+
`;
256+
const res = dom.get_parents(document.querySelector(".level4"));
257+
258+
expect(res.length).toEqual(5);
259+
expect(res[0]).toEqual(document.querySelector(".level3"));
260+
expect(res[1]).toEqual(document.querySelector(".level2"));
261+
expect(res[2]).toEqual(document.querySelector(".level1"));
262+
expect(res[3]).toEqual(document.body);
263+
expect(res[4]).toEqual(document.body.parentNode); // html
264+
265+
done();
266+
});
267+
it("don't break with no element.", (done) => {
268+
const res = dom.get_parents(null);
269+
expect(res.length).toEqual(0);
270+
271+
done();
272+
});
273+
it("don't break with DocumentFragment without a parent.", (done) => {
274+
const el = new DocumentFragment();
275+
el.innerHTML = `<div class="starthere"></div>`;
276+
console.log(el.parentNode);
277+
const res = dom.get_parents(el.querySelector(".starthere"));
278+
expect(res.length).toEqual(0);
279+
280+
done();
281+
});
282+
});
283+
245284
describe("is_visible", () => {
246285
it.skip("checks, if an element is visible or not.", (done) => {
247286
const div1 = document.createElement("div");

0 commit comments

Comments
 (0)