blob: 7935a0e0b48b8d48ceb8f6e0d6c9705dc030966e [file] [log] [blame]
'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;
};