shimShadowCss function
This is a limited shim for Shadow DOM CSS styling.
Shimmed features:
-
Shadow Host Selectors
Allows styling of the shadow host element using :host, :host(), and :host-context() selectors. To shim this feature, these selectors are reformatted and scoped with a host specific class.
:host => .host :host(div) => div.host :host-context(div) => div.host, div .host
-
Encapsulation
Styles defined within a shadow tree apply only to its contents. To shim this feature, all selectors except those preceding or containing shadow host selectors are scoped with a host specific content class.
div => div.content :host(.foo) .bar => .foo.host .bar.content :global-context(.foo) .bar => .foo .bar.content
-
Shadow Piercing Combinators
The ::ng-deep combinator allows a selector to pierce shadow boundaries and target nodes within a child host's shadow tree. To shim this feature, the combinator is replaced by the descendant combinator, and the following selectors aren't scoped with the host specific content class.
.x ::ng-deep .y => .x.content .y
-
Polyfill Selectors - DO NOT USE, SUPPORTED FOR LEGACY ONLY
The 'polyfill-unscoped-rule' selector indicates that the rule set's styles should not be encapsulated.
For example,
polyfill-unscoped-rule { content: '.menu > .menu-item'; font-size: 12px; }
becomes
.menu > .menu-item { font-size: 12px; }
The 'polyfill-next-selector' selector allows for application of a separate selector to a rule set only when this shim is applied. This is useful if the native Shadow DOM CSS selector is unsupported by the shim.
For example,
polyfill-next-selector { content: ':host .menu'; } ::slotted(.menu) { font-size: 12px; }
becomes
.host .menu.content { font-size: 12px; }
Implementation
String shimShadowCss(
String css,
String contentClass,
String hostClass, {
bool useLegacyEncapsulation = false,
}) {
var errors = <Message>[];
var styleSheet = parse(css, errors: errors);
if (errors.isNotEmpty) {
logWarning('Errors parsing CSS:\n${errors.join('\n')}');
}
var shadowTransformer = useLegacyEncapsulation
? _LegacyShadowTransformer(contentClass, hostClass)
: _ShadowTransformer(contentClass, hostClass);
shadowTransformer.visitTree(styleSheet);
var printer = CssPrinter();
printer.visitTree(styleSheet);
return printer.toString();
}