@@ -350,14 +350,14 @@ MdIconProvider.prototype = {
350350 /**
351351 * Configuration item stored in the Icon registry; used for lookups
352352 * to load if not already cached in the `loaded` cache
353- * @param url
354- * @param viewBoxSize
353+ * @param { string } url
354+ * @param { =number } viewBoxSize
355355 * @constructor
356356 */
357357 function ConfigurationItem ( url , viewBoxSize ) {
358- this . url = url ;
359- this . viewBoxSize = viewBoxSize || config . defaultViewBoxSize ;
360- }
358+ this . url = url ;
359+ this . viewBoxSize = viewBoxSize || config . defaultViewBoxSize ;
360+ }
361361
362362/**
363363 * @ngdoc service
@@ -473,13 +473,13 @@ function MdIconService(config, $templateRequest, $q, $log, $mdUtil, $sce) {
473473 }
474474
475475 /**
476- * @param {Icon } cacheElement cached icon from the iconCache
476+ * @param {! Icon } cacheElement cached icon from the iconCache
477477 * @returns {Icon } cloned Icon element with unique ids
478478 */
479479 function transformClone ( cacheElement ) {
480480 var clone = cacheElement . clone ( ) ;
481481 var newUid = $mdUtil . nextUid ( ) ;
482- var cacheSuffix ;
482+ var cacheSuffix , svgElement ;
483483
484484 // Verify that the newUid only contains a number and not some XSS content.
485485 if ( ! isFinite ( Number ( newUid ) ) ) {
@@ -501,11 +501,19 @@ function MdIconService(config, $templateRequest, $q, $log, $mdUtil, $sce) {
501501 angular . forEach ( clone . querySelectorAll ( '[id]' ) , function ( descendantElem ) {
502502 descendantElem . id += cacheSuffix ;
503503 } ) ;
504- // Inject the cacheSuffix into all instances of url(id) and xlink:href="#id".
505- // This use of innerHTML should be safe from XSS attack since we are only injecting the
506- // cacheSuffix with content from $mdUtil.nextUid which we verify is a finite number above.
507- clone . innerHTML = clone . innerHTML . replace ( / ( .* u r l \( # ) ( \w * ) ( \) .* ) / g, addCacheSuffixToId ) ;
508- clone . innerHTML = clone . innerHTML . replace ( / ( .* x l i n k : h r e f = " # ) ( \w * ) ( " .* ) / g, addCacheSuffixToId ) ;
504+ // innerHTML of SVG elements is not supported by IE11
505+ if ( clone . innerHTML === undefined ) {
506+ svgElement = $mdUtil . getInnerHTML ( clone ) ;
507+ svgElement = svgElement . replace ( / ( .* u r l \( # ) ( \w * ) ( \) .* ) / g, addCacheSuffixToId ) ;
508+ svgElement = svgElement . replace ( / ( .* x l i n k : h r e f = " # ) ( \w * ) ( " .* ) / g, addCacheSuffixToId ) ;
509+ clone = angular . element ( svgElement ) [ 0 ] ;
510+ } else {
511+ // Inject the cacheSuffix into all instances of url(id) and xlink:href="#id".
512+ // This use of innerHTML should be safe from XSS attack since we are only injecting the
513+ // cacheSuffix with content from $mdUtil.nextUid which we verify is a finite number above.
514+ clone . innerHTML = clone . innerHTML . replace ( / ( .* u r l \( # ) ( \w * ) ( \) .* ) / g, addCacheSuffixToId ) ;
515+ clone . innerHTML = clone . innerHTML . replace ( / ( .* x l i n k : h r e f = " # ) ( \w * ) ( " .* ) / g, addCacheSuffixToId ) ;
516+ }
509517
510518 return clone ;
511519 }
@@ -605,24 +613,37 @@ function MdIconService(config, $templateRequest, $q, $log, $mdUtil, $sce) {
605613
606614 /**
607615 * Check target signature to see if it is an Icon instance.
616+ * @param {Icon|Element } target
617+ * @returns {boolean } true if the specified target is an Icon object, false otherwise.
608618 */
609619 function isIcon ( target ) {
610620 return angular . isDefined ( target . element ) && angular . isDefined ( target . config ) ;
611621 }
612622
613623 /**
614- * Define the Icon class
624+ * Define the Icon class
625+ * @param {Element } el
626+ * @param {=ConfigurationItem } config
627+ * @constructor
615628 */
616629 function Icon ( el , config ) {
630+ var elementContents ;
617631 // If the node is a <symbol>, it won't be rendered so we have to convert it into <svg>.
618632 if ( el && el . tagName . toLowerCase ( ) === 'symbol' ) {
619633 var viewbox = el . getAttribute ( 'viewBox' ) ;
620- el = angular . element ( '<svg xmlns="http://www.w3.org/2000/svg">' ) . html ( el . innerHTML ) [ 0 ] ;
634+ // Check if innerHTML is supported as IE11 does not support innerHTML on SVG elements.
635+ if ( el . innerHTML ) {
636+ elementContents = el . innerHTML ;
637+ } else {
638+ elementContents = $mdUtil . getInnerHTML ( el ) ;
639+ }
640+ el = angular . element ( '<svg xmlns="http://www.w3.org/2000/svg">' ) . append ( elementContents ) [ 0 ] ;
621641 if ( viewbox ) el . setAttribute ( 'viewBox' , viewbox ) ;
622642 }
623643
624644 if ( el && el . tagName . toLowerCase ( ) !== 'svg' ) {
625- el = angular . element ( '<svg xmlns="http://www.w3.org/2000/svg">' ) . append ( el . cloneNode ( true ) ) [ 0 ] ;
645+ el = angular . element (
646+ '<svg xmlns="http://www.w3.org/2000/svg">' ) . append ( el . cloneNode ( true ) ) [ 0 ] ;
626647 }
627648
628649 // Inject the namespace if not available...
0 commit comments