|  |  | 
 |  |  |   "title": [], | 
 |  |  |   "tspan": ["class", "clip-path", "clip-rule", "dx", "dy", "fill", "fill-opacity", "fill-rule", "filter", "font-family", "font-size", "font-style", "font-weight", "id", "mask", "opacity", "requiredFeatures", "rotate", "stroke", "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin", "stroke-miterlimit", "stroke-opacity", "stroke-width", "style", "systemLanguage", "text-anchor", "textLength", "transform", "x", "xml:space", "y"], | 
 |  |  |   "use": ["class", "clip-path", "clip-rule", "fill", "fill-opacity", "fill-rule", "filter", "height", "id", "mask", "stroke", "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin", "stroke-miterlimit", "stroke-opacity", "stroke-width", "style", "transform", "width", "x", "xlink:href", "y"], | 
 |  |  |    | 
 |  |  |  | 
 |  |  |   // MathML Elements | 
 |  |  |   "annotation": ["encoding"], | 
 |  |  |   "annotation-xml": ["encoding"], | 
 |  |  | 
 |  |  |   var parent = node.parentNode; | 
 |  |  |   // can parent ever be null here?  I think the root node's parent is the document... | 
 |  |  |   if (!doc || !parent) return; | 
 |  |  |    | 
 |  |  |  | 
 |  |  |   var allowedAttrs = svgWhiteList_[node.nodeName]; | 
 |  |  |   var allowedAttrsNS = svgWhiteListNS_[node.nodeName]; | 
 |  |  |  | 
 |  |  | 
 |  |  |   if (allowedAttrs != undefined) { | 
 |  |  |  | 
 |  |  |     var se_attrs = []; | 
 |  |  |    | 
 |  |  |  | 
 |  |  |     var i = node.attributes.length; | 
 |  |  |     while (i--) { | 
 |  |  |       // if the attribute is not in our whitelist, then remove it | 
 |  |  | 
 |  |  |       var attrName = attr.nodeName; | 
 |  |  |       var attrLocalName = attr.localName; | 
 |  |  |       var attrNsURI = attr.namespaceURI; | 
 |  |  |       // Check that an attribute with the correct localName in the correct namespace is on  | 
 |  |  |       // Check that an attribute with the correct localName in the correct namespace is on | 
 |  |  |       // our whitelist or is a namespace declaration for one of our allowed namespaces | 
 |  |  |       if (!(allowedAttrsNS.hasOwnProperty(attrLocalName) && attrNsURI == allowedAttrsNS[attrLocalName] && attrNsURI != xmlnsns) && | 
 |  |  |         !(attrNsURI == xmlnsns && nsMap_[attr.nodeValue]) )  | 
 |  |  |         !(attrNsURI == xmlnsns && nsMap_[attr.nodeValue]) ) | 
 |  |  |       { | 
 |  |  |         // TODO(codedread): Programmatically add the se: attributes to the NS-aware whitelist. | 
 |  |  |         // Bypassing the whitelist to allow se: prefixes. Is there | 
 |  |  |         // a more appropriate way to do this? | 
 |  |  |         if(attrName.indexOf('se:') == 0) { | 
 |  |  |           se_attrs.push([attrName, attr.nodeValue]); | 
 |  |  |         }  | 
 |  |  |         } | 
 |  |  |         node.removeAttributeNS(attrNsURI, attrLocalName); | 
 |  |  |       } | 
 |  |  |        | 
 |  |  |  | 
 |  |  |       // Add spaces before negative signs where necessary | 
 |  |  |       if(svgedit.browser.isGecko()) { | 
 |  |  |         switch ( attrName ) { | 
 |  |  | 
 |  |  |           node.setAttribute(attrName, val); | 
 |  |  |         } | 
 |  |  |       } | 
 |  |  |        | 
 |  |  |  | 
 |  |  |       // for the style attribute, rewrite it in terms of XML presentational attributes | 
 |  |  |       if (attrName == "style") { | 
 |  |  |         var props = attr.nodeValue.split(";"), | 
 |  |  | 
 |  |  |         node.removeAttribute('style'); | 
 |  |  |       } | 
 |  |  |     } | 
 |  |  |      | 
 |  |  |  | 
 |  |  |     $.each(se_attrs, function(i, attr) { | 
 |  |  |       node.setAttributeNS(se_ns, attr[0], attr[1]); | 
 |  |  |     }); | 
 |  |  |      | 
 |  |  |  | 
 |  |  |     // for some elements that have a xlink:href, ensure the URI refers to a local element | 
 |  |  |     // (but not for links) | 
 |  |  |     var href = svgedit.utilities.getHref(node); | 
 |  |  |     if(href &&  | 
 |  |  |     if(href && | 
 |  |  |        ["filter", "linearGradient", "pattern", | 
 |  |  |        "radialGradient", "textPath", "use"].indexOf(node.nodeName) >= 0) | 
 |  |  |     { | 
 |  |  | 
 |  |  |         node.removeAttributeNS(xlinkns, "href"); | 
 |  |  |       } | 
 |  |  |     } | 
 |  |  |      | 
 |  |  |  | 
 |  |  |     // Safari crashes on a <use> without a xlink:href, so we just remove the node here | 
 |  |  |     if (node.nodeName == "use" && !svgedit.utilities.getHref(node)) { | 
 |  |  |       parent.removeChild(node); | 
 |  |  |       return; | 
 |  |  |     } | 
 |  |  |     // if the element has attributes pointing to a non-local reference,  | 
 |  |  |     // if the element has attributes pointing to a non-local reference, | 
 |  |  |     // need to remove the attribute | 
 |  |  |     $.each(["clip-path", "fill", "filter", "marker-end", "marker-mid", "marker-start", "mask", "stroke"],function(i,attr) { | 
 |  |  |       var val = node.getAttribute(attr); | 
 |  |  | 
 |  |  |         } | 
 |  |  |       } | 
 |  |  |     }); | 
 |  |  |      | 
 |  |  |  | 
 |  |  |     // recurse to children | 
 |  |  |     i = node.childNodes.length; | 
 |  |  |     while (i--) { svgedit.sanitize.sanitizeSvg(node.childNodes.item(i)); } |