/** * @license * Copyright Google Inc. All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ import {DOCUMENT} from '@angular/common'; import {Inject, Injectable, OnDestroy} from '@angular/core'; import {getDOM} from './dom_adapter'; @Injectable() export class SharedStylesHost { /** @internal */ protected _stylesSet = new Set(); addStyles(styles: string[]): void { const additions = new Set(); styles.forEach(style => { if (!this._stylesSet.has(style)) { this._stylesSet.add(style); additions.add(style); } }); this.onStylesAdded(additions); } onStylesAdded(additions: Set): void {} getAllStyles(): string[] { return Array.from(this._stylesSet); } } @Injectable() export class DomSharedStylesHost extends SharedStylesHost implements OnDestroy { private _hostNodes = new Set(); private _styleNodes = new Set(); constructor(@Inject(DOCUMENT) private _doc: any) { super(); this._hostNodes.add(_doc.head); } private _addStylesToHost(styles: Set, host: Node): void { styles.forEach((style: string) => { const styleEl = this._doc.createElement('style'); styleEl.textContent = style; this._styleNodes.add(host.appendChild(styleEl)); }); } addHost(hostNode: Node): void { this._addStylesToHost(this._stylesSet, hostNode); this._hostNodes.add(hostNode); } removeHost(hostNode: Node): void { this._hostNodes.delete(hostNode); } onStylesAdded(additions: Set): void { this._hostNodes.forEach(hostNode => this._addStylesToHost(additions, hostNode)); } ngOnDestroy(): void { this._styleNodes.forEach(styleNode => getDOM().remove(styleNode)); } }