|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223 |
- "use strict";
- var __importDefault = (this && this.__importDefault) || function (mod) {
- return (mod && mod.__esModule) ? mod : { "default": mod };
- };
- Object.defineProperty(exports, "__esModule", { value: true });
- const NodeTypeEnum_1 = __importDefault(require("./NodeTypeEnum"));
- /**
- * Node utility.
- */
- class NodeUtility {
- /**
- * Returns boolean indicating if nodeB is an inclusive ancestor of nodeA.
- *
- * Based on:
- * https://github.com/jsdom/jsdom/blob/master/lib/jsdom/living/helpers/node.js
- *
- * @see https://dom.spec.whatwg.org/#concept-tree-inclusive-ancestor
- * @param ancestorNode Ancestor node.
- * @param referenceNode Reference node.
- * @returns "true" if following.
- */
- static isInclusiveAncestor(ancestorNode, referenceNode) {
- let parent = referenceNode;
- while (parent) {
- if (ancestorNode === parent) {
- return true;
- }
- parent = parent.parentNode;
- }
- return false;
- }
- /**
- * Returns boolean indicating if nodeB is following nodeA in the document tree.
- *
- * Based on:
- * https://github.com/jsdom/jsdom/blob/master/lib/jsdom/living/helpers/node.js
- *
- * @see https://dom.spec.whatwg.org/#concept-tree-following
- * @param nodeA Node A.
- * @param nodeB Node B.
- * @returns "true" if following.
- */
- static isFollowing(nodeA, nodeB) {
- if (nodeA === nodeB) {
- return false;
- }
- let current = nodeB;
- while (current) {
- current = this.following(current);
- if (current === nodeA) {
- return true;
- }
- }
- return false;
- }
- /**
- * Node length.
- *
- * Based on:
- * https://github.com/jsdom/jsdom/blob/master/lib/jsdom/living/helpers/node.js
- *
- * @see https://dom.spec.whatwg.org/#concept-node-length
- * @param node Node.
- * @returns Node length.
- */
- static getNodeLength(node) {
- switch (node.nodeType) {
- case NodeTypeEnum_1.default.documentTypeNode:
- return 0;
- case NodeTypeEnum_1.default.textNode:
- case NodeTypeEnum_1.default.processingInstructionNode:
- case NodeTypeEnum_1.default.commentNode:
- return node.data.length;
- default:
- return node.childNodes.length;
- }
- }
- /**
- * Returns boolean indicating if nodeB is following nodeA in the document tree.
- *
- * Based on:
- * https://github.com/jsdom/js-symbol-tree/blob/master/lib/SymbolTree.js#L220
- *
- * @param node Node.
- * @param [root] Root.
- * @returns Following node.
- */
- static following(node, root) {
- const firstChild = node.firstChild;
- if (firstChild) {
- return firstChild;
- }
- let current = node;
- while (current) {
- if (current === root) {
- return null;
- }
- const nextSibling = current.nextSibling;
- if (nextSibling) {
- return nextSibling;
- }
- current = current.parentNode;
- }
- return null;
- }
- /**
- * Returns the next sibling or parents sibling.
- *
- * @param node Node.
- * @returns Next decentant node.
- */
- static nextDecendantNode(node) {
- while (node && !node.nextSibling) {
- node = node.parentNode;
- }
- if (!node) {
- return null;
- }
- return node.nextSibling;
- }
- /**
- * Needed by https://dom.spec.whatwg.org/#concept-node-equals
- *
- * @param elementA
- * @param elementB
- */
- static attributeListsEqual(elementA, elementB) {
- const listA = Object.values(elementA['_attributes']);
- const listB = Object.values(elementB['_attributes']);
- const lengthA = listA.length;
- const lengthB = listB.length;
- if (lengthA !== lengthB) {
- return false;
- }
- for (let i = 0; i < lengthA; ++i) {
- const attrA = listA[i];
- if (!listB.some((attrB) => {
- return ((typeof attrA === 'number' && typeof attrB === 'number' && attrA === attrB) ||
- (typeof attrA === 'object' &&
- typeof attrB === 'object' &&
- NodeUtility.isEqualNode(attrA, attrB)));
- })) {
- return false;
- }
- }
- return true;
- }
- /**
- * Check if node nodeA equals node nodeB.
- * Reference: https://dom.spec.whatwg.org/#concept-node-equals
- *
- * @param nodeA Node A.
- * @param nodeB Node B.
- */
- static isEqualNode(nodeA, nodeB) {
- if (nodeA.nodeType !== nodeB.nodeType) {
- return false;
- }
- switch (nodeA.nodeType) {
- case NodeTypeEnum_1.default.documentTypeNode:
- const documentTypeA = nodeA;
- const documentTypeB = nodeB;
- if (documentTypeA.name !== documentTypeB.name ||
- documentTypeA.publicId !== documentTypeB.publicId ||
- documentTypeA.systemId !== documentTypeB.systemId) {
- return false;
- }
- break;
- case NodeTypeEnum_1.default.elementNode:
- const elementA = nodeA;
- const elementB = nodeB;
- if (elementA.namespaceURI !== elementB.namespaceURI ||
- elementA.prefix !== elementB.prefix ||
- elementA.localName !== elementB.localName ||
- elementA.attributes.length !== elementB.attributes.length) {
- return false;
- }
- break;
- case NodeTypeEnum_1.default.attributeNode:
- const attributeA = nodeA;
- const attributeB = nodeB;
- if (attributeA.namespaceURI !== attributeB.namespaceURI ||
- attributeA.localName !== attributeB.localName ||
- attributeA.value !== attributeB.value) {
- return false;
- }
- break;
- case NodeTypeEnum_1.default.processingInstructionNode:
- const processingInstructionA = nodeA;
- const processingInstructionB = nodeB;
- if (processingInstructionA.target !== processingInstructionB.target ||
- processingInstructionA.data !== processingInstructionB.data) {
- return false;
- }
- break;
- case NodeTypeEnum_1.default.textNode:
- case NodeTypeEnum_1.default.commentNode:
- const textOrCommentA = nodeA;
- const textOrCommentB = nodeB;
- if (textOrCommentA.data !== textOrCommentB.data) {
- return false;
- }
- break;
- }
- if (nodeA.nodeType === NodeTypeEnum_1.default.elementNode &&
- !NodeUtility.attributeListsEqual(nodeA, nodeB)) {
- return false;
- }
- if (nodeA.childNodes.length !== nodeB.childNodes.length) {
- return false;
- }
- for (let i = 0; i < nodeA.childNodes.length; i++) {
- const childNodeA = nodeA.childNodes[i];
- const childNodeB = nodeB.childNodes[i];
- if (!NodeUtility.isEqualNode(childNodeA, childNodeB)) {
- return false;
- }
- }
- return true;
- }
- }
- exports.default = NodeUtility;
- //# sourceMappingURL=NodeUtility.js.map
|