Spaces:
Running
Running
; | |
Object.defineProperty(exports, "__esModule", { value: true }); | |
exports.uniqueSort = exports.compareDocumentPosition = exports.removeSubsets = void 0; | |
var domhandler_1 = require("domhandler"); | |
/** | |
* Given an array of nodes, remove any member that is contained by another. | |
* | |
* @param nodes Nodes to filter. | |
* @returns Remaining nodes that aren't subtrees of each other. | |
*/ | |
function removeSubsets(nodes) { | |
var idx = nodes.length; | |
/* | |
* Check if each node (or one of its ancestors) is already contained in the | |
* array. | |
*/ | |
while (--idx >= 0) { | |
var node = nodes[idx]; | |
/* | |
* Remove the node if it is not unique. | |
* We are going through the array from the end, so we only | |
* have to check nodes that preceed the node under consideration in the array. | |
*/ | |
if (idx > 0 && nodes.lastIndexOf(node, idx - 1) >= 0) { | |
nodes.splice(idx, 1); | |
continue; | |
} | |
for (var ancestor = node.parent; ancestor; ancestor = ancestor.parent) { | |
if (nodes.includes(ancestor)) { | |
nodes.splice(idx, 1); | |
break; | |
} | |
} | |
} | |
return nodes; | |
} | |
exports.removeSubsets = removeSubsets; | |
/** | |
* Compare the position of one node against another node in any other document. | |
* The return value is a bitmask with the following values: | |
* | |
* Document order: | |
* > There is an ordering, document order, defined on all the nodes in the | |
* > document corresponding to the order in which the first character of the | |
* > XML representation of each node occurs in the XML representation of the | |
* > document after expansion of general entities. Thus, the document element | |
* > node will be the first node. Element nodes occur before their children. | |
* > Thus, document order orders element nodes in order of the occurrence of | |
* > their start-tag in the XML (after expansion of entities). The attribute | |
* > nodes of an element occur after the element and before its children. The | |
* > relative order of attribute nodes is implementation-dependent./ | |
* | |
* Source: | |
* http://www.w3.org/TR/DOM-Level-3-Core/glossary.html#dt-document-order | |
* | |
* @param nodeA The first node to use in the comparison | |
* @param nodeB The second node to use in the comparison | |
* @returns A bitmask describing the input nodes' relative position. | |
* | |
* See http://dom.spec.whatwg.org/#dom-node-comparedocumentposition for | |
* a description of these values. | |
*/ | |
function compareDocumentPosition(nodeA, nodeB) { | |
var aParents = []; | |
var bParents = []; | |
if (nodeA === nodeB) { | |
return 0; | |
} | |
var current = (0, domhandler_1.hasChildren)(nodeA) ? nodeA : nodeA.parent; | |
while (current) { | |
aParents.unshift(current); | |
current = current.parent; | |
} | |
current = (0, domhandler_1.hasChildren)(nodeB) ? nodeB : nodeB.parent; | |
while (current) { | |
bParents.unshift(current); | |
current = current.parent; | |
} | |
var maxIdx = Math.min(aParents.length, bParents.length); | |
var idx = 0; | |
while (idx < maxIdx && aParents[idx] === bParents[idx]) { | |
idx++; | |
} | |
if (idx === 0) { | |
return 1 /* DISCONNECTED */; | |
} | |
var sharedParent = aParents[idx - 1]; | |
var siblings = sharedParent.children; | |
var aSibling = aParents[idx]; | |
var bSibling = bParents[idx]; | |
if (siblings.indexOf(aSibling) > siblings.indexOf(bSibling)) { | |
if (sharedParent === nodeB) { | |
return 4 /* FOLLOWING */ | 16 /* CONTAINED_BY */; | |
} | |
return 4 /* FOLLOWING */; | |
} | |
if (sharedParent === nodeA) { | |
return 2 /* PRECEDING */ | 8 /* CONTAINS */; | |
} | |
return 2 /* PRECEDING */; | |
} | |
exports.compareDocumentPosition = compareDocumentPosition; | |
/** | |
* Sort an array of nodes based on their relative position in the document and | |
* remove any duplicate nodes. If the array contains nodes that do not belong | |
* to the same document, sort order is unspecified. | |
* | |
* @param nodes Array of DOM nodes. | |
* @returns Collection of unique nodes, sorted in document order. | |
*/ | |
function uniqueSort(nodes) { | |
nodes = nodes.filter(function (node, i, arr) { return !arr.includes(node, i + 1); }); | |
nodes.sort(function (a, b) { | |
var relative = compareDocumentPosition(a, b); | |
if (relative & 2 /* PRECEDING */) { | |
return -1; | |
} | |
else if (relative & 4 /* FOLLOWING */) { | |
return 1; | |
} | |
return 0; | |
}); | |
return nodes; | |
} | |
exports.uniqueSort = uniqueSort; | |