@@ -64,6 +64,11 @@ export function getMatIconFailedToSanitizeLiteralError(literal: SafeHtml): Error
64
64
`Angular's DomSanitizer. Attempted literal was "${ literal } ".` ) ;
65
65
}
66
66
67
+ /** Options that can be used to configure how an icon or the icons in an icon set are presented. */
68
+ export interface IconOptions {
69
+ /** View box to set on the icon. */
70
+ viewBox ?: string ;
71
+ }
67
72
68
73
/**
69
74
* Configuration for an icon, including the URL and possibly the cached SVG element.
@@ -73,9 +78,9 @@ class SvgIconConfig {
73
78
url : SafeResourceUrl | null ;
74
79
svgElement : SVGElement | null ;
75
80
76
- constructor ( url : SafeResourceUrl ) ;
77
- constructor ( svgElement : SVGElement ) ;
78
- constructor ( data : SafeResourceUrl | SVGElement ) {
81
+ constructor ( url : SafeResourceUrl , options ?: IconOptions ) ;
82
+ constructor ( svgElement : SVGElement , options ?: IconOptions ) ;
83
+ constructor ( data : SafeResourceUrl | SVGElement , public options ?: IconOptions ) {
79
84
// Note that we can't use `instanceof SVGElement` here,
80
85
// because it'll break during server-side rendering.
81
86
if ( ! ! ( data as any ) . nodeName ) {
@@ -136,17 +141,17 @@ export class MatIconRegistry implements OnDestroy {
136
141
* @param iconName Name under which the icon should be registered.
137
142
* @param url
138
143
*/
139
- addSvgIcon ( iconName : string , url : SafeResourceUrl ) : this {
140
- return this . addSvgIconInNamespace ( '' , iconName , url ) ;
144
+ addSvgIcon ( iconName : string , url : SafeResourceUrl , options ?: IconOptions ) : this {
145
+ return this . addSvgIconInNamespace ( '' , iconName , url , options ) ;
141
146
}
142
147
143
148
/**
144
149
* Registers an icon using an HTML string in the default namespace.
145
150
* @param iconName Name under which the icon should be registered.
146
151
* @param literal SVG source of the icon.
147
152
*/
148
- addSvgIconLiteral ( iconName : string , literal : SafeHtml ) : this {
149
- return this . addSvgIconLiteralInNamespace ( '' , iconName , literal ) ;
153
+ addSvgIconLiteral ( iconName : string , literal : SafeHtml , options ?: IconOptions ) : this {
154
+ return this . addSvgIconLiteralInNamespace ( '' , iconName , literal , options ) ;
150
155
}
151
156
152
157
/**
@@ -155,8 +160,9 @@ export class MatIconRegistry implements OnDestroy {
155
160
* @param iconName Name under which the icon should be registered.
156
161
* @param url
157
162
*/
158
- addSvgIconInNamespace ( namespace : string , iconName : string , url : SafeResourceUrl ) : this {
159
- return this . _addSvgIconConfig ( namespace , iconName , new SvgIconConfig ( url ) ) ;
163
+ addSvgIconInNamespace ( namespace : string , iconName : string , url : SafeResourceUrl ,
164
+ options ?: IconOptions ) : this {
165
+ return this . _addSvgIconConfig ( namespace , iconName , new SvgIconConfig ( url , options ) ) ;
160
166
}
161
167
162
168
/**
@@ -165,56 +171,58 @@ export class MatIconRegistry implements OnDestroy {
165
171
* @param iconName Name under which the icon should be registered.
166
172
* @param literal SVG source of the icon.
167
173
*/
168
- addSvgIconLiteralInNamespace ( namespace : string , iconName : string , literal : SafeHtml ) : this {
174
+ addSvgIconLiteralInNamespace ( namespace : string , iconName : string , literal : SafeHtml ,
175
+ options ?: IconOptions ) : this {
169
176
const sanitizedLiteral = this . _sanitizer . sanitize ( SecurityContext . HTML , literal ) ;
170
177
171
178
if ( ! sanitizedLiteral ) {
172
179
throw getMatIconFailedToSanitizeLiteralError ( literal ) ;
173
180
}
174
181
175
- const svgElement = this . _createSvgElementForSingleIcon ( sanitizedLiteral ) ;
176
- return this . _addSvgIconConfig ( namespace , iconName , new SvgIconConfig ( svgElement ) ) ;
182
+ const svgElement = this . _createSvgElementForSingleIcon ( sanitizedLiteral , options ) ;
183
+ return this . _addSvgIconConfig ( namespace , iconName , new SvgIconConfig ( svgElement , options ) ) ;
177
184
}
178
185
179
186
/**
180
187
* Registers an icon set by URL in the default namespace.
181
188
* @param url
182
189
*/
183
- addSvgIconSet ( url : SafeResourceUrl ) : this {
184
- return this . addSvgIconSetInNamespace ( '' , url ) ;
190
+ addSvgIconSet ( url : SafeResourceUrl , options ?: IconOptions ) : this {
191
+ return this . addSvgIconSetInNamespace ( '' , url , options ) ;
185
192
}
186
193
187
194
/**
188
195
* Registers an icon set using an HTML string in the default namespace.
189
196
* @param literal SVG source of the icon set.
190
197
*/
191
- addSvgIconSetLiteral ( literal : SafeHtml ) : this {
192
- return this . addSvgIconSetLiteralInNamespace ( '' , literal ) ;
198
+ addSvgIconSetLiteral ( literal : SafeHtml , options ?: IconOptions ) : this {
199
+ return this . addSvgIconSetLiteralInNamespace ( '' , literal , options ) ;
193
200
}
194
201
195
202
/**
196
203
* Registers an icon set by URL in the specified namespace.
197
204
* @param namespace Namespace in which to register the icon set.
198
205
* @param url
199
206
*/
200
- addSvgIconSetInNamespace ( namespace : string , url : SafeResourceUrl ) : this {
201
- return this . _addSvgIconSetConfig ( namespace , new SvgIconConfig ( url ) ) ;
207
+ addSvgIconSetInNamespace ( namespace : string , url : SafeResourceUrl , options ?: IconOptions ) : this {
208
+ return this . _addSvgIconSetConfig ( namespace , new SvgIconConfig ( url , options ) ) ;
202
209
}
203
210
204
211
/**
205
212
* Registers an icon set using an HTML string in the specified namespace.
206
213
* @param namespace Namespace in which to register the icon set.
207
214
* @param literal SVG source of the icon set.
208
215
*/
209
- addSvgIconSetLiteralInNamespace ( namespace : string , literal : SafeHtml ) : this {
216
+ addSvgIconSetLiteralInNamespace ( namespace : string , literal : SafeHtml ,
217
+ options ?: IconOptions ) : this {
210
218
const sanitizedLiteral = this . _sanitizer . sanitize ( SecurityContext . HTML , literal ) ;
211
219
212
220
if ( ! sanitizedLiteral ) {
213
221
throw getMatIconFailedToSanitizeLiteralError ( literal ) ;
214
222
}
215
223
216
224
const svgElement = this . _svgElementFromString ( sanitizedLiteral ) ;
217
- return this . _addSvgIconSetConfig ( namespace , new SvgIconConfig ( svgElement ) ) ;
225
+ return this . _addSvgIconSetConfig ( namespace , new SvgIconConfig ( svgElement , options ) ) ;
218
226
}
219
227
220
228
/**
@@ -395,7 +403,7 @@ export class MatIconRegistry implements OnDestroy {
395
403
for ( let i = iconSetConfigs . length - 1 ; i >= 0 ; i -- ) {
396
404
const config = iconSetConfigs [ i ] ;
397
405
if ( config . svgElement ) {
398
- const foundIcon = this . _extractSvgIconFromSet ( config . svgElement , iconName ) ;
406
+ const foundIcon = this . _extractSvgIconFromSet ( config . svgElement , iconName , config . options ) ;
399
407
if ( foundIcon ) {
400
408
return foundIcon ;
401
409
}
@@ -410,7 +418,7 @@ export class MatIconRegistry implements OnDestroy {
410
418
*/
411
419
private _loadSvgIconFromConfig ( config : SvgIconConfig ) : Observable < SVGElement > {
412
420
return this . _fetchUrl ( config . url )
413
- . pipe ( map ( svgText => this . _createSvgElementForSingleIcon ( svgText ) ) ) ;
421
+ . pipe ( map ( svgText => this . _createSvgElementForSingleIcon ( svgText , config . options ) ) ) ;
414
422
}
415
423
416
424
/**
@@ -437,9 +445,9 @@ export class MatIconRegistry implements OnDestroy {
437
445
/**
438
446
* Creates a DOM element from the given SVG string, and adds default attributes.
439
447
*/
440
- private _createSvgElementForSingleIcon ( responseText : string ) : SVGElement {
448
+ private _createSvgElementForSingleIcon ( responseText : string , options ?: IconOptions ) : SVGElement {
441
449
const svg = this . _svgElementFromString ( responseText ) ;
442
- this . _setSvgAttributes ( svg ) ;
450
+ this . _setSvgAttributes ( svg , options ) ;
443
451
return svg ;
444
452
}
445
453
@@ -448,7 +456,8 @@ export class MatIconRegistry implements OnDestroy {
448
456
* tag matches the specified name. If found, copies the nested element to a new SVG element and
449
457
* returns it. Returns null if no matching element is found.
450
458
*/
451
- private _extractSvgIconFromSet ( iconSet : SVGElement , iconName : string ) : SVGElement | null {
459
+ private _extractSvgIconFromSet ( iconSet : SVGElement , iconName : string ,
460
+ options ?: IconOptions ) : SVGElement | null {
452
461
// Use the `id="iconName"` syntax in order to escape special
453
462
// characters in the ID (versus using the #iconName syntax).
454
463
const iconSource = iconSet . querySelector ( `[id="${ iconName } "]` ) ;
@@ -465,14 +474,14 @@ export class MatIconRegistry implements OnDestroy {
465
474
// If the icon node is itself an <svg> node, clone and return it directly. If not, set it as
466
475
// the content of a new <svg> node.
467
476
if ( iconElement . nodeName . toLowerCase ( ) === 'svg' ) {
468
- return this . _setSvgAttributes ( iconElement as SVGElement ) ;
477
+ return this . _setSvgAttributes ( iconElement as SVGElement , options ) ;
469
478
}
470
479
471
480
// If the node is a <symbol>, it won't be rendered so we have to convert it into <svg>. Note
472
481
// that the same could be achieved by referring to it via <use href="#id">, however the <use>
473
482
// tag is problematic on Firefox, because it needs to include the current page path.
474
483
if ( iconElement . nodeName . toLowerCase ( ) === 'symbol' ) {
475
- return this . _setSvgAttributes ( this . _toSvgElement ( iconElement ) ) ;
484
+ return this . _setSvgAttributes ( this . _toSvgElement ( iconElement ) , options ) ;
476
485
}
477
486
478
487
// createElement('SVG') doesn't work as expected; the DOM ends up with
@@ -484,7 +493,7 @@ export class MatIconRegistry implements OnDestroy {
484
493
// Clone the node so we don't remove it from the parent icon set element.
485
494
svg . appendChild ( iconElement ) ;
486
495
487
- return this . _setSvgAttributes ( svg ) ;
496
+ return this . _setSvgAttributes ( svg , options ) ;
488
497
}
489
498
490
499
/**
@@ -520,12 +529,17 @@ export class MatIconRegistry implements OnDestroy {
520
529
/**
521
530
* Sets the default attributes for an SVG element to be used as an icon.
522
531
*/
523
- private _setSvgAttributes ( svg : SVGElement ) : SVGElement {
532
+ private _setSvgAttributes ( svg : SVGElement , options ?: IconOptions ) : SVGElement {
524
533
svg . setAttribute ( 'fit' , '' ) ;
525
534
svg . setAttribute ( 'height' , '100%' ) ;
526
535
svg . setAttribute ( 'width' , '100%' ) ;
527
536
svg . setAttribute ( 'preserveAspectRatio' , 'xMidYMid meet' ) ;
528
537
svg . setAttribute ( 'focusable' , 'false' ) ; // Disable IE11 default behavior to make SVGs focusable.
538
+
539
+ if ( options && options . viewBox ) {
540
+ svg . setAttribute ( 'viewBox' , options . viewBox ) ;
541
+ }
542
+
529
543
return svg ;
530
544
}
531
545
0 commit comments