parse5-ns
Version:
My non-standard fork of parse5, the HTML parser and serializer.
220 lines (176 loc) • 5.29 kB
JavaScript
import { DOCUMENT_MODE } from '../common/html.js';
//Node construction
export function createDocument() {
return {
nodeName: '#document',
mode: DOCUMENT_MODE.NO_QUIRKS,
childNodes: [],
};
}
export function createDocumentFragment() {
return {
nodeName: '#document-fragment',
childNodes: [],
};
}
export function createElement(tagName, namespaceURI, attrs) {
return {
nodeName: tagName,
tagName,
attrs,
namespaceURI,
childNodes: [],
parentNode: null,
};
}
export function createCommentNode(data) {
return {
nodeName: '#comment',
data,
parentNode: null,
};
}
const createTextNode = function (value) {
return {
nodeName: '#text',
value,
parentNode: null,
};
};
//Tree mutation
export function appendChild(parentNode, newNode) {
parentNode.childNodes.push(newNode);
newNode.parentNode = parentNode;
}
export function insertBefore(parentNode, newNode, referenceNode) {
const insertionIdx = parentNode.childNodes.indexOf(referenceNode);
parentNode.childNodes.splice(insertionIdx, 0, newNode);
newNode.parentNode = parentNode;
}
export function setTemplateContent(templateElement, contentElement) {
templateElement.content = contentElement;
}
export function getTemplateContent(templateElement) {
return templateElement.content;
}
export function setDocumentType(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,
publicId,
systemId,
});
}
}
export function setDocumentMode(document, mode) {
document.mode = mode;
}
export function getDocumentMode(document) {
return document.mode;
}
export function detachNode(node) {
if (node.parentNode) {
const idx = node.parentNode.childNodes.indexOf(node);
node.parentNode.childNodes.splice(idx, 1);
node.parentNode = null;
}
}
export function insertText(parentNode, text) {
if (parentNode.childNodes.length > 0) {
const prevNode = parentNode.childNodes[parentNode.childNodes.length - 1];
if (prevNode.nodeName === '#text') {
prevNode.value += text;
return;
}
}
appendChild(parentNode, createTextNode(text));
}
export function insertTextBefore(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);
}
}
export function adoptAttributes(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.includes(attrs[j].name)) {
recipient.attrs.push(attrs[j]);
}
}
}
//Tree traversing
export function getFirstChild(node) {
return node.childNodes[0];
}
export function getChildNodes(node) {
return node.childNodes;
}
export function getParentNode(node) {
return node.parentNode;
}
export function getAttrList(element) {
return element.attrs;
}
//Node data
export function getTagName(element) {
return element.tagName;
}
export function getNamespaceURI(element) {
return element.namespaceURI;
}
export function getTextNodeContent(textNode) {
return textNode.value;
}
export function getCommentNodeContent(commentNode) {
return commentNode.data;
}
export function getDocumentTypeNodeName(doctypeNode) {
return doctypeNode.name;
}
export function getDocumentTypeNodePublicId(doctypeNode) {
return doctypeNode.publicId;
}
export function getDocumentTypeNodeSystemId(doctypeNode) {
return doctypeNode.systemId;
}
//Node types
export function isTextNode(node) {
return node.nodeName === '#text';
}
export function isCommentNode(node) {
return node.nodeName === '#comment';
}
export function isDocumentTypeNode(node) {
return node.nodeName === '#documentType';
}
export function isElementNode(node) {
return !!node.tagName;
}
// Source code location
export function setNodeSourceCodeLocation(node, location) {
node.sourceCodeLocation = location;
}
export function getNodeSourceCodeLocation(node) {
return node.sourceCodeLocation;
}
export function updateNodeSourceCodeLocation(node, endLocation) {
node.sourceCodeLocation = { ...node.sourceCodeLocation, ...endLocation };
}