157 lines
5.2 KiB
JavaScript
157 lines
5.2 KiB
JavaScript
|
"use strict";
|
||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||
|
exports.setAttr = exports.getAttr = exports.removeAttr = exports.createTextNode = exports.walkElements = exports.findElement = exports.findElementsByTagNames = exports.removeNode = exports.appendNode = exports.findNextNonTextNode = exports.findNodeIndex = exports.insertBeforeFirstScript = exports.unshiftElement = exports.createElement = void 0;
|
||
|
const namespaces_1 = require("../processing/dom/namespaces");
|
||
|
const ATTR_NAMESPACE_LOCAL_NAME_SEPARATOR = ':';
|
||
|
function isElementNode(el) {
|
||
|
return el.nodeName !== '#document' &&
|
||
|
el.nodeName !== '#text' &&
|
||
|
el.nodeName !== '#documentType' &&
|
||
|
el.nodeName !== '#comment';
|
||
|
}
|
||
|
function getAttrName(attr) {
|
||
|
return attr.prefix ? attr.prefix + ATTR_NAMESPACE_LOCAL_NAME_SEPARATOR + attr.name : attr.name;
|
||
|
}
|
||
|
function parseAttrName(attr) {
|
||
|
const parts = attr.split(ATTR_NAMESPACE_LOCAL_NAME_SEPARATOR);
|
||
|
if (parts.length === 2) {
|
||
|
return {
|
||
|
prefix: parts[0],
|
||
|
name: parts[1],
|
||
|
};
|
||
|
}
|
||
|
return {
|
||
|
name: parts[0],
|
||
|
};
|
||
|
}
|
||
|
function findAttr(el, name) {
|
||
|
for (let i = 0; i < el.attrs.length; i++) {
|
||
|
if (getAttrName(el.attrs[i]) === name)
|
||
|
return el.attrs[i];
|
||
|
}
|
||
|
return null;
|
||
|
}
|
||
|
function createElement(tagName, attrs) {
|
||
|
return {
|
||
|
nodeName: tagName,
|
||
|
tagName: tagName,
|
||
|
attrs: attrs,
|
||
|
childNodes: [],
|
||
|
};
|
||
|
}
|
||
|
exports.createElement = createElement;
|
||
|
function unshiftElement(el, parent) {
|
||
|
var _a;
|
||
|
el.namespaceURI = parent.namespaceURI;
|
||
|
el.parentNode = parent;
|
||
|
(_a = parent.childNodes) === null || _a === void 0 ? void 0 : _a.unshift(el); // eslint-disable-line no-unused-expressions
|
||
|
}
|
||
|
exports.unshiftElement = unshiftElement;
|
||
|
function insertBeforeFirstScript(el, parent) {
|
||
|
var _a;
|
||
|
const firstScriptIndex = findNodeIndex(parent, node => node.tagName === 'script');
|
||
|
const insertIndex = firstScriptIndex !== -1 ? firstScriptIndex : ((_a = parent.childNodes) === null || _a === void 0 ? void 0 : _a.length) || 0;
|
||
|
appendNode(el, parent, insertIndex);
|
||
|
}
|
||
|
exports.insertBeforeFirstScript = insertBeforeFirstScript;
|
||
|
function findNodeIndex(parent, predicate) {
|
||
|
return parent && parent.childNodes
|
||
|
? parent.childNodes.findIndex(predicate)
|
||
|
: -1;
|
||
|
}
|
||
|
exports.findNodeIndex = findNodeIndex;
|
||
|
function findNextNonTextNode(parent, startIndex) {
|
||
|
if (!parent.childNodes)
|
||
|
return null;
|
||
|
let currentNode;
|
||
|
while (currentNode = parent.childNodes[startIndex]) { // eslint-disable-line no-cond-assign
|
||
|
if (currentNode.nodeName !== '#text')
|
||
|
return currentNode;
|
||
|
startIndex++;
|
||
|
}
|
||
|
return currentNode;
|
||
|
}
|
||
|
exports.findNextNonTextNode = findNextNonTextNode;
|
||
|
function appendNode(node, parent, index) {
|
||
|
var _a;
|
||
|
node.namespaceURI = parent.namespaceURI;
|
||
|
node.parentNode = parent;
|
||
|
(_a = parent.childNodes) === null || _a === void 0 ? void 0 : _a.splice(index, 0, node); // eslint-disable-line no-unused-expressions
|
||
|
}
|
||
|
exports.appendNode = appendNode;
|
||
|
function removeNode(node) {
|
||
|
const parent = node.parentNode;
|
||
|
if (!parent || !parent.childNodes)
|
||
|
return;
|
||
|
const elIndex = parent.childNodes.indexOf(node);
|
||
|
parent.childNodes.splice(elIndex, 1);
|
||
|
}
|
||
|
exports.removeNode = removeNode;
|
||
|
function findElementsByTagNames(root, tagNames) {
|
||
|
const elements = {};
|
||
|
walkElements(root, el => {
|
||
|
if (tagNames.includes(el.tagName)) {
|
||
|
elements[el.tagName] = elements[el.tagName] || [];
|
||
|
elements[el.tagName].push(el);
|
||
|
}
|
||
|
});
|
||
|
return elements;
|
||
|
}
|
||
|
exports.findElementsByTagNames = findElementsByTagNames;
|
||
|
function findElement(el, predicate) {
|
||
|
if (isElementNode(el) && predicate(el))
|
||
|
return el;
|
||
|
if (!el.childNodes)
|
||
|
return null;
|
||
|
for (const child of el.childNodes) {
|
||
|
const result = findElement(child, predicate);
|
||
|
if (result)
|
||
|
return result;
|
||
|
}
|
||
|
return null;
|
||
|
}
|
||
|
exports.findElement = findElement;
|
||
|
function walkElements(el, processor) {
|
||
|
if (isElementNode(el))
|
||
|
processor(el);
|
||
|
if (el.childNodes)
|
||
|
el.childNodes.forEach(child => walkElements(child, processor));
|
||
|
}
|
||
|
exports.walkElements = walkElements;
|
||
|
function createTextNode(content, parent) {
|
||
|
return {
|
||
|
nodeName: '#text',
|
||
|
value: content,
|
||
|
parentNode: parent,
|
||
|
};
|
||
|
}
|
||
|
exports.createTextNode = createTextNode;
|
||
|
function removeAttr(el, name) {
|
||
|
for (let i = 0; i < el.attrs.length; i++) {
|
||
|
if (getAttrName(el.attrs[i]) === name) {
|
||
|
el.attrs.splice(i, 1);
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
exports.removeAttr = removeAttr;
|
||
|
function getAttr(el, name) {
|
||
|
const attr = findAttr(el, name);
|
||
|
return attr ? attr.value : null;
|
||
|
}
|
||
|
exports.getAttr = getAttr;
|
||
|
function setAttr(el, name, value) {
|
||
|
const attr = findAttr(el, name);
|
||
|
if (attr) {
|
||
|
attr.value = value;
|
||
|
return value;
|
||
|
}
|
||
|
const parsedAttrName = parseAttrName(name);
|
||
|
const newAttr = { name: parsedAttrName.name, value: value, namespace: void 0 };
|
||
|
if (parsedAttrName.prefix && namespaces_1.NAMESPACE_PREFIX_MAP[parsedAttrName.prefix])
|
||
|
newAttr.namespace = namespaces_1.NAMESPACE_PREFIX_MAP[parsedAttrName.prefix];
|
||
|
el.attrs.push(newAttr);
|
||
|
return value;
|
||
|
}
|
||
|
exports.setAttr = setAttr;
|