diff --git a/aio/src/app/shared/custom-icon-registry.ts b/aio/src/app/shared/custom-icon-registry.ts index af5a06b2ae..5400b88e01 100644 --- a/aio/src/app/shared/custom-icon-registry.ts +++ b/aio/src/app/shared/custom-icon-registry.ts @@ -39,35 +39,48 @@ const DEFAULT_NS = '$$default'; */ @Injectable() export class CustomIconRegistry extends MatIconRegistry { - private preloadedSvgElements: SvgIconMap = {[DEFAULT_NS]: {}}; + private cachedSvgElements: SvgIconMap = {[DEFAULT_NS]: {}}; constructor(http: HttpClient, sanitizer: DomSanitizer, @Optional() @Inject(DOCUMENT) document: Document, - errorHandler: ErrorHandler, @Inject(SVG_ICONS) svgIcons: SvgIconInfo[]) { + errorHandler: ErrorHandler, @Inject(SVG_ICONS) private svgIcons: SvgIconInfo[]) { super(http, sanitizer, document, errorHandler); - this.loadSvgElements(svgIcons); } getNamedSvgIcon(iconName: string, namespace?: string) { - const nsIconMap = this.preloadedSvgElements[namespace || DEFAULT_NS]; - const preloadedElement = nsIconMap && nsIconMap[iconName]; + const nsIconMap = this.cachedSvgElements[namespace || DEFAULT_NS]; + let preloadedElement: SVGElement | undefined = nsIconMap && nsIconMap[iconName]; + if (!preloadedElement) { + preloadedElement = this.loadSvgElement(iconName, namespace); + } return preloadedElement ? of(preloadedElement.cloneNode(true) as SVGElement) : super.getNamedSvgIcon(iconName, namespace); } - private loadSvgElements(svgIcons: SvgIconInfo[]) { - svgIcons.forEach(icon => { - const ns = icon.namespace || DEFAULT_NS; - const nsIconMap = this.preloadedSvgElements[ns] || (this.preloadedSvgElements[ns] = {}); - - // Creating a new `
` per icon is necessary for the SVGs to work correctly in IE11. - const div = document.createElement('DIV'); - - // SECURITY: the source for the SVG icons is provided in code by trusted developers - div.innerHTML = icon.svgSource; - - nsIconMap[icon.name] = div.querySelector('svg')!; + private loadSvgElement(iconName: string, namespace?: string): SVGElement | undefined { + const svgIcon = this.svgIcons.find(icon => { + return namespace + ? icon.name === iconName && icon.namespace === namespace + : icon.name === iconName; }); + + if (!svgIcon) { + return; + } + + const ns = svgIcon.namespace || DEFAULT_NS; + const nsIconMap = this.cachedSvgElements[ns] || (this.cachedSvgElements[ns] = {}); + + // Creating a new `
` per icon is necessary for the SVGs to work correctly in IE11. + const div = document.createElement('DIV'); + + // SECURITY: the source for the SVG icons is provided in code by trusted developers + div.innerHTML = svgIcon.svgSource; + + const svgElement = div.querySelector('svg')!; + nsIconMap[svgIcon.name] = svgElement; + + return svgElement; } }