1b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik'use strict'; 2b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 3b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikvar Doctype = require('../common/doctype'); 4b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 5b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik//Conversion tables for DOM Level1 structure emulation 6b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikvar nodeTypes = { 7b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik element: 1, 8b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik text: 3, 9b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik cdata: 4, 10b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik comment: 8 11b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik}; 12b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 13b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikvar nodePropertyShorthands = { 14b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik tagName: 'name', 15b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik childNodes: 'children', 16b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik parentNode: 'parent', 17b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik previousSibling: 'prev', 18b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik nextSibling: 'next', 19b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik nodeValue: 'data' 20b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik}; 21b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 22b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik//Node 23b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikvar Node = function (props) { 24b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik for (var key in props) { 25b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if (props.hasOwnProperty(key)) 26b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik this[key] = props[key]; 27b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik } 28b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik}; 29b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 30b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris CraikNode.prototype = { 31b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik get firstChild() { 32b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik var children = this.children; 33b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return children && children[0] || null; 34b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik }, 35b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 36b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik get lastChild() { 37b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik var children = this.children; 38b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return children && children[children.length - 1] || null; 39b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik }, 40b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 41b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik get nodeType() { 42b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return nodeTypes[this.type] || nodeTypes.element; 43b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik } 44b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik}; 45b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 46b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris CraikObject.keys(nodePropertyShorthands).forEach(function (key) { 47b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik var shorthand = nodePropertyShorthands[key]; 48b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 49b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik Object.defineProperty(Node.prototype, key, { 50b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik get: function () { 51b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return this[shorthand] || null; 52b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik }, 53b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik set: function (val) { 54b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik this[shorthand] = val; 55b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return val; 56b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik } 57b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik }); 58b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik}); 59b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 60b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 61b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik//Node construction 62b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikexports.createDocument = 63b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikexports.createDocumentFragment = function () { 64b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return new Node({ 65b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik type: 'root', 66b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik name: 'root', 67b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik parent: null, 68b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik prev: null, 69b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik next: null, 70b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik children: [] 71b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik }); 72b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik}; 73b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 74b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikexports.createElement = function (tagName, namespaceURI, attrs) { 75b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik var attribs = {}, 76b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik attribsNamespace = {}, 77b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik attribsPrefix = {}; 78b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 79b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik for (var i = 0; i < attrs.length; i++) { 80b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik var attrName = attrs[i].name; 81b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 82b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik attribs[attrName] = attrs[i].value; 83b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik attribsNamespace[attrName] = attrs[i].namespace; 84b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik attribsPrefix[attrName] = attrs[i].prefix; 85b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik } 86b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 87b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return new Node({ 88b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik type: tagName === 'script' || tagName === 'style' ? tagName : 'tag', 89b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik name: tagName, 90b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik namespace: namespaceURI, 91b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik attribs: attribs, 92b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'x-attribsNamespace': attribsNamespace, 93b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'x-attribsPrefix': attribsPrefix, 94b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik children: [], 95b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik parent: null, 96b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik prev: null, 97b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik next: null 98b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik }); 99b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik}; 100b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 101b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikexports.createCommentNode = function (data) { 102b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return new Node({ 103b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik type: 'comment', 104b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik data: data, 105b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik parent: null, 106b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik prev: null, 107b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik next: null 108b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik }); 109b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik}; 110b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 111b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikvar createTextNode = function (value) { 112b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return new Node({ 113b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik type: 'text', 114b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik data: value, 115b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik parent: null, 116b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik prev: null, 117b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik next: null 118b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik }); 119b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik}; 120b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 121b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 122b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik//Tree mutation 123b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikexports.setDocumentType = function (document, name, publicId, systemId) { 124b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik var data = Doctype.serializeContent(name, publicId, systemId), 125b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik doctypeNode = null; 126b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 127b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik for (var i = 0; i < document.children.length; i++) { 128b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if (document.children[i].type === 'directive' && document.children[i].name === '!doctype') { 129b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik doctypeNode = document.children[i]; 130b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik break; 131b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik } 132b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik } 133b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 134b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if (doctypeNode) { 135b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik doctypeNode.data = data; 136b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik doctypeNode['x-name'] = name; 137b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik doctypeNode['x-publicId'] = publicId; 138b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik doctypeNode['x-systemId'] = systemId; 139b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik } 140b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 141b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik else { 142b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik appendChild(document, new Node({ 143b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik type: 'directive', 144b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik name: '!doctype', 145b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik data: data, 146b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'x-name': name, 147b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'x-publicId': publicId, 148b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'x-systemId': systemId 149b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik })); 150b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik } 151b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 152b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik}; 153b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 154b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikexports.setQuirksMode = function (document) { 155b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik document.quirksMode = true; 156b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik}; 157b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 158b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikexports.isQuirksMode = function (document) { 159b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return document.quirksMode; 160b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik}; 161b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 162b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikvar appendChild = exports.appendChild = function (parentNode, newNode) { 163b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik var prev = parentNode.children[parentNode.children.length - 1]; 164b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 165b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if (prev) { 166b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik prev.next = newNode; 167b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik newNode.prev = prev; 168b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik } 169b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 170b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik parentNode.children.push(newNode); 171b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik newNode.parent = parentNode; 172b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik}; 173b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 174b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikvar insertBefore = exports.insertBefore = function (parentNode, newNode, referenceNode) { 175b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik var insertionIdx = parentNode.children.indexOf(referenceNode), 176b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik prev = referenceNode.prev; 177b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 178b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if (prev) { 179b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik prev.next = newNode; 180b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik newNode.prev = prev; 181b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik } 182b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 183b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik referenceNode.prev = newNode; 184b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik newNode.next = referenceNode; 185b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 186b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik parentNode.children.splice(insertionIdx, 0, newNode); 187b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik newNode.parent = parentNode; 188b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik}; 189b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 190b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikexports.detachNode = function (node) { 191b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if (node.parent) { 192b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik var idx = node.parent.children.indexOf(node), 193b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik prev = node.prev, 194b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik next = node.next; 195b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 196b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik node.prev = null; 197b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik node.next = null; 198b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 199b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if (prev) 200b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik prev.next = next; 201b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 202b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if (next) 203b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik next.prev = prev; 204b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 205b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik node.parent.children.splice(idx, 1); 206b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik node.parent = null; 207b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik } 208b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik}; 209b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 210b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikexports.insertText = function (parentNode, text) { 211b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik var lastChild = parentNode.children[parentNode.children.length - 1]; 212b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 213b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if (lastChild && lastChild.type === 'text') 214b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik lastChild.data += text; 215b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik else 216b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik appendChild(parentNode, createTextNode(text)); 217b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik}; 218b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 219b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikexports.insertTextBefore = function (parentNode, text, referenceNode) { 220b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik var prevNode = parentNode.children[parentNode.children.indexOf(referenceNode) - 1]; 221b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 222b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if (prevNode && prevNode.type === 'text') 223b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik prevNode.data += text; 224b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik else 225b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik insertBefore(parentNode, createTextNode(text), referenceNode); 226b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik}; 227b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 228b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikexports.adoptAttributes = function (recipientNode, attrs) { 229b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik for (var i = 0; i < attrs.length; i++) { 230b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik var attrName = attrs[i].name; 231b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 232b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if (typeof recipientNode.attribs[attrName] === 'undefined') { 233b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik recipientNode.attribs[attrName] = attrs[i].value; 234b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik recipientNode['x-attribsNamespace'][attrName] = attrs[i].namespace; 235b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik recipientNode['x-attribsPrefix'][attrName] = attrs[i].prefix; 236b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik } 237b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik } 238b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik}; 239b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 240b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 241b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik//Tree traversing 242b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikexports.getFirstChild = function (node) { 243b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return node.children[0]; 244b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik}; 245b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 246b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikexports.getChildNodes = function (node) { 247b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return node.children; 248b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik}; 249b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 250b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikexports.getParentNode = function (node) { 251b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return node.parent; 252b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik}; 253b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 254b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikexports.getAttrList = function (node) { 255b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik var attrList = []; 256b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 257b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik for (var name in node.attribs) { 258b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if (node.attribs.hasOwnProperty(name)) { 259b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik attrList.push({ 260b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik name: name, 261b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik value: node.attribs[name], 262b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik namespace: node['x-attribsNamespace'][name], 263b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik prefix: node['x-attribsPrefix'][name] 264b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik }); 265b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik } 266b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik } 267b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 268b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return attrList; 269b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik}; 270b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 271b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 272b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik//Node data 273b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikexports.getTagName = function (element) { 274b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return element.name; 275b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik}; 276b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 277b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikexports.getNamespaceURI = function (element) { 278b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return element.namespace; 279b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik}; 280b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 281b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikexports.getTextNodeContent = function (textNode) { 282b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return textNode.data; 283b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik}; 284b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 285b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikexports.getCommentNodeContent = function (commentNode) { 286b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return commentNode.data; 287b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik}; 288b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 289b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikexports.getDocumentTypeNodeName = function (doctypeNode) { 290b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return doctypeNode['x-name']; 291b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik}; 292b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 293b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikexports.getDocumentTypeNodePublicId = function (doctypeNode) { 294b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return doctypeNode['x-publicId']; 295b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik}; 296b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 297b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikexports.getDocumentTypeNodeSystemId = function (doctypeNode) { 298b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return doctypeNode['x-systemId']; 299b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik}; 300b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 301b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 302b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik//Node types 303b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikexports.isTextNode = function (node) { 304b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return node.type === 'text'; 305b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik}; 306b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 307b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikexports.isCommentNode = function (node) { 308b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return node.type === 'comment'; 309b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik}; 310b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 311b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikexports.isDocumentTypeNode = function (node) { 312b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return node.type === 'directive' && node.name === '!doctype'; 313b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik}; 314b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 315b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikexports.isElementNode = function (node) { 316b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return !!node.attribs; 317b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik}; 318