angular-favicon
Version:
Angular service to set the favicon of a site, and an alternative one for dark mode
146 lines • 11.1 kB
JavaScript
/**
* @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