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