|
@@ -93,32 +93,87 @@ DOMElement.prototype = {
|
|
|
childNodes.push(element);
|
|
|
}
|
|
|
},
|
|
|
- toString: function DOMElement_toString() {
|
|
|
- var buf = [];
|
|
|
- buf.push('<' + this.nodeName);
|
|
|
- if (this.nodeName === 'svg:svg') {
|
|
|
- buf.push(' xmlns:xlink="http://www.w3.org/1999/xlink"' + ' xmlns:svg="http://www.w3.org/2000/svg"');
|
|
|
- }
|
|
|
- for (var i in this.attributes) {
|
|
|
- buf.push(' ' + i + '="' + xmlEncode(this.attributes[i]) + '"');
|
|
|
- }
|
|
|
- buf.push('>');
|
|
|
- if (this.nodeName === 'svg:tspan' || this.nodeName === 'svg:style') {
|
|
|
- buf.push(xmlEncode(this.textContent));
|
|
|
- } else {
|
|
|
- this.childNodes.forEach(function (childNode) {
|
|
|
- buf.push(childNode.toString());
|
|
|
- });
|
|
|
- }
|
|
|
- buf.push('</' + this.nodeName + '>');
|
|
|
- return buf.join('');
|
|
|
- },
|
|
|
cloneNode: function DOMElement_cloneNode() {
|
|
|
var newNode = new DOMElement(this.nodeName);
|
|
|
newNode.childNodes = this.childNodes;
|
|
|
newNode.attributes = this.attributes;
|
|
|
newNode.textContent = this.textContent;
|
|
|
return newNode;
|
|
|
+ },
|
|
|
+ toString: function DOMElement_toString() {
|
|
|
+ var buf = [];
|
|
|
+ var serializer = this.getSerializer();
|
|
|
+ var chunk;
|
|
|
+ while ((chunk = serializer.getNext()) !== null) {
|
|
|
+ buf.push(chunk);
|
|
|
+ }
|
|
|
+ return buf.join('');
|
|
|
+ },
|
|
|
+ getSerializer: function DOMElement_getSerializer() {
|
|
|
+ return new DOMElementSerializer(this);
|
|
|
+ }
|
|
|
+};
|
|
|
+function DOMElementSerializer(node) {
|
|
|
+ this._node = node;
|
|
|
+ this._state = 0;
|
|
|
+ this._loopIndex = 0;
|
|
|
+ this._attributeKeys = null;
|
|
|
+ this._childSerializer = null;
|
|
|
+}
|
|
|
+DOMElementSerializer.prototype = {
|
|
|
+ getNext: function DOMElementSerializer_getNext() {
|
|
|
+ var node = this._node;
|
|
|
+ switch (this._state) {
|
|
|
+ case 0:
|
|
|
+ ++this._state;
|
|
|
+ return '<' + node.nodeName;
|
|
|
+ case 1:
|
|
|
+ ++this._state;
|
|
|
+ if (node.nodeName === 'svg:svg') {
|
|
|
+ return ' xmlns:xlink="http://www.w3.org/1999/xlink"' + ' xmlns:svg="http://www.w3.org/2000/svg"';
|
|
|
+ }
|
|
|
+ case 2:
|
|
|
+ ++this._state;
|
|
|
+ this._loopIndex = 0;
|
|
|
+ this._attributeKeys = Object.keys(node.attributes);
|
|
|
+ case 3:
|
|
|
+ if (this._loopIndex < this._attributeKeys.length) {
|
|
|
+ var name = this._attributeKeys[this._loopIndex++];
|
|
|
+ return ' ' + name + '="' + xmlEncode(node.attributes[name]) + '"';
|
|
|
+ }
|
|
|
+ ++this._state;
|
|
|
+ return '>';
|
|
|
+ case 4:
|
|
|
+ if (node.nodeName === 'svg:tspan' || node.nodeName === 'svg:style') {
|
|
|
+ this._state = 6;
|
|
|
+ return xmlEncode(node.textContent);
|
|
|
+ }
|
|
|
+ ++this._state;
|
|
|
+ this._loopIndex = 0;
|
|
|
+ case 5:
|
|
|
+ var value;
|
|
|
+ while (true) {
|
|
|
+ value = this._childSerializer && this._childSerializer.getNext();
|
|
|
+ if (value !== null) {
|
|
|
+ return value;
|
|
|
+ }
|
|
|
+ var nextChild = node.childNodes[this._loopIndex++];
|
|
|
+ if (nextChild) {
|
|
|
+ this._childSerializer = new DOMElementSerializer(nextChild);
|
|
|
+ } else {
|
|
|
+ this._childSerializer = null;
|
|
|
+ ++this._state;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ case 6:
|
|
|
+ ++this._state;
|
|
|
+ return '</' + node.nodeName + '>';
|
|
|
+ case 7:
|
|
|
+ return null;
|
|
|
+ default:
|
|
|
+ throw new Error('Unexpected serialization state: ' + this._state);
|
|
|
+ }
|
|
|
}
|
|
|
};
|
|
|
var document = {
|