@@ -73,9 +73,9 @@ class SvgIconConfig {
7373 url : SafeResourceUrl | null ;
7474 svgElement : SVGElement | null ;
7575
76- constructor ( url : SafeResourceUrl ) ;
77- constructor ( svgElement : SVGElement ) ;
78- constructor ( data : SafeResourceUrl | SVGElement ) {
76+ constructor ( url : SafeResourceUrl , viewBox ?: string ) ;
77+ constructor ( svgElement : SVGElement , viewBox ?: string ) ;
78+ constructor ( data : SafeResourceUrl | SVGElement , public viewBox ?: string ) {
7979 // Note that we can't use `instanceof SVGElement` here,
8080 // because it'll break during server-side rendering.
8181 if ( ! ! ( data as any ) . nodeName ) {
@@ -136,17 +136,17 @@ export class MatIconRegistry implements OnDestroy {
136136 * @param iconName Name under which the icon should be registered.
137137 * @param url
138138 */
139- addSvgIcon ( iconName : string , url : SafeResourceUrl ) : this {
140- return this . addSvgIconInNamespace ( '' , iconName , url ) ;
139+ addSvgIcon ( iconName : string , url : SafeResourceUrl , viewBox ?: string ) : this {
140+ return this . addSvgIconInNamespace ( '' , iconName , url , viewBox ) ;
141141 }
142142
143143 /**
144144 * Registers an icon using an HTML string in the default namespace.
145145 * @param iconName Name under which the icon should be registered.
146146 * @param literal SVG source of the icon.
147147 */
148- addSvgIconLiteral ( iconName : string , literal : SafeHtml ) : this {
149- return this . addSvgIconLiteralInNamespace ( '' , iconName , literal ) ;
148+ addSvgIconLiteral ( iconName : string , literal : SafeHtml , viewBox ?: string ) : this {
149+ return this . addSvgIconLiteralInNamespace ( '' , iconName , literal , viewBox ) ;
150150 }
151151
152152 /**
@@ -155,8 +155,9 @@ export class MatIconRegistry implements OnDestroy {
155155 * @param iconName Name under which the icon should be registered.
156156 * @param url
157157 */
158- addSvgIconInNamespace ( namespace : string , iconName : string , url : SafeResourceUrl ) : this {
159- return this . _addSvgIconConfig ( namespace , iconName , new SvgIconConfig ( url ) ) ;
158+ addSvgIconInNamespace ( namespace : string , iconName : string , url : SafeResourceUrl ,
159+ viewBox ?: string ) : this {
160+ return this . _addSvgIconConfig ( namespace , iconName , new SvgIconConfig ( url , viewBox ) ) ;
160161 }
161162
162163 /**
@@ -165,56 +166,57 @@ export class MatIconRegistry implements OnDestroy {
165166 * @param iconName Name under which the icon should be registered.
166167 * @param literal SVG source of the icon.
167168 */
168- addSvgIconLiteralInNamespace ( namespace : string , iconName : string , literal : SafeHtml ) : this {
169+ addSvgIconLiteralInNamespace ( namespace : string , iconName : string , literal : SafeHtml ,
170+ viewBox ?: string ) : this {
169171 const sanitizedLiteral = this . _sanitizer . sanitize ( SecurityContext . HTML , literal ) ;
170172
171173 if ( ! sanitizedLiteral ) {
172174 throw getMatIconFailedToSanitizeLiteralError ( literal ) ;
173175 }
174176
175- const svgElement = this . _createSvgElementForSingleIcon ( sanitizedLiteral ) ;
176- return this . _addSvgIconConfig ( namespace , iconName , new SvgIconConfig ( svgElement ) ) ;
177+ const svgElement = this . _createSvgElementForSingleIcon ( sanitizedLiteral , viewBox ) ;
178+ return this . _addSvgIconConfig ( namespace , iconName , new SvgIconConfig ( svgElement , viewBox ) ) ;
177179 }
178180
179181 /**
180182 * Registers an icon set by URL in the default namespace.
181183 * @param url
182184 */
183- addSvgIconSet ( url : SafeResourceUrl ) : this {
184- return this . addSvgIconSetInNamespace ( '' , url ) ;
185+ addSvgIconSet ( url : SafeResourceUrl , viewBox ?: string ) : this {
186+ return this . addSvgIconSetInNamespace ( '' , url , viewBox ) ;
185187 }
186188
187189 /**
188190 * Registers an icon set using an HTML string in the default namespace.
189191 * @param literal SVG source of the icon set.
190192 */
191- addSvgIconSetLiteral ( literal : SafeHtml ) : this {
192- return this . addSvgIconSetLiteralInNamespace ( '' , literal ) ;
193+ addSvgIconSetLiteral ( literal : SafeHtml , viewBox ?: string ) : this {
194+ return this . addSvgIconSetLiteralInNamespace ( '' , literal , viewBox ) ;
193195 }
194196
195197 /**
196198 * Registers an icon set by URL in the specified namespace.
197199 * @param namespace Namespace in which to register the icon set.
198200 * @param url
199201 */
200- addSvgIconSetInNamespace ( namespace : string , url : SafeResourceUrl ) : this {
201- return this . _addSvgIconSetConfig ( namespace , new SvgIconConfig ( url ) ) ;
202+ addSvgIconSetInNamespace ( namespace : string , url : SafeResourceUrl , viewBox ?: string ) : this {
203+ return this . _addSvgIconSetConfig ( namespace , new SvgIconConfig ( url , viewBox ) ) ;
202204 }
203205
204206 /**
205207 * Registers an icon set using an HTML string in the specified namespace.
206208 * @param namespace Namespace in which to register the icon set.
207209 * @param literal SVG source of the icon set.
208210 */
209- addSvgIconSetLiteralInNamespace ( namespace : string , literal : SafeHtml ) : this {
211+ addSvgIconSetLiteralInNamespace ( namespace : string , literal : SafeHtml , viewBox ?: string ) : this {
210212 const sanitizedLiteral = this . _sanitizer . sanitize ( SecurityContext . HTML , literal ) ;
211213
212214 if ( ! sanitizedLiteral ) {
213215 throw getMatIconFailedToSanitizeLiteralError ( literal ) ;
214216 }
215217
216218 const svgElement = this . _svgElementFromString ( sanitizedLiteral ) ;
217- return this . _addSvgIconSetConfig ( namespace , new SvgIconConfig ( svgElement ) ) ;
219+ return this . _addSvgIconSetConfig ( namespace , new SvgIconConfig ( svgElement , viewBox ) ) ;
218220 }
219221
220222 /**
@@ -395,7 +397,7 @@ export class MatIconRegistry implements OnDestroy {
395397 for ( let i = iconSetConfigs . length - 1 ; i >= 0 ; i -- ) {
396398 const config = iconSetConfigs [ i ] ;
397399 if ( config . svgElement ) {
398- const foundIcon = this . _extractSvgIconFromSet ( config . svgElement , iconName ) ;
400+ const foundIcon = this . _extractSvgIconFromSet ( config . svgElement , iconName , config . viewBox ) ;
399401 if ( foundIcon ) {
400402 return foundIcon ;
401403 }
@@ -410,7 +412,7 @@ export class MatIconRegistry implements OnDestroy {
410412 */
411413 private _loadSvgIconFromConfig ( config : SvgIconConfig ) : Observable < SVGElement > {
412414 return this . _fetchUrl ( config . url )
413- . pipe ( map ( svgText => this . _createSvgElementForSingleIcon ( svgText ) ) ) ;
415+ . pipe ( map ( svgText => this . _createSvgElementForSingleIcon ( svgText , config . viewBox ) ) ) ;
414416 }
415417
416418 /**
@@ -437,9 +439,9 @@ export class MatIconRegistry implements OnDestroy {
437439 /**
438440 * Creates a DOM element from the given SVG string, and adds default attributes.
439441 */
440- private _createSvgElementForSingleIcon ( responseText : string ) : SVGElement {
442+ private _createSvgElementForSingleIcon ( responseText : string , viewBox ?: string ) : SVGElement {
441443 const svg = this . _svgElementFromString ( responseText ) ;
442- this . _setSvgAttributes ( svg ) ;
444+ this . _setSvgAttributes ( svg , viewBox ) ;
443445 return svg ;
444446 }
445447
@@ -448,7 +450,8 @@ export class MatIconRegistry implements OnDestroy {
448450 * tag matches the specified name. If found, copies the nested element to a new SVG element and
449451 * returns it. Returns null if no matching element is found.
450452 */
451- private _extractSvgIconFromSet ( iconSet : SVGElement , iconName : string ) : SVGElement | null {
453+ private _extractSvgIconFromSet ( iconSet : SVGElement , iconName : string ,
454+ viewBox ?: string ) : SVGElement | null {
452455 // Use the `id="iconName"` syntax in order to escape special
453456 // characters in the ID (versus using the #iconName syntax).
454457 const iconSource = iconSet . querySelector ( `[id="${ iconName } "]` ) ;
@@ -465,14 +468,14 @@ export class MatIconRegistry implements OnDestroy {
465468 // If the icon node is itself an <svg> node, clone and return it directly. If not, set it as
466469 // the content of a new <svg> node.
467470 if ( iconElement . nodeName . toLowerCase ( ) === 'svg' ) {
468- return this . _setSvgAttributes ( iconElement as SVGElement ) ;
471+ return this . _setSvgAttributes ( iconElement as SVGElement , viewBox ) ;
469472 }
470473
471474 // If the node is a <symbol>, it won't be rendered so we have to convert it into <svg>. Note
472475 // that the same could be achieved by referring to it via <use href="#id">, however the <use>
473476 // tag is problematic on Firefox, because it needs to include the current page path.
474477 if ( iconElement . nodeName . toLowerCase ( ) === 'symbol' ) {
475- return this . _setSvgAttributes ( this . _toSvgElement ( iconElement ) ) ;
478+ return this . _setSvgAttributes ( this . _toSvgElement ( iconElement ) , viewBox ) ;
476479 }
477480
478481 // createElement('SVG') doesn't work as expected; the DOM ends up with
@@ -484,7 +487,7 @@ export class MatIconRegistry implements OnDestroy {
484487 // Clone the node so we don't remove it from the parent icon set element.
485488 svg . appendChild ( iconElement ) ;
486489
487- return this . _setSvgAttributes ( svg ) ;
490+ return this . _setSvgAttributes ( svg , viewBox ) ;
488491 }
489492
490493 /**
@@ -520,12 +523,17 @@ export class MatIconRegistry implements OnDestroy {
520523 /**
521524 * Sets the default attributes for an SVG element to be used as an icon.
522525 */
523- private _setSvgAttributes ( svg : SVGElement ) : SVGElement {
526+ private _setSvgAttributes ( svg : SVGElement , viewBox ?: string ) : SVGElement {
524527 svg . setAttribute ( 'fit' , '' ) ;
525528 svg . setAttribute ( 'height' , '100%' ) ;
526529 svg . setAttribute ( 'width' , '100%' ) ;
527530 svg . setAttribute ( 'preserveAspectRatio' , 'xMidYMid meet' ) ;
528531 svg . setAttribute ( 'focusable' , 'false' ) ; // Disable IE11 default behavior to make SVGs focusable.
532+
533+ if ( viewBox ) {
534+ svg . setAttribute ( 'viewBox' , viewBox ) ;
535+ }
536+
529537 return svg ;
530538 }
531539
0 commit comments