UNPKG

@angular-mdc/web

Version:
1,741 lines 74.2 kB
/**
 * @license
 * Copyright (c) Dominic Carretto
 *
 * Use of this source code is governed by an MIT-style license that can be
 * found in the LICENSE file at https://github.com/trimox/angular-mdc-web/blob/master/LICENSE
 */
(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('@angular/common'), require('@angular/cdk/coercion'), require('rxjs/operators'), require('@angular/common/http'), require('@angular/platform-browser'), require('rxjs')) :
    typeof define === 'function' && define.amd ? define('@angular-mdc/web/icon', ['exports', '@angular/core', '@angular/common', '@angular/cdk/coercion', 'rxjs/operators', '@angular/common/http', '@angular/platform-browser', 'rxjs'], factory) :
    (global = global || self, factory((global.ng = global.ng || {}, global.ng.web = global.ng.web || {}, global.ng.web.icon = {}), global.ng.core, global.ng.common, global.ng.cdk.coercion, global.rxjs.operators, global.ng.common.http, global.ng.platformBrowser, global.rxjs));
}(this, (function (exports, core, common, coercion, operators, http, platformBrowser, rxjs) { 'use strict';

    /**
     * @fileoverview added by tsickle
     * Generated from: icon/material-icons.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    var MdcMaterialIcons = /** @class */ (function () {
        function MdcMaterialIcons() {
        }
        MdcMaterialIcons.decorators = [
            { type: core.Directive, args: [{
                        selector: '[materialIcons]',
                        host: {
                            'class': 'material-icons'
                        }
                    },] },
        ];
        return MdcMaterialIcons;
    }());

    /**
     * @fileoverview added by tsickle
     * Generated from: icon/icon-registry.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    /**
     * Returns an exception to be thrown in the case when attempting to
     * load an icon with a name that cannot be found.
     * @param {?} iconName
     * @return {?}
     */
    function getMdcIconNameNotFoundError(iconName) {
        return Error("Unable to find icon with the name \"" + iconName + "\"");
    }
    /**
     * Returns an exception to be thrown when the consumer attempts to use
     * `<mdc-icon>` without including \@angular/common/http.
     * \@docs-private
     * @return {?}
     */
    function getMdcIconNoHttpProviderError() {
        return Error('Could not find HttpClient provider for use with Angular Material icons. ' +
            'Please include the HttpClientModule from @angular/common/http in your ' +
            'app imports.');
    }
    /**
     * Returns an exception to be thrown when a URL couldn't be sanitized.
     * \@docs-private
     * @param {?} url URL that was attempted to be sanitized.
     * @return {?}
     */
    function getMdcIconFailedToSanitizeUrlError(url) {
        return Error("The URL provided to MatIconRegistry was not trusted as a resource URL " +
            ("via Angular's DomSanitizer. Attempted URL was \"" + url + "\"."));
    }
    /**
     * Returns an exception to be thrown when a HTML string couldn't be sanitized.
     * \@docs-private
     * @param {?} literal HTML that was attempted to be sanitized.
     * @return {?}
     */
    function getMdcIconFailedToSanitizeLiteralError(literal) {
        return Error("The literal provided to MatIconRegistry was not trusted as safe HTML by " +
            ("Angular's DomSanitizer. Attempted literal was \"" + literal + "\"."));
    }
    /**
     * Configuration for an icon, including the URL and possibly the cached SVG element.
     * \@docs-private
     */
    var /**
     * Configuration for an icon, including the URL and possibly the cached SVG element.
     * \@docs-private
     */
    SvgIconConfig = /** @class */ (function () {
        function SvgIconConfig(data, options) {
            this.options = options;
            this.url = null;
            this.svgElement = null;
            // Note that we can't use `instanceof SVGElement` here,
            // because it'll break during server-side rendering.
            if (!!((/** @type {?} */ (data))).nodeName) {
                this.svgElement = (/** @type {?} */ (data));
            }
            else {
                this.url = (/** @type {?} */ (data));
            }
        }
        return SvgIconConfig;
    }());
    /**
     * Service to register and display icons used by the `<mdc-icon>` component.
     * - Registers icon URLs by namespace and name.
     * - Registers icon set URLs by namespace.
     * - Registers aliases for CSS classes, for use with icon fonts.
     * - Loads icons from URLs and extracts individual icons from icon sets.
     */
    var MdcIconRegistry = /** @class */ (function () {
        function MdcIconRegistry(_httpClient, _sanitizer, document) {
            this._httpClient = _httpClient;
            this._sanitizer = _sanitizer;
            /**
             * URLs and cached SVG elements for individual icons. Keys are of the format "[namespace]:[icon]".
             */
            this._svgIconConfigs = new Map();
            /**
             * SvgIconConfig objects and cached SVG elements for icon sets, keyed by namespace.
             * Multiple icon sets can be registered under the same namespace.
             */
            this._iconSetConfigs = new Map();
            /**
             * Cache for icons loaded by direct URLs.
             */
            this._cachedIconsByUrl = new Map();
            /**
             * In-progress icon fetches. Used to coalesce multiple requests to the same URL.
             */
            this._inProgressUrlFetches = new Map();
            /**
             * Map from font identifiers to their CSS class names. Used for icon fonts.
             */
            this._fontCssClassesByAlias = new Map();
            /**
             * The CSS classes to apply when an `<mdc-icon>` component has no icon name, url, or font specified.
             * The default 'material-icons' value assumes that the material icon font has been loaded as
             * described at http://google.github.io/material-design-icons/#icon-font-for-the-web
             */
            this._defaultFontSetClass = ['material-icons'];
            this._document = document;
        }
        /**
         * Registers an icon by URL in the default namespace.
         * @param iconName Name under which the icon should be registered.
         * @param url
         */
        /**
         * Registers an icon by URL in the default namespace.
         * @template THIS
         * @this {THIS}
         * @param {?} iconName Name under which the icon should be registered.
         * @param {?} url
         * @param {?=} options
         * @return {THIS}
         */
        MdcIconRegistry.prototype.addSvgIcon = /**
         * Registers an icon by URL in the default namespace.
         * @template THIS
         * @this {THIS}
         * @param {?} iconName Name under which the icon should be registered.
         * @param {?} url
         * @param {?=} options
         * @return {THIS}
         */
        function (iconName, url, options) {
            return (/** @type {?} */ (this)).addSvgIconInNamespace('', iconName, url, options);
        };
        /**
         * Registers an icon using an HTML string in the default namespace.
         * @param iconName Name under which the icon should be registered.
         * @param literal SVG source of the icon.
         */
        /**
         * Registers an icon using an HTML string in the default namespace.
         * @template THIS
         * @this {THIS}
         * @param {?} iconName Name under which the icon should be registered.
         * @param {?} literal SVG source of the icon.
         * @param {?=} options
         * @return {THIS}
         */
        MdcIconRegistry.prototype.addSvgIconLiteral = /**
         * Registers an icon using an HTML string in the default namespace.
         * @template THIS
         * @this {THIS}
         * @param {?} iconName Name under which the icon should be registered.
         * @param {?} literal SVG source of the icon.
         * @param {?=} options
         * @return {THIS}
         */
        function (iconName, literal, options) {
            return (/** @type {?} */ (this)).addSvgIconLiteralInNamespace('', iconName, literal, options);
        };
        /**
         * Registers an icon by URL in the specified namespace.
         * @param namespace Namespace in which the icon should be registered.
         * @param iconName Name under which the icon should be registered.
         * @param url
         */
        /**
         * Registers an icon by URL in the specified namespace.
         * @template THIS
         * @this {THIS}
         * @param {?} namespace Namespace in which the icon should be registered.
         * @param {?} iconName Name under which the icon should be registered.
         * @param {?} url
         * @param {?=} options
         * @return {THIS}
         */
        MdcIconRegistry.prototype.addSvgIconInNamespace = /**
         * Registers an icon by URL in the specified namespace.
         * @template THIS
         * @this {THIS}
         * @param {?} namespace Namespace in which the icon should be registered.
         * @param {?} iconName Name under which the icon should be registered.
         * @param {?} url
         * @param {?=} options
         * @return {THIS}
         */
        function (namespace, iconName, url, options) {
            return (/** @type {?} */ (this))._addSvgIconConfig(namespace, iconName, new SvgIconConfig(url, options));
        };
        /**
         * Registers an icon using an HTML string in the specified namespace.
         * @param namespace Namespace in which the icon should be registered.
         * @param iconName Name under which the icon should be registered.
         * @param literal SVG source of the icon.
         */
        /**
         * Registers an icon using an HTML string in the specified namespace.
         * @template THIS
         * @this {THIS}
         * @param {?} namespace Namespace in which the icon should be registered.
         * @param {?} iconName Name under which the icon should be registered.
         * @param {?} literal SVG source of the icon.
         * @param {?=} options
         * @return {THIS}
         */
        MdcIconRegistry.prototype.addSvgIconLiteralInNamespace = /**
         * Registers an icon using an HTML string in the specified namespace.
         * @template THIS
         * @this {THIS}
         * @param {?} namespace Namespace in which the icon should be registered.
         * @param {?} iconName Name under which the icon should be registered.
         * @param {?} literal SVG source of the icon.
         * @param {?=} options
         * @return {THIS}
         */
        function (namespace, iconName, literal, options) {
            /** @type {?} */
            var sanitizedLiteral = (/** @type {?} */ (this))._sanitizer.sanitize(core.SecurityContext.HTML, literal);
            if (!sanitizedLiteral) {
                throw getMdcIconFailedToSanitizeLiteralError(literal);
            }
            /** @type {?} */
            var svgElement = (/** @type {?} */ (this))._createSvgElementForSingleIcon(sanitizedLiteral, options);
            return (/** @type {?} */ (this))._addSvgIconConfig(namespace, iconName, new SvgIconConfig(svgElement, options));
        };
        /**
         * Registers an icon set by URL in the default namespace.
         * @param url
         */
        /**
         * Registers an icon set by URL in the default namespace.
         * @template THIS
         * @this {THIS}
         * @param {?} url
         * @param {?=} options
         * @return {THIS}
         */
        MdcIconRegistry.prototype.addSvgIconSet = /**
         * Registers an icon set by URL in the default namespace.
         * @template THIS
         * @this {THIS}
         * @param {?} url
         * @param {?=} options
         * @return {THIS}
         */
        function (url, options) {
            return (/** @type {?} */ (this)).addSvgIconSetInNamespace('', url, options);
        };
        /**
         * Registers an icon set using an HTML string in the default namespace.
         * @param literal SVG source of the icon set.
         */
        /**
         * Registers an icon set using an HTML string in the default namespace.
         * @template THIS
         * @this {THIS}
         * @param {?} literal SVG source of the icon set.
         * @param {?=} options
         * @return {THIS}
         */
        MdcIconRegistry.prototype.addSvgIconSetLiteral = /**
         * Registers an icon set using an HTML string in the default namespace.
         * @template THIS
         * @this {THIS}
         * @param {?} literal SVG source of the icon set.
         * @param {?=} options
         * @return {THIS}
         */
        function (literal, options) {
            return (/** @type {?} */ (this)).addSvgIconSetLiteralInNamespace('', literal, options);
        };
        /**
         * Registers an icon set by URL in the specified namespace.
         * @param namespace Namespace in which to register the icon set.
         * @param url
         */
        /**
         * Registers an icon set by URL in the specified namespace.
         * @template THIS
         * @this {THIS}
         * @param {?} namespace Namespace in which to register the icon set.
         * @param {?} url
         * @param {?=} options
         * @return {THIS}
         */
        MdcIconRegistry.prototype.addSvgIconSetInNamespace = /**
         * Registers an icon set by URL in the specified namespace.
         * @template THIS
         * @this {THIS}
         * @param {?} namespace Namespace in which to register the icon set.
         * @param {?} url
         * @param {?=} options
         * @return {THIS}
         */
        function (namespace, url, options) {
            return (/** @type {?} */ (this))._addSvgIconSetConfig(namespace, new SvgIconConfig(url, options));
        };
        /**
         * Registers an icon set using an HTML string in the specified namespace.
         * @param namespace Namespace in which to register the icon set.
         * @param literal SVG source of the icon set.
         */
        /**
         * Registers an icon set using an HTML string in the specified namespace.
         * @template THIS
         * @this {THIS}
         * @param {?} namespace Namespace in which to register the icon set.
         * @param {?} literal SVG source of the icon set.
         * @param {?=} options
         * @return {THIS}
         */
        MdcIconRegistry.prototype.addSvgIconSetLiteralInNamespace = /**
         * Registers an icon set using an HTML string in the specified namespace.
         * @template THIS
         * @this {THIS}
         * @param {?} namespace Namespace in which to register the icon set.
         * @param {?} literal SVG source of the icon set.
         * @param {?=} options
         * @return {THIS}
         */
        function (namespace, literal, options) {
            /** @type {?} */
            var sanitizedLiteral = (/** @type {?} */ (this))._sanitizer.sanitize(core.SecurityContext.HTML, literal);
            if (!sanitizedLiteral) {
                throw getMdcIconFailedToSanitizeLiteralError(literal);
            }
            /** @type {?} */
            var svgElement = (/** @type {?} */ (this))._svgElementFromString(sanitizedLiteral);
            return (/** @type {?} */ (this))._addSvgIconSetConfig(namespace, new SvgIconConfig(svgElement, options));
        };
        /**
         * Defines an alias for a CSS class name to be used for icon fonts. Creating an mdcIcon
         * component with the alias as the fontSet input will cause the class name to be applied
         * to the `<mdc-icon>` element.
         *
         * @param alias Alias for the font.
         * @param className Class name override to be used instead of the alias.
         */
        /**
         * Defines an alias for a CSS class name to be used for icon fonts. Creating an mdcIcon
         * component with the alias as the fontSet input will cause the class name to be applied
         * to the `<mdc-icon>` element.
         *
         * @template THIS
         * @this {THIS}
         * @param {?} alias Alias for the font.
         * @param {?=} className Class name override to be used instead of the alias.
         * @return {THIS}
         */
        MdcIconRegistry.prototype.registerFontClassAlias = /**
         * Defines an alias for a CSS class name to be used for icon fonts. Creating an mdcIcon
         * component with the alias as the fontSet input will cause the class name to be applied
         * to the `<mdc-icon>` element.
         *
         * @template THIS
         * @this {THIS}
         * @param {?} alias Alias for the font.
         * @param {?=} className Class name override to be used instead of the alias.
         * @return {THIS}
         */
        function (alias, className) {
            if (className === void 0) { className = alias; }
            (/** @type {?} */ (this))._fontCssClassesByAlias.set(alias, className);
            return (/** @type {?} */ (this));
        };
        /**
         * Returns the CSS class name associated with the alias by a previous call to
         * registerFontClassAlias. If no CSS class has been associated, returns the alias unmodified.
         */
        /**
         * Returns the CSS class name associated with the alias by a previous call to
         * registerFontClassAlias. If no CSS class has been associated, returns the alias unmodified.
         * @param {?} alias
         * @return {?}
         */
        MdcIconRegistry.prototype.classNameForFontAlias = /**
         * Returns the CSS class name associated with the alias by a previous call to
         * registerFontClassAlias. If no CSS class has been associated, returns the alias unmodified.
         * @param {?} alias
         * @return {?}
         */
        function (alias) {
            return this._fontCssClassesByAlias.get(alias) || alias;
        };
        /**
         * Sets the CSS class name to be used for icon fonts when an `<mdc-icon>` component does not
         * have a fontSet input value, and is not loading an icon by name or URL.
         *
         * @param className
         */
        /**
         * Sets the CSS class name to be used for icon fonts when an `<mdc-icon>` component does not
         * have a fontSet input value, and is not loading an icon by name or URL.
         *
         * @template THIS
         * @this {THIS}
         * @param {...?} classNames
         * @return {THIS}
         */
        MdcIconRegistry.prototype.setDefaultFontSetClass = /**
         * Sets the CSS class name to be used for icon fonts when an `<mdc-icon>` component does not
         * have a fontSet input value, and is not loading an icon by name or URL.
         *
         * @template THIS
         * @this {THIS}
         * @param {...?} classNames
         * @return {THIS}
         */
        function () {
            var classNames = [];
            for (var _i = 0; _i < arguments.length; _i++) {
                classNames[_i] = arguments[_i];
            }
            (/** @type {?} */ (this))._defaultFontSetClass = classNames;
            return (/** @type {?} */ (this));
        };
        /**
         * Returns the CSS class name to be used for icon fonts when an `<mdc-icon>` component does not
         * have a fontSet input value, and is not loading an icon by name or URL.
         */
        /**
         * Returns the CSS class name to be used for icon fonts when an `<mdc-icon>` component does not
         * have a fontSet input value, and is not loading an icon by name or URL.
         * @return {?}
         */
        MdcIconRegistry.prototype.getDefaultFontSetClass = /**
         * Returns the CSS class name to be used for icon fonts when an `<mdc-icon>` component does not
         * have a fontSet input value, and is not loading an icon by name or URL.
         * @return {?}
         */
        function () {
            return this._defaultFontSetClass;
        };
        /**
         * Returns an Observable that produces the icon (as an `<svg>` DOM element) from the given URL.
         * The response from the URL may be cached so this will not always cause an HTTP request, but
         * the produced element will always be a new copy of the originally fetched icon. (That is,
         * it will not contain any modifications made to elements previously returned).
         *
         * @param safeUrl URL from which to fetch the SVG icon.
         */
        /**
         * Returns an Observable that produces the icon (as an `<svg>` DOM element) from the given URL.
         * The response from the URL may be cached so this will not always cause an HTTP request, but
         * the produced element will always be a new copy of the originally fetched icon. (That is,
         * it will not contain any modifications made to elements previously returned).
         *
         * @param {?} safeUrl URL from which to fetch the SVG icon.
         * @return {?}
         */
        MdcIconRegistry.prototype.getSvgIconFromUrl = /**
         * Returns an Observable that produces the icon (as an `<svg>` DOM element) from the given URL.
         * The response from the URL may be cached so this will not always cause an HTTP request, but
         * the produced element will always be a new copy of the originally fetched icon. (That is,
         * it will not contain any modifications made to elements previously returned).
         *
         * @param {?} safeUrl URL from which to fetch the SVG icon.
         * @return {?}
         */
        function (safeUrl) {
            var _this = this;
            /** @type {?} */
            var url = this._sanitizer.sanitize(core.SecurityContext.RESOURCE_URL, safeUrl);
            if (!url) {
                throw getMdcIconFailedToSanitizeUrlError(safeUrl);
            }
            /** @type {?} */
            var cachedIcon = this._cachedIconsByUrl.get(url);
            if (cachedIcon) {
                return rxjs.of(cloneSvg(cachedIcon));
            }
            return this._loadSvgIconFromConfig(new SvgIconConfig(safeUrl)).pipe(operators.tap((/**
             * @param {?} svg
             * @return {?}
             */
            function (svg) { return _this._cachedIconsByUrl.set((/** @type {?} */ (url)), svg); })), operators.map((/**
             * @param {?} svg
             * @return {?}
             */
            function (svg) { return cloneSvg(svg); })));
        };
        /**
         * Returns an Observable that produces the icon (as an `<svg>` DOM element) with the given name
         * and namespace. The icon must have been previously registered with addIcon or addIconSet;
         * if not, the Observable will throw an error.
         *
         * @param name Name of the icon to be retrieved.
         * @param namespace Namespace in which to look for the icon.
         */
        /**
         * Returns an Observable that produces the icon (as an `<svg>` DOM element) with the given name
         * and namespace. The icon must have been previously registered with addIcon or addIconSet;
         * if not, the Observable will throw an error.
         *
         * @param {?} name Name of the icon to be retrieved.
         * @param {?=} namespace Namespace in which to look for the icon.
         * @return {?}
         */
        MdcIconRegistry.prototype.getNamedSvgIcon = /**
         * Returns an Observable that produces the icon (as an `<svg>` DOM element) with the given name
         * and namespace. The icon must have been previously registered with addIcon or addIconSet;
         * if not, the Observable will throw an error.
         *
         * @param {?} name Name of the icon to be retrieved.
         * @param {?=} namespace Namespace in which to look for the icon.
         * @return {?}
         */
        function (name, namespace) {
            if (namespace === void 0) { namespace = ''; }
            // Return (copy of) cached icon if possible.
            /** @type {?} */
            var key = iconKey(namespace, name);
            /** @type {?} */
            var config = this._svgIconConfigs.get(key);
            if (config) {
                return this._getSvgFromConfig(config);
            }
            // See if we have any icon sets registered for the namespace.
            /** @type {?} */
            var iconSetConfigs = this._iconSetConfigs.get(namespace);
            if (iconSetConfigs) {
                return this._getSvgFromIconSetConfigs(name, iconSetConfigs);
            }
            return rxjs.throwError(getMdcIconNameNotFoundError(key));
        };
        /**
         * @return {?}
         */
        MdcIconRegistry.prototype.ngOnDestroy = /**
         * @return {?}
         */
        function () {
            this._svgIconConfigs.clear();
            this._iconSetConfigs.clear();
            this._cachedIconsByUrl.clear();
        };
        /**
         * Returns the cached icon for a SvgIconConfig if available, or fetches it from its URL if not.
         */
        /**
         * Returns the cached icon for a SvgIconConfig if available, or fetches it from its URL if not.
         * @private
         * @param {?} config
         * @return {?}
         */
        MdcIconRegistry.prototype._getSvgFromConfig = /**
         * Returns the cached icon for a SvgIconConfig if available, or fetches it from its URL if not.
         * @private
         * @param {?} config
         * @return {?}
         */
        function (config) {
            if (config.svgElement) {
                // We already have the SVG element for this icon, return a copy.
                return rxjs.of(cloneSvg(config.svgElement));
            }
            else {
                // Fetch the icon from the config's URL, cache it, and return a copy.
                return this._loadSvgIconFromConfig(config).pipe(operators.tap((/**
                 * @param {?} svg
                 * @return {?}
                 */
                function (svg) { return config.svgElement = svg; })), operators.map((/**
                 * @param {?} svg
                 * @return {?}
                 */
                function (svg) { return cloneSvg(svg); })));
            }
        };
        /**
         * Attempts to find an icon with the specified name in any of the SVG icon sets.
         * First searches the available cached icons for a nested element with a matching name, and
         * if found copies the element to a new `<svg>` element. If not found, fetches all icon sets
         * that have not been cached, and searches again after all fetches are completed.
         * The returned Observable produces the SVG element if possible, and throws
         * an error if no icon with the specified name can be found.
         */
        /**
         * Attempts to find an icon with the specified name in any of the SVG icon sets.
         * First searches the available cached icons for a nested element with a matching name, and
         * if found copies the element to a new `<svg>` element. If not found, fetches all icon sets
         * that have not been cached, and searches again after all fetches are completed.
         * The returned Observable produces the SVG element if possible, and throws
         * an error if no icon with the specified name can be found.
         * @private
         * @param {?} name
         * @param {?} iconSetConfigs
         * @return {?}
         */
        MdcIconRegistry.prototype._getSvgFromIconSetConfigs = /**
         * Attempts to find an icon with the specified name in any of the SVG icon sets.
         * First searches the available cached icons for a nested element with a matching name, and
         * if found copies the element to a new `<svg>` element. If not found, fetches all icon sets
         * that have not been cached, and searches again after all fetches are completed.
         * The returned Observable produces the SVG element if possible, and throws
         * an error if no icon with the specified name can be found.
         * @private
         * @param {?} name
         * @param {?} iconSetConfigs
         * @return {?}
         */
        function (name, iconSetConfigs) {
            var _this = this;
            // For all the icon set SVG elements we've fetched, see if any contain an icon with the
            // requested name.
            /** @type {?} */
            var namedIcon = this._extractIconWithNameFromAnySet(name, iconSetConfigs);
            if (namedIcon) {
                // We could cache namedIcon in _svgIconConfigs, but since we have to make a copy every
                // time anyway, there's probably not much advantage compared to just always extracting
                // it from the icon set.
                return rxjs.of(namedIcon);
            }
            // Not found in any cached icon sets. If there are icon sets with URLs that we haven't
            // fetched, fetch them now and look for iconName in the results.
            /** @type {?} */
            var iconSetFetchRequests = iconSetConfigs
                .filter((/**
             * @param {?} iconSetConfig
             * @return {?}
             */
            function (iconSetConfig) { return !iconSetConfig.svgElement; }))
                .map((/**
             * @param {?} iconSetConfig
             * @return {?}
             */
            function (iconSetConfig) {
                return _this._loadSvgIconSetFromConfig(iconSetConfig).pipe(operators.catchError((/**
                 * @param {?} err
                 * @return {?}
                 */
                function (err) {
                    /** @type {?} */
                    var url = _this._sanitizer.sanitize(core.SecurityContext.RESOURCE_URL, iconSetConfig.url);
                    // Swallow errors fetching individual URLs so the
                    // combined Observable won't necessarily fail.
                    console.error("Loading icon set URL: " + url + " failed: " + err.message);
                    return rxjs.of(null);
                })));
            }));
            // Fetch all the icon set URLs. When the requests complete, every IconSet should have a
            // cached SVG element (unless the request failed), and we can check again for the icon.
            return rxjs.forkJoin(iconSetFetchRequests).pipe(operators.map((/**
             * @return {?}
             */
            function () {
                /** @type {?} */
                var foundIcon = _this._extractIconWithNameFromAnySet(name, iconSetConfigs);
                if (!foundIcon) {
                    throw getMdcIconNameNotFoundError(name);
                }
                return foundIcon;
            })));
        };
        /**
         * Searches the cached SVG elements for the given icon sets for a nested icon element whose "id"
         * tag matches the specified name. If found, copies the nested element to a new SVG element and
         * returns it. Returns null if no matching element is found.
         */
        /**
         * Searches the cached SVG elements for the given icon sets for a nested icon element whose "id"
         * tag matches the specified name. If found, copies the nested element to a new SVG element and
         * returns it. Returns null if no matching element is found.
         * @private
         * @param {?} iconName
         * @param {?} iconSetConfigs
         * @return {?}
         */
        MdcIconRegistry.prototype._extractIconWithNameFromAnySet = /**
         * Searches the cached SVG elements for the given icon sets for a nested icon element whose "id"
         * tag matches the specified name. If found, copies the nested element to a new SVG element and
         * returns it. Returns null if no matching element is found.
         * @private
         * @param {?} iconName
         * @param {?} iconSetConfigs
         * @return {?}
         */
        function (iconName, iconSetConfigs) {
            // Iterate backwards, so icon sets added later have precedence.
            for (var i = iconSetConfigs.length - 1; i >= 0; i--) {
                /** @type {?} */
                var config = iconSetConfigs[i];
                if (config.svgElement) {
                    /** @type {?} */
                    var foundIcon = this._extractSvgIconFromSet(config.svgElement, iconName, config.options);
                    if (foundIcon) {
                        return foundIcon;
                    }
                }
            }
            return null;
        };
        /**
         * Loads the content of the icon URL specified in the SvgIconConfig and creates an SVG element
         * from it.
         */
        /**
         * Loads the content of the icon URL specified in the SvgIconConfig and creates an SVG element
         * from it.
         * @private
         * @param {?} config
         * @return {?}
         */
        MdcIconRegistry.prototype._loadSvgIconFromConfig = /**
         * Loads the content of the icon URL specified in the SvgIconConfig and creates an SVG element
         * from it.
         * @private
         * @param {?} config
         * @return {?}
         */
        function (config) {
            var _this = this;
            return this._fetchUrl(config.url)
                .pipe(operators.map((/**
             * @param {?} svgText
             * @return {?}
             */
            function (svgText) { return _this._createSvgElementForSingleIcon(svgText, config.options); })));
        };
        /**
         * Loads the content of the icon set URL specified in the SvgIconConfig and creates an SVG element
         * from it.
         */
        /**
         * Loads the content of the icon set URL specified in the SvgIconConfig and creates an SVG element
         * from it.
         * @private
         * @param {?} config
         * @return {?}
         */
        MdcIconRegistry.prototype._loadSvgIconSetFromConfig = /**
         * Loads the content of the icon set URL specified in the SvgIconConfig and creates an SVG element
         * from it.
         * @private
         * @param {?} config
         * @return {?}
         */
        function (config) {
            var _this = this;
            // If the SVG for this icon set has already been parsed, do nothing.
            if (config.svgElement) {
                return rxjs.of(config.svgElement);
            }
            return this._fetchUrl(config.url).pipe(operators.map((/**
             * @param {?} svgText
             * @return {?}
             */
            function (svgText) {
                // It is possible that the icon set was parsed and cached by an earlier request, so parsing
                // only needs to occur if the cache is yet unset.
                if (!config.svgElement) {
                    config.svgElement = _this._svgElementFromString(svgText);
                }
                return config.svgElement;
            })));
        };
        /**
         * Creates a DOM element from the given SVG string, and adds default attributes.
         */
        /**
         * Creates a DOM element from the given SVG string, and adds default attributes.
         * @private
         * @param {?} responseText
         * @param {?=} options
         * @return {?}
         */
        MdcIconRegistry.prototype._createSvgElementForSingleIcon = /**
         * Creates a DOM element from the given SVG string, and adds default attributes.
         * @private
         * @param {?} responseText
         * @param {?=} options
         * @return {?}
         */
        function (responseText, options) {
            /** @type {?} */
            var svg = this._svgElementFromString(responseText);
            this._setSvgAttributes(svg, options);
            return svg;
        };
        /**
         * Searches the cached element of the given SvgIconConfig for a nested icon element whose "id"
         * tag matches the specified name. If found, copies the nested element to a new SVG element and
         * returns it. Returns null if no matching element is found.
         */
        /**
         * Searches the cached element of the given SvgIconConfig for a nested icon element whose "id"
         * tag matches the specified name. If found, copies the nested element to a new SVG element and
         * returns it. Returns null if no matching element is found.
         * @private
         * @param {?} iconSet
         * @param {?} iconName
         * @param {?=} options
         * @return {?}
         */
        MdcIconRegistry.prototype._extractSvgIconFromSet = /**
         * Searches the cached element of the given SvgIconConfig for a nested icon element whose "id"
         * tag matches the specified name. If found, copies the nested element to a new SVG element and
         * returns it. Returns null if no matching element is found.
         * @private
         * @param {?} iconSet
         * @param {?} iconName
         * @param {?=} options
         * @return {?}
         */
        function (iconSet, iconName, options) {
            // Use the `id="iconName"` syntax in order to escape special
            // characters in the ID (versus using the #iconName syntax).
            /** @type {?} */
            var iconSource = iconSet.querySelector("[id=\"" + iconName + "\"]");
            if (!iconSource) {
                return null;
            }
            // Clone the element and remove the ID to prevent multiple elements from being added
            // to the page with the same ID.
            /** @type {?} */
            var iconElement = (/** @type {?} */ (iconSource.cloneNode(true)));
            iconElement.removeAttribute('id');
            // If the icon node is itself an <svg> node, clone and return it directly. If not, set it as
            // the content of a new <svg> node.
            if (iconElement.nodeName.toLowerCase() === 'svg') {
                return this._setSvgAttributes((/** @type {?} */ (iconElement)), options);
            }
            // If the node is a <symbol>, it won't be rendered so we have to convert it into <svg>. Note
            // that the same could be achieved by referring to it via <use href="#id">, however the <use>
            // tag is problematic on Firefox, because it needs to include the current page path.
            if (iconElement.nodeName.toLowerCase() === 'symbol') {
                return this._setSvgAttributes(this._toSvgElement(iconElement), options);
            }
            // createElement('SVG') doesn't work as expected; the DOM ends up with
            // the correct nodes, but the SVG content doesn't render. Instead we
            // have to create an empty SVG node using innerHTML and append its content.
            // Elements created using DOMParser.parseFromString have the same problem.
            // http://stackoverflow.com/questions/23003278/svg-innerhtml-in-firefox-can-not-display
            /** @type {?} */
            var svg = this._svgElementFromString('<svg></svg>');
            // Clone the node so we don't remove it from the parent icon set element.
            svg.appendChild(iconElement);
            return this._setSvgAttributes(svg, options);
        };
        /**
         * Creates a DOM element from the given SVG string.
         */
        /**
         * Creates a DOM element from the given SVG string.
         * @private
         * @param {?} str
         * @return {?}
         */
        MdcIconRegistry.prototype._svgElementFromString = /**
         * Creates a DOM element from the given SVG string.
         * @private
         * @param {?} str
         * @return {?}
         */
        function (str) {
            /** @type {?} */
            var div = this._document.createElement('DIV');
            div.innerHTML = str;
            /** @type {?} */
            var svg = (/** @type {?} */ (div.querySelector('svg')));
            if (!svg) {
                throw Error('<svg> tag not found');
            }
            return svg;
        };
        /**
         * Converts an element into an SVG node by cloning all of its children.
         */
        /**
         * Converts an element into an SVG node by cloning all of its children.
         * @private
         * @param {?} element
         * @return {?}
         */
        MdcIconRegistry.prototype._toSvgElement = /**
         * Converts an element into an SVG node by cloning all of its children.
         * @private
         * @param {?} element
         * @return {?}
         */
        function (element) {
            /** @type {?} */
            var svg = this._svgElementFromString('<svg></svg>');
            /** @type {?} */
            var attributes = element.attributes;
            // Copy over all the attributes from the `symbol` to the new SVG, except the id.
            for (var i = 0; i < attributes.length; i++) {
                var _a = attributes[i], name_1 = _a.name, value = _a.value;
                if (name_1 !== 'id') {
                    svg.setAttribute(name_1, value);
                }
            }
            for (var i = 0; i < element.childNodes.length; i++) {
                if (element.childNodes[i].nodeType === this._document.ELEMENT_NODE) {
                    svg.appendChild(element.childNodes[i].cloneNode(true));
                }
            }
            return svg;
        };
        /**
         * Sets the default attributes for an SVG element to be used as an icon.
         */
        /**
         * Sets the default attributes for an SVG element to be used as an icon.
         * @private
         * @param {?} svg
         * @param {?=} options
         * @return {?}
         */
        MdcIconRegistry.prototype._setSvgAttributes = /**
         * Sets the default attributes for an SVG element to be used as an icon.
         * @private
         * @param {?} svg
         * @param {?=} options
         * @return {?}
         */
        function (svg, options) {
            svg.setAttribute('fit', '');
            svg.setAttribute('height', '100%');
            svg.setAttribute('width', '100%');
            svg.setAttribute('preserveAspectRatio', 'xMidYMid meet');
            svg.setAttribute('focusable', 'false'); // Disable IE11 default behavior to make SVGs focusable.
            if (options && options.viewBox) {
                svg.setAttribute('viewBox', options.viewBox);
            }
            return svg;
        };
        /**
         * Returns an Observable which produces the string contents of the given URL. Results may be
         * cached, so future calls with the same URL may not cause another HTTP request.
         */
        /**
         * Returns an Observable which produces the string contents of the given URL. Results may be
         * cached, so future calls with the same URL may not cause another HTTP request.
         * @private
         * @param {?} safeUrl
         * @return {?}
         */
        MdcIconRegistry.prototype._fetchUrl = /**
         * Returns an Observable which produces the string contents of the given URL. Results may be
         * cached, so future calls with the same URL may not cause another HTTP request.
         * @private
         * @param {?} safeUrl
         * @return {?}
         */
        function (safeUrl) {
            var _this = this;
            if (!this._httpClient) {
                throw getMdcIconNoHttpProviderError();
            }
            if (safeUrl == null) {
                throw Error("Cannot fetch icon from URL \"" + safeUrl + "\".");
            }
            /** @type {?} */
            var url = this._sanitizer.sanitize(core.SecurityContext.RESOURCE_URL, safeUrl);
            if (!url) {
                throw getMdcIconFailedToSanitizeUrlError(safeUrl);
            }
            // Store in-progress fetches to avoid sending a duplicate request for a URL when there is
            // already a request in progress for that URL. It's necessary to call share() on the
            // Observable returned by http.get() so that multiple subscribers don't cause multiple XHRs.
            /** @type {?} */
            var inProgressFetch = this._inProgressUrlFetches.get(url);
            if (inProgressFetch) {
                return inProgressFetch;
            }
            // TODO(jelbourn): for some reason, the `finalize` operator "loses" the generic type on the
            // Observable. Figure out why and fix it.
            /** @type {?} */
            var req = this._httpClient.get(url, { responseType: 'text' }).pipe(operators.finalize((/**
             * @return {?}
             */
            function () { return _this._inProgressUrlFetches.delete(url); })), operators.share());
            this._inProgressUrlFetches.set(url, req);
            return req;
        };
        /**
         * Registers an icon config by name in the specified namespace.
         * @param namespace Namespace in which to register the icon config.
         * @param iconName Name under which to register the config.
         * @param config Config to be registered.
         */
        /**
         * Registers an icon config by name in the specified namespace.
         * @private
         * @template THIS
         * @this {THIS}
         * @param {?} namespace Namespace in which to register the icon config.
         * @param {?} iconName Name under which to register the config.
         * @param {?} config Config to be registered.
         * @return {THIS}
         */
        MdcIconRegistry.prototype._addSvgIconConfig = /**
         * Registers an icon config by name in the specified namespace.
         * @private
         * @template THIS
         * @this {THIS}
         * @param {?} namespace Namespace in which to register the icon config.
         * @param {?} iconName Name under which to register the config.
         * @param {?} config Config to be registered.
         * @return {THIS}
         */
        function (namespace, iconName, config) {
            (/** @type {?} */ (this))._svgIconConfigs.set(iconKey(namespace, iconName), config);
            return (/** @type {?} */ (this));
        };
        /**
         * Registers an icon set config in the specified namespace.
         * @param namespace Namespace in which to register the icon config.
         * @param config Config to be registered.
         */
        /**
         * Registers an icon set config in the specified namespace.
         * @private
         * @template THIS
         * @this {THIS}
         * @param {?} namespace Namespace in which to register the icon config.
         * @param {?} config Config to be registered.
         * @return {THIS}
         */
        MdcIconRegistry.prototype._addSvgIconSetConfig = /**
         * Registers an icon set config in the specified namespace.
         * @private
         * @template THIS
         * @this {THIS}
         * @param {?} namespace Namespace in which to register the icon config.
         * @param {?} config Config to be registered.
         * @return {THIS}
         */
        function (namespace, config) {
            /** @type {?} */
            var configNamespace = (/** @type {?} */ (this))._iconSetConfigs.get(namespace);
            if (configNamespace) {
                configNamespace.push(config);
            }
            else {
                (/** @type {?} */ (this))._iconSetConfigs.set(namespace, [config]);
            }
            return (/** @type {?} */ (this));
        };
        MdcIconRegistry.decorators = [
            { type: core.Injectable, args: [{ providedIn: 'root' },] },
        ];
        /** @nocollapse */
        MdcIconRegistry.ctorParameters = function () { return [
            { type: http.HttpClient, decorators: [{ type: core.Optional }] },
            { type: platformBrowser.DomSanitizer },
            { type: undefined, decorators: [{ type: core.Optional }, { type: core.Inject, args: [common.DOCUMENT,] }] }
        ]; };
        /** @nocollapse */ MdcIconRegistry.ɵprov5 = core["ɵɵdefineInjectable"]({ factory: function MdcIconRegistry_Factory() { return new MdcIconRegistry(core["ɵɵinject"](http.HttpClient, 8), core["ɵɵinject"](platformBrowser.DomSanitizer), core["ɵɵinject"](common.DOCUMENT, 8)); }, token: MdcIconRegistry, providedIn: "root" });
        return MdcIconRegistry;
    }());
    /**
     * \@docs-private
     * @param {?} parentRegistry
     * @param {?} httpClient
     * @param {?} sanitizer
     * @param {?=} document
     * @return {?}
     */
    function ICON_REGISTRY_PROVIDER_FACTORY(parentRegistry, httpClient, sanitizer, document) {
        return parentRegistry || new MdcIconRegistry(httpClient, sanitizer, document);
    }
    /**
     * \@docs-private
     * @type {?}
     */
    var ICON_REGISTRY_PROVIDER = {
        // If there is already an MdcIconRegistry available, use that. Otherwise, provide a new one.
        provide: MdcIconRegistry,
        deps: [
            [new core.Optional(), new core.SkipSelf(), MdcIconRegistry],
            [new core.Optional(), http.HttpClient],
            platformBrowser.DomSanitizer,
            [new core.Optional(), (/** @type {?} */ (common.DOCUMENT))],
        ],
        useFactory: ICON_REGISTRY_PROVIDER_FACTORY,
    };
    /**
     * Clones an SVGElement while preserving type information.
     * @param {?} svg
     * @return {?}
     */
    function cloneSvg(svg) {
        return (/** @type {?} */ (svg.cloneNode(true)));
    }
    /**
     * Returns the cache key to use for an icon namespace and name.
     * @param {?} namespace
     * @param {?} name
     * @return {?}
     */
    function iconKey(namespace, name) {
        return namespace + ':' + name;
    }

    /**
     * @fileoverview added by tsickle
     * Generated from: icon/icon.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    /**
     * @return {?}
     */
    function MDC_ICON_LOCATION_FACTORY() {
        /** @type {?} */
        var _document = core.inject(common.DOCUMENT);
        /** @type {?} */
        var _location = _document ? _document.location : null;
        return {
            // Note that this needs to be a function, rather than a property, because Angular
            // will only resolve it once, but we want the current path on each call.
            getPathname: (/**
             * @return {?}
             */
            function () { return _location ? (_location.pathname + _location.search) : ''; })
        };
    }
    /**
     * Injection token used to provide the current location to `MdcIcon`.
     * Used to handle server-side rendering and to stub out during unit tests.
     * @type {?}
     */
    var MDC_ICON_LOCATION = new core.InjectionToken('mdc-icon-location', {
        providedIn: 'root',
        factory: MDC_ICON_LOCATION_FACTORY
    });
    /**
     * SVG attributes that accept a FuncIRI (e.g. `url(<something>)`).
     * @type {?}
     */
    var funcIriAttributes = [
        'clip-path',
        'color-profile',
        'src',
        'cursor',
        'fill',
        'filter',
        'marker',
        'marker-start',
        'marker-mid',
        'marker-end',
        'mask',
        'stroke'
    ];
    var ɵ0 = /**
     * @param {?} attr
     * @return {?}
     */
    function (attr) { return "[" + attr + "]"; };
    /**
     * Selector that can be used to find all elements that are using a `FuncIRI`.
     * @type {?}
     */
    var funcIriAttributeSelector = funcIriAttributes.map((ɵ0)).join(', ');
    /**
     * Regex that can be used to extract the id out of a FuncIRI.
     * @type {?}
     */
    var funcIriPattern = /^url\(['"]?#(.*?)['"]?\)$/;
    var MdcIcon = /** @class */ (function () {
        function MdcIcon(elementRef, _iconRegistry, ariaHidden, _location) {
            this.elementRef = elementRef;
            this._iconRegistry = _iconRegistry;
            this._location = _location;
            this._previousFontSetClass = [];
            this._inline = false;
            this.role = 'img';
            this._fontSet = '';
            this._fontIcon = '';
            this._clickable = false;
            if (!ariaHidden) {
                this._getHostElement().setAttribute('aria-hidden', 'true');
            }
        }
        Object.defineProperty(MdcIcon.prototype, "inline", {
            /**
             * Whether the icon should be inlined, automatically sizing the icon to match the font size of
             * the element the icon is contained in.
             */
            get: /**
             * Whether the icon should be inlined, automatically sizing the icon to match the font size of
             * the element the icon is contained in.
             * @return {?}
             */
            function () {
                return this._inline;
            },
            set: /**
             * @param {?} inline
             * @return {?}
             */
            function (inline) {
                this._inline = coercion.coerceBooleanProperty(inline);
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(MdcIcon.prototype, "fontSet", {
            /** Font set that the icon is a part of. */
            get: /**
             * Font set that the icon is a part of.
             * @return {?}
             */
            function () {
                return this._fontSet;
            },
            set: /**
             * @param {?} value
             * @return {?}
             */
            function (value) {
                this._fontSet = this._cleanupFontValue(value);
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(MdcIcon.prototype, "fontIcon", {
            /** Name of an icon within a font set. */
            get: /**
             * Name of an icon within a font set.
             * @return {?}
             */
            function () {
                return this._fontIcon;
            },
            set: /**
             * @param {?} value
             * @return {?}
             */
            function (value) {
                this._fontIcon = this._cleanupFontValue(value);
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(MdcIcon.prototype, "clickable", {
            get: /**
             * @return {?}
             */
            function () {
                return this._clickable;
            },
            set: /**
             * @param {?} value
             * @return {?}
             */
            function (value) {
                this._clickable = coercion.coerceBooleanProperty(value);
                if (this._clickable) {
                    this.role = 'button';
                }
                else {
                    this.role = null;
                }
            },
            enumerable: true,
            configurable: true
        });
        /**
         * @return {?}
         */
        MdcIcon.prototype.ngAfterViewChecked = /**
         * @return {?}
         */
        function () {
            /** @type {?} */
            var cachedElements = this._elementsWithExternalReferences;
            if (cachedElements && this._location && cachedElements.size) {
                /** @type {?} */
                var newPath = this._location.getPathname();
                // We need to check whether the URL has changed on each change detection since
                // the browser doesn't have an API that will let us react on link clicks and
                // we can't depend on the Angular router. The references need to be updated,
                // because while most browsers don't care whether the URL is correct after
                // the first render, Safari will break if the user navigates to a different
                // page and the SVG isn't re-rendered.
                if (newPath !== this._previousPath) {
                    this._previousPath = newPath;
                    this._prependPathToReferences(newPath);
                }
            }
        };
        /**
         * @return {?}
         */
        MdcIcon.prototype.ngOnDestroy = /**
         * @return {?}
         */
        function () {
            var _a;
            (_a = this._elementsWithExternalReferences) === null || _a === void 0 ? void 0 : _a.clear();
        };
        /**
         * Splits an svgIcon binding value into its icon set and icon name components.
         * Returns a 2-element array of [(icon set), (icon name)].
         * The separator for the two fields is ':'. If there is no separator, an empty
         * string is returned for the icon set and the entire value is returned for
         * the icon name. If the argument is falsy, returns an array of two empty strings.
         * Throws an error if the name contains two or more ':' separators.
         * Examples:
         *   `'social:cake' -> ['social', 'cake']
         *   'penguin' -> ['', 'penguin']
         *   null -> ['', '']
         *   'a:b:c' -> (throws Error)`
         */
        /**
         * Splits an svgIcon binding value into its icon set and icon name components.
         * Returns a 2-element array of [(icon set), (icon name)].
         * The separator for the two fields is ':'. If there is no separator, an empty
         * string is returned for the icon set and the entire value is returned for
         * the icon name. If the argument is falsy, returns an array of two empty strings.
         * Throws an error if the name contains two or more ':' separators.
         * Examples:
         *   `'social:cake' -> ['social', 'cake']
         *   'penguin' -> ['', 'penguin']
         *   null -> ['', '']
         *   'a:b:c' -> (throws Error)`
         * @private
         * @param {?} iconName
         * @return {?}
         */
        MdcIcon.prototype._splitIconName = /**
         * Splits an svgIcon binding value into its icon set and icon name components.
         * Returns a 2-element array of [(icon set), (icon name)].
         * The separator for the two fields is ':'. If there is no separator, an empty
         * string is returned for the icon set and the entire value is returned for
         * the icon name. If the argument is falsy, returns an array of two empty strings.
         * Throws an error if the name contains two or more ':' separators.
         * Examples:
         *   `'social:cake' -> ['social', 'cake']
         *   'penguin' -> ['', 'penguin']
         *   null -> ['', '']
         *   'a:b:c' -> (throws Error)`
         * @private
         * @param {?} iconName
         * @return {?}
         */
        function (iconName) {
            if (!iconName) {
                return ['', ''];
            }
            /** @type {?} */
            var parts = iconName.split(':');
            switch (parts.length) {
                case 1: return ['', parts[0]]; // Use default namespace.
                case 2: return (/** @type {?} */ (parts));
                default: throw Error("Invalid icon name: \"" + iconName + "\"");
            }
        };
        /**
         * @param {?} changes
         * @return {?}
         */
        MdcIcon.prototype.ngOnChanges = /**
         * @param {?} changes
         * @return {?}
         */
        function (changes) {
            var _this = this;
            // Only update the inline SVG icon if the inputs changed, to avoid unnecessary DOM operations.
            /** @type {?} */
            var svgIconChanges = changes['svgIcon'];
            if (svgIconChanges) {
                if (this.svgIcon) {
                    var _a = this._splitIconName(this.svgIcon), namespace = _a[0], iconName = _a[1];
                    this._iconRegistry.getNamedSvgIcon(iconName, namespace).pipe(operators.take(1)).subscribe((/**
                     * @param {?} svg
                     * @return {?}
                     */
                    function (svg) { return _this._setSvgElement(svg); }), (/**
                     * @param {?} err
                     * @return {?}
                     */
                    function (err) { return console.log("Error retrieving icon: " + err.message); }));
                }
                else if (svgIconChanges.previousValue) {
                    this._clearSvgElement();
                }
            }
            if (this._usingFontIcon()) {
                this._updateFontIconClasses();
            }
        };
        /**
         * @return {?}
         */
        MdcIcon.prototype.ngOnInit = /**
         * @return {?}
         */
        function () {
            // Update font classes because ngOnChanges won't be called if none of the inputs are present,
            // e.g. <mdc-icon>arrow</mdc-icon> In this case we need to add a CSS class for the default font.
            if (this._usingFontIcon()) {
                this._updateFontIconClasses();
            }
        };
        /**
         * @private
         * @return {?}
         */
        MdcIcon.prototype._usingFontIcon = /**
         * @private
         * @return {?}
         */
        function () {
            return !this.svgIcon;
        };
        /**
         * @private
         * @param {?} svg
         * @return {?}
         */
        MdcIcon.prototype._setSvgElement = /**
         * @private
         * @param {?} svg
         * @return {?}
         */
        function (svg) {
            this._clearSvgElement();
            // Workaround for IE11 and Edge ignoring `style` tags inside dynamically-created SVGs.
            // See: https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/10898469/
            // Do this before inserting the element into the DOM, in order to avoid a style recalculation.
            /** @type {?} */
            var styleTags = (/** @type {?} */ (svg.querySelectorAll('style')));
            for (var i = 0; i < styleTags.length; i++) {
                styleTags[i].textContent += ' ';
            }
            // Note: we do this fix here, rather than the icon registry, because the
            // references have to point to the URL at the time that the icon was created.
            if (this._location) {
                /** @type {?} */
                var path = this._location.getPathname();
                this._previousPath = path;
                this._cacheChildrenWithExternalReferences(svg);
                this._prependPathToReferences(path);
            }
            this._getHostElement().appendChild(svg);
        };
        /**
         * @private
         * @return {?}
         */
        MdcIcon.prototype._clearSvgElement = /**
         * @private
         * @return {?}
         */
        function () {
            /** @type {?} */
            var layoutElement = this._getHostElement();
            /** @type {?} */
            var childCount = layoutElement.childNodes.length;
            if (this._elementsWithExternalReferences) {
                this._elementsWithExternalReferences.clear();
            }
            // Remove existing non-element child nodes and SVGs, and add the new SVG element. Note that
            // we can't use innerHTML, because IE will throw if the element has a data binding.
            while (childCount--) {
                /** @type {?} */
                var child = layoutElement.childNodes[childCount];
                // 1 corresponds to Node.ELEMENT_NODE. We remove all non-element nodes in order to get rid
                // of any loose text nodes, as well as any SVG elements in order to remove any old icons.
                if (child.nodeType !== 1 || child.nodeName.toLowerCase() === 'svg') {
                    layoutElement.removeChild(child);
                }
            }
        };
        /**
         * @private
         * @return {?}
         */
        MdcIcon.prototype._updateFontIconClasses = /**
         * @private
         * @return {?}
         */
        function () {
            if (!this._usingFontIcon()) {
                return;
            }
            /** @type {?} */
            var elem = this._getHostElement();
            /** @type {?} */
            var fontSetClasses = this.fontSet ?
                [this._iconRegistry.classNameForFontAlias(this.fontSet)] :
                this._iconRegistry.getDefaultFontSetClass();
            (/** @type {?} */ (this._previousFontSetClass)).forEach((/**
             * @param {?} className
             * @return {?}
             */
            function (className) { return elem.classList.remove(className); }));
            fontSetClasses.forEach((/**
             * @param {?} className
             * @return {?}
             */
            function (className) { return elem.classList.add(className); }));
            this._previousFontSetClass = fontSetClasses;
            if (this.fontIcon !== this._previousFontIconClass) {
                if (this._previousFontIconClass) {
                    elem.classList.remove(this._previousFontIconClass);
                }
                if (this.fontIcon) {
                    elem.classList.add(this.fontIcon);
                }
                this._previousFontIconClass = this.fontIcon;
            }
        };
        /**
         * Cleans up a value to be used as a fontIcon or fontSet.
         * Since the value ends up being assigned as a CSS class, we
         * have to trim the value and omit space-separated values.
         */
        /**
         * Cleans up a value to be used as a fontIcon or fontSet.
         * Since the value ends up being assigned as a CSS class, we
         * have to trim the value and omit space-separated values.
         * @private
         * @param {?} value
         * @return {?}
         */
        MdcIcon.prototype._cleanupFontValue = /**
         * Cleans up a value to be used as a fontIcon or fontSet.
         * Since the value ends up being assigned as a CSS class, we
         * have to trim the value and omit space-separated values.
         * @private
         * @param {?} value
         * @return {?}
         */
        function (value) {
            return typeof value === 'string' ? value.trim().split(' ')[0] : value;
        };
        /**
         * Prepends the current path to all elements that have an attribute pointing to a `FuncIRI`
         * reference. This is required because WebKit browsers require references to be prefixed with
         * the current path, if the page has a `base` tag.
         */
        /**
         * Prepends the current path to all elements that have an attribute pointing to a `FuncIRI`
         * reference. This is required because WebKit browsers require references to be prefixed with
         * the current path, if the page has a `base` tag.
         * @private
         * @param {?} path
         * @return {?}
         */
        MdcIcon.prototype._prependPathToReferences = /**
         * Prepends the current path to all elements that have an attribute pointing to a `FuncIRI`
         * reference. This is required because WebKit browsers require references to be prefixed with
         * the current path, if the page has a `base` tag.
         * @private
         * @param {?} path
         * @return {?}
         */
        function (path) {
            /** @type {?} */
            var elements = this._elementsWithExternalReferences;
            if (elements) {
                elements.forEach((/**
                 * @param {?} attrs
                 * @param {?} element
                 * @return {?}
                 */
                function (attrs, element) {
                    attrs.forEach((/**
                     * @param {?} attr
                     * @return {?}
                     */
                    function (attr) {
                        element.setAttribute(attr.name, "url('" + path + "#" + attr.value + "')");
                    }));
                }));
            }
        };
        /**
         * Caches the children of an SVG element that have `url()`
         * references that we need to prefix with the current path.
         */
        /**
         * Caches the children of an SVG element that have `url()`
         * references that we need to prefix with the current path.
         * @private
         * @param {?} element
         * @return {?}
         */
        MdcIcon.prototype._cacheChildrenWithExternalReferences = /**
         * Caches the children of an SVG element that have `url()`
         * references that we need to prefix with the current path.
         * @private
         * @param {?} element
         * @return {?}
         */
        function (element) {
            /** @type {?} */
            var elementsWithFuncIri = element.querySelectorAll(funcIriAttributeSelector);
            /** @type {?} */
            var elements = this._elementsWithExternalReferences =
                this._elementsWithExternalReferences || new Map();
            var _loop_1 = function (i) {
                funcIriAttributes.forEach((/**
                 * @param {?} attr
                 * @return {?}
                 */
                function (attr) {
                    /** @type {?} */
                    var elementWithReference = elementsWithFuncIri[i];
                    /** @type {?} */
                    var value = elementWithReference.getAttribute(attr);
                    /** @type {?} */
                    var match = value ? value.match(funcIriPattern) : null;
                    if (match) {
                        /** @type {?} */
                        var attributes = elements.get(elementWithReference);
                        if (!attributes) {
                            attributes = [];
                            elements.set(elementWithReference, attributes);
                        }
                        (/** @type {?} */ (attributes)).push({ name: attr, value: match[1] });
                    }
                }));
            };
            for (var i = 0; i < elementsWithFuncIri.length; i++) {
                _loop_1(i);
            }
        };
        /** Retrieves the DOM element of the component host. */
        /**
         * Retrieves the DOM element of the component host.
         * @protected
         * @return {?}
         */
        MdcIcon.prototype._getHostElement = /**
         * Retrieves the DOM element of the component host.
         * @protected
         * @return {?}
         */
        function () {
            return this.elementRef.nativeElement;
        };
        MdcIcon.decorators = [
            { type: core.Component, args: [{selector: 'mdc-icon, [mdcIcon]',
                        exportAs: 'mdcIcon',
                        host: {
                            '[attr.role]': 'role',
                            'class': 'ngx-mdc-icon',
                            '[class.ngx-mdc-icon--clickable]': 'clickable',
                            '[class.ngx-mdc-icon--inline]': 'inline'
                        },
                        template: '<ng-content></ng-content>',
                        encapsulation: core.ViewEncapsulation.None,
                        changeDetection: core.ChangeDetectionStrategy.OnPush
                    },] },
        ];
        /** @nocollapse */
        MdcIcon.ctorParameters = function () { return [
            { type: core.ElementRef },
            { type: MdcIconRegistry },
            { type: String, decorators: [{ type: core.Attribute, args: ['aria-hidden',] }] },
            { type: undefined, decorators: [{ type: core.Inject, args: [MDC_ICON_LOCATION,] }] }
        ]; };
        MdcIcon.propDecorators = {
            inline: [{ type: core.Input }],
            svgIcon: [{ type: core.Input }],
            role: [{ type: core.Input }],
            fontSet: [{ type: core.Input }],
            fontIcon: [{ type: core.Input }],
            clickable: [{ type: core.Input }]
        };
        return MdcIcon;
    }());

    /**
     * @fileoverview added by tsickle
     * Generated from: icon/module.ts
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    /** @type {?} */
    var ICON_DECLARATIONS = [
        MdcIcon,
        MdcMaterialIcons
    ];
    var MdcIconModule = /** @class */ (function () {
        function MdcIconModule() {
        }
        MdcIconModule.decorators = [
            { type: core.NgModule, args: [{
                        exports: ICON_DECLARATIONS,
                        declarations: ICON_DECLARATIONS
                    },] },
        ];
        return MdcIconModule;
    }());

    exports.ICON_REGISTRY_PROVIDER = ICON_REGISTRY_PROVIDER;
    exports.ICON_REGISTRY_PROVIDER_FACTORY = ICON_REGISTRY_PROVIDER_FACTORY;
    exports.MDC_ICON_LOCATION = MDC_ICON_LOCATION;
    exports.MDC_ICON_LOCATION_FACTORY = MDC_ICON_LOCATION_FACTORY;
    exports.MdcIcon = MdcIcon;
    exports.MdcIconModule = MdcIconModule;
    exports.MdcIconRegistry = MdcIconRegistry;
    exports.MdcMaterialIcons = MdcMaterialIcons;
    exports.getMdcIconFailedToSanitizeLiteralError = getMdcIconFailedToSanitizeLiteralError;
    exports.getMdcIconFailedToSanitizeUrlError = getMdcIconFailedToSanitizeUrlError;
    exports.getMdcIconNameNotFoundError = getMdcIconNameNotFoundError;
    exports.getMdcIconNoHttpProviderError = getMdcIconNoHttpProviderError;

    Object.defineProperty(exports, '__esModule', { value: true });

})));
//# sourceMappingURL=web-icon.umd.js.map