UNPKG

@nativescript/core

Version:

A JavaScript library providing an easy to use api for interacting with iOS and Android platform APIs.

934 lines • 33 kB
import { parse as convertToCSSWhatSelector } from 'css-what'; import '../../globals'; import { isCssVariable } from '../core/properties'; import { isNullOrUndefined } from '../../utils/types'; import { checkIfMediaQueryMatches } from '../../media-query-list'; export const MEDIA_QUERY_SEPARATOR = '&&'; var Combinator; (function (Combinator) { Combinator["descendant"] = " "; Combinator["child"] = ">"; Combinator["adjacent"] = "+"; Combinator["sibling"] = "~"; // Not supported Combinator["parent"] = "<"; Combinator["column-combinator"] = "||"; })(Combinator || (Combinator = {})); var AttributeSelectorOperator; (function (AttributeSelectorOperator) { AttributeSelectorOperator["exists"] = ""; AttributeSelectorOperator["equals"] = "="; AttributeSelectorOperator["start"] = "^="; AttributeSelectorOperator["end"] = "$="; AttributeSelectorOperator["any"] = "*="; AttributeSelectorOperator["element"] = "~="; AttributeSelectorOperator["hyphen"] = "|="; })(AttributeSelectorOperator || (AttributeSelectorOperator = {})); var Match; (function (Match) { /** * Depends on attributes or pseudoclasses state; */ Match.Dynamic = true; /** * Depends only on the tree structure. */ Match.Static = false; })(Match || (Match = {})); function eachNodePreviousGeneralSibling(node, callback) { if (!node.parent || !node.parent.getChildIndex || !node.parent.getChildAt || !node.parent.getChildrenCount) { return; } const nodeIndex = node.parent.getChildIndex(node); if (nodeIndex === 0) { return; } const count = node.parent.getChildrenCount(); let retVal = true; for (let i = nodeIndex - 1; i >= 0 && retVal; i--) { const sibling = node.parent.getChildAt(i); retVal = callback(sibling); } } function getNodePreviousDirectSibling(node) { if (!node.parent || !node.parent.getChildIndex || !node.parent.getChildAt) { return null; } const nodeIndex = node.parent.getChildIndex(node); if (nodeIndex === 0) { return null; } return node.parent.getChildAt(nodeIndex - 1); } function SelectorProperties(specificity, rarity, dynamic = false) { return (cls) => { cls.prototype.specificity = specificity; cls.prototype.rarity = rarity; cls.prototype.combinator = undefined; cls.prototype.dynamic = dynamic; return cls; }; } function FunctionalPseudoClassProperties(specificity, rarity, pseudoSelectorListType) { return (cls) => { cls.prototype.specificity = specificity; cls.prototype.rarity = rarity; cls.prototype.combinator = undefined; cls.prototype.dynamic = false; cls.prototype.pseudoSelectorListType = pseudoSelectorListType; return cls; }; } export class SelectorBase { } let SelectorCore = class SelectorCore extends SelectorBase { lookupSort(sorter, base) { sorter.sortAsUniversal(base || this); } }; SelectorCore = __decorate([ SelectorProperties(0 /* Specificity.Universal */, 0 /* Rarity.Universal */, Match.Static) ], SelectorCore); export { SelectorCore }; export class SimpleSelector extends SelectorCore { accumulateChanges(node, map) { if (!this.dynamic) { return this.match(node); } else if (this.mayMatch(node)) { this.trackChanges(node, map); return true; } return false; } mayMatch(node) { return this.match(node); } trackChanges(node, map) { // No-op, silence the tslint 'block is empty'. // Some derived classes (dynamic) will actually fill the map with stuff here, some (static) won't do anything. } } function wrap(text) { return text ? ` ${text} ` : ''; } let InvalidSelector = class InvalidSelector extends SimpleSelector { constructor(e) { super(); this.e = e; } toString() { return `<${this.e}>`; } match(node) { return false; } lookupSort(sorter, base) { // No-op, silence the tslint 'block is empty'. // It feels like tslint has problems with simple polymorphism... // This selector is invalid and will never match so we won't bother sorting it to further appear in queries. } }; InvalidSelector = __decorate([ SelectorProperties(0 /* Specificity.Invalid */, 4 /* Rarity.Invalid */, Match.Static), __metadata("design:paramtypes", [Error]) ], InvalidSelector); export { InvalidSelector }; let UniversalSelector = class UniversalSelector extends SimpleSelector { toString() { return `*${wrap(this.combinator)}`; } match(node) { return true; } }; UniversalSelector = __decorate([ SelectorProperties(0 /* Specificity.Universal */, 0 /* Rarity.Universal */, Match.Static) ], UniversalSelector); export { UniversalSelector }; let IdSelector = class IdSelector extends SimpleSelector { constructor(id) { super(); this.id = id; } toString() { return `#${this.id}${wrap(this.combinator)}`; } match(node) { return node.id === this.id; } lookupSort(sorter, base) { sorter.sortById(this.id, base || this); } }; IdSelector = __decorate([ SelectorProperties(100 /* Specificity.Id */, 3 /* Rarity.Id */, Match.Static), __metadata("design:paramtypes", [String]) ], IdSelector); export { IdSelector }; let TypeSelector = class TypeSelector extends SimpleSelector { constructor(cssType) { super(); this.cssType = cssType; } toString() { return `${this.cssType}${wrap(this.combinator)}`; } match(node) { return node.cssType === this.cssType; } lookupSort(sorter, base) { sorter.sortByType(this.cssType, base || this); } }; TypeSelector = __decorate([ SelectorProperties(1 /* Specificity.Type */, 1 /* Rarity.Type */, Match.Static), __metadata("design:paramtypes", [String]) ], TypeSelector); export { TypeSelector }; let ClassSelector = class ClassSelector extends SimpleSelector { constructor(cssClass) { super(); this.cssClass = cssClass; } toString() { return `.${this.cssClass}${wrap(this.combinator)}`; } match(node) { return node.cssClasses && node.cssClasses.has(this.cssClass); } lookupSort(sorter, base) { sorter.sortByClass(this.cssClass, base || this); } }; ClassSelector = __decorate([ SelectorProperties(10 /* Specificity.Class */, 2 /* Rarity.Class */, Match.Static), __metadata("design:paramtypes", [String]) ], ClassSelector); export { ClassSelector }; let AttributeSelector = class AttributeSelector extends SimpleSelector { constructor(attribute, test, value, ignoreCase) { super(); this.attribute = attribute; this.test = test; this.value = value; this.ignoreCase = ignoreCase; } toString() { return `[${this.attribute}${wrap(AttributeSelectorOperator[this.test] ?? this.test)}${this.value || ''}]${wrap(this.combinator)}`; } match(node) { let attr = node[this.attribute]; if (this.test === 'exists') { return !isNullOrUndefined(attr); } if (!this.value) { return false; } // Now, convert value to string attr += ''; if (this.ignoreCase) { attr = attr.toLowerCase(); this.value = this.value.toLowerCase(); } // = if (this.test === 'equals') { return attr === this.value; } // ^= if (this.test === 'start') { return attr.startsWith(this.value); } // $= if (this.test === 'end') { return attr.endsWith(this.value); } // *= if (this.test === 'any') { return attr.indexOf(this.value) !== -1; } // ~= if (this.test === 'element') { const words = attr.split(' '); return words && words.indexOf(this.value) !== -1; } // |= if (this.test === 'hyphen') { return attr === this.value || attr.startsWith(this.value + '-'); } return false; } mayMatch(node) { return true; } trackChanges(node, map) { map.addAttribute(node, this.attribute); } }; AttributeSelector = __decorate([ SelectorProperties(10 /* Specificity.Attribute */, 0 /* Rarity.Attribute */, Match.Dynamic), __metadata("design:paramtypes", [String, String, String, Boolean]) ], AttributeSelector); export { AttributeSelector }; let PseudoClassSelector = class PseudoClassSelector extends SimpleSelector { constructor(cssPseudoClass) { super(); this.cssPseudoClass = cssPseudoClass; } toString() { return `:${this.cssPseudoClass}${wrap(this.combinator)}`; } match(node) { return node.cssPseudoClasses && node.cssPseudoClasses.has(this.cssPseudoClass); } mayMatch(node) { return true; } trackChanges(node, map) { map.addPseudoClass(node, this.cssPseudoClass); } }; PseudoClassSelector = __decorate([ SelectorProperties(10 /* Specificity.PseudoClass */, 0 /* Rarity.PseudoClass */, Match.Dynamic), __metadata("design:paramtypes", [String]) ], PseudoClassSelector); export { PseudoClassSelector }; export class FunctionalPseudoClassSelector extends PseudoClassSelector { constructor(cssPseudoClass, dataType) { super(cssPseudoClass); const selectors = []; const needsHighestSpecificity = this.specificity === -1 /* Specificity.SelectorListHighest */; let specificity = 0; if (Array.isArray(dataType)) { for (const asts of dataType) { const selector = createSelectorFromAst(asts); if (selector instanceof InvalidSelector) { // Only forgiving selector list can ignore invalid selectors if (this.selectorListType !== 1 /* PseudoClassSelectorList.Forgiving */) { selectors.splice(0); specificity = 0; break; } continue; } // The specificity of some pseudo-classes is replaced by the specificity of the most specific selector in its comma-separated argument of selectors if (needsHighestSpecificity && selector.specificity > specificity) { specificity = selector.specificity; } selectors.push(selector); } } this.selectors = selectors; this.specificity = specificity; // Functional pseudo-classes become dynamic based on selectors in selector list this.dynamic = this.selectors.some((sel) => sel.dynamic); } toString() { return `:${this.cssPseudoClass}(${this.selectors.join(', ')})${wrap(this.combinator)}`; } match(node) { return false; } mayMatch(node) { return true; } trackChanges(node, map) { this.selectors.forEach((sel) => sel.trackChanges(node, map)); } } let NotFunctionalPseudoClassSelector = class NotFunctionalPseudoClassSelector extends FunctionalPseudoClassSelector { match(node) { return !this.selectors.some((sel) => sel.match(node)); } }; NotFunctionalPseudoClassSelector = __decorate([ FunctionalPseudoClassProperties(-1 /* Specificity.SelectorListHighest */, 0 /* Rarity.PseudoClass */, 0 /* PseudoClassSelectorList.Regular */) ], NotFunctionalPseudoClassSelector); export { NotFunctionalPseudoClassSelector }; let IsFunctionalPseudoClassSelector = class IsFunctionalPseudoClassSelector extends FunctionalPseudoClassSelector { match(node) { return this.selectors.some((sel) => sel.match(node)); } lookupSort(sorter, base) { // A faster lookup can be performed when selector list contains just a single selector if (this.selectors.length === 1) { this.selectors[0].lookupSort(sorter, base || this); } else { super.lookupSort(sorter, base || this); } } }; IsFunctionalPseudoClassSelector = __decorate([ FunctionalPseudoClassProperties(-1 /* Specificity.SelectorListHighest */, 0 /* Rarity.PseudoClass */, 1 /* PseudoClassSelectorList.Forgiving */) ], IsFunctionalPseudoClassSelector); export { IsFunctionalPseudoClassSelector }; let WhereFunctionalPseudoClassSelector = class WhereFunctionalPseudoClassSelector extends FunctionalPseudoClassSelector { match(node) { return this.selectors.some((sel) => sel.match(node)); } lookupSort(sorter, base) { // A faster lookup can be performed when selector list contains just a single selector if (this.selectors.length === 1) { this.selectors[0].lookupSort(sorter, base || this); } else { super.lookupSort(sorter, base || this); } } }; WhereFunctionalPseudoClassSelector = __decorate([ FunctionalPseudoClassProperties(0 /* Specificity.Zero */, 0 /* Rarity.PseudoClass */, 1 /* PseudoClassSelectorList.Forgiving */) ], WhereFunctionalPseudoClassSelector); export { WhereFunctionalPseudoClassSelector }; export class SimpleSelectorSequence extends SimpleSelector { constructor(selectors) { super(); this.selectors = selectors; this.specificity = selectors.reduce((sum, sel) => sel.specificity + sum, 0); this.head = selectors.reduce((prev, curr) => (!prev || curr.rarity > prev.rarity ? curr : prev), null); this.dynamic = selectors.some((sel) => sel.dynamic); } toString() { return `${this.selectors.join('')}${wrap(this.combinator)}`; } match(node) { return this.selectors.every((sel) => sel.match(node)); } mayMatch(node) { return this.selectors.every((sel) => sel.mayMatch(node)); } trackChanges(node, map) { this.selectors.forEach((sel) => sel.trackChanges(node, map)); } lookupSort(sorter, base) { this.head.lookupSort(sorter, base || this); } } export class ComplexSelector extends SelectorCore { constructor(selectors) { super(); this.selectors = selectors; let siblingsToGroup; let currentGroup; const groups = []; this.specificity = 0; this.dynamic = false; for (let i = selectors.length - 1; i >= 0; i--) { const sel = selectors[i]; switch (sel.combinator) { case undefined: case Combinator.descendant: siblingsToGroup = []; currentGroup = [siblingsToGroup]; groups.push(currentGroup); break; case Combinator.child: siblingsToGroup = []; currentGroup.push(siblingsToGroup); break; case Combinator.adjacent: case Combinator.sibling: break; default: throw new Error(`Unsupported combinator "${sel.combinator}" for selector ${sel}.`); } this.specificity += sel.specificity; if (sel.dynamic) { this.dynamic = true; } siblingsToGroup.push(sel); } this.groups = groups.map((g) => new Selector.ChildGroup(g.map((selectors) => (selectors.length > 1 ? new Selector.SiblingGroup(selectors) : selectors[0])))); this.last = selectors[selectors.length - 1]; } toString() { return this.selectors.join(''); } match(node) { return this.groups.every((group, i) => { if (i === 0) { node = group.getMatchingNode(node, true); return !!node; } else { let ancestor = node; while ((ancestor = ancestor.parent ?? ancestor._modalParent)) { if ((node = group.getMatchingNode(ancestor, true))) { return true; } } return false; } }); } mayMatch(node) { return false; } trackChanges(node, map) { this.selectors.forEach((sel) => sel.trackChanges(node, map)); } lookupSort(sorter, base) { this.last.lookupSort(sorter, base || this); } accumulateChanges(node, map) { if (!this.dynamic) { return this.match(node); } const bounds = []; const mayMatch = this.groups.every((group, i) => { if (i === 0) { const nextNode = group.getMatchingNode(node, false); bounds.push({ left: node, right: node }); node = nextNode; return !!node; } else { let ancestor = node; while ((ancestor = ancestor.parent)) { const nextNode = group.getMatchingNode(ancestor, false); if (nextNode) { bounds.push({ left: ancestor, right: null }); node = nextNode; return true; } } return false; } }); // Calculating the right bounds for each selectors won't save much if (!mayMatch) { return false; } if (!map) { return mayMatch; } for (let i = 0; i < this.groups.length; i++) { const group = this.groups[i]; if (!group.dynamic) { continue; } const bound = bounds[i]; let node = bound.left; do { if (group.mayMatch(node)) { group.trackChanges(node, map); } } while (node !== bound.right && (node = node.parent)); } return mayMatch; } } export var Selector; (function (Selector) { // Non-spec. Selector sequences are grouped by ancestor then by child combinators for easier backtracking. class ChildGroup extends SelectorBase { constructor(selectors) { super(); this.selectors = selectors; this.dynamic = selectors.some((sel) => sel.dynamic); } getMatchingNode(node, strict) { const funcName = strict ? 'match' : 'mayMatch'; return this.selectors.every((sel, i) => (node = i === 0 ? node : node.parent) && sel[funcName](node)) ? node : null; } match(node) { return this.getMatchingNode(node, true) != null; } mayMatch(node) { return this.getMatchingNode(node, false) != null; } trackChanges(node, map) { this.selectors.forEach((sel, i) => { if (i === 0) { node && sel.trackChanges(node, map); } else { node = node.parent; if (node && sel.mayMatch(node)) { sel.trackChanges(node, map); } } }); } } Selector.ChildGroup = ChildGroup; class SiblingGroup extends SelectorBase { constructor(selectors) { super(); this.selectors = selectors; this.dynamic = selectors.some((sel) => sel.dynamic); } match(node) { return this.selectors.every((sel, i) => { if (i === 0) { return node && sel.match(node); } if (sel.combinator === Combinator.adjacent) { node = getNodePreviousDirectSibling(node); return node && sel.match(node); } // Sibling combinator let isMatching = false; eachNodePreviousGeneralSibling(node, (sibling) => { isMatching = sel.match(sibling); return !isMatching; }); return isMatching; }); } mayMatch(node) { return this.selectors.every((sel, i) => { if (i === 0) { return node && sel.mayMatch(node); } if (sel.combinator === Combinator.adjacent) { node = getNodePreviousDirectSibling(node); return node && sel.mayMatch(node); } // Sibling combinator let isMatching = false; eachNodePreviousGeneralSibling(node, (sibling) => { isMatching = sel.mayMatch(sibling); return !isMatching; }); return isMatching; }); } trackChanges(node, map) { this.selectors.forEach((sel, i) => { if (i === 0) { if (node) { sel.trackChanges(node, map); } } else { if (sel.combinator === Combinator.adjacent) { node = getNodePreviousDirectSibling(node); if (node && sel.mayMatch(node)) { sel.trackChanges(node, map); } } else { // Sibling combinator let matchingSibling; eachNodePreviousGeneralSibling(node, (sibling) => { const isMatching = sel.mayMatch(sibling); if (isMatching) { matchingSibling = sibling; } return !isMatching; }); if (matchingSibling) { sel.trackChanges(matchingSibling, map); } } } }); } } Selector.SiblingGroup = SiblingGroup; })(Selector || (Selector = {})); export class RuleSet { constructor(selectors, declarations) { this.selectors = selectors; this.declarations = declarations; this.selectors.forEach((sel) => (sel.ruleset = this)); } toString() { let desc = `${this.selectors.join(', ')} {${this.declarations.map((d, i) => `${i === 0 ? ' ' : ''}${d.property}: ${d.value}`).join('; ')} }`; if (this.mediaQueryString) { desc = `@media ${this.mediaQueryString} { ${desc} }`; } return desc; } lookupSort(sorter) { this.selectors.forEach((sel) => sel.lookupSort(sorter)); } } export function fromAstNode(astRule) { const declarations = astRule.declarations.filter(isDeclaration).map(createDeclaration); const selectors = astRule.selectors.map(createSelector); return new RuleSet(selectors, declarations); } function createDeclaration(decl) { return { property: isCssVariable(decl.property) ? decl.property : decl.property.toLowerCase(), value: decl.value }; } function createSimpleSelectorFromAst(ast) { if (ast.type === 'attribute') { if (ast.name === 'class') { return new ClassSelector(ast.value); } if (ast.name === 'id') { return new IdSelector(ast.value); } return new AttributeSelector(ast.name, ast.action, ast.value, !!ast.ignoreCase); } if (ast.type === 'tag') { return new TypeSelector(ast.name.replace('-', '').toLowerCase()); } if (ast.type === 'pseudo') { if (ast.name === 'is') { return new IsFunctionalPseudoClassSelector(ast.name, ast.data); } if (ast.name === 'where') { return new WhereFunctionalPseudoClassSelector(ast.name, ast.data); } if (ast.name === 'not') { return new NotFunctionalPseudoClassSelector(ast.name, ast.data); } return new PseudoClassSelector(ast.name); } if (ast.type === 'universal') { return new UniversalSelector(); } return new InvalidSelector(new Error(ast.type)); } function createSimpleSelectorSequenceFromAst(asts) { if (asts.length === 0) { return new InvalidSelector(new Error('Empty simple selector sequence.')); } if (asts.length === 1) { return createSimpleSelectorFromAst(asts[0]); } const sequenceSelectors = []; for (const ast of asts) { const selector = createSimpleSelectorFromAst(ast); if (selector instanceof InvalidSelector) { return selector; } sequenceSelectors.push(selector); } return new SimpleSelectorSequence(sequenceSelectors); } function createSelectorFromAst(asts) { let result; if (asts.length === 0) { return new InvalidSelector(new Error('Empty selector.')); } if (asts.length === 1) { return createSimpleSelectorFromAst(asts[0]); } const simpleSelectorSequences = []; let sequenceAsts = []; let combinatorCount = 0; for (const ast of asts) { const combinator = Combinator[ast.type]; // Combinator means the end of a sequence if (combinator != null) { const selector = createSimpleSelectorSequenceFromAst(sequenceAsts); if (selector instanceof InvalidSelector) { return selector; } selector.combinator = combinator; simpleSelectorSequences.push(selector); combinatorCount++; // Cleanup stored selectors for the new sequence to take place sequenceAsts = []; } else { sequenceAsts.push(ast); } } if (combinatorCount > 0) { // Create a sequence using the remaining selectors after the last combinator if (sequenceAsts.length) { const selector = createSimpleSelectorSequenceFromAst(sequenceAsts); if (selector instanceof InvalidSelector) { return selector; } simpleSelectorSequences.push(selector); } return new ComplexSelector(simpleSelectorSequences); } return createSimpleSelectorSequenceFromAst(sequenceAsts); } export function createSelector(sel) { try { const result = convertToCSSWhatSelector(sel); if (!result?.length) { return new InvalidSelector(new Error('Empty selector')); } return createSelectorFromAst(result[0]); } catch (e) { return new InvalidSelector(e); } } function isDeclaration(node) { return node.type === 'declaration'; } export function matchMediaQueryString(mediaQueryString, cachedQueries) { // It can be a single or multiple queries in case of nested media queries const mediaQueryStrings = mediaQueryString.split(MEDIA_QUERY_SEPARATOR); return mediaQueryStrings.every((mq) => { let isMatching; // Query has already been validated if (cachedQueries.includes(mq)) { isMatching = true; } else { isMatching = checkIfMediaQueryMatches(mq); if (isMatching) { cachedQueries.push(mq); } } return isMatching; }); } export class SelectorScope { constructor() { this.id = {}; this.class = {}; this.type = {}; this.universal = []; this.position = 0; } getSelectorCandidates(node) { const { cssClasses, id, cssType } = node; const selectorClasses = [this.universal, this.id[id], this.type[cssType]]; if (cssClasses && cssClasses.size) { cssClasses.forEach((c) => selectorClasses.push(this.class[c])); } return selectorClasses.reduce((cur, next) => cur.concat(next || []), []); } sortById(id, sel) { this.addToMap(this.id, id, sel); } sortByClass(cssClass, sel) { this.addToMap(this.class, cssClass, sel); } sortByType(cssType, sel) { this.addToMap(this.type, cssType, sel); } sortAsUniversal(sel) { this.universal.push(this.makeDocSelector(sel)); } addToMap(map, head, sel) { if (!map[head]) { map[head] = []; } map[head].push(this.makeDocSelector(sel)); } makeDocSelector(sel) { sel.pos = this.position++; return sel; } } export class MediaQuerySelectorScope extends SelectorScope { constructor(mediaQueryString) { super(); this._mediaQueryString = mediaQueryString; } get mediaQueryString() { return this._mediaQueryString; } } export class StyleSheetSelectorScope extends SelectorScope { constructor(rulesets) { super(); this.lookupRulesets(rulesets); } createMediaQuerySelectorScope(mediaQueryString) { const selectorScope = new MediaQuerySelectorScope(mediaQueryString); selectorScope.position = this.position; if (this.mediaQuerySelectorScopes) { this.mediaQuerySelectorScopes.push(selectorScope); } else { this.mediaQuerySelectorScopes = [selectorScope]; } return selectorScope; } lookupRulesets(rulesets) { let lastMediaSelectorScope; for (let i = 0, length = rulesets.length; i < length; i++) { const ruleset = rulesets[i]; if (lastMediaSelectorScope && lastMediaSelectorScope.mediaQueryString !== ruleset.mediaQueryString) { // Once done with current media query scope, update stylesheet scope position this.position = lastMediaSelectorScope.position; lastMediaSelectorScope = null; } if (ruleset.mediaQueryString) { // Create media query selector scope and register selector lookups there if (!lastMediaSelectorScope) { lastMediaSelectorScope = this.createMediaQuerySelectorScope(ruleset.mediaQueryString); } ruleset.lookupSort(lastMediaSelectorScope); } else { ruleset.lookupSort(this); } } // If reference of last media selector scope is still kept, update stylesheet scope position if (lastMediaSelectorScope) { this.position = lastMediaSelectorScope.position; lastMediaSelectorScope = null; } } query(node) { const selectorsMatch = new SelectorsMatch(); const selectors = this.getSelectorCandidates(node); // Validate media queries and include their selectors if needed if (this.mediaQuerySelectorScopes) { // Cache media query results to avoid validations of other identical queries const validatedMediaQueries = []; for (let i = 0, length = this.mediaQuerySelectorScopes.length; i < length; i++) { const selectorScope = this.mediaQuerySelectorScopes[i]; const isMatchingAllQueries = matchMediaQueryString(selectorScope.mediaQueryString, validatedMediaQueries); if (isMatchingAllQueries) { const mediaQuerySelectors = selectorScope.getSelectorCandidates(node); selectors.push(...mediaQuerySelectors); } } } selectorsMatch.selectors = selectors.filter((sel) => sel.accumulateChanges(node, selectorsMatch)).sort((a, b) => a.specificity - b.specificity || a.pos - b.pos); return selectorsMatch; } } export class SelectorsMatch { constructor() { this.changeMap = new Map(); } addAttribute(node, attribute) { const deps = this.properties(node); if (!deps.attributes) { deps.attributes = new Set(); } deps.attributes.add(attribute); } addPseudoClass(node, pseudoClass) { const deps = this.properties(node); if (!deps.pseudoClasses) { deps.pseudoClasses = new Set(); } deps.pseudoClasses.add(pseudoClass); } properties(node) { let set = this.changeMap.get(node); if (!set) { this.changeMap.set(node, (set = {})); } return set; } } export const CSSHelper = { createSelector, SelectorCore, SimpleSelector, InvalidSelector, UniversalSelector, TypeSelector, ClassSelector, AttributeSelector, PseudoClassSelector, SimpleSelectorSequence, Selector, RuleSet, SelectorScope, MediaQuerySelectorScope, StyleSheetSelectorScope, fromAstNode, SelectorsMatch, }; //# sourceMappingURL=css-selector.js.map