/** * innerHTML property for SVGElement * Copyright(c) 2010, Jeff Schiller * * Licensed under the Apache License, Version 2 * * Works in a SVG document in Chrome 6+, Safari 5+, Firefox 4+ and IE9+. * Works in a HTML5 document in Chrome 7+, Firefox 4+ and IE9+. * Does not work in Opera since it doesn't support the SVGElement interface yet. * * I haven't decided on the best name for this property - thus the duplication. */ (function() { var serializeXML = function(node, output) { var nodeType = node.nodeType; if (nodeType == 3) { // TEXT nodes. // Replace special XML characters with their entities. output.push(node.textContent.replace(/&/, '&').replace(/', '>')); } else if (nodeType == 1) { // ELEMENT nodes. // Serialize Element nodes. output.push('<', node.tagName); if (node.hasAttributes()) { var attrMap = node.attributes; for (var i = 0, len = attrMap.length; i < len; ++i) { var attrNode = attrMap.item(i); output.push(' ', attrNode.name, '=\'', attrNode.value, '\''); } } if (node.hasChildNodes()) { output.push('>'); var childNodes = node.childNodes; for (var i = 0, len = childNodes.length; i < len; ++i) { serializeXML(childNodes.item(i), output); } output.push(''); } else { output.push('/>'); } } else if (nodeType == 8) { // TODO(codedread): Replace special characters with XML entities? output.push(''); } else { // TODO: Handle CDATA nodes. // TODO: Handle ENTITY nodes. // TODO: Handle DOCUMENT nodes. throw 'Error serializing XML. Unhandled node of type: ' + nodeType; } } // The innerHTML DOM property for SVGElement. Object.defineProperty(SVGElement.prototype, 'innerHTML', { get: function() { var output = []; var childNode = this.firstChild; while (childNode) { serializeXML(childNode, output); childNode = childNode.nextSibling; } return output.join(''); }, set: function(markupText) { // Wipe out the current contents of the element. while (this.firstChild) { this.removeChild(this.firstChild); } try { // Parse the markup into valid nodes. var dXML = new DOMParser(); dXML.async = false; // Wrap the markup into a SVG node to ensure parsing works. sXML = '' + markupText + ''; var svgDocElement = dXML.parseFromString(sXML, 'text/xml').documentElement; // Now take each node, import it and append to this element. var childNode = svgDocElement.firstChild; while(childNode) { this.appendChild(this.ownerDocument.importNode(childNode, true)); childNode = childNode.nextSibling; } } catch(e) { throw new Error('Error parsing XML string'); }; } }); // The innerSVG DOM property for SVGElement. Object.defineProperty(SVGElement.prototype, 'innerSVG', { get: function() { return this.innerHTML; }, set: function(markupText) { this.innerHTML = markupText; } }); })();