| 563 | } |
| 564 | |
| 565 | class ShadowDomRenderer extends DefaultDomRenderer2 { |
| 566 | private shadowRoot: any; |
| 567 | |
| 568 | constructor( |
| 569 | eventManager: EventManager, |
| 570 | private hostEl: any, |
| 571 | component: RendererType2, |
| 572 | doc: Document, |
| 573 | ngZone: NgZone, |
| 574 | nonce: string | null, |
| 575 | tracingService: TracingService<TracingSnapshot> | null, |
| 576 | cssVarNamespace: string, |
| 577 | private sharedStylesHost?: SharedStylesHost, |
| 578 | ) { |
| 579 | super(eventManager, doc, ngZone, tracingService, cssVarNamespace); |
| 580 | this.shadowRoot = (hostEl as any).attachShadow({mode: 'open'}); |
| 581 | |
| 582 | // SharedStylesHost is used to add styles to the shadow root by ShadowDom. |
| 583 | // This is optional as it is not used by ExperimentalIsolatedShadowDom. |
| 584 | if (this.sharedStylesHost) { |
| 585 | this.sharedStylesHost.addHost(this.shadowRoot); |
| 586 | } |
| 587 | let styles = component.styles; |
| 588 | if (ngDevMode) { |
| 589 | // We only do this in development, as for production users should not add CSS sourcemaps to components. |
| 590 | const baseHref = getDOM().getBaseHref(doc) ?? ''; |
| 591 | styles = addBaseHrefToCssSourceMap(baseHref, styles); |
| 592 | } |
| 593 | |
| 594 | styles = shimStylesContent(component.id, styles).map((s) => |
| 595 | s.replace(/%NS%/g, cssVarNamespace), |
| 596 | ); |
| 597 | |
| 598 | for (const style of styles) { |
| 599 | const styleEl = document.createElement('style'); |
| 600 | |
| 601 | if (nonce) { |
| 602 | styleEl.setAttribute('nonce', nonce); |
| 603 | } |
| 604 | |
| 605 | styleEl.textContent = style; |
| 606 | this.shadowRoot.appendChild(styleEl); |
| 607 | } |
| 608 | |
| 609 | // Apply any external component styles to the shadow root for the component's element. |
| 610 | // The ShadowDOM renderer uses an alternative execution path for component styles that |
| 611 | // does not use the SharedStylesHost that other encapsulation modes leverage. Much like |
| 612 | // the manual addition of embedded styles directly above, any external stylesheets |
| 613 | // must be manually added here to ensure ShadowDOM components are correctly styled. |
| 614 | // TODO: Consider reworking the DOM Renderers to consolidate style handling. |
| 615 | const styleUrls = component.getExternalStyles?.(); |
| 616 | if (styleUrls) { |
| 617 | for (const styleUrl of styleUrls) { |
| 618 | const linkEl = createLinkElement(styleUrl, doc); |
| 619 | if (nonce) { |
| 620 | linkEl.setAttribute('nonce', nonce); |
| 621 | } |
| 622 | this.shadowRoot.appendChild(linkEl); |
nothing calls this directly
no outgoing calls
no test coverage detected