@edynamix/mf-isolation 0.0.27 → 0.0.29
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 +3 -1
- package/dist/angular-location.d.ts +2 -1
- package/dist/angular-location.d.ts.map +1 -1
- package/dist/angular-location.js +11 -0
- package/dist/angular-location.js.map +1 -1
- package/dist/postcss.d.ts.map +1 -1
- package/dist/postcss.js +41 -1
- package/dist/postcss.js.map +1 -1
- package/package.json +1 -1
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` instead use `[data-edyn-mf="<scope-id>"]` so module overrides retain sufficient cascade strength. When that root carries an id, as `body#app` does, the boundary becomes `:is([data-edyn-mf="<scope-id>"], edyn-mf-root edyn-mf-root#edyn-mf-root:not(*))`: the second argument never matches, but it gives the override the same id and type weight it had on the standalone page, so it still beats Angular Material's own rules.
|
|
41
41
|
|
|
42
42
|
### Angular with Vite
|
|
43
43
|
|
|
@@ -148,6 +148,8 @@ export class AppModule {}
|
|
|
148
148
|
|
|
149
149
|
The base is the module's `APP_BASE_HREF` (or the document's `<base>`); a root base (`/`) is left untouched. A host that redirects case variants of a module's path to lowercase can stop doing so once the module installs this strategy.
|
|
150
150
|
|
|
151
|
+
The strategy also passes the router only the address changes within the module's base and aliases. In a host, Back or Forward to another module changes the address before the module is unmounted; the module's router would otherwise take that address for one of its own and either log `NG04002` (no match) or write it back under the module's base (a catch-all or redirect), leaving the page in the wrong module.
|
|
152
|
+
|
|
151
153
|
## Angular CDK overlays
|
|
152
154
|
|
|
153
155
|
The Angular integration targets Angular/CDK 19.x. In a hosted application, install the complete provider array so global and connected overlays share the module boundary's viewport and coordinate system:
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PathLocationStrategy, PlatformLocation } from '@angular/common';
|
|
1
|
+
import { type LocationChangeListener, PathLocationStrategy, PlatformLocation } from '@angular/common';
|
|
2
2
|
import { type StaticProvider } from '@angular/core';
|
|
3
3
|
export declare class CaseInsensitiveBasePathLocationStrategy extends PathLocationStrategy {
|
|
4
4
|
private readonly addressLocation;
|
|
@@ -7,6 +7,7 @@ export declare class CaseInsensitiveBasePathLocationStrategy extends PathLocatio
|
|
|
7
7
|
constructor(platformLocation: PlatformLocation, href?: string, aliases?: readonly string[]);
|
|
8
8
|
path(includeHash?: boolean): string;
|
|
9
9
|
prepareExternalUrl(internal: string): string;
|
|
10
|
+
onPopState(fn: LocationChangeListener): void;
|
|
10
11
|
}
|
|
11
12
|
export declare const provideCaseInsensitiveBasePath: (aliases?: readonly string[]) => StaticProvider[];
|
|
12
13
|
//# sourceMappingURL=angular-location.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"angular-location.d.ts","sourceRoot":"","sources":["../src/angular-location.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"angular-location.d.ts","sourceRoot":"","sources":["../src/angular-location.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,sBAAsB,EAAoB,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACvI,OAAO,EAAoB,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AAOtE,qBAAa,uCAAwC,SAAQ,oBAAoB;IAC/E,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAmB;IACnD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAoB;gBAE9B,gBAAgB,EAAE,gBAAgB,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,OAAO,GAAE,SAAS,MAAM,EAAO;IAOrF,IAAI,CAAC,WAAW,UAAQ,GAAG,MAAM;IAIjC,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;IAS5C,UAAU,CAAC,EAAE,EAAE,sBAAsB,GAAG,IAAI;CAOtD;AAGD,eAAO,MAAM,8BAA8B,GAAI,UAAS,SAAS,MAAM,EAAO,KAAG,cAAc,EAO9F,CAAC","sourcesContent":["import { APP_BASE_HREF, type LocationChangeListener, LocationStrategy, PathLocationStrategy, PlatformLocation } from '@angular/common';\nimport { Inject, Optional, type StaticProvider } from '@angular/core';\n\n// IIS serves a module at any letter case of its path, and old bookmarks keep the old case (/AutoPoint/...), but Angular's\n// Location strips the base only on an exact, case-sensitive match, so such an address showed the module's 404 page.\n// This strategy reads the address with the base in its configured case and writes addresses with the base in the case\n// the address bar shows, so /AutoPoint/... and /autopoint/... both work and stay as typed, without a redirect. Aliases\n// are earlier names of the module's path (motcleanse for autocleanse, for example) that open it the same way.\nexport class CaseInsensitiveBasePathLocationStrategy extends PathLocationStrategy {\n private readonly addressLocation: PlatformLocation;\n private readonly base: string;\n private readonly bases: readonly string[];\n\n constructor(platformLocation: PlatformLocation, href?: string, aliases: readonly string[] = []) {\n super(platformLocation, href);\n this.addressLocation = platformLocation;\n this.base = withoutTrailingSlash(this.getBaseHref());\n this.bases = this.base ? [this.base, ...aliases.map(aliasBase)] : [];\n }\n\n override path(includeHash = false): string {\n return replaceBase(super.path(includeHash), this.bases, this.base);\n }\n\n override prepareExternalUrl(internal: string): string {\n const addressBase = matchedBasePrefix(this.addressLocation.pathname, this.bases) ?? this.base;\n return replaceBase(super.prepareExternalUrl(internal), this.bases, addressBase);\n }\n\n // In the host, Back or Forward to another module changes the address before this module is unmounted. Its router\n // would take that address for one of its own: no match logs NG04002, and a catch-all or redirect writes it back\n // under this module's base, so the page leaves the module it was going to. Changes to an address outside the base\n // and its aliases are not passed on; without a base (the development root), every change is.\n override onPopState(fn: LocationChangeListener): void {\n super.onPopState((event) => {\n if (this.bases.length === 0 || matchedBasePrefix(this.addressLocation.pathname, this.bases) !== undefined) {\n fn(event);\n }\n });\n }\n}\n\n// The module's LocationStrategy: its base path (APP_BASE_HREF, or the document's <base>) in any letter case, plus aliases.\nexport const provideCaseInsensitiveBasePath = (aliases: readonly string[] = []): StaticProvider[] => [\n {\n provide: LocationStrategy,\n useFactory: (platformLocation: PlatformLocation, href: string | null) =>\n new CaseInsensitiveBasePathLocationStrategy(platformLocation, href ?? undefined, aliases),\n deps: [PlatformLocation, [new Optional(), new Inject(APP_BASE_HREF)]],\n },\n];\n\n// The start of path that is one of bases in any letter case, followed by the end of the path or a path, query, fragment\n// or matrix separator; undefined when path starts with none of them.\nconst matchedBasePrefix = (path: string, bases: readonly string[]): string | undefined => {\n for (const base of bases) {\n const prefix = path.slice(0, base.length);\n const next = path.charAt(base.length);\n if (base && prefix.toLowerCase() === base.toLowerCase() && (next === '' || '/?#;'.includes(next))) {\n return prefix;\n }\n }\n\n return undefined;\n};\n\nconst replaceBase = (path: string, bases: readonly string[], base: string): string => {\n const prefix = matchedBasePrefix(path, bases);\n return prefix === undefined ? path : base + path.slice(prefix.length);\n};\n\nconst aliasBase = (alias: string): string => `/${alias.replace(/^\\/+|\\/+$/g, '')}`;\n\nconst withoutTrailingSlash = (href: string): string => href.replace(/\\/+$/, '');\n"]}
|
package/dist/angular-location.js
CHANGED
|
@@ -22,6 +22,17 @@ export class CaseInsensitiveBasePathLocationStrategy extends PathLocationStrateg
|
|
|
22
22
|
const addressBase = matchedBasePrefix(this.addressLocation.pathname, this.bases) ?? this.base;
|
|
23
23
|
return replaceBase(super.prepareExternalUrl(internal), this.bases, addressBase);
|
|
24
24
|
}
|
|
25
|
+
// In the host, Back or Forward to another module changes the address before this module is unmounted. Its router
|
|
26
|
+
// would take that address for one of its own: no match logs NG04002, and a catch-all or redirect writes it back
|
|
27
|
+
// under this module's base, so the page leaves the module it was going to. Changes to an address outside the base
|
|
28
|
+
// and its aliases are not passed on; without a base (the development root), every change is.
|
|
29
|
+
onPopState(fn) {
|
|
30
|
+
super.onPopState((event) => {
|
|
31
|
+
if (this.bases.length === 0 || matchedBasePrefix(this.addressLocation.pathname, this.bases) !== undefined) {
|
|
32
|
+
fn(event);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
}
|
|
25
36
|
}
|
|
26
37
|
// The module's LocationStrategy: its base path (APP_BASE_HREF, or the document's <base>) in any letter case, plus aliases.
|
|
27
38
|
export const provideCaseInsensitiveBasePath = (aliases = []) => [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"angular-location.js","sourceRoot":"","sources":["../src/angular-location.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,
|
|
1
|
+
{"version":3,"file":"angular-location.js","sourceRoot":"","sources":["../src/angular-location.ts"],"names":[],"mappings":"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","sourcesContent":["import { APP_BASE_HREF, type LocationChangeListener, LocationStrategy, PathLocationStrategy, PlatformLocation } from '@angular/common';\nimport { Inject, Optional, type StaticProvider } from '@angular/core';\n\n// IIS serves a module at any letter case of its path, and old bookmarks keep the old case (/AutoPoint/...), but Angular's\n// Location strips the base only on an exact, case-sensitive match, so such an address showed the module's 404 page.\n// This strategy reads the address with the base in its configured case and writes addresses with the base in the case\n// the address bar shows, so /AutoPoint/... and /autopoint/... both work and stay as typed, without a redirect. Aliases\n// are earlier names of the module's path (motcleanse for autocleanse, for example) that open it the same way.\nexport class CaseInsensitiveBasePathLocationStrategy extends PathLocationStrategy {\n private readonly addressLocation: PlatformLocation;\n private readonly base: string;\n private readonly bases: readonly string[];\n\n constructor(platformLocation: PlatformLocation, href?: string, aliases: readonly string[] = []) {\n super(platformLocation, href);\n this.addressLocation = platformLocation;\n this.base = withoutTrailingSlash(this.getBaseHref());\n this.bases = this.base ? [this.base, ...aliases.map(aliasBase)] : [];\n }\n\n override path(includeHash = false): string {\n return replaceBase(super.path(includeHash), this.bases, this.base);\n }\n\n override prepareExternalUrl(internal: string): string {\n const addressBase = matchedBasePrefix(this.addressLocation.pathname, this.bases) ?? this.base;\n return replaceBase(super.prepareExternalUrl(internal), this.bases, addressBase);\n }\n\n // In the host, Back or Forward to another module changes the address before this module is unmounted. Its router\n // would take that address for one of its own: no match logs NG04002, and a catch-all or redirect writes it back\n // under this module's base, so the page leaves the module it was going to. Changes to an address outside the base\n // and its aliases are not passed on; without a base (the development root), every change is.\n override onPopState(fn: LocationChangeListener): void {\n super.onPopState((event) => {\n if (this.bases.length === 0 || matchedBasePrefix(this.addressLocation.pathname, this.bases) !== undefined) {\n fn(event);\n }\n });\n }\n}\n\n// The module's LocationStrategy: its base path (APP_BASE_HREF, or the document's <base>) in any letter case, plus aliases.\nexport const provideCaseInsensitiveBasePath = (aliases: readonly string[] = []): StaticProvider[] => [\n {\n provide: LocationStrategy,\n useFactory: (platformLocation: PlatformLocation, href: string | null) =>\n new CaseInsensitiveBasePathLocationStrategy(platformLocation, href ?? undefined, aliases),\n deps: [PlatformLocation, [new Optional(), new Inject(APP_BASE_HREF)]],\n },\n];\n\n// The start of path that is one of bases in any letter case, followed by the end of the path or a path, query, fragment\n// or matrix separator; undefined when path starts with none of them.\nconst matchedBasePrefix = (path: string, bases: readonly string[]): string | undefined => {\n for (const base of bases) {\n const prefix = path.slice(0, base.length);\n const next = path.charAt(base.length);\n if (base && prefix.toLowerCase() === base.toLowerCase() && (next === '' || '/?#;'.includes(next))) {\n return prefix;\n }\n }\n\n return undefined;\n};\n\nconst replaceBase = (path: string, bases: readonly string[], base: string): string => {\n const prefix = matchedBasePrefix(path, bases);\n return prefix === undefined ? path : base + path.slice(prefix.length);\n};\n\nconst aliasBase = (alias: string): string => `/${alias.replace(/^\\/+|\\/+$/g, '')}`;\n\nconst withoutTrailingSlash = (href: string): string => href.replace(/\\/+$/, '');\n"]}
|
package/dist/postcss.d.ts.map
CHANGED
|
@@ -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;AA6ND,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 // A rooted boundary written by rootedDescendantScope(): :is(<scope>, <specificity carrier>).\n if (node?.type === 'pseudo' && node.value === ':is' && node.nodes[0]?.nodes.length === 1 && isScopeNode(node.nodes[0].first, 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 overrides such as `html body#app .mdc-checkbox__background` won over Angular Material's own rules through the\n// id and types of the document root they start from. Replacing that root with the scope attribute alone drops the id,\n// so Material wins again. This carrier has the same id, class and type counts as the root part it replaces; inside\n// :is(<scope>, <carrier>) it never matches (`:not(*)`), and :is() takes its strongest argument's specificity. Only roots\n// with an id need it: without one the scope attribute already outweighs them. Neutral names keep `html`, `body` and\n// `#app` out of the emitted CSS.\nconst rootSpecificityCarrier = (selector: selectorParser.Selector): string | undefined => {\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 let ids = 0;\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 compoundIds = compound.filter((node) => node.type === 'id').length;\n ids += compoundIds;\n carrier.push(\n `${SPECIFICITY_CARRIER.repeat(Math.min(types, 1))}${`.${SPECIFICITY_CARRIER}`.repeat(pseudoRoots)}${`#${SPECIFICITY_CARRIER}`.repeat(compoundIds)}`,\n );\n }\n\n return ids > 0 ? `${carrier.filter(Boolean).join(' ')}:not(*)` : undefined;\n};\n\nconst rootedDescendantScope = (selector: selectorParser.Selector, scopeId: string): string => {\n const scope = `[${MF_SCOPE_ATTRIBUTE}=\"${scopeId}\"]`;\n const carrier = rootSpecificityCarrier(selector);\n return carrier ? `:is(${scope}, ${carrier})` : scope;\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 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"]}
|
package/dist/postcss.js
CHANGED
|
@@ -89,6 +89,10 @@ const isScopeNode = (node, scopeId) => {
|
|
|
89
89
|
if (node?.type === 'attribute' && node.attribute === MF_SCOPE_ATTRIBUTE && node.operator === '=' && node.value === scopeId) {
|
|
90
90
|
return true;
|
|
91
91
|
}
|
|
92
|
+
// A rooted boundary written by rootedDescendantScope(): :is(<scope>, <specificity carrier>).
|
|
93
|
+
if (node?.type === 'pseudo' && node.value === ':is' && node.nodes[0]?.nodes.length === 1 && isScopeNode(node.nodes[0].first, scopeId)) {
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
92
96
|
const normalized = node?.toString().replaceAll('"', '').replaceAll("'", '');
|
|
93
97
|
return (node?.type === 'pseudo' &&
|
|
94
98
|
(normalized === `:where([${MF_SCOPE_ATTRIBUTE}=${scopeId}])` ||
|
|
@@ -119,6 +123,42 @@ const removeRootIdentityIds = (selector) => {
|
|
|
119
123
|
}
|
|
120
124
|
removeIdsFromRootCompound();
|
|
121
125
|
};
|
|
126
|
+
const SPECIFICITY_CARRIER = 'edyn-mf-root';
|
|
127
|
+
// Legacy overrides such as `html body#app .mdc-checkbox__background` won over Angular Material's own rules through the
|
|
128
|
+
// id and types of the document root they start from. Replacing that root with the scope attribute alone drops the id,
|
|
129
|
+
// so Material wins again. This carrier has the same id, class and type counts as the root part it replaces; inside
|
|
130
|
+
// :is(<scope>, <carrier>) it never matches (`:not(*)`), and :is() takes its strongest argument's specificity. Only roots
|
|
131
|
+
// with an id need it: without one the scope attribute already outweighs them. Neutral names keep `html`, `body` and
|
|
132
|
+
// `#app` out of the emitted CSS.
|
|
133
|
+
const rootSpecificityCarrier = (selector) => {
|
|
134
|
+
const compounds = [[]];
|
|
135
|
+
for (const node of selector.nodes) {
|
|
136
|
+
if (node.type === 'combinator') {
|
|
137
|
+
compounds.push([]);
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
compounds.at(-1)?.push(node);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
let ids = 0;
|
|
144
|
+
const carrier = [];
|
|
145
|
+
for (const compound of compounds) {
|
|
146
|
+
if (!compound.some(isRootNode)) {
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
const types = compound.filter((node) => node.type === 'tag' && isRootNode(node)).length;
|
|
150
|
+
const pseudoRoots = compound.filter((node) => node.type === 'pseudo' && isRootNode(node)).length;
|
|
151
|
+
const compoundIds = compound.filter((node) => node.type === 'id').length;
|
|
152
|
+
ids += compoundIds;
|
|
153
|
+
carrier.push(`${SPECIFICITY_CARRIER.repeat(Math.min(types, 1))}${`.${SPECIFICITY_CARRIER}`.repeat(pseudoRoots)}${`#${SPECIFICITY_CARRIER}`.repeat(compoundIds)}`);
|
|
154
|
+
}
|
|
155
|
+
return ids > 0 ? `${carrier.filter(Boolean).join(' ')}:not(*)` : undefined;
|
|
156
|
+
};
|
|
157
|
+
const rootedDescendantScope = (selector, scopeId) => {
|
|
158
|
+
const scope = `[${MF_SCOPE_ATTRIBUTE}="${scopeId}"]`;
|
|
159
|
+
const carrier = rootSpecificityCarrier(selector);
|
|
160
|
+
return carrier ? `:is(${scope}, ${carrier})` : scope;
|
|
161
|
+
};
|
|
122
162
|
const isRootOnlySelector = (selector) => {
|
|
123
163
|
const compounds = [[]];
|
|
124
164
|
for (const node of selector.nodes) {
|
|
@@ -162,7 +202,7 @@ const scopeSelectorList = (selectorList, scopeId, scopeSelector, rootScopeSelect
|
|
|
162
202
|
for (const selector of sourceSelectors) {
|
|
163
203
|
const rootNodes = selector.nodes.filter(isRootNode);
|
|
164
204
|
if (rootNodes.length > 0) {
|
|
165
|
-
const replacementSelectors = isRootOnlySelector(selector) ? rootScopeSelectors : [
|
|
205
|
+
const replacementSelectors = isRootOnlySelector(selector) ? rootScopeSelectors : [rootedDescendantScope(selector, scopeId)];
|
|
166
206
|
for (const replacementSelector of replacementSelectors) {
|
|
167
207
|
const variant = selector.clone();
|
|
168
208
|
removeRootIdentityIds(variant);
|
package/dist/postcss.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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 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 // A rooted boundary written by rootedDescendantScope(): :is(<scope>, <specificity carrier>).\n if (node?.type === 'pseudo' && node.value === ':is' && node.nodes[0]?.nodes.length === 1 && isScopeNode(node.nodes[0].first, 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 overrides such as `html body#app .mdc-checkbox__background` won over Angular Material's own rules through the\n// id and types of the document root they start from. Replacing that root with the scope attribute alone drops the id,\n// so Material wins again. This carrier has the same id, class and type counts as the root part it replaces; inside\n// :is(<scope>, <carrier>) it never matches (`:not(*)`), and :is() takes its strongest argument's specificity. Only roots\n// with an id need it: without one the scope attribute already outweighs them. Neutral names keep `html`, `body` and\n// `#app` out of the emitted CSS.\nconst rootSpecificityCarrier = (selector: selectorParser.Selector): string | undefined => {\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 let ids = 0;\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 compoundIds = compound.filter((node) => node.type === 'id').length;\n ids += compoundIds;\n carrier.push(\n `${SPECIFICITY_CARRIER.repeat(Math.min(types, 1))}${`.${SPECIFICITY_CARRIER}`.repeat(pseudoRoots)}${`#${SPECIFICITY_CARRIER}`.repeat(compoundIds)}`,\n );\n }\n\n return ids > 0 ? `${carrier.filter(Boolean).join(' ')}:not(*)` : undefined;\n};\n\nconst rootedDescendantScope = (selector: selectorParser.Selector, scopeId: string): string => {\n const scope = `[${MF_SCOPE_ATTRIBUTE}=\"${scopeId}\"]`;\n const carrier = rootSpecificityCarrier(selector);\n return carrier ? `:is(${scope}, ${carrier})` : scope;\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 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"]}
|