|
| 1 | +/** |
| 2 | + * @license |
| 3 | + * Copyright Google LLC All Rights Reserved. |
| 4 | + * |
| 5 | + * Use of this source code is governed by an MIT-style license that can be |
| 6 | + * found in the LICENSE file at https://angular.io/license |
| 7 | + */ |
| 8 | + |
| 9 | +import { |
| 10 | + ApplicationRef, |
| 11 | + ComponentRef, |
| 12 | + createComponent, |
| 13 | + EnvironmentInjector, |
| 14 | + inject, |
| 15 | + Injectable, |
| 16 | + Type, |
| 17 | +} from '@angular/core'; |
| 18 | + |
| 19 | +/** Apps in which we've loaded styles. */ |
| 20 | +const appsWithLoaders = new WeakMap< |
| 21 | + ApplicationRef, |
| 22 | + { |
| 23 | + /** Style loaders that have been added. */ |
| 24 | + loaders: Set<Type<unknown>>; |
| 25 | + |
| 26 | + /** References to the instantiated loaders. */ |
| 27 | + refs: ComponentRef<unknown>[]; |
| 28 | + } |
| 29 | +>(); |
| 30 | + |
| 31 | +/** |
| 32 | + * Service that loads structural styles dynamically |
| 33 | + * and ensures that they're only loaded once per app. |
| 34 | + */ |
| 35 | +@Injectable({providedIn: 'root'}) |
| 36 | +export class _CdkPrivateStyleLoader { |
| 37 | + private _appRef = inject(ApplicationRef); |
| 38 | + private _environmentInjector = inject(EnvironmentInjector); |
| 39 | + |
| 40 | + /** |
| 41 | + * Loads a set of styles. |
| 42 | + * @param loader Component which will be instantiated to load the styles. |
| 43 | + */ |
| 44 | + load(loader: Type<unknown>): void { |
| 45 | + let data = appsWithLoaders.get(this._appRef); |
| 46 | + |
| 47 | + // If we haven't loaded for this app before, we have to initialize it. |
| 48 | + if (!data) { |
| 49 | + data = {loaders: new Set(), refs: []}; |
| 50 | + appsWithLoaders.set(this._appRef, data); |
| 51 | + |
| 52 | + // When the app is destroyed, we need to clean up all the related loaders. |
| 53 | + this._appRef.onDestroy(() => { |
| 54 | + appsWithLoaders.get(this._appRef)?.refs.forEach(ref => ref.destroy()); |
| 55 | + appsWithLoaders.delete(this._appRef); |
| 56 | + }); |
| 57 | + } |
| 58 | + |
| 59 | + // If the loader hasn't been loaded before, we need to instatiate it. |
| 60 | + if (!data.loaders.has(loader)) { |
| 61 | + data.loaders.add(loader); |
| 62 | + data.refs.push(createComponent(loader, {environmentInjector: this._environmentInjector})); |
| 63 | + } |
| 64 | + } |
| 65 | +} |
0 commit comments