UNPKG

angular-favicon

Version:

Angular service to set the favicon of a site, and an alternative one for dark mode

146 lines 11.1 kB
/** * @fileoverview added by tsickle * Generated from: lib/angular-favicon.service.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import { Injectable, Inject, RendererFactory2 } from '@angular/core'; import { DOCUMENT } from '@angular/common'; import { fromEventPattern } from 'rxjs'; import { pluck } from 'rxjs/operators'; import * as i0 from "@angular/core"; import * as i1 from "@angular/common"; /** * A service to set the favicon. */ export class AngularFaviconService { /** * @param {?} _doc * @param {?} rendererFactory */ constructor(_doc, rendererFactory) { this._doc = _doc; this.rendererFactory = rendererFactory; this.darkScheme = '(prefers-color-scheme:dark)'; this.prefersColorScheme$ = fromEventPattern((/** * @param {?} handler * @return {?} */ handler => window.matchMedia(this.darkScheme).addListener((/** @type {?} */ (handler))))).pipe(pluck('matches')); this.renderer = rendererFactory.createRenderer(null, null); } /** * Get the favicon of the current HTML document. * @return {?} */ getFavicon() { return this._doc.querySelector("link[rel*='icon']"); } /** * Set the title of the current HTML document. * @param {?} iconURL - Default favicon URL * @param {?=} altIconURL - Optional, dark theme favicon URL * @return {?} */ setFavicon(iconURL, altIconURL) { /** @type {?} */ const link = this.getFavicon() || this.renderer.createElement('link'); /** @type {?} */ let currentLinkHref = iconURL; if (altIconURL) { this.subscribeToChangesInTheme(link, iconURL, altIconURL); if (window.matchMedia(this.darkScheme).matches) { currentLinkHref = altIconURL; } } this.appendLinkTag(link, currentLinkHref); } /** * Subscribe to the theme color changes in browser/OS and apply the appropiate favicon * @private * @param {?} link - DOM element * @param {?} iconURL - Default favicon URL * @param {?} altIconURL - Optional, dark theme favicon URL * @return {?} */ subscribeToChangesInTheme(link, iconURL, altIconURL) { this.subscriptionToColorScheme = this.prefersColorScheme$.subscribe((/** * @param {?} isDarkTheme * @return {?} */ isDarkTheme => { if (isDarkTheme) { this.appendLinkTag(link, altIconURL); } else { this.appendLinkTag(link, iconURL); } })); } /** * Append new link to HEAD * @private * @param {?} link - DOM element * @param {?} iconURL - favicon URL * @return {?} */ appendLinkTag(link, iconURL) { link.type = 'image/x-icon'; link.rel = 'shortcut icon'; link.href = iconURL; /** @type {?} */ const head = this._doc.getElementsByTagName('head')[0]; this.renderer.appendChild(head, link); } /** * @return {?} */ ngOnDestroy() { if (this.subscriptionToColorScheme) { this.subscriptionToColorScheme.unsubscribe(); } } } AngularFaviconService.decorators = [ { type: Injectable, args: [{ providedIn: 'root' },] } ]; /** @nocollapse */ AngularFaviconService.ctorParameters = () => [ { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] }] }, { type: RendererFactory2 } ]; /** @nocollapse */ AngularFaviconService.ɵprov = i0.ɵɵdefineInjectable({ factory: function AngularFaviconService_Factory() { return new AngularFaviconService(i0.ɵɵinject(i1.DOCUMENT), i0.ɵɵinject(i0.RendererFactory2)); }, token: AngularFaviconService, providedIn: "root" }); if (false) { /** * @type {?} * @private */ AngularFaviconService.prototype.renderer; /** * @type {?} * @private */ AngularFaviconService.prototype.darkScheme; /** * @type {?} * @private */ AngularFaviconService.prototype.subscriptionToColorScheme; /** * @type {?} * @private */ AngularFaviconService.prototype.prefersColorScheme$; /** * @type {?} * @private */ AngularFaviconService.prototype._doc; /** * @type {?} * @private */ AngularFaviconService.prototype.rendererFactory; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYW5ndWxhci1mYXZpY29uLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiL1VzZXJzL2RpZWdvL1dvcmtzcGFjZS9QZXJzb25hbC9OZ3gtRmF2aWNvbi9wcm9qZWN0cy9hbmd1bGFyLWZhdmljb24vc3JjLyIsInNvdXJjZXMiOlsibGliL2FuZ3VsYXItZmF2aWNvbi5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQXdCLGdCQUFnQixFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNGLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMzQyxPQUFPLEVBQUUsZ0JBQWdCLEVBQWdCLE1BQU0sTUFBTSxDQUFDO0FBQ3RELE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQzs7Ozs7O0FBUXZDLE1BQU0sT0FBTyxxQkFBcUI7Ozs7O0lBR2hDLFlBQXNDLElBQVMsRUFBVSxlQUFpQztRQUFwRCxTQUFJLEdBQUosSUFBSSxDQUFLO1FBQVUsb0JBQWUsR0FBZixlQUFlLENBQWtCO1FBSWxGLGVBQVUsR0FBRyw2QkFBNkIsQ0FBQztRQUUzQyx3QkFBbUIsR0FBRyxnQkFBZ0I7Ozs7UUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxtQkFBQSxPQUFPLEVBQWlCLENBQUMsRUFBQyxDQUFDLElBQUksQ0FDdEksS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUNqQixDQUFDO1FBUEEsSUFBSSxDQUFDLFFBQVEsR0FBRyxlQUFlLENBQUMsY0FBYyxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztJQUM3RCxDQUFDOzs7OztJQVdELFVBQVU7UUFDUixPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLG1CQUFtQixDQUFDLENBQUM7SUFDdEQsQ0FBQzs7Ozs7OztJQU9ELFVBQVUsQ0FBQyxPQUFlLEVBQUUsVUFBbUI7O2NBQ3ZDLElBQUksR0FBRyxJQUFJLENBQUMsVUFBVSxFQUFFLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDOztZQUNqRSxlQUFlLEdBQUcsT0FBTztRQUU3QixJQUFJLFVBQVUsRUFBRTtZQUNkLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxJQUFJLEVBQUUsT0FBTyxFQUFFLFVBQVUsQ0FBQyxDQUFDO1lBRTFELElBQUksTUFBTSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsT0FBTyxFQUFFO2dCQUM5QyxlQUFlLEdBQUcsVUFBVSxDQUFDO2FBQzlCO1NBQ0Y7UUFFRCxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksRUFBRSxlQUFlLENBQUMsQ0FBQztJQUM1QyxDQUFDOzs7Ozs7Ozs7SUFRTyx5QkFBeUIsQ0FBQyxJQUFTLEVBQUUsT0FBZSxFQUFFLFVBQWtCO1FBQzlFLElBQUksQ0FBQyx5QkFBeUIsR0FBRyxJQUFJLENBQUMsbUJBQW1CLENBQUMsU0FBUzs7OztRQUFDLFdBQVcsQ0FBQyxFQUFFO1lBQ2hGLElBQUksV0FBVyxFQUFFO2dCQUNmLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxFQUFFLFVBQVUsQ0FBQyxDQUFDO2FBQ3RDO2lCQUFNO2dCQUNMLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxFQUFFLE9BQU8sQ0FBQyxDQUFDO2FBQ25DO1FBQ0gsQ0FBQyxFQUFDLENBQUM7SUFDTCxDQUFDOzs7Ozs7OztJQU9PLGFBQWEsQ0FBQyxJQUFTLEVBQUUsT0FBZTtRQUM5QyxJQUFJLENBQUMsSUFBSSxHQUFHLGNBQWMsQ0FBQztRQUMzQixJQUFJLENBQUMsR0FBRyxHQUFHLGVBQWUsQ0FBQztRQUMzQixJQUFJLENBQUMsSUFBSSxHQUFHLE9BQU8sQ0FBQzs7Y0FDZCxJQUFJLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdEQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQ3hDLENBQUM7Ozs7SUFFRCxXQUFXO1FBQ1QsSUFBSSxJQUFJLENBQUMseUJBQXlCLEVBQUU7WUFDbEMsSUFBSSxDQUFDLHlCQUF5QixDQUFDLFdBQVcsRUFBRSxDQUFDO1NBQzlDO0lBQ0gsQ0FBQzs7O1lBNUVGLFVBQVUsU0FBQztnQkFDVixVQUFVLEVBQUUsTUFBTTthQUNuQjs7Ozs0Q0FJYyxNQUFNLFNBQUMsUUFBUTtZQWRxQixnQkFBZ0I7Ozs7Ozs7O0lBWWpFLHlDQUE0Qjs7Ozs7SUFNNUIsMkNBQW1EOzs7OztJQUNuRCwwREFBZ0Q7Ozs7O0lBQ2hELG9EQUVFOzs7OztJQVJVLHFDQUFtQzs7Ozs7SUFBRSxnREFBeUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlLCBJbmplY3QsIE9uRGVzdHJveSwgUmVuZGVyZXIyLCBSZW5kZXJlckZhY3RvcnkyIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBET0NVTUVOVCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBmcm9tRXZlbnRQYXR0ZXJuLCBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IHBsdWNrIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG4vKipcbiAqIEEgc2VydmljZSB0byBzZXQgdGhlIGZhdmljb24uXG4gKi9cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnXG59KVxuZXhwb3J0IGNsYXNzIEFuZ3VsYXJGYXZpY29uU2VydmljZSBpbXBsZW1lbnRzIE9uRGVzdHJveSB7XG4gIHByaXZhdGUgcmVuZGVyZXI6IFJlbmRlcmVyMjtcblxuICBjb25zdHJ1Y3RvcihASW5qZWN0KERPQ1VNRU5UKSBwcml2YXRlIF9kb2M6IGFueSwgcHJpdmF0ZSByZW5kZXJlckZhY3Rvcnk6IFJlbmRlcmVyRmFjdG9yeTIpIHtcbiAgICB0aGlzLnJlbmRlcmVyID0gcmVuZGVyZXJGYWN0b3J5LmNyZWF0ZVJlbmRlcmVyKG51bGwsIG51bGwpO1xuICB9XG5cbiAgcHJpdmF0ZSBkYXJrU2NoZW1lID0gJyhwcmVmZXJzLWNvbG9yLXNjaGVtZTpkYXJrKSc7XG4gIHByaXZhdGUgc3Vic2NyaXB0aW9uVG9Db2xvclNjaGVtZTogU3Vic2NyaXB0aW9uO1xuICBwcml2YXRlIHByZWZlcnNDb2xvclNjaGVtZSQgPSBmcm9tRXZlbnRQYXR0ZXJuKGhhbmRsZXIgPT4gd2luZG93Lm1hdGNoTWVkaWEodGhpcy5kYXJrU2NoZW1lKS5hZGRMaXN0ZW5lcihoYW5kbGVyIGFzIEV2ZW50TGlzdGVuZXIpKS5waXBlKFxuICAgIHBsdWNrKCdtYXRjaGVzJylcbiAgKTtcblxuICAvKipcbiAgICogR2V0IHRoZSBmYXZpY29uIG9mIHRoZSBjdXJyZW50IEhUTUwgZG9jdW1lbnQuXG4gICAqL1xuICBnZXRGYXZpY29uKCkge1xuICAgIHJldHVybiB0aGlzLl9kb2MucXVlcnlTZWxlY3RvcihcImxpbmtbcmVsKj0naWNvbiddXCIpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldCB0aGUgdGl0bGUgb2YgdGhlIGN1cnJlbnQgSFRNTCBkb2N1bWVudC5cbiAgICogQHBhcmFtIGljb25VUkwgLSBEZWZhdWx0IGZhdmljb24gVVJMXG4gICAqIEBwYXJhbSBhbHRJY29uVVJMIC0gT3B0aW9uYWwsIGRhcmsgdGhlbWUgZmF2aWNvbiBVUkxcbiAgICovXG4gIHNldEZhdmljb24oaWNvblVSTDogc3RyaW5nLCBhbHRJY29uVVJMPzogc3RyaW5nKSB7XG4gICAgY29uc3QgbGluayA9IHRoaXMuZ2V0RmF2aWNvbigpIHx8IHRoaXMucmVuZGVyZXIuY3JlYXRlRWxlbWVudCgnbGluaycpO1xuICAgIGxldCBjdXJyZW50TGlua0hyZWYgPSBpY29uVVJMO1xuXG4gICAgaWYgKGFsdEljb25VUkwpIHtcbiAgICAgIHRoaXMuc3Vic2NyaWJlVG9DaGFuZ2VzSW5UaGVtZShsaW5rLCBpY29uVVJMLCBhbHRJY29uVVJMKTtcblxuICAgICAgaWYgKHdpbmRvdy5tYXRjaE1lZGlhKHRoaXMuZGFya1NjaGVtZSkubWF0Y2hlcykge1xuICAgICAgICBjdXJyZW50TGlua0hyZWYgPSBhbHRJY29uVVJMO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuYXBwZW5kTGlua1RhZyhsaW5rLCBjdXJyZW50TGlua0hyZWYpO1xuICB9XG5cbiAgLyoqXG4gICAqIFN1YnNjcmliZSB0byB0aGUgdGhlbWUgY29sb3IgY2hhbmdlcyBpbiBicm93c2VyL09TIGFuZCBhcHBseSB0aGUgYXBwcm9waWF0ZSBmYXZpY29uXG4gICAqIEBwYXJhbSBsaW5rIC0gRE9NIGVsZW1lbnRcbiAgICogQHBhcmFtIGljb25VUkwgLSBEZWZhdWx0IGZhdmljb24gVVJMXG4gICAqIEBwYXJhbSBhbHRJY29uVVJMIC0gT3B0aW9uYWwsIGRhcmsgdGhlbWUgZmF2aWNvbiBVUkxcbiAgICovXG4gIHByaXZhdGUgc3Vic2NyaWJlVG9DaGFuZ2VzSW5UaGVtZShsaW5rOiBhbnksIGljb25VUkw6IHN0cmluZywgYWx0SWNvblVSTDogc3RyaW5nKSB7XG4gICAgdGhpcy5zdWJzY3JpcHRpb25Ub0NvbG9yU2NoZW1lID0gdGhpcy5wcmVmZXJzQ29sb3JTY2hlbWUkLnN1YnNjcmliZShpc0RhcmtUaGVtZSA9PiB7XG4gICAgICBpZiAoaXNEYXJrVGhlbWUpIHtcbiAgICAgICAgdGhpcy5hcHBlbmRMaW5rVGFnKGxpbmssIGFsdEljb25VUkwpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5hcHBlbmRMaW5rVGFnKGxpbmssIGljb25VUkwpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEFwcGVuZCBuZXcgbGluayB0byBIRUFEXG4gICAqIEBwYXJhbSBsaW5rIC0gRE9NIGVsZW1lbnRcbiAgICogQHBhcmFtIGljb25VUkwgLSBmYXZpY29uIFVSTFxuICAgKi9cbiAgcHJpdmF0ZSBhcHBlbmRMaW5rVGFnKGxpbms6IGFueSwgaWNvblVSTDogc3RyaW5nKSB7XG4gICAgbGluay50eXBlID0gJ2ltYWdlL3gtaWNvbic7XG4gICAgbGluay5yZWwgPSAnc2hvcnRjdXQgaWNvbic7XG4gICAgbGluay5ocmVmID0gaWNvblVSTDtcbiAgICBjb25zdCBoZWFkID0gdGhpcy5fZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCdoZWFkJylbMF07XG4gICAgdGhpcy5yZW5kZXJlci5hcHBlbmRDaGlsZChoZWFkLCBsaW5rKTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCkge1xuICAgIGlmICh0aGlzLnN1YnNjcmlwdGlvblRvQ29sb3JTY2hlbWUpIHtcbiAgICAgIHRoaXMuc3Vic2NyaXB0aW9uVG9Db2xvclNjaGVtZS51bnN1YnNjcmliZSgpO1xuICAgIH1cbiAgfVxufVxuIl19