@@ -64,6 +64,11 @@ export function getMatIconFailedToSanitizeLiteralError(literal: SafeHtml): Error
6464 `Angular's DomSanitizer. Attempted literal was "${ literal } ".` ) ;
6565}
6666
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+ }
6772
6873/**
6974 * Configuration for an icon, including the URL and possibly the cached SVG element.
@@ -73,9 +78,9 @@ class SvgIconConfig {
7378 url : SafeResourceUrl | null ;
7479 svgElement : SVGElement | null ;
7580
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 ) {
7984 // Note that we can't use `instanceof SVGElement` here,
8085 // because it'll break during server-side rendering.
8186 if ( ! ! ( data as any ) . nodeName ) {
@@ -136,17 +141,17 @@ export class MatIconRegistry implements OnDestroy {
136141 * @param iconName Name under which the icon should be registered.
137142 * @param url
138143 */
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 ) ;
141146 }
142147
143148 /**
144149 * Registers an icon using an HTML string in the default namespace.
145150 * @param iconName Name under which the icon should be registered.
146151 * @param literal SVG source of the icon.
147152 */
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 ) ;
150155 }
151156
152157 /**
@@ -155,8 +160,9 @@ export class MatIconRegistry implements OnDestroy {
155160 * @param iconName Name under which the icon should be registered.
156161 * @param url
157162 */
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 ) ) ;
160166 }
161167
162168 /**
@@ -165,56 +171,58 @@ export class MatIconRegistry implements OnDestroy {
165171 * @param iconName Name under which the icon should be registered.
166172 * @param literal SVG source of the icon.
167173 */
168- addSvgIconLiteralInNamespace ( namespace : string , iconName : string , literal : SafeHtml ) : this {
174+ addSvgIconLiteralInNamespace ( namespace : string , iconName : string , literal : SafeHtml ,
175+ options ?: IconOptions ) : this {
169176 const sanitizedLiteral = this . _sanitizer . sanitize ( SecurityContext . HTML , literal ) ;
170177
171178 if ( ! sanitizedLiteral ) {
172179 throw getMatIconFailedToSanitizeLiteralError ( literal ) ;
173180 }
174181
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 ) ) ;
177184 }
178185
179186 /**
180187 * Registers an icon set by URL in the default namespace.
181188 * @param url
182189 */
183- addSvgIconSet ( url : SafeResourceUrl ) : this {
184- return this . addSvgIconSetInNamespace ( '' , url ) ;
190+ addSvgIconSet ( url : SafeResourceUrl , options ?: IconOptions ) : this {
191+ return this . addSvgIconSetInNamespace ( '' , url , options ) ;
185192 }
186193
187194 /**
188195 * Registers an icon set using an HTML string in the default namespace.
189196 * @param literal SVG source of the icon set.
190197 */
191- addSvgIconSetLiteral ( literal : SafeHtml ) : this {
192- return this . addSvgIconSetLiteralInNamespace ( '' , literal ) ;
198+ addSvgIconSetLiteral ( literal : SafeHtml , options ?: IconOptions ) : this {
199+ return this . addSvgIconSetLiteralInNamespace ( '' , literal , options ) ;
193200 }
194201
195202 /**
196203 * Registers an icon set by URL in the specified namespace.
197204 * @param namespace Namespace in which to register the icon set.
198205 * @param url
199206 */
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 ) ) ;
202209 }
203210
204211 /**
205212 * Registers an icon set using an HTML string in the specified namespace.
206213 * @param namespace Namespace in which to register the icon set.
207214 * @param literal SVG source of the icon set.
208215 */
209- addSvgIconSetLiteralInNamespace ( namespace : string , literal : SafeHtml ) : this {
216+ addSvgIconSetLiteralInNamespace ( namespace : string , literal : SafeHtml ,
217+ options ?: IconOptions ) : this {
210218 const sanitizedLiteral = this . _sanitizer . sanitize ( SecurityContext . HTML , literal ) ;
211219
212220 if ( ! sanitizedLiteral ) {
213221 throw getMatIconFailedToSanitizeLiteralError ( literal ) ;
214222 }
215223
216224 const svgElement = this . _svgElementFromString ( sanitizedLiteral ) ;
217- return this . _addSvgIconSetConfig ( namespace , new SvgIconConfig ( svgElement ) ) ;
225+ return this . _addSvgIconSetConfig ( namespace , new SvgIconConfig ( svgElement , options ) ) ;
218226 }
219227
220228 /**
@@ -395,7 +403,7 @@ export class MatIconRegistry implements OnDestroy {
395403 for ( let i = iconSetConfigs . length - 1 ; i >= 0 ; i -- ) {
396404 const config = iconSetConfigs [ i ] ;
397405 if ( config . svgElement ) {
398- const foundIcon = this . _extractSvgIconFromSet ( config . svgElement , iconName ) ;
406+ const foundIcon = this . _extractSvgIconFromSet ( config . svgElement , iconName , config . options ) ;
399407 if ( foundIcon ) {
400408 return foundIcon ;
401409 }
@@ -410,7 +418,7 @@ export class MatIconRegistry implements OnDestroy {
410418 */
411419 private _loadSvgIconFromConfig ( config : SvgIconConfig ) : Observable < SVGElement > {
412420 return this . _fetchUrl ( config . url )
413- . pipe ( map ( svgText => this . _createSvgElementForSingleIcon ( svgText ) ) ) ;
421+ . pipe ( map ( svgText => this . _createSvgElementForSingleIcon ( svgText , config . options ) ) ) ;
414422 }
415423
416424 /**
@@ -437,9 +445,9 @@ export class MatIconRegistry implements OnDestroy {
437445 /**
438446 * Creates a DOM element from the given SVG string, and adds default attributes.
439447 */
440- private _createSvgElementForSingleIcon ( responseText : string ) : SVGElement {
448+ private _createSvgElementForSingleIcon ( responseText : string , options ?: IconOptions ) : SVGElement {
441449 const svg = this . _svgElementFromString ( responseText ) ;
442- this . _setSvgAttributes ( svg ) ;
450+ this . _setSvgAttributes ( svg , options ) ;
443451 return svg ;
444452 }
445453
@@ -448,7 +456,8 @@ export class MatIconRegistry implements OnDestroy {
448456 * tag matches the specified name. If found, copies the nested element to a new SVG element and
449457 * returns it. Returns null if no matching element is found.
450458 */
451- private _extractSvgIconFromSet ( iconSet : SVGElement , iconName : string ) : SVGElement | null {
459+ private _extractSvgIconFromSet ( iconSet : SVGElement , iconName : string ,
460+ options ?: IconOptions ) : SVGElement | null {
452461 // Use the `id="iconName"` syntax in order to escape special
453462 // characters in the ID (versus using the #iconName syntax).
454463 const iconSource = iconSet . querySelector ( `[id="${ iconName } "]` ) ;
@@ -465,14 +474,14 @@ export class MatIconRegistry implements OnDestroy {
465474 // If the icon node is itself an <svg> node, clone and return it directly. If not, set it as
466475 // the content of a new <svg> node.
467476 if ( iconElement . nodeName . toLowerCase ( ) === 'svg' ) {
468- return this . _setSvgAttributes ( iconElement as SVGElement ) ;
477+ return this . _setSvgAttributes ( iconElement as SVGElement , options ) ;
469478 }
470479
471480 // If the node is a <symbol>, it won't be rendered so we have to convert it into <svg>. Note
472481 // that the same could be achieved by referring to it via <use href="#id">, however the <use>
473482 // tag is problematic on Firefox, because it needs to include the current page path.
474483 if ( iconElement . nodeName . toLowerCase ( ) === 'symbol' ) {
475- return this . _setSvgAttributes ( this . _toSvgElement ( iconElement ) ) ;
484+ return this . _setSvgAttributes ( this . _toSvgElement ( iconElement ) , options ) ;
476485 }
477486
478487 // createElement('SVG') doesn't work as expected; the DOM ends up with
@@ -484,7 +493,7 @@ export class MatIconRegistry implements OnDestroy {
484493 // Clone the node so we don't remove it from the parent icon set element.
485494 svg . appendChild ( iconElement ) ;
486495
487- return this . _setSvgAttributes ( svg ) ;
496+ return this . _setSvgAttributes ( svg , options ) ;
488497 }
489498
490499 /**
@@ -520,12 +529,17 @@ export class MatIconRegistry implements OnDestroy {
520529 /**
521530 * Sets the default attributes for an SVG element to be used as an icon.
522531 */
523- private _setSvgAttributes ( svg : SVGElement ) : SVGElement {
532+ private _setSvgAttributes ( svg : SVGElement , options ?: IconOptions ) : SVGElement {
524533 svg . setAttribute ( 'fit' , '' ) ;
525534 svg . setAttribute ( 'height' , '100%' ) ;
526535 svg . setAttribute ( 'width' , '100%' ) ;
527536 svg . setAttribute ( 'preserveAspectRatio' , 'xMidYMid meet' ) ;
528537 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+
529543 return svg ;
530544 }
531545
0 commit comments