1- import { Injectable , Optional , SkipSelf } from '@angular/core' ;
1+ import { Inject , Injectable , Optional , SkipSelf } from '@angular/core' ;
22import { HttpClient } from '@angular/common/http' ;
33
44import { Observable } from 'rxjs/Observable' ;
@@ -8,57 +8,62 @@ import 'rxjs/add/operator/do';
88import 'rxjs/add/operator/finally' ;
99import 'rxjs/add/operator/map' ;
1010import 'rxjs/add/operator/share' ;
11+ import 'rxjs/observable/throw' ;
1112
12-
13- @Injectable ( )
1413export class SvgIconRegistryService {
1514
16- private iconsByUrl = new Map < string , SVGElement > ( ) ;
17- private iconsLoadingByUrl = new Map < string , Observable < SVGElement > > ( ) ;
18-
19- constructor ( private http :HttpClient ) {
20- }
15+ private iconsByUrl = new Map < string , SVGElement > ( ) ;
16+ private iconsLoadingByUrl = new Map < string , Observable < SVGElement > > ( ) ;
2117
22- loadSvg ( url :string ) : Observable < SVGElement > {
18+ constructor ( private http : HttpClient , private fallbackIconUrl : string ) {
19+ }
2320
24- if ( this . iconsByUrl . has ( url ) ) {
25- return Observable . of ( this . iconsByUrl . get ( url ) ) ;
26- } else if ( this . iconsLoadingByUrl . has ( url ) ) {
27- return this . iconsLoadingByUrl . get ( url ) ;
28- } else {
29- const o = < Observable < SVGElement > > this . http . get ( url , { responseType : 'text' } )
30- . map ( svg => {
31- const div = document . createElement ( 'DIV' ) ;
32- div . innerHTML = svg ;
33- return < SVGElement > div . querySelector ( 'svg' ) ;
34- } )
35- . do ( svg => {
36- this . iconsByUrl . set ( url , svg ) ;
37- } )
38- . finally ( ( ) => {
39- this . iconsLoadingByUrl . delete ( url ) ;
40- } )
41- . share ( ) ;
21+ loadSvg ( url : string ) : Observable < SVGElement > {
22+ if ( this . iconsByUrl . has ( url ) ) {
23+ return Observable . of ( this . iconsByUrl . get ( url ) ) ;
24+ } else if ( this . iconsLoadingByUrl . has ( url ) ) {
25+ return this . iconsLoadingByUrl . get ( url ) ;
26+ } else {
27+ const o = this . http . get ( url , { responseType : 'text' } )
28+ . map ( svg => {
29+ const div = document . createElement ( 'DIV' ) ;
30+ div . innerHTML = svg ;
31+ return < SVGElement > div . querySelector ( 'svg' ) ;
32+ } )
33+ . catch ( ( error ) => {
34+ if ( this . fallbackIconUrl ) {
35+ return this . loadSvg ( this . fallbackIconUrl ) ;
36+ } else {
37+ return Observable . throw ( error ) ;
38+ }
39+ } )
40+ . do ( svg => {
41+ this . iconsByUrl . set ( url , svg ) ;
42+ } )
43+ . finally ( ( ) => {
44+ this . iconsLoadingByUrl . delete ( url ) ;
45+ } )
46+ . share ( ) ;
47+ this . iconsLoadingByUrl . set ( url , o ) ;
48+ return o ;
49+ }
4250
43- this . iconsLoadingByUrl . set ( url , o ) ;
44- return o ;
45- }
46- }
51+ }
4752
48- unloadSvg ( url :string ) {
49- if ( this . iconsByUrl . has ( url ) ) {
50- this . iconsByUrl . delete ( url ) ;
51- }
52- }
53+ unloadSvg ( url : string ) {
54+ if ( this . iconsByUrl . has ( url ) ) {
55+ this . iconsByUrl . delete ( url ) ;
56+ }
57+ }
5358
5459}
5560
56- export function SVG_ICON_REGISTRY_PROVIDER_FACTORY ( parentRegistry :SvgIconRegistryService , http :HttpClient ) {
57- return parentRegistry || new SvgIconRegistryService ( http ) ;
61+ export function SVG_ICON_REGISTRY_PROVIDER_FACTORY ( parentRegistry : SvgIconRegistryService , http : HttpClient , fallBackIconUrl : string ) {
62+ return parentRegistry || new SvgIconRegistryService ( http , fallBackIconUrl ) ;
5863}
5964
6065export const SVG_ICON_REGISTRY_PROVIDER = {
61- provide : SvgIconRegistryService ,
62- deps : [ [ new Optional ( ) , new SkipSelf ( ) , SvgIconRegistryService ] , HttpClient ] ,
63- useFactory : SVG_ICON_REGISTRY_PROVIDER_FACTORY
66+ provide : SvgIconRegistryService ,
67+ deps : [ [ new Optional ( ) , new SkipSelf ( ) , SvgIconRegistryService ] , HttpClient , [ new Inject ( 'FALLBACK_ICON' ) ] ] ,
68+ useFactory : SVG_ICON_REGISTRY_PROVIDER_FACTORY ,
6469} ;
0 commit comments