({
selector,
scopeSelector,
hostSelector,
isParentSelector,
}: {
selector: string;
scopeSelector: string;
hostSelector: string;
isParentSelector?: boolean;
})
| 730 | // return a selector with [name] suffix on each simple selector |
| 731 | // e.g. .foo.bar > .zot becomes .foo[name].bar[name] > .zot[name] /** @internal */ |
| 732 | private _applySelectorScope({ |
| 733 | selector, |
| 734 | scopeSelector, |
| 735 | hostSelector, |
| 736 | isParentSelector, |
| 737 | }: { |
| 738 | selector: string; |
| 739 | scopeSelector: string; |
| 740 | hostSelector: string; |
| 741 | isParentSelector?: boolean; |
| 742 | }): string { |
| 743 | const isRe = /\[is=([^\]]*)\]/g; |
| 744 | scopeSelector = scopeSelector.replace(isRe, (_: string, ...parts: string[]) => parts[0]); |
| 745 | |
| 746 | const attrName = `[${scopeSelector}]`; |
| 747 | |
| 748 | const _scopeSelectorPart = (p: string) => { |
| 749 | let scopedP = p.trim(); |
| 750 | |
| 751 | if (!scopedP) { |
| 752 | return p; |
| 753 | } |
| 754 | |
| 755 | if (p.includes(_polyfillHostNoCombinator)) { |
| 756 | scopedP = this._applySimpleSelectorScope(p, scopeSelector, hostSelector); |
| 757 | if (!p.match(_polyfillHostNoCombinatorOutsidePseudoFunction)) { |
| 758 | const [_, before, colon, after] = scopedP.match(/([^:]*)(:*)([\s\S]*)/)!; |
| 759 | scopedP = before + attrName + colon + after; |
| 760 | } |
| 761 | } else { |
| 762 | // remove :host since it should be unnecessary |
| 763 | const t = p.replace(_polyfillHostRe, ''); |
| 764 | if (t.length > 0) { |
| 765 | const matches = t.match(/([^:]*)(:*)([\s\S]*)/); |
| 766 | if (matches) { |
| 767 | scopedP = matches[1] + attrName + matches[2] + matches[3]; |
| 768 | } |
| 769 | } |
| 770 | } |
| 771 | |
| 772 | return scopedP; |
| 773 | }; |
| 774 | |
| 775 | // Wraps `_scopeSelectorPart()` to not use it directly on selectors with |
| 776 | // pseudo selector functions like `:where()`. Selectors within pseudo selector |
| 777 | // functions are recursively sent to `_scopeSelector()`. |
| 778 | const _pseudoFunctionAwareScopeSelectorPart = (selectorPart: string) => { |
| 779 | let scopedPart = ''; |
| 780 | |
| 781 | // Collect all outer `:where()` and `:is()` selectors, |
| 782 | // counting parenthesis to keep nested selectors intact. |
| 783 | const pseudoSelectorParts = []; |
| 784 | let pseudoSelectorMatch: RegExpExecArray | null; |
| 785 | while ( |
| 786 | (pseudoSelectorMatch = _cssPrefixWithPseudoSelectorFunction.exec(selectorPart)) !== null |
| 787 | ) { |
| 788 | let openedBrackets = 1; |
| 789 | let index = _cssPrefixWithPseudoSelectorFunction.lastIndex; |
no test coverage detected