Skip to content

Commit d3a2db3

Browse files
committed
feat(core dom): Add acquire_attribute to get the value of the first occurence of a defined attribute up the DOM tree.
1 parent 8cfeeb8 commit d3a2db3

File tree

2 files changed

+96
-0
lines changed

2 files changed

+96
-0
lines changed

src/core/dom.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,26 @@ const get_parents = (el) => {
8989
return parents;
9090
};
9191

92+
/**
93+
* Return the value of the first attribute found in the list of parents.
94+
*
95+
* @param {DOM element} el - The DOM element to start the acquisition search for the given attribute.
96+
* @param {string} attribute - Name of the attribute to search for.
97+
* @param {Boolean} include_empty - Also return empty values.
98+
*
99+
* @returns {*} - Returns the value of the searched attribute.
100+
*/
101+
const acquire_attribute = (el, attribute, include_empty = false) => {
102+
let _el = el;
103+
while (_el) {
104+
const val = _el.getAttribute(attribute);
105+
if (val || (include_empty && val === "")) {
106+
return val;
107+
}
108+
_el = _el.parentElement;
109+
}
110+
};
111+
92112
const is_visible = (el) => {
93113
// Check, if element is visible in DOM.
94114
// https://stackoverflow.com/a/19808107/1337474
@@ -169,6 +189,7 @@ const dom = {
169189
find_parents: find_parents,
170190
find_scoped: find_scoped,
171191
get_parents: get_parents,
192+
acquire_attribute: acquire_attribute,
172193
is_visible: is_visible,
173194
create_from_string: create_from_string,
174195
add_event_listener: add_event_listener,

src/core/dom.test.js

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,81 @@ describe("core.dom tests", () => {
269269
});
270270
});
271271

272+
describe("acquire_attribute", () => {
273+
it("finds the first occurrence of an non-empty attribute in all parents.", (done) => {
274+
document.body.innerHTML = `
275+
<div lang="en">
276+
<div id="start" lang="">
277+
</div>
278+
</div>
279+
`;
280+
const el = document.querySelector("#start");
281+
const res = dom.acquire_attribute(el, "lang");
282+
expect(res).toBe("en");
283+
284+
done();
285+
});
286+
it("finds the first occurrence of an attribute in all parents, even if empty.", (done) => {
287+
document.body.innerHTML = `
288+
<div lang="en">
289+
<div lang="">
290+
<div id="start">
291+
</div>
292+
</div>
293+
</div>
294+
`;
295+
const el = document.querySelector("#start");
296+
const res = dom.acquire_attribute(el, "lang", true);
297+
expect(res).toBe("");
298+
299+
done();
300+
});
301+
it("traverses up a long way to find an attribute.", (done) => {
302+
document.body.innerHTML = `
303+
<div lang="en">
304+
<div>
305+
<div lang="">
306+
<div>
307+
<div lang="">
308+
<div>
309+
<div lang="">
310+
<div>
311+
<div lang="">
312+
<div>
313+
<div id="start" lang="">
314+
</div>
315+
</div>
316+
</div>
317+
</div>
318+
</div>
319+
</div>
320+
</div>
321+
</div>
322+
</div>
323+
</div>
324+
</div>
325+
`;
326+
const el = document.querySelector("#start");
327+
const res = dom.acquire_attribute(el, "lang");
328+
expect(res).toBe("en");
329+
330+
done();
331+
});
332+
it("just returns if it finds nothing.", (done) => {
333+
document.body.innerHTML = `
334+
<div>
335+
<div id="start">
336+
</div>
337+
</div>
338+
`;
339+
const el = document.querySelector("#start");
340+
const res = dom.acquire_attribute(el, "lang");
341+
expect(res).toBe(undefined);
342+
343+
done();
344+
});
345+
});
346+
272347
describe("is_visible", () => {
273348
it.skip("checks, if an element is visible or not.", (done) => {
274349
const div1 = document.createElement("div");

0 commit comments

Comments
 (0)