1'use strict'; 2 3//Node construction 4exports.createDocument = function () { 5 return { 6 nodeName: '#document', 7 quirksMode: false, 8 childNodes: [] 9 }; 10}; 11 12exports.createDocumentFragment = function () { 13 return { 14 nodeName: '#document-fragment', 15 quirksMode: false, 16 childNodes: [] 17 }; 18}; 19 20exports.createElement = function (tagName, namespaceURI, attrs) { 21 return { 22 nodeName: tagName, 23 tagName: tagName, 24 attrs: attrs, 25 namespaceURI: namespaceURI, 26 childNodes: [], 27 parentNode: null 28 }; 29}; 30 31exports.createCommentNode = function (data) { 32 return { 33 nodeName: '#comment', 34 data: data, 35 parentNode: null 36 }; 37}; 38 39var createTextNode = function (value) { 40 return { 41 nodeName: '#text', 42 value: value, 43 parentNode: null 44 } 45}; 46 47 48//Tree mutation 49exports.setDocumentType = function (document, name, publicId, systemId) { 50 var doctypeNode = null; 51 52 for (var i = 0; i < document.childNodes.length; i++) { 53 if (document.childNodes[i].nodeName === '#documentType') { 54 doctypeNode = document.childNodes[i]; 55 break; 56 } 57 } 58 59 if (doctypeNode) { 60 doctypeNode.name = name; 61 doctypeNode.publicId = publicId; 62 doctypeNode.systemId = systemId; 63 } 64 65 else { 66 appendChild(document, { 67 nodeName: '#documentType', 68 name: name, 69 publicId: publicId, 70 systemId: systemId 71 }); 72 } 73}; 74 75exports.setQuirksMode = function (document) { 76 document.quirksMode = true; 77}; 78 79exports.isQuirksMode = function (document) { 80 return document.quirksMode; 81}; 82 83var appendChild = exports.appendChild = function (parentNode, newNode) { 84 parentNode.childNodes.push(newNode); 85 newNode.parentNode = parentNode; 86}; 87 88var insertBefore = exports.insertBefore = function (parentNode, newNode, referenceNode) { 89 var insertionIdx = parentNode.childNodes.indexOf(referenceNode); 90 91 parentNode.childNodes.splice(insertionIdx, 0, newNode); 92 newNode.parentNode = parentNode; 93}; 94 95exports.detachNode = function (node) { 96 if (node.parentNode) { 97 var idx = node.parentNode.childNodes.indexOf(node); 98 99 node.parentNode.childNodes.splice(idx, 1); 100 node.parentNode = null; 101 } 102}; 103 104exports.insertText = function (parentNode, text) { 105 if (parentNode.childNodes.length) { 106 var prevNode = parentNode.childNodes[parentNode.childNodes.length - 1]; 107 108 if (prevNode.nodeName === '#text') { 109 prevNode.value += text; 110 return; 111 } 112 } 113 114 appendChild(parentNode, createTextNode(text)); 115}; 116 117exports.insertTextBefore = function (parentNode, text, referenceNode) { 118 var prevNode = parentNode.childNodes[parentNode.childNodes.indexOf(referenceNode) - 1]; 119 120 if (prevNode && prevNode.nodeName === '#text') 121 prevNode.value += text; 122 else 123 insertBefore(parentNode, createTextNode(text), referenceNode); 124}; 125 126exports.adoptAttributes = function (recipientNode, attrs) { 127 var recipientAttrsMap = []; 128 129 for (var i = 0; i < recipientNode.attrs.length; i++) 130 recipientAttrsMap.push(recipientNode.attrs[i].name); 131 132 for (var j = 0; j < attrs.length; j++) { 133 if (recipientAttrsMap.indexOf(attrs[j].name) === -1) 134 recipientNode.attrs.push(attrs[j]); 135 } 136}; 137 138 139//Tree traversing 140exports.getFirstChild = function (node) { 141 return node.childNodes[0]; 142}; 143 144exports.getChildNodes = function (node) { 145 return node.childNodes; 146}; 147 148exports.getParentNode = function (node) { 149 return node.parentNode; 150}; 151 152exports.getAttrList = function (node) { 153 return node.attrs; 154}; 155 156//Node data 157exports.getTagName = function (element) { 158 return element.tagName; 159}; 160 161exports.getNamespaceURI = function (element) { 162 return element.namespaceURI; 163}; 164 165exports.getTextNodeContent = function (textNode) { 166 return textNode.value; 167}; 168 169exports.getCommentNodeContent = function (commentNode) { 170 return commentNode.data; 171}; 172 173exports.getDocumentTypeNodeName = function (doctypeNode) { 174 return doctypeNode.name; 175}; 176 177exports.getDocumentTypeNodePublicId = function (doctypeNode) { 178 return doctypeNode.publicId; 179}; 180 181exports.getDocumentTypeNodeSystemId = function (doctypeNode) { 182 return doctypeNode.systemId; 183}; 184 185//Node types 186exports.isTextNode = function (node) { 187 return node.nodeName === '#text'; 188}; 189 190exports.isCommentNode = function (node) { 191 return node.nodeName === '#comment'; 192}; 193 194exports.isDocumentTypeNode = function (node) { 195 return node.nodeName === '#documentType'; 196}; 197 198exports.isElementNode = function (node) { 199 return !!node.tagName; 200}; 201