@edynamix/mf-isolation 0.0.28 → 0.0.30

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -37,7 +37,7 @@ export default {
37
37
  };
38
38
  ```
39
39
 
40
- The host and remote must use the same `scopeId`. Both PostCSS plugins keep ordinary global and vendor selectors under the zero-specificity `:where([data-edyn-mf="<scope-id>"])` boundary. Document-root descendants such as `html body#app button` instead use `[data-edyn-mf="<scope-id>"]` so module overrides retain sufficient cascade strength.
40
+ The host and remote must use the same `scopeId`. Both PostCSS plugins keep ordinary global and vendor selectors under the zero-specificity `:where([data-edyn-mf="<scope-id>"])` boundary. Document-root descendants such as `html body#app button` or `html body button` keep the weight of the root they start from: it becomes `:where([data-edyn-mf="<scope-id>"]):not(<carrier>)`, where `:where()` weighs nothing and the carrier (for example `edyn-mf-root edyn-mf-root#edyn-mf-root` for `html body#app`) has the same id, class and type counts as the replaced root and never matches the scope element. Module overrides therefore win or lose against Angular Material exactly as on the standalone page.
41
41
 
42
42
  ### Angular with Vite
43
43
 
@@ -1 +1 @@
1
- {"version":3,"file":"postcss.d.ts","sourceRoot":"","sources":["../src/postcss.ts"],"names":[],"mappings":"AACA,OAAO,EAAQ,KAAK,MAAM,EAAwB,MAAM,SAAS,CAAC;AAKlE,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,MAAM,CAAC;CACjB;AA8KD,eAAO,MAAM,gCAAgC,GAAI,WAAW,MAAM,GAAG,SAAS,KAAG,OAEhF,CAAC;AA0NF,eAAO,MAAM,cAAc,GAAI,aAAa,sBAAsB,KAAG,MAWpE,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAAI,aAAa,sBAAsB,KAAG,MAiB3E,CAAC","sourcesContent":["import { existsSync, readFileSync } from 'node:fs';\nimport { list, type Plugin, type Root, type Rule } from 'postcss';\nimport selectorParser from 'postcss-selector-parser';\nimport valueParser from 'postcss-value-parser';\nimport { getMfScopeSelector, MF_ROOT_SELECTOR, MF_SCOPE_ATTRIBUTE, validateMfScopeId } from './index.js';\n\nexport interface IScopeRemoteCssOptions {\n scopeId: string;\n}\n\nconst ANGULAR_COMPONENT_STYLE_PATTERN = /\\.component\\.(?:css|less|sass|scss)$/i;\nconst VIEW_ENCAPSULATION_NONE_PATTERN = /(?:^|[,{])\\s*encapsulation\\s*:\\s*(?:[A-Za-z_$][\\w$]*\\s*\\.\\s*)+None\\b/m;\nconst MF_OVERLAY_ATTRIBUTE = 'data-edyn-mf-overlay';\n\ntype TTypeScriptMaskState = 'block-comment' | 'code' | 'double-quote' | 'line-comment' | 'single-quote' | 'template';\n\nconst maskTypeScriptCommentsAndStrings = (source: string): string => {\n let maskedSource = '';\n let state: TTypeScriptMaskState = 'code';\n let escaped = false;\n\n const maskCharacter = (character: string): string => {\n return character === '\\n' || character === '\\r' ? character : ' ';\n };\n\n for (let index = 0; index < source.length; index += 1) {\n const character = source[index] ?? '';\n const nextCharacter = source[index + 1];\n\n if (state === 'code') {\n if (character === '/' && nextCharacter === '/') {\n maskedSource += ' ';\n index += 1;\n state = 'line-comment';\n } else if (character === '/' && nextCharacter === '*') {\n maskedSource += ' ';\n index += 1;\n state = 'block-comment';\n } else if (character === \"'\") {\n maskedSource += ' ';\n state = 'single-quote';\n } else if (character === '\"') {\n maskedSource += ' ';\n state = 'double-quote';\n } else if (character === '`') {\n maskedSource += ' ';\n state = 'template';\n } else {\n maskedSource += character;\n }\n continue;\n }\n\n if (state === 'line-comment') {\n maskedSource += maskCharacter(character);\n if (character === '\\n' || character === '\\r') {\n state = 'code';\n }\n continue;\n }\n\n if (state === 'block-comment') {\n if (character === '*' && nextCharacter === '/') {\n maskedSource += ' ';\n index += 1;\n state = 'code';\n } else {\n maskedSource += maskCharacter(character);\n }\n continue;\n }\n\n maskedSource += maskCharacter(character);\n if (escaped) {\n escaped = false;\n } else if (character === '\\\\') {\n escaped = true;\n } else if (\n (state === 'single-quote' && character === \"'\") ||\n (state === 'double-quote' && character === '\"') ||\n (state === 'template' && character === '`')\n ) {\n state = 'code';\n }\n }\n\n return maskedSource;\n};\n\nconst isKeyframesRule = (rule: Rule): boolean => {\n const parent = rule.parent;\n return parent?.type === 'atrule' && /keyframes$/i.test(parent.name);\n};\n\nconst isRootNode = (node: selectorParser.Node): boolean => {\n return (\n (node.type === 'tag' && (node.value.toLowerCase() === 'html' || node.value.toLowerCase() === 'body')) ||\n (node.type === 'pseudo' && (node.value === ':root' || node.value === MF_ROOT_SELECTOR))\n );\n};\n\nconst isScopeNode = (node: selectorParser.Node | undefined, scopeId: string): boolean => {\n if (node?.type === 'attribute' && node.attribute === MF_SCOPE_ATTRIBUTE && node.operator === '=' && node.value === scopeId) {\n return true;\n }\n\n const normalized = node?.toString().replaceAll('\"', '').replaceAll(\"'\", '');\n return (\n node?.type === 'pseudo' &&\n (normalized === `:where([${MF_SCOPE_ATTRIBUTE}=${scopeId}])` ||\n normalized === `:where([${MF_SCOPE_ATTRIBUTE}=${scopeId}]:not([${MF_OVERLAY_ATTRIBUTE}]))`)\n );\n};\n\nconst startsWithHostPseudo = (selector: selectorParser.Selector): boolean => {\n return selector.first?.type === 'pseudo' && selector.first.value === ':host';\n};\n\nconst removeRootIdentityIds = (selector: selectorParser.Selector): void => {\n let compound: selectorParser.Node[] = [];\n const removeIdsFromRootCompound = (): void => {\n if (compound.some(isRootNode)) {\n for (const node of compound) {\n if (node.type === 'id') {\n node.remove();\n }\n }\n }\n };\n\n for (const node of [...selector.nodes]) {\n if (node.type === 'combinator') {\n removeIdsFromRootCompound();\n compound = [];\n } else {\n compound.push(node);\n }\n }\n removeIdsFromRootCompound();\n};\n\nconst isRootOnlySelector = (selector: selectorParser.Selector): boolean => {\n const compounds: selectorParser.Node[][] = [[]];\n\n for (const node of selector.nodes) {\n if (node.type === 'combinator') {\n compounds.push([]);\n } else {\n compounds.at(-1)?.push(node);\n }\n }\n\n return compounds.every((compound) => compound.some(isRootNode));\n};\n\nconst hasRootOnlySelector = (selectorList: string): boolean => {\n let result = false;\n selectorParser((root) => {\n result = root.nodes.some(isRootOnlySelector);\n }).processSync(selectorList);\n return result;\n};\n\nconst getAngularComponentSourcePath = (stylePath: string): string | undefined => {\n const cleanStylePath = stylePath.replace(/[?#].*$/, '');\n if (!ANGULAR_COMPONENT_STYLE_PATTERN.test(cleanStylePath)) {\n return undefined;\n }\n\n return cleanStylePath.replace(/\\.(?:css|less|sass|scss)$/i, '.ts');\n};\n\nconst usesViewEncapsulationNone = (stylePath: string): boolean => {\n const componentSourcePath = getAngularComponentSourcePath(stylePath);\n if (!componentSourcePath || !existsSync(componentSourcePath)) {\n return false;\n }\n\n const componentSource = readFileSync(componentSourcePath, 'utf8');\n return VIEW_ENCAPSULATION_NONE_PATTERN.test(maskTypeScriptCommentsAndStrings(componentSource));\n};\n\nexport const shouldUseAngularComponentScoping = (stylePath: string | undefined): boolean => {\n return !!stylePath && !!getAngularComponentSourcePath(stylePath) && !usesViewEncapsulationNone(stylePath);\n};\n\nconst scopeSelectorList = (selectorList: string, scopeId: string, scopeSelector: string, rootScopeSelectors: string[]): string => {\n return selectorParser((root) => {\n const sourceSelectors = [...root.nodes];\n\n for (const selector of sourceSelectors) {\n const rootNodes = selector.nodes.filter(isRootNode);\n\n if (rootNodes.length > 0) {\n const replacementSelectors = isRootOnlySelector(selector) ? rootScopeSelectors : [`[${MF_SCOPE_ATTRIBUTE}=\"${scopeId}\"]`];\n\n for (const replacementSelector of replacementSelectors) {\n const variant = selector.clone();\n removeRootIdentityIds(variant);\n const [firstRoot, ...duplicateRoots] = variant.nodes.filter(isRootNode);\n const scopeNode = selectorParser().astSync(replacementSelector).first.first.clone();\n firstRoot?.replaceWith(scopeNode);\n\n for (const duplicateRoot of duplicateRoots) {\n const previous = duplicateRoot.prev();\n if (previous?.type === 'combinator') {\n previous.remove();\n }\n duplicateRoot.remove();\n }\n\n root.insertBefore(selector, variant);\n }\n selector.remove();\n continue;\n }\n\n if (startsWithHostPseudo(selector) || isScopeNode(selector.first, scopeId)) {\n continue;\n }\n\n const first = selector.first;\n const needsBoundaryVariant = first?.type === 'universal' || (first?.type === 'pseudo' && first.value.startsWith('::'));\n\n if (needsBoundaryVariant) {\n const hasSiblingCombinator = selector.nodes.some((node) => node.type === 'combinator' && (node.value === '+' || node.value === '~'));\n\n if (!hasSiblingCombinator) {\n const boundaryVariant = selector.clone();\n const boundaryScope = selectorParser().astSync(scopeSelector).first.first.clone();\n boundaryVariant.first.rawSpaceBefore = '';\n if (boundaryVariant.first.type === 'universal') {\n boundaryVariant.first.replaceWith(boundaryScope);\n } else {\n boundaryVariant.prepend(boundaryScope);\n }\n root.insertBefore(selector, boundaryVariant);\n }\n }\n\n const descendantScope = selectorParser().astSync(`${scopeSelector} *`).first;\n const prefixNodes = descendantScope.nodes.slice(0, -1).map((node) => node.clone());\n selector.first.rawSpaceBefore = '';\n for (const prefixNode of prefixNodes.reverse()) {\n selector.prepend(prefixNode);\n }\n }\n\n const seenSelectors = new Set<string>();\n for (const selector of [...root.nodes]) {\n const normalizedSelector = selector.toString().trim();\n if (seenSelectors.has(normalizedSelector)) {\n selector.remove();\n } else {\n seenSelectors.add(normalizedSelector);\n }\n }\n }).processSync(selectorList);\n};\n\nconst findFunctionalPseudoEnd = (selector: string, openParenthesisIndex: number): number => {\n let depth = 0;\n let quote: '\"' | \"'\" | undefined;\n\n for (let index = openParenthesisIndex; index < selector.length; index += 1) {\n const character = selector[index];\n const previousCharacter = selector[index - 1];\n\n if (quote) {\n if (character === quote && previousCharacter !== '\\\\') {\n quote = undefined;\n }\n continue;\n }\n\n if (character === '\"' || character === \"'\") {\n quote = character;\n continue;\n }\n\n if (character === '(') {\n depth += 1;\n } else if (character === ')') {\n depth -= 1;\n if (depth === 0) {\n return index;\n }\n }\n }\n\n return -1;\n};\n\nconst scopeAngularSelector = (selector: string, boundarySelector: string): string => {\n const normalizedSelector = selector.trim();\n const angularBoundary = `:host-context(${boundarySelector})`;\n const normalizedBoundary = normalizedSelector.slice(0, angularBoundary.length).replaceAll(\"'\", '\"');\n\n if (normalizedBoundary === angularBoundary) {\n return normalizedSelector;\n }\n\n if (/^:host-context\\(/i.test(normalizedSelector)) {\n return `${angularBoundary}${normalizedSelector}`;\n }\n\n if (/^:host\\(/i.test(normalizedSelector)) {\n const openParenthesisIndex = normalizedSelector.indexOf('(');\n const closeParenthesisIndex = findFunctionalPseudoEnd(normalizedSelector, openParenthesisIndex);\n if (closeParenthesisIndex !== -1) {\n const hostSelector = normalizedSelector.slice(openParenthesisIndex + 1, closeParenthesisIndex);\n const remainder = normalizedSelector.slice(closeParenthesisIndex + 1);\n return list\n .comma(hostSelector)\n .map((hostSelectorVariant) => `${angularBoundary}${hostSelectorVariant}${remainder}`)\n .join(', ');\n }\n }\n\n if (/^:host\\b/i.test(normalizedSelector)) {\n return normalizedSelector.replace(/^:host\\b/i, angularBoundary);\n }\n\n return `${angularBoundary} ${normalizedSelector}`;\n};\n\nconst scopeAngularSelectorList = (selectorList: string, boundarySelector: string): string => {\n return list\n .comma(selectorList)\n .map((selector) => scopeAngularSelector(selector, boundarySelector))\n .join(', ');\n};\n\nconst namespaceKeyframes = (root: Root, keyframePrefix: string): void => {\n const keyframes = new Map<string, string>();\n\n root.walkAtRules((atRule) => {\n if (!/keyframes$/i.test(atRule.name) || atRule.params.startsWith(keyframePrefix)) {\n return;\n }\n\n const originalName = atRule.params.trim();\n const scopedName = `${keyframePrefix}${originalName}`;\n keyframes.set(originalName, scopedName);\n atRule.params = scopedName;\n });\n\n root.walkDecls((declaration) => {\n if (!/^(?:-webkit-)?animation(?:-name)?$/i.test(declaration.prop) && !declaration.prop.startsWith('--animate-')) {\n return;\n }\n\n const parsed = valueParser(declaration.value);\n parsed.walk((node) => {\n if (node.type === 'word') {\n node.value = keyframes.get(node.value) ?? node.value;\n }\n });\n declaration.value = parsed.toString();\n });\n};\n\nconst scopeGlobalRoot = (root: Root, scopeId: string, scopeSelector: string, keyframePrefix: string): void => {\n namespaceKeyframes(root, keyframePrefix);\n const contentRootSelector = `:where([${MF_SCOPE_ATTRIBUTE}=\"${scopeId}\"]:not([${MF_OVERLAY_ATTRIBUTE}]))`;\n root.walkRules((rule) => {\n if (!isKeyframesRule(rule)) {\n const declarations = rule.nodes.filter((node) => node.type === 'decl');\n const customProperties = declarations.filter((declaration) => declaration.prop.startsWith('--'));\n const standardDeclarations = declarations.filter((declaration) => !declaration.prop.startsWith('--'));\n\n if (customProperties.length > 0 && standardDeclarations.length > 0 && hasRootOnlySelector(rule.selector)) {\n const customPropertyRule = rule.cloneBefore();\n customPropertyRule.walkDecls((declaration) => {\n if (!declaration.prop.startsWith('--')) {\n declaration.remove();\n }\n });\n customPropertyRule.selector = scopeSelectorList(customPropertyRule.selector, scopeId, scopeSelector, [':host', scopeSelector]);\n rule.walkDecls((declaration) => {\n if (declaration.prop.startsWith('--')) {\n declaration.remove();\n }\n });\n }\n\n const containsOnlyCustomProperties = declarations.length > 0 && declarations.every((declaration) => declaration.prop.startsWith('--'));\n const rootScopeSelectors = containsOnlyCustomProperties ? [':host', scopeSelector] : [':host', contentRootSelector];\n rule.selector = scopeSelectorList(rule.selector, scopeId, scopeSelector, rootScopeSelectors);\n }\n });\n};\n\nconst scopeAngularComponentRoot = (root: Root, boundarySelector: string, keyframePrefix: string): void => {\n namespaceKeyframes(root, keyframePrefix);\n root.walkRules((rule) => {\n if (!isKeyframesRule(rule)) {\n rule.selector = scopeAngularSelectorList(rule.selector, boundarySelector);\n }\n });\n};\n\nexport const scopeRemoteCss = ({ scopeId }: IScopeRemoteCssOptions): Plugin => {\n const validScopeId = validateMfScopeId(scopeId);\n const scopeSelector = getMfScopeSelector(validScopeId);\n const keyframePrefix = `edyn-mf-${validScopeId}--`;\n\n return {\n postcssPlugin: `edyn-mf-isolation-${validScopeId}`,\n Once(root) {\n scopeGlobalRoot(root, validScopeId, scopeSelector, keyframePrefix);\n },\n };\n};\n\nexport const scopeAngularRemoteCss = ({ scopeId }: IScopeRemoteCssOptions): Plugin => {\n const validScopeId = validateMfScopeId(scopeId);\n const scopeSelector = getMfScopeSelector(validScopeId);\n const boundarySelector = `[${MF_SCOPE_ATTRIBUTE}=\"${validScopeId}\"]`;\n const keyframePrefix = `edyn-mf-${validScopeId}--`;\n\n return {\n postcssPlugin: `edyn-mf-angular-isolation-${validScopeId}`,\n Once(root) {\n if (shouldUseAngularComponentScoping(root.source?.input.file)) {\n scopeAngularComponentRoot(root, boundarySelector, keyframePrefix);\n return;\n }\n\n scopeGlobalRoot(root, validScopeId, scopeSelector, keyframePrefix);\n },\n };\n};\n"]}
1
+ {"version":3,"file":"postcss.d.ts","sourceRoot":"","sources":["../src/postcss.ts"],"names":[],"mappings":"AACA,OAAO,EAAQ,KAAK,MAAM,EAAwB,MAAM,SAAS,CAAC;AAKlE,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,MAAM,CAAC;CACjB;AAqND,eAAO,MAAM,gCAAgC,GAAI,WAAW,MAAM,GAAG,SAAS,KAAG,OAEhF,CAAC;AAqOF,eAAO,MAAM,cAAc,GAAI,aAAa,sBAAsB,KAAG,MAWpE,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAAI,aAAa,sBAAsB,KAAG,MAiB3E,CAAC","sourcesContent":["import { existsSync, readFileSync } from 'node:fs';\nimport { list, type Plugin, type Root, type Rule } from 'postcss';\nimport selectorParser from 'postcss-selector-parser';\nimport valueParser from 'postcss-value-parser';\nimport { getMfScopeSelector, MF_ROOT_SELECTOR, MF_SCOPE_ATTRIBUTE, validateMfScopeId } from './index.js';\n\nexport interface IScopeRemoteCssOptions {\n scopeId: string;\n}\n\nconst ANGULAR_COMPONENT_STYLE_PATTERN = /\\.component\\.(?:css|less|sass|scss)$/i;\nconst VIEW_ENCAPSULATION_NONE_PATTERN = /(?:^|[,{])\\s*encapsulation\\s*:\\s*(?:[A-Za-z_$][\\w$]*\\s*\\.\\s*)+None\\b/m;\nconst MF_OVERLAY_ATTRIBUTE = 'data-edyn-mf-overlay';\n\ntype TTypeScriptMaskState = 'block-comment' | 'code' | 'double-quote' | 'line-comment' | 'single-quote' | 'template';\n\nconst maskTypeScriptCommentsAndStrings = (source: string): string => {\n let maskedSource = '';\n let state: TTypeScriptMaskState = 'code';\n let escaped = false;\n\n const maskCharacter = (character: string): string => {\n return character === '\\n' || character === '\\r' ? character : ' ';\n };\n\n for (let index = 0; index < source.length; index += 1) {\n const character = source[index] ?? '';\n const nextCharacter = source[index + 1];\n\n if (state === 'code') {\n if (character === '/' && nextCharacter === '/') {\n maskedSource += ' ';\n index += 1;\n state = 'line-comment';\n } else if (character === '/' && nextCharacter === '*') {\n maskedSource += ' ';\n index += 1;\n state = 'block-comment';\n } else if (character === \"'\") {\n maskedSource += ' ';\n state = 'single-quote';\n } else if (character === '\"') {\n maskedSource += ' ';\n state = 'double-quote';\n } else if (character === '`') {\n maskedSource += ' ';\n state = 'template';\n } else {\n maskedSource += character;\n }\n continue;\n }\n\n if (state === 'line-comment') {\n maskedSource += maskCharacter(character);\n if (character === '\\n' || character === '\\r') {\n state = 'code';\n }\n continue;\n }\n\n if (state === 'block-comment') {\n if (character === '*' && nextCharacter === '/') {\n maskedSource += ' ';\n index += 1;\n state = 'code';\n } else {\n maskedSource += maskCharacter(character);\n }\n continue;\n }\n\n maskedSource += maskCharacter(character);\n if (escaped) {\n escaped = false;\n } else if (character === '\\\\') {\n escaped = true;\n } else if (\n (state === 'single-quote' && character === \"'\") ||\n (state === 'double-quote' && character === '\"') ||\n (state === 'template' && character === '`')\n ) {\n state = 'code';\n }\n }\n\n return maskedSource;\n};\n\nconst isKeyframesRule = (rule: Rule): boolean => {\n const parent = rule.parent;\n return parent?.type === 'atrule' && /keyframes$/i.test(parent.name);\n};\n\nconst isRootNode = (node: selectorParser.Node): boolean => {\n return (\n (node.type === 'tag' && (node.value.toLowerCase() === 'html' || node.value.toLowerCase() === 'body')) ||\n (node.type === 'pseudo' && (node.value === ':root' || node.value === MF_ROOT_SELECTOR))\n );\n};\n\nconst isScopeNode = (node: selectorParser.Node | undefined, scopeId: string): boolean => {\n if (node?.type === 'attribute' && node.attribute === MF_SCOPE_ATTRIBUTE && node.operator === '=' && node.value === scopeId) {\n return true;\n }\n\n const normalized = node?.toString().replaceAll('\"', '').replaceAll(\"'\", '');\n return (\n node?.type === 'pseudo' &&\n (normalized === `:where([${MF_SCOPE_ATTRIBUTE}=${scopeId}])` ||\n normalized === `:where([${MF_SCOPE_ATTRIBUTE}=${scopeId}]:not([${MF_OVERLAY_ATTRIBUTE}]))`)\n );\n};\n\nconst startsWithHostPseudo = (selector: selectorParser.Selector): boolean => {\n return selector.first?.type === 'pseudo' && selector.first.value === ':host';\n};\n\nconst removeRootIdentityIds = (selector: selectorParser.Selector): void => {\n let compound: selectorParser.Node[] = [];\n const removeIdsFromRootCompound = (): void => {\n if (compound.some(isRootNode)) {\n for (const node of compound) {\n if (node.type === 'id') {\n node.remove();\n }\n }\n }\n };\n\n for (const node of [...selector.nodes]) {\n if (node.type === 'combinator') {\n removeIdsFromRootCompound();\n compound = [];\n } else {\n compound.push(node);\n }\n }\n removeIdsFromRootCompound();\n};\n\nconst SPECIFICITY_CARRIER = 'edyn-mf-root';\n\n// Legacy rules such as `html body button` or `html body#app .mdc-checkbox__background` are weighed against Angular\n// Material's own rules by the html, body and #app they start from, so the scope that replaces that root must weigh\n// exactly the same. A plain scope attribute (0,1,0) drops the id of `body#app`, letting Material's checked colour win,\n// and outweighs the two types of `html body`, letting an override that lost to `.mat-mdc-button` on the old site win\n// hosted. The root becomes :where(<scope>):not(<carrier>): :where() weighs nothing, and the carrier has the same id,\n// class and type counts as the root part it replaces and never matches the scope element, so :not() always matches and\n// weighs exactly that. Neutral names keep `html`, `body` and `#app` out of the emitted CSS.\nconst rootSpecificityCarrier = (selector: selectorParser.Selector): string => {\n const compounds: selectorParser.Node[][] = [[]];\n for (const node of selector.nodes) {\n if (node.type === 'combinator') {\n compounds.push([]);\n } else {\n compounds.at(-1)?.push(node);\n }\n }\n\n const carrier: string[] = [];\n for (const compound of compounds) {\n if (!compound.some(isRootNode)) {\n continue;\n }\n const types = compound.filter((node) => node.type === 'tag' && isRootNode(node)).length;\n const pseudoRoots = compound.filter((node) => node.type === 'pseudo' && isRootNode(node)).length;\n const ids = compound.filter((node) => node.type === 'id').length;\n carrier.push(\n `${SPECIFICITY_CARRIER.repeat(Math.min(types, 1))}${`.${SPECIFICITY_CARRIER}`.repeat(pseudoRoots)}${`#${SPECIFICITY_CARRIER}`.repeat(ids)}`,\n );\n }\n\n return carrier.filter(Boolean).join(' ');\n};\n\nconst rootedDescendantScope = (selector: selectorParser.Selector, scopeId: string): string => {\n return `:where([${MF_SCOPE_ATTRIBUTE}=\"${scopeId}\"]):not(${rootSpecificityCarrier(selector)})`;\n};\n\nconst isRootOnlySelector = (selector: selectorParser.Selector): boolean => {\n const compounds: selectorParser.Node[][] = [[]];\n\n for (const node of selector.nodes) {\n if (node.type === 'combinator') {\n compounds.push([]);\n } else {\n compounds.at(-1)?.push(node);\n }\n }\n\n return compounds.every((compound) => compound.some(isRootNode));\n};\n\nconst hasRootOnlySelector = (selectorList: string): boolean => {\n let result = false;\n selectorParser((root) => {\n result = root.nodes.some(isRootOnlySelector);\n }).processSync(selectorList);\n return result;\n};\n\nconst getAngularComponentSourcePath = (stylePath: string): string | undefined => {\n const cleanStylePath = stylePath.replace(/[?#].*$/, '');\n if (!ANGULAR_COMPONENT_STYLE_PATTERN.test(cleanStylePath)) {\n return undefined;\n }\n\n return cleanStylePath.replace(/\\.(?:css|less|sass|scss)$/i, '.ts');\n};\n\nconst usesViewEncapsulationNone = (stylePath: string): boolean => {\n const componentSourcePath = getAngularComponentSourcePath(stylePath);\n if (!componentSourcePath || !existsSync(componentSourcePath)) {\n return false;\n }\n\n const componentSource = readFileSync(componentSourcePath, 'utf8');\n return VIEW_ENCAPSULATION_NONE_PATTERN.test(maskTypeScriptCommentsAndStrings(componentSource));\n};\n\nexport const shouldUseAngularComponentScoping = (stylePath: string | undefined): boolean => {\n return !!stylePath && !!getAngularComponentSourcePath(stylePath) && !usesViewEncapsulationNone(stylePath);\n};\n\nconst scopeSelectorList = (selectorList: string, scopeId: string, scopeSelector: string, rootScopeSelectors: string[]): string => {\n return selectorParser((root) => {\n const sourceSelectors = [...root.nodes];\n\n for (const selector of sourceSelectors) {\n const rootNodes = selector.nodes.filter(isRootNode);\n\n if (rootNodes.length > 0) {\n const replacementSelectors = isRootOnlySelector(selector) ? rootScopeSelectors : [rootedDescendantScope(selector, scopeId)];\n\n for (const replacementSelector of replacementSelectors) {\n const variant = selector.clone();\n removeRootIdentityIds(variant);\n const [firstRoot, ...duplicateRoots] = variant.nodes.filter(isRootNode);\n // The replacement can be a compound of several nodes, e.g. :where(<scope>):not(<carrier>).\n const scopeNodes = selectorParser()\n .astSync(replacementSelector)\n .first.nodes.map((node) => node.clone());\n const [scopeNode, ...followingScopeNodes] = scopeNodes;\n if (firstRoot && scopeNode) {\n firstRoot.replaceWith(scopeNode);\n let previous = scopeNode;\n for (const node of followingScopeNodes) {\n variant.insertAfter(previous, node);\n previous = node;\n }\n }\n\n for (const duplicateRoot of duplicateRoots) {\n const previous = duplicateRoot.prev();\n if (previous?.type === 'combinator') {\n previous.remove();\n }\n duplicateRoot.remove();\n }\n\n root.insertBefore(selector, variant);\n }\n selector.remove();\n continue;\n }\n\n if (startsWithHostPseudo(selector) || isScopeNode(selector.first, scopeId)) {\n continue;\n }\n\n const first = selector.first;\n const needsBoundaryVariant = first?.type === 'universal' || (first?.type === 'pseudo' && first.value.startsWith('::'));\n\n if (needsBoundaryVariant) {\n const hasSiblingCombinator = selector.nodes.some((node) => node.type === 'combinator' && (node.value === '+' || node.value === '~'));\n\n if (!hasSiblingCombinator) {\n const boundaryVariant = selector.clone();\n const boundaryScope = selectorParser().astSync(scopeSelector).first.first.clone();\n boundaryVariant.first.rawSpaceBefore = '';\n if (boundaryVariant.first.type === 'universal') {\n boundaryVariant.first.replaceWith(boundaryScope);\n } else {\n boundaryVariant.prepend(boundaryScope);\n }\n root.insertBefore(selector, boundaryVariant);\n }\n }\n\n const descendantScope = selectorParser().astSync(`${scopeSelector} *`).first;\n const prefixNodes = descendantScope.nodes.slice(0, -1).map((node) => node.clone());\n selector.first.rawSpaceBefore = '';\n for (const prefixNode of prefixNodes.reverse()) {\n selector.prepend(prefixNode);\n }\n }\n\n const seenSelectors = new Set<string>();\n for (const selector of [...root.nodes]) {\n const normalizedSelector = selector.toString().trim();\n if (seenSelectors.has(normalizedSelector)) {\n selector.remove();\n } else {\n seenSelectors.add(normalizedSelector);\n }\n }\n }).processSync(selectorList);\n};\n\nconst findFunctionalPseudoEnd = (selector: string, openParenthesisIndex: number): number => {\n let depth = 0;\n let quote: '\"' | \"'\" | undefined;\n\n for (let index = openParenthesisIndex; index < selector.length; index += 1) {\n const character = selector[index];\n const previousCharacter = selector[index - 1];\n\n if (quote) {\n if (character === quote && previousCharacter !== '\\\\') {\n quote = undefined;\n }\n continue;\n }\n\n if (character === '\"' || character === \"'\") {\n quote = character;\n continue;\n }\n\n if (character === '(') {\n depth += 1;\n } else if (character === ')') {\n depth -= 1;\n if (depth === 0) {\n return index;\n }\n }\n }\n\n return -1;\n};\n\nconst scopeAngularSelector = (selector: string, boundarySelector: string): string => {\n const normalizedSelector = selector.trim();\n const angularBoundary = `:host-context(${boundarySelector})`;\n const normalizedBoundary = normalizedSelector.slice(0, angularBoundary.length).replaceAll(\"'\", '\"');\n\n if (normalizedBoundary === angularBoundary) {\n return normalizedSelector;\n }\n\n if (/^:host-context\\(/i.test(normalizedSelector)) {\n return `${angularBoundary}${normalizedSelector}`;\n }\n\n if (/^:host\\(/i.test(normalizedSelector)) {\n const openParenthesisIndex = normalizedSelector.indexOf('(');\n const closeParenthesisIndex = findFunctionalPseudoEnd(normalizedSelector, openParenthesisIndex);\n if (closeParenthesisIndex !== -1) {\n const hostSelector = normalizedSelector.slice(openParenthesisIndex + 1, closeParenthesisIndex);\n const remainder = normalizedSelector.slice(closeParenthesisIndex + 1);\n return list\n .comma(hostSelector)\n .map((hostSelectorVariant) => `${angularBoundary}${hostSelectorVariant}${remainder}`)\n .join(', ');\n }\n }\n\n if (/^:host\\b/i.test(normalizedSelector)) {\n return normalizedSelector.replace(/^:host\\b/i, angularBoundary);\n }\n\n return `${angularBoundary} ${normalizedSelector}`;\n};\n\nconst scopeAngularSelectorList = (selectorList: string, boundarySelector: string): string => {\n return list\n .comma(selectorList)\n .map((selector) => scopeAngularSelector(selector, boundarySelector))\n .join(', ');\n};\n\nconst namespaceKeyframes = (root: Root, keyframePrefix: string): void => {\n const keyframes = new Map<string, string>();\n\n root.walkAtRules((atRule) => {\n if (!/keyframes$/i.test(atRule.name) || atRule.params.startsWith(keyframePrefix)) {\n return;\n }\n\n const originalName = atRule.params.trim();\n const scopedName = `${keyframePrefix}${originalName}`;\n keyframes.set(originalName, scopedName);\n atRule.params = scopedName;\n });\n\n root.walkDecls((declaration) => {\n if (!/^(?:-webkit-)?animation(?:-name)?$/i.test(declaration.prop) && !declaration.prop.startsWith('--animate-')) {\n return;\n }\n\n const parsed = valueParser(declaration.value);\n parsed.walk((node) => {\n if (node.type === 'word') {\n node.value = keyframes.get(node.value) ?? node.value;\n }\n });\n declaration.value = parsed.toString();\n });\n};\n\nconst scopeGlobalRoot = (root: Root, scopeId: string, scopeSelector: string, keyframePrefix: string): void => {\n namespaceKeyframes(root, keyframePrefix);\n const contentRootSelector = `:where([${MF_SCOPE_ATTRIBUTE}=\"${scopeId}\"]:not([${MF_OVERLAY_ATTRIBUTE}]))`;\n root.walkRules((rule) => {\n if (!isKeyframesRule(rule)) {\n const declarations = rule.nodes.filter((node) => node.type === 'decl');\n const customProperties = declarations.filter((declaration) => declaration.prop.startsWith('--'));\n const standardDeclarations = declarations.filter((declaration) => !declaration.prop.startsWith('--'));\n\n if (customProperties.length > 0 && standardDeclarations.length > 0 && hasRootOnlySelector(rule.selector)) {\n const customPropertyRule = rule.cloneBefore();\n customPropertyRule.walkDecls((declaration) => {\n if (!declaration.prop.startsWith('--')) {\n declaration.remove();\n }\n });\n customPropertyRule.selector = scopeSelectorList(customPropertyRule.selector, scopeId, scopeSelector, [':host', scopeSelector]);\n rule.walkDecls((declaration) => {\n if (declaration.prop.startsWith('--')) {\n declaration.remove();\n }\n });\n }\n\n const containsOnlyCustomProperties = declarations.length > 0 && declarations.every((declaration) => declaration.prop.startsWith('--'));\n const rootScopeSelectors = containsOnlyCustomProperties ? [':host', scopeSelector] : [':host', contentRootSelector];\n rule.selector = scopeSelectorList(rule.selector, scopeId, scopeSelector, rootScopeSelectors);\n }\n });\n};\n\nconst scopeAngularComponentRoot = (root: Root, boundarySelector: string, keyframePrefix: string): void => {\n namespaceKeyframes(root, keyframePrefix);\n root.walkRules((rule) => {\n if (!isKeyframesRule(rule)) {\n rule.selector = scopeAngularSelectorList(rule.selector, boundarySelector);\n }\n });\n};\n\nexport const scopeRemoteCss = ({ scopeId }: IScopeRemoteCssOptions): Plugin => {\n const validScopeId = validateMfScopeId(scopeId);\n const scopeSelector = getMfScopeSelector(validScopeId);\n const keyframePrefix = `edyn-mf-${validScopeId}--`;\n\n return {\n postcssPlugin: `edyn-mf-isolation-${validScopeId}`,\n Once(root) {\n scopeGlobalRoot(root, validScopeId, scopeSelector, keyframePrefix);\n },\n };\n};\n\nexport const scopeAngularRemoteCss = ({ scopeId }: IScopeRemoteCssOptions): Plugin => {\n const validScopeId = validateMfScopeId(scopeId);\n const scopeSelector = getMfScopeSelector(validScopeId);\n const boundarySelector = `[${MF_SCOPE_ATTRIBUTE}=\"${validScopeId}\"]`;\n const keyframePrefix = `edyn-mf-${validScopeId}--`;\n\n return {\n postcssPlugin: `edyn-mf-angular-isolation-${validScopeId}`,\n Once(root) {\n if (shouldUseAngularComponentScoping(root.source?.input.file)) {\n scopeAngularComponentRoot(root, boundarySelector, keyframePrefix);\n return;\n }\n\n scopeGlobalRoot(root, validScopeId, scopeSelector, keyframePrefix);\n },\n };\n};\n"]}
package/dist/postcss.js CHANGED
@@ -119,6 +119,39 @@ const removeRootIdentityIds = (selector) => {
119
119
  }
120
120
  removeIdsFromRootCompound();
121
121
  };
122
+ const SPECIFICITY_CARRIER = 'edyn-mf-root';
123
+ // Legacy rules such as `html body button` or `html body#app .mdc-checkbox__background` are weighed against Angular
124
+ // Material's own rules by the html, body and #app they start from, so the scope that replaces that root must weigh
125
+ // exactly the same. A plain scope attribute (0,1,0) drops the id of `body#app`, letting Material's checked colour win,
126
+ // and outweighs the two types of `html body`, letting an override that lost to `.mat-mdc-button` on the old site win
127
+ // hosted. The root becomes :where(<scope>):not(<carrier>): :where() weighs nothing, and the carrier has the same id,
128
+ // class and type counts as the root part it replaces and never matches the scope element, so :not() always matches and
129
+ // weighs exactly that. Neutral names keep `html`, `body` and `#app` out of the emitted CSS.
130
+ const rootSpecificityCarrier = (selector) => {
131
+ const compounds = [[]];
132
+ for (const node of selector.nodes) {
133
+ if (node.type === 'combinator') {
134
+ compounds.push([]);
135
+ }
136
+ else {
137
+ compounds.at(-1)?.push(node);
138
+ }
139
+ }
140
+ const carrier = [];
141
+ for (const compound of compounds) {
142
+ if (!compound.some(isRootNode)) {
143
+ continue;
144
+ }
145
+ const types = compound.filter((node) => node.type === 'tag' && isRootNode(node)).length;
146
+ const pseudoRoots = compound.filter((node) => node.type === 'pseudo' && isRootNode(node)).length;
147
+ const ids = compound.filter((node) => node.type === 'id').length;
148
+ carrier.push(`${SPECIFICITY_CARRIER.repeat(Math.min(types, 1))}${`.${SPECIFICITY_CARRIER}`.repeat(pseudoRoots)}${`#${SPECIFICITY_CARRIER}`.repeat(ids)}`);
149
+ }
150
+ return carrier.filter(Boolean).join(' ');
151
+ };
152
+ const rootedDescendantScope = (selector, scopeId) => {
153
+ return `:where([${MF_SCOPE_ATTRIBUTE}="${scopeId}"]):not(${rootSpecificityCarrier(selector)})`;
154
+ };
122
155
  const isRootOnlySelector = (selector) => {
123
156
  const compounds = [[]];
124
157
  for (const node of selector.nodes) {
@@ -162,13 +195,24 @@ const scopeSelectorList = (selectorList, scopeId, scopeSelector, rootScopeSelect
162
195
  for (const selector of sourceSelectors) {
163
196
  const rootNodes = selector.nodes.filter(isRootNode);
164
197
  if (rootNodes.length > 0) {
165
- const replacementSelectors = isRootOnlySelector(selector) ? rootScopeSelectors : [`[${MF_SCOPE_ATTRIBUTE}="${scopeId}"]`];
198
+ const replacementSelectors = isRootOnlySelector(selector) ? rootScopeSelectors : [rootedDescendantScope(selector, scopeId)];
166
199
  for (const replacementSelector of replacementSelectors) {
167
200
  const variant = selector.clone();
168
201
  removeRootIdentityIds(variant);
169
202
  const [firstRoot, ...duplicateRoots] = variant.nodes.filter(isRootNode);
170
- const scopeNode = selectorParser().astSync(replacementSelector).first.first.clone();
171
- firstRoot?.replaceWith(scopeNode);
203
+ // The replacement can be a compound of several nodes, e.g. :where(<scope>):not(<carrier>).
204
+ const scopeNodes = selectorParser()
205
+ .astSync(replacementSelector)
206
+ .first.nodes.map((node) => node.clone());
207
+ const [scopeNode, ...followingScopeNodes] = scopeNodes;
208
+ if (firstRoot && scopeNode) {
209
+ firstRoot.replaceWith(scopeNode);
210
+ let previous = scopeNode;
211
+ for (const node of followingScopeNodes) {
212
+ variant.insertAfter(previous, node);
213
+ previous = node;
214
+ }
215
+ }
172
216
  for (const duplicateRoot of duplicateRoots) {
173
217
  const previous = duplicateRoot.prev();
174
218
  if (previous?.type === 'combinator') {
@@ -1 +1 @@
1
- {"version":3,"file":"postcss.js","sourceRoot":"","sources":["../src/postcss.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAqC,MAAM,SAAS,CAAC;AAClE,OAAO,cAAc,MAAM,yBAAyB,CAAC;AACrD,OAAO,WAAW,MAAM,sBAAsB,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAMzG,MAAM,+BAA+B,GAAG,uCAAuC,CAAC;AAChF,MAAM,+BAA+B,GAAG,uEAAuE,CAAC;AAChH,MAAM,oBAAoB,GAAG,sBAAsB,CAAC;AAIpD,MAAM,gCAAgC,GAAG,CAAC,MAAc,EAAU,EAAE;IAClE,IAAI,YAAY,GAAG,EAAE,CAAC;IACtB,IAAI,KAAK,GAAyB,MAAM,CAAC;IACzC,IAAI,OAAO,GAAG,KAAK,CAAC;IAEpB,MAAM,aAAa,GAAG,CAAC,SAAiB,EAAU,EAAE;QAClD,OAAO,SAAS,KAAK,IAAI,IAAI,SAAS,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC;IACpE,CAAC,CAAC;IAEF,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QACtD,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QACtC,MAAM,aAAa,GAAG,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;QAExC,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;YACrB,IAAI,SAAS,KAAK,GAAG,IAAI,aAAa,KAAK,GAAG,EAAE,CAAC;gBAC/C,YAAY,IAAI,IAAI,CAAC;gBACrB,KAAK,IAAI,CAAC,CAAC;gBACX,KAAK,GAAG,cAAc,CAAC;YACzB,CAAC;iBAAM,IAAI,SAAS,KAAK,GAAG,IAAI,aAAa,KAAK,GAAG,EAAE,CAAC;gBACtD,YAAY,IAAI,IAAI,CAAC;gBACrB,KAAK,IAAI,CAAC,CAAC;gBACX,KAAK,GAAG,eAAe,CAAC;YAC1B,CAAC;iBAAM,IAAI,SAAS,KAAK,GAAG,EAAE,CAAC;gBAC7B,YAAY,IAAI,GAAG,CAAC;gBACpB,KAAK,GAAG,cAAc,CAAC;YACzB,CAAC;iBAAM,IAAI,SAAS,KAAK,GAAG,EAAE,CAAC;gBAC7B,YAAY,IAAI,GAAG,CAAC;gBACpB,KAAK,GAAG,cAAc,CAAC;YACzB,CAAC;iBAAM,IAAI,SAAS,KAAK,GAAG,EAAE,CAAC;gBAC7B,YAAY,IAAI,GAAG,CAAC;gBACpB,KAAK,GAAG,UAAU,CAAC;YACrB,CAAC;iBAAM,CAAC;gBACN,YAAY,IAAI,SAAS,CAAC;YAC5B,CAAC;YACD,SAAS;QACX,CAAC;QAED,IAAI,KAAK,KAAK,cAAc,EAAE,CAAC;YAC7B,YAAY,IAAI,aAAa,CAAC,SAAS,CAAC,CAAC;YACzC,IAAI,SAAS,KAAK,IAAI,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;gBAC7C,KAAK,GAAG,MAAM,CAAC;YACjB,CAAC;YACD,SAAS;QACX,CAAC;QAED,IAAI,KAAK,KAAK,eAAe,EAAE,CAAC;YAC9B,IAAI,SAAS,KAAK,GAAG,IAAI,aAAa,KAAK,GAAG,EAAE,CAAC;gBAC/C,YAAY,IAAI,IAAI,CAAC;gBACrB,KAAK,IAAI,CAAC,CAAC;gBACX,KAAK,GAAG,MAAM,CAAC;YACjB,CAAC;iBAAM,CAAC;gBACN,YAAY,IAAI,aAAa,CAAC,SAAS,CAAC,CAAC;YAC3C,CAAC;YACD,SAAS;QACX,CAAC;QAED,YAAY,IAAI,aAAa,CAAC,SAAS,CAAC,CAAC;QACzC,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,GAAG,KAAK,CAAC;QAClB,CAAC;aAAM,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;YAC9B,OAAO,GAAG,IAAI,CAAC;QACjB,CAAC;aAAM,IACL,CAAC,KAAK,KAAK,cAAc,IAAI,SAAS,KAAK,GAAG,CAAC;YAC/C,CAAC,KAAK,KAAK,cAAc,IAAI,SAAS,KAAK,GAAG,CAAC;YAC/C,CAAC,KAAK,KAAK,UAAU,IAAI,SAAS,KAAK,GAAG,CAAC,EAC3C,CAAC;YACD,KAAK,GAAG,MAAM,CAAC;QACjB,CAAC;IACH,CAAC;IAED,OAAO,YAAY,CAAC;AACtB,CAAC,CAAC;AAEF,MAAM,eAAe,GAAG,CAAC,IAAU,EAAW,EAAE;IAC9C,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;IAC3B,OAAO,MAAM,EAAE,IAAI,KAAK,QAAQ,IAAI,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AACtE,CAAC,CAAC;AAEF,MAAM,UAAU,GAAG,CAAC,IAAyB,EAAW,EAAE;IACxD,OAAO,CACL,CAAC,IAAI,CAAC,IAAI,KAAK,KAAK,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,MAAM,IAAI,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,MAAM,CAAC,CAAC;QACrG,CAAC,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,IAAI,CAAC,KAAK,KAAK,OAAO,IAAI,IAAI,CAAC,KAAK,KAAK,gBAAgB,CAAC,CAAC,CACxF,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,WAAW,GAAG,CAAC,IAAqC,EAAE,OAAe,EAAW,EAAE;IACtF,IAAI,IAAI,EAAE,IAAI,KAAK,WAAW,IAAI,IAAI,CAAC,SAAS,KAAK,kBAAkB,IAAI,IAAI,CAAC,QAAQ,KAAK,GAAG,IAAI,IAAI,CAAC,KAAK,KAAK,OAAO,EAAE,CAAC;QAC3H,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,EAAE,QAAQ,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IAC5E,OAAO,CACL,IAAI,EAAE,IAAI,KAAK,QAAQ;QACvB,CAAC,UAAU,KAAK,WAAW,kBAAkB,IAAI,OAAO,IAAI;YAC1D,UAAU,KAAK,WAAW,kBAAkB,IAAI,OAAO,UAAU,oBAAoB,KAAK,CAAC,CAC9F,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,oBAAoB,GAAG,CAAC,QAAiC,EAAW,EAAE;IAC1E,OAAO,QAAQ,CAAC,KAAK,EAAE,IAAI,KAAK,QAAQ,IAAI,QAAQ,CAAC,KAAK,CAAC,KAAK,KAAK,OAAO,CAAC;AAC/E,CAAC,CAAC;AAEF,MAAM,qBAAqB,GAAG,CAAC,QAAiC,EAAQ,EAAE;IACxE,IAAI,QAAQ,GAA0B,EAAE,CAAC;IACzC,MAAM,yBAAyB,GAAG,GAAS,EAAE;QAC3C,IAAI,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;YAC9B,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;gBAC5B,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;oBACvB,IAAI,CAAC,MAAM,EAAE,CAAC;gBAChB,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC,CAAC;IAEF,KAAK,MAAM,IAAI,IAAI,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACvC,IAAI,IAAI,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;YAC/B,yBAAyB,EAAE,CAAC;YAC5B,QAAQ,GAAG,EAAE,CAAC;QAChB,CAAC;aAAM,CAAC;YACN,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtB,CAAC;IACH,CAAC;IACD,yBAAyB,EAAE,CAAC;AAC9B,CAAC,CAAC;AAEF,MAAM,kBAAkB,GAAG,CAAC,QAAiC,EAAW,EAAE;IACxE,MAAM,SAAS,GAA4B,CAAC,EAAE,CAAC,CAAC;IAEhD,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;QAClC,IAAI,IAAI,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;YAC/B,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACrB,CAAC;aAAM,CAAC;YACN,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC;IAED,OAAO,SAAS,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;AAClE,CAAC,CAAC;AAEF,MAAM,mBAAmB,GAAG,CAAC,YAAoB,EAAW,EAAE;IAC5D,IAAI,MAAM,GAAG,KAAK,CAAC;IACnB,cAAc,CAAC,CAAC,IAAI,EAAE,EAAE;QACtB,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;IAC7B,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AAEF,MAAM,6BAA6B,GAAG,CAAC,SAAiB,EAAsB,EAAE;IAC9E,MAAM,cAAc,GAAG,SAAS,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;IACxD,IAAI,CAAC,+BAA+B,CAAC,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC;QAC1D,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO,cAAc,CAAC,OAAO,CAAC,4BAA4B,EAAE,KAAK,CAAC,CAAC;AACrE,CAAC,CAAC;AAEF,MAAM,yBAAyB,GAAG,CAAC,SAAiB,EAAW,EAAE;IAC/D,MAAM,mBAAmB,GAAG,6BAA6B,CAAC,SAAS,CAAC,CAAC;IACrE,IAAI,CAAC,mBAAmB,IAAI,CAAC,UAAU,CAAC,mBAAmB,CAAC,EAAE,CAAC;QAC7D,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,eAAe,GAAG,YAAY,CAAC,mBAAmB,EAAE,MAAM,CAAC,CAAC;IAClE,OAAO,+BAA+B,CAAC,IAAI,CAAC,gCAAgC,CAAC,eAAe,CAAC,CAAC,CAAC;AACjG,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,gCAAgC,GAAG,CAAC,SAA6B,EAAW,EAAE;IACzF,OAAO,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,6BAA6B,CAAC,SAAS,CAAC,IAAI,CAAC,yBAAyB,CAAC,SAAS,CAAC,CAAC;AAC5G,CAAC,CAAC;AAEF,MAAM,iBAAiB,GAAG,CAAC,YAAoB,EAAE,OAAe,EAAE,aAAqB,EAAE,kBAA4B,EAAU,EAAE;IAC/H,OAAO,cAAc,CAAC,CAAC,IAAI,EAAE,EAAE;QAC7B,MAAM,eAAe,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;QAExC,KAAK,MAAM,QAAQ,IAAI,eAAe,EAAE,CAAC;YACvC,MAAM,SAAS,GAAG,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YAEpD,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACzB,MAAM,oBAAoB,GAAG,kBAAkB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,IAAI,kBAAkB,KAAK,OAAO,IAAI,CAAC,CAAC;gBAE1H,KAAK,MAAM,mBAAmB,IAAI,oBAAoB,EAAE,CAAC;oBACvD,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,EAAE,CAAC;oBACjC,qBAAqB,CAAC,OAAO,CAAC,CAAC;oBAC/B,MAAM,CAAC,SAAS,EAAE,GAAG,cAAc,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;oBACxE,MAAM,SAAS,GAAG,cAAc,EAAE,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;oBACpF,SAAS,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;oBAElC,KAAK,MAAM,aAAa,IAAI,cAAc,EAAE,CAAC;wBAC3C,MAAM,QAAQ,GAAG,aAAa,CAAC,IAAI,EAAE,CAAC;wBACtC,IAAI,QAAQ,EAAE,IAAI,KAAK,YAAY,EAAE,CAAC;4BACpC,QAAQ,CAAC,MAAM,EAAE,CAAC;wBACpB,CAAC;wBACD,aAAa,CAAC,MAAM,EAAE,CAAC;oBACzB,CAAC;oBAED,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;gBACvC,CAAC;gBACD,QAAQ,CAAC,MAAM,EAAE,CAAC;gBAClB,SAAS;YACX,CAAC;YAED,IAAI,oBAAoB,CAAC,QAAQ,CAAC,IAAI,WAAW,CAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE,CAAC;gBAC3E,SAAS;YACX,CAAC;YAED,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC;YAC7B,MAAM,oBAAoB,GAAG,KAAK,EAAE,IAAI,KAAK,WAAW,IAAI,CAAC,KAAK,EAAE,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;YAEvH,IAAI,oBAAoB,EAAE,CAAC;gBACzB,MAAM,oBAAoB,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,YAAY,IAAI,CAAC,IAAI,CAAC,KAAK,KAAK,GAAG,IAAI,IAAI,CAAC,KAAK,KAAK,GAAG,CAAC,CAAC,CAAC;gBAErI,IAAI,CAAC,oBAAoB,EAAE,CAAC;oBAC1B,MAAM,eAAe,GAAG,QAAQ,CAAC,KAAK,EAAE,CAAC;oBACzC,MAAM,aAAa,GAAG,cAAc,EAAE,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;oBAClF,eAAe,CAAC,KAAK,CAAC,cAAc,GAAG,EAAE,CAAC;oBAC1C,IAAI,eAAe,CAAC,KAAK,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;wBAC/C,eAAe,CAAC,KAAK,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC;oBACnD,CAAC;yBAAM,CAAC;wBACN,eAAe,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;oBACzC,CAAC;oBACD,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;gBAC/C,CAAC;YACH,CAAC;YAED,MAAM,eAAe,GAAG,cAAc,EAAE,CAAC,OAAO,CAAC,GAAG,aAAa,IAAI,CAAC,CAAC,KAAK,CAAC;YAC7E,MAAM,WAAW,GAAG,eAAe,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;YACnF,QAAQ,CAAC,KAAK,CAAC,cAAc,GAAG,EAAE,CAAC;YACnC,KAAK,MAAM,UAAU,IAAI,WAAW,CAAC,OAAO,EAAE,EAAE,CAAC;gBAC/C,QAAQ,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;YAC/B,CAAC;QACH,CAAC;QAED,MAAM,aAAa,GAAG,IAAI,GAAG,EAAU,CAAC;QACxC,KAAK,MAAM,QAAQ,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YACvC,MAAM,kBAAkB,GAAG,QAAQ,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC;YACtD,IAAI,aAAa,CAAC,GAAG,CAAC,kBAAkB,CAAC,EAAE,CAAC;gBAC1C,QAAQ,CAAC,MAAM,EAAE,CAAC;YACpB,CAAC;iBAAM,CAAC;gBACN,aAAa,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;YACxC,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;AAC/B,CAAC,CAAC;AAEF,MAAM,uBAAuB,GAAG,CAAC,QAAgB,EAAE,oBAA4B,EAAU,EAAE;IACzF,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,KAA4B,CAAC;IAEjC,KAAK,IAAI,KAAK,GAAG,oBAAoB,EAAE,KAAK,GAAG,QAAQ,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QAC3E,MAAM,SAAS,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;QAClC,MAAM,iBAAiB,GAAG,QAAQ,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;QAE9C,IAAI,KAAK,EAAE,CAAC;YACV,IAAI,SAAS,KAAK,KAAK,IAAI,iBAAiB,KAAK,IAAI,EAAE,CAAC;gBACtD,KAAK,GAAG,SAAS,CAAC;YACpB,CAAC;YACD,SAAS;QACX,CAAC;QAED,IAAI,SAAS,KAAK,GAAG,IAAI,SAAS,KAAK,GAAG,EAAE,CAAC;YAC3C,KAAK,GAAG,SAAS,CAAC;YAClB,SAAS;QACX,CAAC;QAED,IAAI,SAAS,KAAK,GAAG,EAAE,CAAC;YACtB,KAAK,IAAI,CAAC,CAAC;QACb,CAAC;aAAM,IAAI,SAAS,KAAK,GAAG,EAAE,CAAC;YAC7B,KAAK,IAAI,CAAC,CAAC;YACX,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;gBAChB,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,CAAC,CAAC,CAAC;AACZ,CAAC,CAAC;AAEF,MAAM,oBAAoB,GAAG,CAAC,QAAgB,EAAE,gBAAwB,EAAU,EAAE;IAClF,MAAM,kBAAkB,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC;IAC3C,MAAM,eAAe,GAAG,iBAAiB,gBAAgB,GAAG,CAAC;IAC7D,MAAM,kBAAkB,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC,EAAE,eAAe,CAAC,MAAM,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAEpG,IAAI,kBAAkB,KAAK,eAAe,EAAE,CAAC;QAC3C,OAAO,kBAAkB,CAAC;IAC5B,CAAC;IAED,IAAI,mBAAmB,CAAC,IAAI,CAAC,kBAAkB,CAAC,EAAE,CAAC;QACjD,OAAO,GAAG,eAAe,GAAG,kBAAkB,EAAE,CAAC;IACnD,CAAC;IAED,IAAI,WAAW,CAAC,IAAI,CAAC,kBAAkB,CAAC,EAAE,CAAC;QACzC,MAAM,oBAAoB,GAAG,kBAAkB,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC7D,MAAM,qBAAqB,GAAG,uBAAuB,CAAC,kBAAkB,EAAE,oBAAoB,CAAC,CAAC;QAChG,IAAI,qBAAqB,KAAK,CAAC,CAAC,EAAE,CAAC;YACjC,MAAM,YAAY,GAAG,kBAAkB,CAAC,KAAK,CAAC,oBAAoB,GAAG,CAAC,EAAE,qBAAqB,CAAC,CAAC;YAC/F,MAAM,SAAS,GAAG,kBAAkB,CAAC,KAAK,CAAC,qBAAqB,GAAG,CAAC,CAAC,CAAC;YACtE,OAAO,IAAI;iBACR,KAAK,CAAC,YAAY,CAAC;iBACnB,GAAG,CAAC,CAAC,mBAAmB,EAAE,EAAE,CAAC,GAAG,eAAe,GAAG,mBAAmB,GAAG,SAAS,EAAE,CAAC;iBACpF,IAAI,CAAC,IAAI,CAAC,CAAC;QAChB,CAAC;IACH,CAAC;IAED,IAAI,WAAW,CAAC,IAAI,CAAC,kBAAkB,CAAC,EAAE,CAAC;QACzC,OAAO,kBAAkB,CAAC,OAAO,CAAC,WAAW,EAAE,eAAe,CAAC,CAAC;IAClE,CAAC;IAED,OAAO,GAAG,eAAe,IAAI,kBAAkB,EAAE,CAAC;AACpD,CAAC,CAAC;AAEF,MAAM,wBAAwB,GAAG,CAAC,YAAoB,EAAE,gBAAwB,EAAU,EAAE;IAC1F,OAAO,IAAI;SACR,KAAK,CAAC,YAAY,CAAC;SACnB,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,oBAAoB,CAAC,QAAQ,EAAE,gBAAgB,CAAC,CAAC;SACnE,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC,CAAC;AAEF,MAAM,kBAAkB,GAAG,CAAC,IAAU,EAAE,cAAsB,EAAQ,EAAE;IACtE,MAAM,SAAS,GAAG,IAAI,GAAG,EAAkB,CAAC;IAE5C,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,EAAE,EAAE;QAC1B,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;YACjF,OAAO;QACT,CAAC;QAED,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QAC1C,MAAM,UAAU,GAAG,GAAG,cAAc,GAAG,YAAY,EAAE,CAAC;QACtD,SAAS,CAAC,GAAG,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;QACxC,MAAM,CAAC,MAAM,GAAG,UAAU,CAAC;IAC7B,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,EAAE;QAC7B,IAAI,CAAC,qCAAqC,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;YAChH,OAAO;QACT,CAAC;QAED,MAAM,MAAM,GAAG,WAAW,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QAC9C,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;YACnB,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;gBACzB,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC;YACvD,CAAC;QACH,CAAC,CAAC,CAAC;QACH,WAAW,CAAC,KAAK,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;IACxC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,MAAM,eAAe,GAAG,CAAC,IAAU,EAAE,OAAe,EAAE,aAAqB,EAAE,cAAsB,EAAQ,EAAE;IAC3G,kBAAkB,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;IACzC,MAAM,mBAAmB,GAAG,WAAW,kBAAkB,KAAK,OAAO,WAAW,oBAAoB,KAAK,CAAC;IAC1G,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE;QACtB,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC;YAC3B,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC;YACvE,MAAM,gBAAgB,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;YACjG,MAAM,oBAAoB,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;YAEtG,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,IAAI,oBAAoB,CAAC,MAAM,GAAG,CAAC,IAAI,mBAAmB,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACzG,MAAM,kBAAkB,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;gBAC9C,kBAAkB,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,EAAE;oBAC3C,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;wBACvC,WAAW,CAAC,MAAM,EAAE,CAAC;oBACvB,CAAC;gBACH,CAAC,CAAC,CAAC;gBACH,kBAAkB,CAAC,QAAQ,GAAG,iBAAiB,CAAC,kBAAkB,CAAC,QAAQ,EAAE,OAAO,EAAE,aAAa,EAAE,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC;gBAC/H,IAAI,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,EAAE;oBAC7B,IAAI,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;wBACtC,WAAW,CAAC,MAAM,EAAE,CAAC;oBACvB,CAAC;gBACH,CAAC,CAAC,CAAC;YACL,CAAC;YAED,MAAM,4BAA4B,GAAG,YAAY,CAAC,MAAM,GAAG,CAAC,IAAI,YAAY,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;YACvI,MAAM,kBAAkB,GAAG,4BAA4B,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAC;YACpH,IAAI,CAAC,QAAQ,GAAG,iBAAiB,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,aAAa,EAAE,kBAAkB,CAAC,CAAC;QAC/F,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,MAAM,yBAAyB,GAAG,CAAC,IAAU,EAAE,gBAAwB,EAAE,cAAsB,EAAQ,EAAE;IACvG,kBAAkB,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;IACzC,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE;QACtB,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC;YAC3B,IAAI,CAAC,QAAQ,GAAG,wBAAwB,CAAC,IAAI,CAAC,QAAQ,EAAE,gBAAgB,CAAC,CAAC;QAC5E,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,EAAE,OAAO,EAA0B,EAAU,EAAE;IAC5E,MAAM,YAAY,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAChD,MAAM,aAAa,GAAG,kBAAkB,CAAC,YAAY,CAAC,CAAC;IACvD,MAAM,cAAc,GAAG,WAAW,YAAY,IAAI,CAAC;IAEnD,OAAO;QACL,aAAa,EAAE,qBAAqB,YAAY,EAAE;QAClD,IAAI,CAAC,IAAI;YACP,eAAe,CAAC,IAAI,EAAE,YAAY,EAAE,aAAa,EAAE,cAAc,CAAC,CAAC;QACrE,CAAC;KACF,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,EAAE,OAAO,EAA0B,EAAU,EAAE;IACnF,MAAM,YAAY,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAChD,MAAM,aAAa,GAAG,kBAAkB,CAAC,YAAY,CAAC,CAAC;IACvD,MAAM,gBAAgB,GAAG,IAAI,kBAAkB,KAAK,YAAY,IAAI,CAAC;IACrE,MAAM,cAAc,GAAG,WAAW,YAAY,IAAI,CAAC;IAEnD,OAAO;QACL,aAAa,EAAE,6BAA6B,YAAY,EAAE;QAC1D,IAAI,CAAC,IAAI;YACP,IAAI,gCAAgC,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC9D,yBAAyB,CAAC,IAAI,EAAE,gBAAgB,EAAE,cAAc,CAAC,CAAC;gBAClE,OAAO;YACT,CAAC;YAED,eAAe,CAAC,IAAI,EAAE,YAAY,EAAE,aAAa,EAAE,cAAc,CAAC,CAAC;QACrE,CAAC;KACF,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import { existsSync, readFileSync } from 'node:fs';\nimport { list, type Plugin, type Root, type Rule } from 'postcss';\nimport selectorParser from 'postcss-selector-parser';\nimport valueParser from 'postcss-value-parser';\nimport { getMfScopeSelector, MF_ROOT_SELECTOR, MF_SCOPE_ATTRIBUTE, validateMfScopeId } from './index.js';\n\nexport interface IScopeRemoteCssOptions {\n scopeId: string;\n}\n\nconst ANGULAR_COMPONENT_STYLE_PATTERN = /\\.component\\.(?:css|less|sass|scss)$/i;\nconst VIEW_ENCAPSULATION_NONE_PATTERN = /(?:^|[,{])\\s*encapsulation\\s*:\\s*(?:[A-Za-z_$][\\w$]*\\s*\\.\\s*)+None\\b/m;\nconst MF_OVERLAY_ATTRIBUTE = 'data-edyn-mf-overlay';\n\ntype TTypeScriptMaskState = 'block-comment' | 'code' | 'double-quote' | 'line-comment' | 'single-quote' | 'template';\n\nconst maskTypeScriptCommentsAndStrings = (source: string): string => {\n let maskedSource = '';\n let state: TTypeScriptMaskState = 'code';\n let escaped = false;\n\n const maskCharacter = (character: string): string => {\n return character === '\\n' || character === '\\r' ? character : ' ';\n };\n\n for (let index = 0; index < source.length; index += 1) {\n const character = source[index] ?? '';\n const nextCharacter = source[index + 1];\n\n if (state === 'code') {\n if (character === '/' && nextCharacter === '/') {\n maskedSource += ' ';\n index += 1;\n state = 'line-comment';\n } else if (character === '/' && nextCharacter === '*') {\n maskedSource += ' ';\n index += 1;\n state = 'block-comment';\n } else if (character === \"'\") {\n maskedSource += ' ';\n state = 'single-quote';\n } else if (character === '\"') {\n maskedSource += ' ';\n state = 'double-quote';\n } else if (character === '`') {\n maskedSource += ' ';\n state = 'template';\n } else {\n maskedSource += character;\n }\n continue;\n }\n\n if (state === 'line-comment') {\n maskedSource += maskCharacter(character);\n if (character === '\\n' || character === '\\r') {\n state = 'code';\n }\n continue;\n }\n\n if (state === 'block-comment') {\n if (character === '*' && nextCharacter === '/') {\n maskedSource += ' ';\n index += 1;\n state = 'code';\n } else {\n maskedSource += maskCharacter(character);\n }\n continue;\n }\n\n maskedSource += maskCharacter(character);\n if (escaped) {\n escaped = false;\n } else if (character === '\\\\') {\n escaped = true;\n } else if (\n (state === 'single-quote' && character === \"'\") ||\n (state === 'double-quote' && character === '\"') ||\n (state === 'template' && character === '`')\n ) {\n state = 'code';\n }\n }\n\n return maskedSource;\n};\n\nconst isKeyframesRule = (rule: Rule): boolean => {\n const parent = rule.parent;\n return parent?.type === 'atrule' && /keyframes$/i.test(parent.name);\n};\n\nconst isRootNode = (node: selectorParser.Node): boolean => {\n return (\n (node.type === 'tag' && (node.value.toLowerCase() === 'html' || node.value.toLowerCase() === 'body')) ||\n (node.type === 'pseudo' && (node.value === ':root' || node.value === MF_ROOT_SELECTOR))\n );\n};\n\nconst isScopeNode = (node: selectorParser.Node | undefined, scopeId: string): boolean => {\n if (node?.type === 'attribute' && node.attribute === MF_SCOPE_ATTRIBUTE && node.operator === '=' && node.value === scopeId) {\n return true;\n }\n\n const normalized = node?.toString().replaceAll('\"', '').replaceAll(\"'\", '');\n return (\n node?.type === 'pseudo' &&\n (normalized === `:where([${MF_SCOPE_ATTRIBUTE}=${scopeId}])` ||\n normalized === `:where([${MF_SCOPE_ATTRIBUTE}=${scopeId}]:not([${MF_OVERLAY_ATTRIBUTE}]))`)\n );\n};\n\nconst startsWithHostPseudo = (selector: selectorParser.Selector): boolean => {\n return selector.first?.type === 'pseudo' && selector.first.value === ':host';\n};\n\nconst removeRootIdentityIds = (selector: selectorParser.Selector): void => {\n let compound: selectorParser.Node[] = [];\n const removeIdsFromRootCompound = (): void => {\n if (compound.some(isRootNode)) {\n for (const node of compound) {\n if (node.type === 'id') {\n node.remove();\n }\n }\n }\n };\n\n for (const node of [...selector.nodes]) {\n if (node.type === 'combinator') {\n removeIdsFromRootCompound();\n compound = [];\n } else {\n compound.push(node);\n }\n }\n removeIdsFromRootCompound();\n};\n\nconst isRootOnlySelector = (selector: selectorParser.Selector): boolean => {\n const compounds: selectorParser.Node[][] = [[]];\n\n for (const node of selector.nodes) {\n if (node.type === 'combinator') {\n compounds.push([]);\n } else {\n compounds.at(-1)?.push(node);\n }\n }\n\n return compounds.every((compound) => compound.some(isRootNode));\n};\n\nconst hasRootOnlySelector = (selectorList: string): boolean => {\n let result = false;\n selectorParser((root) => {\n result = root.nodes.some(isRootOnlySelector);\n }).processSync(selectorList);\n return result;\n};\n\nconst getAngularComponentSourcePath = (stylePath: string): string | undefined => {\n const cleanStylePath = stylePath.replace(/[?#].*$/, '');\n if (!ANGULAR_COMPONENT_STYLE_PATTERN.test(cleanStylePath)) {\n return undefined;\n }\n\n return cleanStylePath.replace(/\\.(?:css|less|sass|scss)$/i, '.ts');\n};\n\nconst usesViewEncapsulationNone = (stylePath: string): boolean => {\n const componentSourcePath = getAngularComponentSourcePath(stylePath);\n if (!componentSourcePath || !existsSync(componentSourcePath)) {\n return false;\n }\n\n const componentSource = readFileSync(componentSourcePath, 'utf8');\n return VIEW_ENCAPSULATION_NONE_PATTERN.test(maskTypeScriptCommentsAndStrings(componentSource));\n};\n\nexport const shouldUseAngularComponentScoping = (stylePath: string | undefined): boolean => {\n return !!stylePath && !!getAngularComponentSourcePath(stylePath) && !usesViewEncapsulationNone(stylePath);\n};\n\nconst scopeSelectorList = (selectorList: string, scopeId: string, scopeSelector: string, rootScopeSelectors: string[]): string => {\n return selectorParser((root) => {\n const sourceSelectors = [...root.nodes];\n\n for (const selector of sourceSelectors) {\n const rootNodes = selector.nodes.filter(isRootNode);\n\n if (rootNodes.length > 0) {\n const replacementSelectors = isRootOnlySelector(selector) ? rootScopeSelectors : [`[${MF_SCOPE_ATTRIBUTE}=\"${scopeId}\"]`];\n\n for (const replacementSelector of replacementSelectors) {\n const variant = selector.clone();\n removeRootIdentityIds(variant);\n const [firstRoot, ...duplicateRoots] = variant.nodes.filter(isRootNode);\n const scopeNode = selectorParser().astSync(replacementSelector).first.first.clone();\n firstRoot?.replaceWith(scopeNode);\n\n for (const duplicateRoot of duplicateRoots) {\n const previous = duplicateRoot.prev();\n if (previous?.type === 'combinator') {\n previous.remove();\n }\n duplicateRoot.remove();\n }\n\n root.insertBefore(selector, variant);\n }\n selector.remove();\n continue;\n }\n\n if (startsWithHostPseudo(selector) || isScopeNode(selector.first, scopeId)) {\n continue;\n }\n\n const first = selector.first;\n const needsBoundaryVariant = first?.type === 'universal' || (first?.type === 'pseudo' && first.value.startsWith('::'));\n\n if (needsBoundaryVariant) {\n const hasSiblingCombinator = selector.nodes.some((node) => node.type === 'combinator' && (node.value === '+' || node.value === '~'));\n\n if (!hasSiblingCombinator) {\n const boundaryVariant = selector.clone();\n const boundaryScope = selectorParser().astSync(scopeSelector).first.first.clone();\n boundaryVariant.first.rawSpaceBefore = '';\n if (boundaryVariant.first.type === 'universal') {\n boundaryVariant.first.replaceWith(boundaryScope);\n } else {\n boundaryVariant.prepend(boundaryScope);\n }\n root.insertBefore(selector, boundaryVariant);\n }\n }\n\n const descendantScope = selectorParser().astSync(`${scopeSelector} *`).first;\n const prefixNodes = descendantScope.nodes.slice(0, -1).map((node) => node.clone());\n selector.first.rawSpaceBefore = '';\n for (const prefixNode of prefixNodes.reverse()) {\n selector.prepend(prefixNode);\n }\n }\n\n const seenSelectors = new Set<string>();\n for (const selector of [...root.nodes]) {\n const normalizedSelector = selector.toString().trim();\n if (seenSelectors.has(normalizedSelector)) {\n selector.remove();\n } else {\n seenSelectors.add(normalizedSelector);\n }\n }\n }).processSync(selectorList);\n};\n\nconst findFunctionalPseudoEnd = (selector: string, openParenthesisIndex: number): number => {\n let depth = 0;\n let quote: '\"' | \"'\" | undefined;\n\n for (let index = openParenthesisIndex; index < selector.length; index += 1) {\n const character = selector[index];\n const previousCharacter = selector[index - 1];\n\n if (quote) {\n if (character === quote && previousCharacter !== '\\\\') {\n quote = undefined;\n }\n continue;\n }\n\n if (character === '\"' || character === \"'\") {\n quote = character;\n continue;\n }\n\n if (character === '(') {\n depth += 1;\n } else if (character === ')') {\n depth -= 1;\n if (depth === 0) {\n return index;\n }\n }\n }\n\n return -1;\n};\n\nconst scopeAngularSelector = (selector: string, boundarySelector: string): string => {\n const normalizedSelector = selector.trim();\n const angularBoundary = `:host-context(${boundarySelector})`;\n const normalizedBoundary = normalizedSelector.slice(0, angularBoundary.length).replaceAll(\"'\", '\"');\n\n if (normalizedBoundary === angularBoundary) {\n return normalizedSelector;\n }\n\n if (/^:host-context\\(/i.test(normalizedSelector)) {\n return `${angularBoundary}${normalizedSelector}`;\n }\n\n if (/^:host\\(/i.test(normalizedSelector)) {\n const openParenthesisIndex = normalizedSelector.indexOf('(');\n const closeParenthesisIndex = findFunctionalPseudoEnd(normalizedSelector, openParenthesisIndex);\n if (closeParenthesisIndex !== -1) {\n const hostSelector = normalizedSelector.slice(openParenthesisIndex + 1, closeParenthesisIndex);\n const remainder = normalizedSelector.slice(closeParenthesisIndex + 1);\n return list\n .comma(hostSelector)\n .map((hostSelectorVariant) => `${angularBoundary}${hostSelectorVariant}${remainder}`)\n .join(', ');\n }\n }\n\n if (/^:host\\b/i.test(normalizedSelector)) {\n return normalizedSelector.replace(/^:host\\b/i, angularBoundary);\n }\n\n return `${angularBoundary} ${normalizedSelector}`;\n};\n\nconst scopeAngularSelectorList = (selectorList: string, boundarySelector: string): string => {\n return list\n .comma(selectorList)\n .map((selector) => scopeAngularSelector(selector, boundarySelector))\n .join(', ');\n};\n\nconst namespaceKeyframes = (root: Root, keyframePrefix: string): void => {\n const keyframes = new Map<string, string>();\n\n root.walkAtRules((atRule) => {\n if (!/keyframes$/i.test(atRule.name) || atRule.params.startsWith(keyframePrefix)) {\n return;\n }\n\n const originalName = atRule.params.trim();\n const scopedName = `${keyframePrefix}${originalName}`;\n keyframes.set(originalName, scopedName);\n atRule.params = scopedName;\n });\n\n root.walkDecls((declaration) => {\n if (!/^(?:-webkit-)?animation(?:-name)?$/i.test(declaration.prop) && !declaration.prop.startsWith('--animate-')) {\n return;\n }\n\n const parsed = valueParser(declaration.value);\n parsed.walk((node) => {\n if (node.type === 'word') {\n node.value = keyframes.get(node.value) ?? node.value;\n }\n });\n declaration.value = parsed.toString();\n });\n};\n\nconst scopeGlobalRoot = (root: Root, scopeId: string, scopeSelector: string, keyframePrefix: string): void => {\n namespaceKeyframes(root, keyframePrefix);\n const contentRootSelector = `:where([${MF_SCOPE_ATTRIBUTE}=\"${scopeId}\"]:not([${MF_OVERLAY_ATTRIBUTE}]))`;\n root.walkRules((rule) => {\n if (!isKeyframesRule(rule)) {\n const declarations = rule.nodes.filter((node) => node.type === 'decl');\n const customProperties = declarations.filter((declaration) => declaration.prop.startsWith('--'));\n const standardDeclarations = declarations.filter((declaration) => !declaration.prop.startsWith('--'));\n\n if (customProperties.length > 0 && standardDeclarations.length > 0 && hasRootOnlySelector(rule.selector)) {\n const customPropertyRule = rule.cloneBefore();\n customPropertyRule.walkDecls((declaration) => {\n if (!declaration.prop.startsWith('--')) {\n declaration.remove();\n }\n });\n customPropertyRule.selector = scopeSelectorList(customPropertyRule.selector, scopeId, scopeSelector, [':host', scopeSelector]);\n rule.walkDecls((declaration) => {\n if (declaration.prop.startsWith('--')) {\n declaration.remove();\n }\n });\n }\n\n const containsOnlyCustomProperties = declarations.length > 0 && declarations.every((declaration) => declaration.prop.startsWith('--'));\n const rootScopeSelectors = containsOnlyCustomProperties ? [':host', scopeSelector] : [':host', contentRootSelector];\n rule.selector = scopeSelectorList(rule.selector, scopeId, scopeSelector, rootScopeSelectors);\n }\n });\n};\n\nconst scopeAngularComponentRoot = (root: Root, boundarySelector: string, keyframePrefix: string): void => {\n namespaceKeyframes(root, keyframePrefix);\n root.walkRules((rule) => {\n if (!isKeyframesRule(rule)) {\n rule.selector = scopeAngularSelectorList(rule.selector, boundarySelector);\n }\n });\n};\n\nexport const scopeRemoteCss = ({ scopeId }: IScopeRemoteCssOptions): Plugin => {\n const validScopeId = validateMfScopeId(scopeId);\n const scopeSelector = getMfScopeSelector(validScopeId);\n const keyframePrefix = `edyn-mf-${validScopeId}--`;\n\n return {\n postcssPlugin: `edyn-mf-isolation-${validScopeId}`,\n Once(root) {\n scopeGlobalRoot(root, validScopeId, scopeSelector, keyframePrefix);\n },\n };\n};\n\nexport const scopeAngularRemoteCss = ({ scopeId }: IScopeRemoteCssOptions): Plugin => {\n const validScopeId = validateMfScopeId(scopeId);\n const scopeSelector = getMfScopeSelector(validScopeId);\n const boundarySelector = `[${MF_SCOPE_ATTRIBUTE}=\"${validScopeId}\"]`;\n const keyframePrefix = `edyn-mf-${validScopeId}--`;\n\n return {\n postcssPlugin: `edyn-mf-angular-isolation-${validScopeId}`,\n Once(root) {\n if (shouldUseAngularComponentScoping(root.source?.input.file)) {\n scopeAngularComponentRoot(root, boundarySelector, keyframePrefix);\n return;\n }\n\n scopeGlobalRoot(root, validScopeId, scopeSelector, keyframePrefix);\n },\n };\n};\n"]}
1
+ {"version":3,"file":"postcss.js","sourceRoot":"","sources":["../src/postcss.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, readFileSync } from 'node:fs';\nimport { list, type Plugin, type Root, type Rule } from 'postcss';\nimport selectorParser from 'postcss-selector-parser';\nimport valueParser from 'postcss-value-parser';\nimport { getMfScopeSelector, MF_ROOT_SELECTOR, MF_SCOPE_ATTRIBUTE, validateMfScopeId } from './index.js';\n\nexport interface IScopeRemoteCssOptions {\n scopeId: string;\n}\n\nconst ANGULAR_COMPONENT_STYLE_PATTERN = /\\.component\\.(?:css|less|sass|scss)$/i;\nconst VIEW_ENCAPSULATION_NONE_PATTERN = /(?:^|[,{])\\s*encapsulation\\s*:\\s*(?:[A-Za-z_$][\\w$]*\\s*\\.\\s*)+None\\b/m;\nconst MF_OVERLAY_ATTRIBUTE = 'data-edyn-mf-overlay';\n\ntype TTypeScriptMaskState = 'block-comment' | 'code' | 'double-quote' | 'line-comment' | 'single-quote' | 'template';\n\nconst maskTypeScriptCommentsAndStrings = (source: string): string => {\n let maskedSource = '';\n let state: TTypeScriptMaskState = 'code';\n let escaped = false;\n\n const maskCharacter = (character: string): string => {\n return character === '\\n' || character === '\\r' ? character : ' ';\n };\n\n for (let index = 0; index < source.length; index += 1) {\n const character = source[index] ?? '';\n const nextCharacter = source[index + 1];\n\n if (state === 'code') {\n if (character === '/' && nextCharacter === '/') {\n maskedSource += ' ';\n index += 1;\n state = 'line-comment';\n } else if (character === '/' && nextCharacter === '*') {\n maskedSource += ' ';\n index += 1;\n state = 'block-comment';\n } else if (character === \"'\") {\n maskedSource += ' ';\n state = 'single-quote';\n } else if (character === '\"') {\n maskedSource += ' ';\n state = 'double-quote';\n } else if (character === '`') {\n maskedSource += ' ';\n state = 'template';\n } else {\n maskedSource += character;\n }\n continue;\n }\n\n if (state === 'line-comment') {\n maskedSource += maskCharacter(character);\n if (character === '\\n' || character === '\\r') {\n state = 'code';\n }\n continue;\n }\n\n if (state === 'block-comment') {\n if (character === '*' && nextCharacter === '/') {\n maskedSource += ' ';\n index += 1;\n state = 'code';\n } else {\n maskedSource += maskCharacter(character);\n }\n continue;\n }\n\n maskedSource += maskCharacter(character);\n if (escaped) {\n escaped = false;\n } else if (character === '\\\\') {\n escaped = true;\n } else if (\n (state === 'single-quote' && character === \"'\") ||\n (state === 'double-quote' && character === '\"') ||\n (state === 'template' && character === '`')\n ) {\n state = 'code';\n }\n }\n\n return maskedSource;\n};\n\nconst isKeyframesRule = (rule: Rule): boolean => {\n const parent = rule.parent;\n return parent?.type === 'atrule' && /keyframes$/i.test(parent.name);\n};\n\nconst isRootNode = (node: selectorParser.Node): boolean => {\n return (\n (node.type === 'tag' && (node.value.toLowerCase() === 'html' || node.value.toLowerCase() === 'body')) ||\n (node.type === 'pseudo' && (node.value === ':root' || node.value === MF_ROOT_SELECTOR))\n );\n};\n\nconst isScopeNode = (node: selectorParser.Node | undefined, scopeId: string): boolean => {\n if (node?.type === 'attribute' && node.attribute === MF_SCOPE_ATTRIBUTE && node.operator === '=' && node.value === scopeId) {\n return true;\n }\n\n const normalized = node?.toString().replaceAll('\"', '').replaceAll(\"'\", '');\n return (\n node?.type === 'pseudo' &&\n (normalized === `:where([${MF_SCOPE_ATTRIBUTE}=${scopeId}])` ||\n normalized === `:where([${MF_SCOPE_ATTRIBUTE}=${scopeId}]:not([${MF_OVERLAY_ATTRIBUTE}]))`)\n );\n};\n\nconst startsWithHostPseudo = (selector: selectorParser.Selector): boolean => {\n return selector.first?.type === 'pseudo' && selector.first.value === ':host';\n};\n\nconst removeRootIdentityIds = (selector: selectorParser.Selector): void => {\n let compound: selectorParser.Node[] = [];\n const removeIdsFromRootCompound = (): void => {\n if (compound.some(isRootNode)) {\n for (const node of compound) {\n if (node.type === 'id') {\n node.remove();\n }\n }\n }\n };\n\n for (const node of [...selector.nodes]) {\n if (node.type === 'combinator') {\n removeIdsFromRootCompound();\n compound = [];\n } else {\n compound.push(node);\n }\n }\n removeIdsFromRootCompound();\n};\n\nconst SPECIFICITY_CARRIER = 'edyn-mf-root';\n\n// Legacy rules such as `html body button` or `html body#app .mdc-checkbox__background` are weighed against Angular\n// Material's own rules by the html, body and #app they start from, so the scope that replaces that root must weigh\n// exactly the same. A plain scope attribute (0,1,0) drops the id of `body#app`, letting Material's checked colour win,\n// and outweighs the two types of `html body`, letting an override that lost to `.mat-mdc-button` on the old site win\n// hosted. The root becomes :where(<scope>):not(<carrier>): :where() weighs nothing, and the carrier has the same id,\n// class and type counts as the root part it replaces and never matches the scope element, so :not() always matches and\n// weighs exactly that. Neutral names keep `html`, `body` and `#app` out of the emitted CSS.\nconst rootSpecificityCarrier = (selector: selectorParser.Selector): string => {\n const compounds: selectorParser.Node[][] = [[]];\n for (const node of selector.nodes) {\n if (node.type === 'combinator') {\n compounds.push([]);\n } else {\n compounds.at(-1)?.push(node);\n }\n }\n\n const carrier: string[] = [];\n for (const compound of compounds) {\n if (!compound.some(isRootNode)) {\n continue;\n }\n const types = compound.filter((node) => node.type === 'tag' && isRootNode(node)).length;\n const pseudoRoots = compound.filter((node) => node.type === 'pseudo' && isRootNode(node)).length;\n const ids = compound.filter((node) => node.type === 'id').length;\n carrier.push(\n `${SPECIFICITY_CARRIER.repeat(Math.min(types, 1))}${`.${SPECIFICITY_CARRIER}`.repeat(pseudoRoots)}${`#${SPECIFICITY_CARRIER}`.repeat(ids)}`,\n );\n }\n\n return carrier.filter(Boolean).join(' ');\n};\n\nconst rootedDescendantScope = (selector: selectorParser.Selector, scopeId: string): string => {\n return `:where([${MF_SCOPE_ATTRIBUTE}=\"${scopeId}\"]):not(${rootSpecificityCarrier(selector)})`;\n};\n\nconst isRootOnlySelector = (selector: selectorParser.Selector): boolean => {\n const compounds: selectorParser.Node[][] = [[]];\n\n for (const node of selector.nodes) {\n if (node.type === 'combinator') {\n compounds.push([]);\n } else {\n compounds.at(-1)?.push(node);\n }\n }\n\n return compounds.every((compound) => compound.some(isRootNode));\n};\n\nconst hasRootOnlySelector = (selectorList: string): boolean => {\n let result = false;\n selectorParser((root) => {\n result = root.nodes.some(isRootOnlySelector);\n }).processSync(selectorList);\n return result;\n};\n\nconst getAngularComponentSourcePath = (stylePath: string): string | undefined => {\n const cleanStylePath = stylePath.replace(/[?#].*$/, '');\n if (!ANGULAR_COMPONENT_STYLE_PATTERN.test(cleanStylePath)) {\n return undefined;\n }\n\n return cleanStylePath.replace(/\\.(?:css|less|sass|scss)$/i, '.ts');\n};\n\nconst usesViewEncapsulationNone = (stylePath: string): boolean => {\n const componentSourcePath = getAngularComponentSourcePath(stylePath);\n if (!componentSourcePath || !existsSync(componentSourcePath)) {\n return false;\n }\n\n const componentSource = readFileSync(componentSourcePath, 'utf8');\n return VIEW_ENCAPSULATION_NONE_PATTERN.test(maskTypeScriptCommentsAndStrings(componentSource));\n};\n\nexport const shouldUseAngularComponentScoping = (stylePath: string | undefined): boolean => {\n return !!stylePath && !!getAngularComponentSourcePath(stylePath) && !usesViewEncapsulationNone(stylePath);\n};\n\nconst scopeSelectorList = (selectorList: string, scopeId: string, scopeSelector: string, rootScopeSelectors: string[]): string => {\n return selectorParser((root) => {\n const sourceSelectors = [...root.nodes];\n\n for (const selector of sourceSelectors) {\n const rootNodes = selector.nodes.filter(isRootNode);\n\n if (rootNodes.length > 0) {\n const replacementSelectors = isRootOnlySelector(selector) ? rootScopeSelectors : [rootedDescendantScope(selector, scopeId)];\n\n for (const replacementSelector of replacementSelectors) {\n const variant = selector.clone();\n removeRootIdentityIds(variant);\n const [firstRoot, ...duplicateRoots] = variant.nodes.filter(isRootNode);\n // The replacement can be a compound of several nodes, e.g. :where(<scope>):not(<carrier>).\n const scopeNodes = selectorParser()\n .astSync(replacementSelector)\n .first.nodes.map((node) => node.clone());\n const [scopeNode, ...followingScopeNodes] = scopeNodes;\n if (firstRoot && scopeNode) {\n firstRoot.replaceWith(scopeNode);\n let previous = scopeNode;\n for (const node of followingScopeNodes) {\n variant.insertAfter(previous, node);\n previous = node;\n }\n }\n\n for (const duplicateRoot of duplicateRoots) {\n const previous = duplicateRoot.prev();\n if (previous?.type === 'combinator') {\n previous.remove();\n }\n duplicateRoot.remove();\n }\n\n root.insertBefore(selector, variant);\n }\n selector.remove();\n continue;\n }\n\n if (startsWithHostPseudo(selector) || isScopeNode(selector.first, scopeId)) {\n continue;\n }\n\n const first = selector.first;\n const needsBoundaryVariant = first?.type === 'universal' || (first?.type === 'pseudo' && first.value.startsWith('::'));\n\n if (needsBoundaryVariant) {\n const hasSiblingCombinator = selector.nodes.some((node) => node.type === 'combinator' && (node.value === '+' || node.value === '~'));\n\n if (!hasSiblingCombinator) {\n const boundaryVariant = selector.clone();\n const boundaryScope = selectorParser().astSync(scopeSelector).first.first.clone();\n boundaryVariant.first.rawSpaceBefore = '';\n if (boundaryVariant.first.type === 'universal') {\n boundaryVariant.first.replaceWith(boundaryScope);\n } else {\n boundaryVariant.prepend(boundaryScope);\n }\n root.insertBefore(selector, boundaryVariant);\n }\n }\n\n const descendantScope = selectorParser().astSync(`${scopeSelector} *`).first;\n const prefixNodes = descendantScope.nodes.slice(0, -1).map((node) => node.clone());\n selector.first.rawSpaceBefore = '';\n for (const prefixNode of prefixNodes.reverse()) {\n selector.prepend(prefixNode);\n }\n }\n\n const seenSelectors = new Set<string>();\n for (const selector of [...root.nodes]) {\n const normalizedSelector = selector.toString().trim();\n if (seenSelectors.has(normalizedSelector)) {\n selector.remove();\n } else {\n seenSelectors.add(normalizedSelector);\n }\n }\n }).processSync(selectorList);\n};\n\nconst findFunctionalPseudoEnd = (selector: string, openParenthesisIndex: number): number => {\n let depth = 0;\n let quote: '\"' | \"'\" | undefined;\n\n for (let index = openParenthesisIndex; index < selector.length; index += 1) {\n const character = selector[index];\n const previousCharacter = selector[index - 1];\n\n if (quote) {\n if (character === quote && previousCharacter !== '\\\\') {\n quote = undefined;\n }\n continue;\n }\n\n if (character === '\"' || character === \"'\") {\n quote = character;\n continue;\n }\n\n if (character === '(') {\n depth += 1;\n } else if (character === ')') {\n depth -= 1;\n if (depth === 0) {\n return index;\n }\n }\n }\n\n return -1;\n};\n\nconst scopeAngularSelector = (selector: string, boundarySelector: string): string => {\n const normalizedSelector = selector.trim();\n const angularBoundary = `:host-context(${boundarySelector})`;\n const normalizedBoundary = normalizedSelector.slice(0, angularBoundary.length).replaceAll(\"'\", '\"');\n\n if (normalizedBoundary === angularBoundary) {\n return normalizedSelector;\n }\n\n if (/^:host-context\\(/i.test(normalizedSelector)) {\n return `${angularBoundary}${normalizedSelector}`;\n }\n\n if (/^:host\\(/i.test(normalizedSelector)) {\n const openParenthesisIndex = normalizedSelector.indexOf('(');\n const closeParenthesisIndex = findFunctionalPseudoEnd(normalizedSelector, openParenthesisIndex);\n if (closeParenthesisIndex !== -1) {\n const hostSelector = normalizedSelector.slice(openParenthesisIndex + 1, closeParenthesisIndex);\n const remainder = normalizedSelector.slice(closeParenthesisIndex + 1);\n return list\n .comma(hostSelector)\n .map((hostSelectorVariant) => `${angularBoundary}${hostSelectorVariant}${remainder}`)\n .join(', ');\n }\n }\n\n if (/^:host\\b/i.test(normalizedSelector)) {\n return normalizedSelector.replace(/^:host\\b/i, angularBoundary);\n }\n\n return `${angularBoundary} ${normalizedSelector}`;\n};\n\nconst scopeAngularSelectorList = (selectorList: string, boundarySelector: string): string => {\n return list\n .comma(selectorList)\n .map((selector) => scopeAngularSelector(selector, boundarySelector))\n .join(', ');\n};\n\nconst namespaceKeyframes = (root: Root, keyframePrefix: string): void => {\n const keyframes = new Map<string, string>();\n\n root.walkAtRules((atRule) => {\n if (!/keyframes$/i.test(atRule.name) || atRule.params.startsWith(keyframePrefix)) {\n return;\n }\n\n const originalName = atRule.params.trim();\n const scopedName = `${keyframePrefix}${originalName}`;\n keyframes.set(originalName, scopedName);\n atRule.params = scopedName;\n });\n\n root.walkDecls((declaration) => {\n if (!/^(?:-webkit-)?animation(?:-name)?$/i.test(declaration.prop) && !declaration.prop.startsWith('--animate-')) {\n return;\n }\n\n const parsed = valueParser(declaration.value);\n parsed.walk((node) => {\n if (node.type === 'word') {\n node.value = keyframes.get(node.value) ?? node.value;\n }\n });\n declaration.value = parsed.toString();\n });\n};\n\nconst scopeGlobalRoot = (root: Root, scopeId: string, scopeSelector: string, keyframePrefix: string): void => {\n namespaceKeyframes(root, keyframePrefix);\n const contentRootSelector = `:where([${MF_SCOPE_ATTRIBUTE}=\"${scopeId}\"]:not([${MF_OVERLAY_ATTRIBUTE}]))`;\n root.walkRules((rule) => {\n if (!isKeyframesRule(rule)) {\n const declarations = rule.nodes.filter((node) => node.type === 'decl');\n const customProperties = declarations.filter((declaration) => declaration.prop.startsWith('--'));\n const standardDeclarations = declarations.filter((declaration) => !declaration.prop.startsWith('--'));\n\n if (customProperties.length > 0 && standardDeclarations.length > 0 && hasRootOnlySelector(rule.selector)) {\n const customPropertyRule = rule.cloneBefore();\n customPropertyRule.walkDecls((declaration) => {\n if (!declaration.prop.startsWith('--')) {\n declaration.remove();\n }\n });\n customPropertyRule.selector = scopeSelectorList(customPropertyRule.selector, scopeId, scopeSelector, [':host', scopeSelector]);\n rule.walkDecls((declaration) => {\n if (declaration.prop.startsWith('--')) {\n declaration.remove();\n }\n });\n }\n\n const containsOnlyCustomProperties = declarations.length > 0 && declarations.every((declaration) => declaration.prop.startsWith('--'));\n const rootScopeSelectors = containsOnlyCustomProperties ? [':host', scopeSelector] : [':host', contentRootSelector];\n rule.selector = scopeSelectorList(rule.selector, scopeId, scopeSelector, rootScopeSelectors);\n }\n });\n};\n\nconst scopeAngularComponentRoot = (root: Root, boundarySelector: string, keyframePrefix: string): void => {\n namespaceKeyframes(root, keyframePrefix);\n root.walkRules((rule) => {\n if (!isKeyframesRule(rule)) {\n rule.selector = scopeAngularSelectorList(rule.selector, boundarySelector);\n }\n });\n};\n\nexport const scopeRemoteCss = ({ scopeId }: IScopeRemoteCssOptions): Plugin => {\n const validScopeId = validateMfScopeId(scopeId);\n const scopeSelector = getMfScopeSelector(validScopeId);\n const keyframePrefix = `edyn-mf-${validScopeId}--`;\n\n return {\n postcssPlugin: `edyn-mf-isolation-${validScopeId}`,\n Once(root) {\n scopeGlobalRoot(root, validScopeId, scopeSelector, keyframePrefix);\n },\n };\n};\n\nexport const scopeAngularRemoteCss = ({ scopeId }: IScopeRemoteCssOptions): Plugin => {\n const validScopeId = validateMfScopeId(scopeId);\n const scopeSelector = getMfScopeSelector(validScopeId);\n const boundarySelector = `[${MF_SCOPE_ATTRIBUTE}=\"${validScopeId}\"]`;\n const keyframePrefix = `edyn-mf-${validScopeId}--`;\n\n return {\n postcssPlugin: `edyn-mf-angular-isolation-${validScopeId}`,\n Once(root) {\n if (shouldUseAngularComponentScoping(root.source?.input.file)) {\n scopeAngularComponentRoot(root, boundarySelector, keyframePrefix);\n return;\n }\n\n scopeGlobalRoot(root, validScopeId, scopeSelector, keyframePrefix);\n },\n };\n};\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@edynamix/mf-isolation",
3
- "version": "0.0.28",
3
+ "version": "0.0.30",
4
4
  "description": "CSS and overlay isolation helpers for eDynamix microfrontends.",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",