You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
221 lines
5.2 KiB
221 lines
5.2 KiB
'use strict'; |
|
|
|
const { DOCUMENT_MODE } = require('../common/html'); |
|
|
|
//Node construction |
|
exports.createDocument = function() { |
|
return { |
|
nodeName: '#document', |
|
mode: DOCUMENT_MODE.NO_QUIRKS, |
|
childNodes: [] |
|
}; |
|
}; |
|
|
|
exports.createDocumentFragment = function() { |
|
return { |
|
nodeName: '#document-fragment', |
|
childNodes: [] |
|
}; |
|
}; |
|
|
|
exports.createElement = function(tagName, namespaceURI, attrs) { |
|
return { |
|
nodeName: tagName, |
|
tagName: tagName, |
|
attrs: attrs, |
|
namespaceURI: namespaceURI, |
|
childNodes: [], |
|
parentNode: null |
|
}; |
|
}; |
|
|
|
exports.createCommentNode = function(data) { |
|
return { |
|
nodeName: '#comment', |
|
data: data, |
|
parentNode: null |
|
}; |
|
}; |
|
|
|
const createTextNode = function(value) { |
|
return { |
|
nodeName: '#text', |
|
value: value, |
|
parentNode: null |
|
}; |
|
}; |
|
|
|
//Tree mutation |
|
const appendChild = (exports.appendChild = function(parentNode, newNode) { |
|
parentNode.childNodes.push(newNode); |
|
newNode.parentNode = parentNode; |
|
}); |
|
|
|
const insertBefore = (exports.insertBefore = function(parentNode, newNode, referenceNode) { |
|
const insertionIdx = parentNode.childNodes.indexOf(referenceNode); |
|
|
|
parentNode.childNodes.splice(insertionIdx, 0, newNode); |
|
newNode.parentNode = parentNode; |
|
}); |
|
|
|
exports.setTemplateContent = function(templateElement, contentElement) { |
|
templateElement.content = contentElement; |
|
}; |
|
|
|
exports.getTemplateContent = function(templateElement) { |
|
return templateElement.content; |
|
}; |
|
|
|
exports.setDocumentType = function(document, name, publicId, systemId) { |
|
let doctypeNode = null; |
|
|
|
for (let i = 0; i < document.childNodes.length; i++) { |
|
if (document.childNodes[i].nodeName === '#documentType') { |
|
doctypeNode = document.childNodes[i]; |
|
break; |
|
} |
|
} |
|
|
|
if (doctypeNode) { |
|
doctypeNode.name = name; |
|
doctypeNode.publicId = publicId; |
|
doctypeNode.systemId = systemId; |
|
} else { |
|
appendChild(document, { |
|
nodeName: '#documentType', |
|
name: name, |
|
publicId: publicId, |
|
systemId: systemId |
|
}); |
|
} |
|
}; |
|
|
|
exports.setDocumentMode = function(document, mode) { |
|
document.mode = mode; |
|
}; |
|
|
|
exports.getDocumentMode = function(document) { |
|
return document.mode; |
|
}; |
|
|
|
exports.detachNode = function(node) { |
|
if (node.parentNode) { |
|
const idx = node.parentNode.childNodes.indexOf(node); |
|
|
|
node.parentNode.childNodes.splice(idx, 1); |
|
node.parentNode = null; |
|
} |
|
}; |
|
|
|
exports.insertText = function(parentNode, text) { |
|
if (parentNode.childNodes.length) { |
|
const prevNode = parentNode.childNodes[parentNode.childNodes.length - 1]; |
|
|
|
if (prevNode.nodeName === '#text') { |
|
prevNode.value += text; |
|
return; |
|
} |
|
} |
|
|
|
appendChild(parentNode, createTextNode(text)); |
|
}; |
|
|
|
exports.insertTextBefore = function(parentNode, text, referenceNode) { |
|
const prevNode = parentNode.childNodes[parentNode.childNodes.indexOf(referenceNode) - 1]; |
|
|
|
if (prevNode && prevNode.nodeName === '#text') { |
|
prevNode.value += text; |
|
} else { |
|
insertBefore(parentNode, createTextNode(text), referenceNode); |
|
} |
|
}; |
|
|
|
exports.adoptAttributes = function(recipient, attrs) { |
|
const recipientAttrsMap = []; |
|
|
|
for (let i = 0; i < recipient.attrs.length; i++) { |
|
recipientAttrsMap.push(recipient.attrs[i].name); |
|
} |
|
|
|
for (let j = 0; j < attrs.length; j++) { |
|
if (recipientAttrsMap.indexOf(attrs[j].name) === -1) { |
|
recipient.attrs.push(attrs[j]); |
|
} |
|
} |
|
}; |
|
|
|
//Tree traversing |
|
exports.getFirstChild = function(node) { |
|
return node.childNodes[0]; |
|
}; |
|
|
|
exports.getChildNodes = function(node) { |
|
return node.childNodes; |
|
}; |
|
|
|
exports.getParentNode = function(node) { |
|
return node.parentNode; |
|
}; |
|
|
|
exports.getAttrList = function(element) { |
|
return element.attrs; |
|
}; |
|
|
|
//Node data |
|
exports.getTagName = function(element) { |
|
return element.tagName; |
|
}; |
|
|
|
exports.getNamespaceURI = function(element) { |
|
return element.namespaceURI; |
|
}; |
|
|
|
exports.getTextNodeContent = function(textNode) { |
|
return textNode.value; |
|
}; |
|
|
|
exports.getCommentNodeContent = function(commentNode) { |
|
return commentNode.data; |
|
}; |
|
|
|
exports.getDocumentTypeNodeName = function(doctypeNode) { |
|
return doctypeNode.name; |
|
}; |
|
|
|
exports.getDocumentTypeNodePublicId = function(doctypeNode) { |
|
return doctypeNode.publicId; |
|
}; |
|
|
|
exports.getDocumentTypeNodeSystemId = function(doctypeNode) { |
|
return doctypeNode.systemId; |
|
}; |
|
|
|
//Node types |
|
exports.isTextNode = function(node) { |
|
return node.nodeName === '#text'; |
|
}; |
|
|
|
exports.isCommentNode = function(node) { |
|
return node.nodeName === '#comment'; |
|
}; |
|
|
|
exports.isDocumentTypeNode = function(node) { |
|
return node.nodeName === '#documentType'; |
|
}; |
|
|
|
exports.isElementNode = function(node) { |
|
return !!node.tagName; |
|
}; |
|
|
|
// Source code location |
|
exports.setNodeSourceCodeLocation = function(node, location) { |
|
node.sourceCodeLocation = location; |
|
}; |
|
|
|
exports.getNodeSourceCodeLocation = function(node) { |
|
return node.sourceCodeLocation; |
|
}; |
|
|
|
exports.updateNodeSourceCodeLocation = function(node, endLocation) { |
|
node.sourceCodeLocation = Object.assign(node.sourceCodeLocation, endLocation); |
|
};
|
|
|