.gitignore added
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / domutils / lib / helpers.js
1 // removeSubsets
2 // Given an array of nodes, remove any member that is contained by another.
3 exports.removeSubsets = function(nodes) {
4         var idx = nodes.length, node, ancestor, replace;
5
6         // Check if each node (or one of its ancestors) is already contained in the
7         // array.
8         while (--idx > -1) {
9                 node = ancestor = nodes[idx];
10
11                 // Temporarily remove the node under consideration
12                 nodes[idx] = null;
13                 replace = true;
14
15                 while (ancestor) {
16                         if (nodes.indexOf(ancestor) > -1) {
17                                 replace = false;
18                                 nodes.splice(idx, 1);
19                                 break;
20                         }
21                         ancestor = ancestor.parent;
22                 }
23
24                 // If the node has been found to be unique, re-insert it.
25                 if (replace) {
26                         nodes[idx] = node;
27                 }
28         }
29
30         return nodes;
31 };
32
33 // Source: http://dom.spec.whatwg.org/#dom-node-comparedocumentposition
34 var POSITION = {
35         DISCONNECTED: 1,
36         PRECEDING: 2,
37         FOLLOWING: 4,
38         CONTAINS: 8,
39         CONTAINED_BY: 16
40 };
41
42 // Compare the position of one node against another node in any other document.
43 // The return value is a bitmask with the following values:
44 //
45 // document order:
46 // > There is an ordering, document order, defined on all the nodes in the
47 // > document corresponding to the order in which the first character of the
48 // > XML representation of each node occurs in the XML representation of the
49 // > document after expansion of general entities. Thus, the document element
50 // > node will be the first node. Element nodes occur before their children.
51 // > Thus, document order orders element nodes in order of the occurrence of
52 // > their start-tag in the XML (after expansion of entities). The attribute
53 // > nodes of an element occur after the element and before its children. The
54 // > relative order of attribute nodes is implementation-dependent./
55 // Source:
56 // http://www.w3.org/TR/DOM-Level-3-Core/glossary.html#dt-document-order
57 //
58 // @argument {Node} nodaA The first node to use in the comparison
59 // @argument {Node} nodeB The second node to use in the comparison
60 //
61 // @return {Number} A bitmask describing the input nodes' relative position.
62 //         See http://dom.spec.whatwg.org/#dom-node-comparedocumentposition for
63 //         a description of these values.
64 var comparePos = exports.compareDocumentPosition = function(nodeA, nodeB) {
65         var aParents = [];
66         var bParents = [];
67         var current, sharedParent, siblings, aSibling, bSibling, idx;
68
69         if (nodeA === nodeB) {
70                 return 0;
71         }
72
73         current = nodeA;
74         while (current) {
75                 aParents.unshift(current);
76                 current = current.parent;
77         }
78         current = nodeB;
79         while (current) {
80                 bParents.unshift(current);
81                 current = current.parent;
82         }
83
84         idx = 0;
85         while (aParents[idx] === bParents[idx]) {
86                 idx++;
87         }
88
89         if (idx === 0) {
90                 return POSITION.DISCONNECTED;
91         }
92
93         sharedParent = aParents[idx - 1];
94         siblings = sharedParent.children;
95         aSibling = aParents[idx];
96         bSibling = bParents[idx];
97
98         if (siblings.indexOf(aSibling) > siblings.indexOf(bSibling)) {
99                 if (sharedParent === nodeB) {
100                         return POSITION.FOLLOWING | POSITION.CONTAINED_BY;
101                 }
102                 return POSITION.FOLLOWING;
103         } else {
104                 if (sharedParent === nodeA) {
105                         return POSITION.PRECEDING | POSITION.CONTAINS;
106                 }
107                 return POSITION.PRECEDING;
108         }
109 };
110
111 // Sort an array of nodes based on their relative position in the document and
112 // remove any duplicate nodes. If the array contains nodes that do not belong
113 // to the same document, sort order is unspecified.
114 //
115 // @argument {Array} nodes Array of DOM nodes
116 //
117 // @returns {Array} collection of unique nodes, sorted in document order
118 exports.uniqueSort = function(nodes) {
119         var idx = nodes.length, node, position;
120
121         nodes = nodes.slice();
122
123         while (--idx > -1) {
124                 node = nodes[idx];
125                 position = nodes.indexOf(node);
126                 if (position > -1 && position < idx) {
127                         nodes.splice(idx, 1);
128                 }
129         }
130         nodes.sort(function(a, b) {
131                 var relative = comparePos(a, b);
132                 if (relative & POSITION.PRECEDING) {
133                         return -1;
134                 } else if (relative & POSITION.FOLLOWING) {
135                         return 1;
136                 }
137                 return 0;
138         });
139
140         return nodes;
141 };