import { trustedHTMLFromString } from '@angular/cdk/private';
import * as i1 from '@angular/common/http';
import * as i0 from '@angular/core';
import { SecurityContext, DOCUMENT, Injectable, Optional, Inject } from '@angular/core';
import * as i2 from '@angular/platform-browser';
import { of, throwError, forkJoin } from 'rxjs';
import { tap, map, catchError, finalize, share } from 'rxjs/operators';
function getMatIconNameNotFoundError(iconName) {
return Error(`Unable to find icon with the name "${iconName}"`);
}
function getMatIconNoHttpProviderError() {
return Error('Could not find HttpClient for use with Angular Material icons. ' + 'Please add provideHttpClient() to your providers.');
}
function getMatIconFailedToSanitizeUrlError(url) {
return Error(`The URL provided to MatIconRegistry was not trusted as a resource URL ` + `via Angular's DomSanitizer. Attempted URL was "${url}".`);
}
function getMatIconFailedToSanitizeLiteralError(literal) {
return Error(`The literal provided to MatIconRegistry was not trusted as safe HTML by ` + `Angular's DomSanitizer. Attempted literal was "${literal}".`);
}
class SvgIconConfig {
url;
svgText;
options;
svgElement = null;
constructor(url, svgText, options) {
this.url = url;
this.svgText = svgText;
this.options = options;
}
}
class MatIconRegistry {
_httpClient;
_sanitizer;
_errorHandler;
_document;
_svgIconConfigs = new Map();
_iconSetConfigs = new Map();
_cachedIconsByUrl = new Map();
_inProgressUrlFetches = new Map();
_fontCssClassesByAlias = new Map();
_resolvers = [];
_defaultFontSetClass = ['material-icons', 'mat-ligature-font'];
constructor(_httpClient, _sanitizer, document, _errorHandler) {
this._httpClient = _httpClient;
this._sanitizer = _sanitizer;
this._errorHandler = _errorHandler;
this._document = document;
}
addSvgIcon(iconName, url, options) {
return this.addSvgIconInNamespace('', iconName, url, options);
}
addSvgIconLiteral(iconName, literal, options) {
return this.addSvgIconLiteralInNamespace('', iconName, literal, options);
}
addSvgIconInNamespace(namespace, iconName, url, options) {
return this._addSvgIconConfig(namespace, iconName, new SvgIconConfig(url, null, options));
}
addSvgIconResolver(resolver) {
this._resolvers.push(resolver);
return this;
}
addSvgIconLiteralInNamespace(namespace, iconName, literal, options) {
const cleanLiteral = this._sanitizer.sanitize(SecurityContext.HTML, literal);
if (!cleanLiteral) {
throw getMatIconFailedToSanitizeLiteralError(literal);
}
const trustedLiteral = trustedHTMLFromString(cleanLiteral);
return this._addSvgIconConfig(namespace, iconName, new SvgIconConfig('', trustedLiteral, options));
}
addSvgIconSet(url, options) {
return this.addSvgIconSetInNamespace('', url, options);
}
addSvgIconSetLiteral(literal, options) {
return this.addSvgIconSetLiteralInNamespace('', literal, options);
}
addSvgIconSetInNamespace(namespace, url, options) {
return this._addSvgIconSetConfig(namespace, new SvgIconConfig(url, null, options));
}
addSvgIconSetLiteralInNamespace(namespace, literal, options) {
const cleanLiteral = this._sanitizer.sanitize(SecurityContext.HTML, literal);
if (!cleanLiteral) {
throw getMatIconFailedToSanitizeLiteralError(literal);
}
const trustedLiteral = trustedHTMLFromString(cleanLiteral);
return this._addSvgIconSetConfig(namespace, new SvgIconConfig('', trustedLiteral, options));
}
registerFontClassAlias(alias, classNames = alias) {
this._fontCssClassesByAlias.set(alias, classNames);
return this;
}
classNameForFontAlias(alias) {
return this._fontCssClassesByAlias.get(alias) || alias;
}
setDefaultFontSetClass(...classNames) {
this._defaultFontSetClass = classNames;
return this;
}
getDefaultFontSetClass() {
return this._defaultFontSetClass;
}
getSvgIconFromUrl(safeUrl) {
const url = this._sanitizer.sanitize(SecurityContext.RESOURCE_URL, safeUrl);
if (!url) {
throw getMatIconFailedToSanitizeUrlError(safeUrl);
}
const cachedIcon = this._cachedIconsByUrl.get(url);
if (cachedIcon) {
return of(cloneSvg(cachedIcon));
}
return this._loadSvgIconFromConfig(new SvgIconConfig(safeUrl, null)).pipe(tap(svg => this._cachedIconsByUrl.set(url, svg)), map(svg => cloneSvg(svg)));
}
getNamedSvgIcon(name, namespace = '') {
const key = iconKey(namespace, name);
let config = this._svgIconConfigs.get(key);
if (config) {
return this._getSvgFromConfig(config);
}
config = this._getIconConfigFromResolvers(namespace, name);
if (config) {
this._svgIconConfigs.set(key, config);
return this._getSvgFromConfig(config);
}
const iconSetConfigs = this._iconSetConfigs.get(namespace);
if (iconSetConfigs) {
return this._getSvgFromIconSetConfigs(name, iconSetConfigs);
}
return throwError(getMatIconNameNotFoundError(key));
}
ngOnDestroy() {
this._resolvers = [];
this._svgIconConfigs.clear();
this._iconSetConfigs.clear();
this._cachedIconsByUrl.clear();
}
_getSvgFromConfig(config) {
if (config.svgText) {
return of(cloneSvg(this._svgElementFromConfig(config)));
} else {
return this._loadSvgIconFromConfig(config).pipe(map(svg => cloneSvg(svg)));
}
}
_getSvgFromIconSetConfigs(name, iconSetConfigs) {
const namedIcon = this._extractIconWithNameFromAnySet(name, iconSetConfigs);
if (namedIcon) {
return of(namedIcon);
}
const iconSetFetchRequests = iconSetConfigs.filter(iconSetConfig => !iconSetConfig.svgText).map(iconSetConfig => {
return this._loadSvgIconSetFromConfig(iconSetConfig).pipe(catchError(err => {
const url = this._sanitizer.sanitize(SecurityContext.RESOURCE_URL, iconSetConfig.url);
const errorMessage = `Loading icon set URL: ${url} failed: ${err.message}`;
this._errorHandler.handleError(new Error(errorMessage));
return of(null);
}));
});
return forkJoin(iconSetFetchRequests).pipe(map(() => {
const foundIcon = this._extractIconWithNameFromAnySet(name, iconSetConfigs);
if (!foundIcon) {
throw getMatIconNameNotFoundError(name);
}
return foundIcon;
}));
}
_extractIconWithNameFromAnySet(iconName, iconSetConfigs) {
for (let i = iconSetConfigs.length - 1; i >= 0; i--) {
const config = iconSetConfigs[i];
if (config.svgText && config.svgText.toString().indexOf(iconName) > -1) {
const svg = this._svgElementFromConfig(config);
const foundIcon = this._extractSvgIconFromSet(svg, iconName, config.options);
if (foundIcon) {
return foundIcon;
}
}
}
return null;
}
_loadSvgIconFromConfig(config) {
return this._fetchIcon(config).pipe(tap(svgText => config.svgText = svgText), map(() => this._svgElementFromConfig(config)));
}
_loadSvgIconSetFromConfig(config) {
if (config.svgText) {
return of(null);
}
return this._fetchIcon(config).pipe(tap(svgText => config.svgText = svgText));
}
_extractSvgIconFromSet(iconSet, iconName, options) {
const iconSource = iconSet.querySelector(`[id="${iconName}"]`);
if (!iconSource) {
return null;
}
const iconElement = iconSource.cloneNode(true);
iconElement.removeAttribute('id');
if (iconElement.nodeName.toLowerCase() === 'svg') {
return this._setSvgAttributes(iconElement, options);
}
if (iconElement.nodeName.toLowerCase() === 'symbol') {
return this._setSvgAttributes(this._toSvgElement(iconElement), options);
}
const svg = this._svgElementFromString(trustedHTMLFromString(''));
svg.appendChild(iconElement);
return this._setSvgAttributes(svg, options);
}
_svgElementFromString(str) {
const div = this._document.createElement('DIV');
div.innerHTML = str;
const svg = div.querySelector('svg');
if (!svg) {
throw Error('