/** * @summary traverse-parents * * @version 3.0.0 * @since 1.0.0 * * @author Arian Khosravi <arian.khosravi@aofl.com> */ /** * Finds parent based on the validity of the `cb` function * * @memberof module:@aofl/component-utils * * @param {HTMLElement} node * @param {Function} cb * * @return {(HTMLElement|Boolean)} Returns a HTMLElement matching the pattern defined in cb or false. */ const traverseParents = (node, cb) => { let parent = node; while (parent !== null) { if (parent.assignedSlot) { parent = parent.assignedSlot; } else if (typeof parent.tagName === 'undefined' && typeof parent.host !== 'undefined') { parent = parent.host; } else if (parent.parentNode) { parent = parent.parentNode; } else { break; } if (cb(parent)) { return parent; } } return false; }; /** * Finds parent method with matching signature * * @memberof module:@aofl/component-utils * @param {HTMLElement} node * @param {*} args * @return {Object} */ const findParent = (node, ...args) => { return traverseParents(node, (parent) => { let found = true; for (let i = 0; i < args.length; i++) { if (typeof parent[args[i]] === 'undefined') { found = false; break; } } return found; }); }; /** * Finds parent method with matching attributes * * @memberof module:@aofl/component-utils * @param {HTMLElement} node * @param {*} args * @return {Object} */ const findParentByAttributes = (node, ...args) => { return traverseParents(node, (parent) => { let found = true; for (let i = 0; i < args.length; i++) { if (typeof parent.hasAttribute === 'undefined' || !parent.hasAttribute(args[i])) { found = false; break; } } return found; }); }; export { findParent, findParentByAttributes, traverseParents };