UNPKG

@taiga-ui/cdk

Version:

Base library for creating Angular components and applications using Taiga UI principles regarding of actual visual appearance

118 lines 5.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.findElementsByFn = findElementsByFn; exports.findElementsInTemplateByFn = findElementsInTemplateByFn; exports.findElementsByTagName = findElementsByTagName; exports.findElementsByTagNames = findElementsByTagNames; exports.findElementsWithDirective = findElementsWithDirective; exports.findElementsWithAttribute = findElementsWithAttribute; exports.findElementsWithAttributeOnTag = findElementsWithAttributeOnTag; exports.findAttributeOnElementWithTag = findAttributeOnElementWithTag; exports.findAttributeOnElementWithAttrs = findAttributeOnElementWithAttrs; exports.hasElementAttribute = hasElementAttribute; exports.hasElementAttributeWithValue = hasElementAttributeWithValue; exports.getStartOffsetOfAttribute = getStartOffsetOfAttribute; const parse5_1 = require("parse5"); function findElementsByFn(nodes, predicateFn) { const elements = []; const visitNodes = (nodes) => { nodes.forEach((n) => { const node = n; if (node.childNodes) { visitNodes(node.childNodes); } if (predicateFn(node)) { elements.push(node); } }); }; visitNodes(nodes); return elements; } function findElementsInTemplateByFn(html, predicateFn) { // utf8 with BOM adds an extra character to the beginning of the string if (html.charCodeAt(0) === 0xfeff) { html = html.slice(1); } const document = (0, parse5_1.parseFragment)(html, { sourceCodeLocationInfo: true }); return findElementsByFn(document.childNodes, predicateFn); } function findElementsByTagName(html, tagName, filterFn = () => true) { return findElementsInTemplateByFn(html, (el) => el.tagName === tagName && filterFn(el)); } function findElementsByTagNames(html, tagNames) { return findElementsInTemplateByFn(html, (el) => tagNames.includes(el.tagName)); } /** * Parses a HTML fragment and traverses all AST nodes in order find elements that * include the specified directive as attribute or input. */ function findElementsWithDirective(html, attributeName) { const lowercasedAttrName = attributeName.toLowerCase(); const inputName = `[${lowercasedAttrName}]`; return findElementsInTemplateByFn(html, (el) => { var _a; return (_a = el.attrs) === null || _a === void 0 ? void 0 : _a.some(({ name }) => name === lowercasedAttrName || name === inputName); }); } /** * Parses a HTML fragment and traverses all AST nodes in order find elements that * include the specified attribute. */ function findElementsWithAttribute(html, attributeName) { return findElementsInTemplateByFn(html, (el) => { var _a; return (_a = el.attrs) === null || _a === void 0 ? void 0 : _a.some((attr) => attr.name === attributeName.toLowerCase()); }); } /** * Parses a HTML fragment and traverses all AST nodes in order find elements that include the specified attribute and tag name. * @param html * @param attributeName */ function findElementsWithAttributeOnTag(html, attributeNames, tagNames = [], filterFn = () => true) { return findElementsInTemplateByFn(html, (el) => { var _a; return (!attributeNames.length || ((_a = el.attrs) === null || _a === void 0 ? void 0 : _a.some((attr) => attributeNames.map((name) => name.toLowerCase()).includes(attr.name)))) && (tagNames.includes(el.tagName) || tagNames.includes('*') || !tagNames.length) && filterFn(el); }); } /** * Finds elements with explicit tag names that also contain the specified attribute. Returns the * attribute start offset based on the specified HTML. */ function findAttributeOnElementWithTag(html, name, tagNames, filterFn = () => true) { return findElementsWithAttribute(html, name) .filter((element) => (tagNames.includes(element.tagName) || tagNames.includes('*')) && filterFn(element)) .map((element) => getStartOffsetOfAttribute(element, name)); } /** * Finds elements that contain the given attribute and contain at least one of the other * specified attributes. Returns the primary attribute's start offset based on the specified HTML. */ function findAttributeOnElementWithAttrs(html, name, attrs, filterFn = () => true) { return findElementsWithAttribute(html, name) .filter((element) => attrs.some((attr) => hasElementAttribute(element, attr)) && filterFn(element)) .map((element) => getStartOffsetOfAttribute(element, name)); } /** Shorthand function that checks if the specified element contains the given attribute. */ function hasElementAttribute(element, attributeName) { var _a; const lowercasedAttrName = attributeName.toLowerCase(); return (_a = element.attrs) === null || _a === void 0 ? void 0 : _a.some((attr) => attr.name === lowercasedAttrName || attr.name === `[${lowercasedAttrName}]`); } function hasElementAttributeWithValue(element, attributeName, attributeValue) { var _a; const lowercasedAttrName = attributeName.toLowerCase(); const lowercasedValue = attributeValue.toLowerCase(); return (_a = element.attrs) === null || _a === void 0 ? void 0 : _a.some((attr) => (attr.name === lowercasedAttrName && attr.value === lowercasedValue) || (attr.name === `[${lowercasedAttrName}]` && (attr.value === `'${attributeValue}'` || attr.value === `"${attributeValue}"`))); } /** Gets the start offset of the given attribute from a Parse5 element. */ function getStartOffsetOfAttribute(element, attributeName) { var _a, _b, _c; return (((_c = (_b = (_a = element.sourceCodeLocation) === null || _a === void 0 ? void 0 : _a.attrs) === null || _b === void 0 ? void 0 : _b[attributeName.toLowerCase()]) === null || _c === void 0 ? void 0 : _c.startOffset) || 0); } //# sourceMappingURL=elements.js.map