1 | import Set from '../set';
|
2 | import cache from './cache-traversal-call';
|
3 |
|
4 | let elesfn = ({
|
5 | parent: function( selector ){
|
6 | let parents = [];
|
7 |
|
8 |
|
9 | if( this.length === 1 ){
|
10 | let parent = this[0]._private.parent;
|
11 |
|
12 | if( parent ){ return parent; }
|
13 | }
|
14 |
|
15 | for( let i = 0; i < this.length; i++ ){
|
16 | let ele = this[ i ];
|
17 | let parent = ele._private.parent;
|
18 |
|
19 | if( parent ){
|
20 | parents.push( parent );
|
21 | }
|
22 | }
|
23 |
|
24 | return this.spawn( parents, true ).filter( selector );
|
25 | },
|
26 |
|
27 | parents: function( selector ){
|
28 | let parents = [];
|
29 |
|
30 | let eles = this.parent();
|
31 | while( eles.nonempty() ){
|
32 | for( let i = 0; i < eles.length; i++ ){
|
33 | let ele = eles[ i ];
|
34 | parents.push( ele );
|
35 | }
|
36 |
|
37 | eles = eles.parent();
|
38 | }
|
39 |
|
40 | return this.spawn( parents, true ).filter( selector );
|
41 | },
|
42 |
|
43 | commonAncestors: function( selector ){
|
44 | let ancestors;
|
45 |
|
46 | for( let i = 0; i < this.length; i++ ){
|
47 | let ele = this[ i ];
|
48 | let parents = ele.parents();
|
49 |
|
50 | ancestors = ancestors || parents;
|
51 |
|
52 | ancestors = ancestors.intersect( parents );
|
53 | }
|
54 |
|
55 | return ancestors.filter( selector );
|
56 | },
|
57 |
|
58 | orphans: function( selector ){
|
59 | return this.stdFilter( function( ele ){
|
60 | return ele.isOrphan();
|
61 | } ).filter( selector );
|
62 | },
|
63 |
|
64 | nonorphans: function( selector ){
|
65 | return this.stdFilter( function( ele ){
|
66 | return ele.isChild();
|
67 | } ).filter( selector );
|
68 | },
|
69 |
|
70 | children: cache( function( selector ){
|
71 | let children = [];
|
72 |
|
73 | for( let i = 0; i < this.length; i++ ){
|
74 | let ele = this[ i ];
|
75 | let eleChildren = ele._private.children;
|
76 |
|
77 | for( let j = 0; j < eleChildren.length; j++ ){
|
78 | children.push( eleChildren[j] );
|
79 | }
|
80 | }
|
81 |
|
82 | return this.spawn( children, true ).filter( selector );
|
83 | }, 'children' ),
|
84 |
|
85 | siblings: function( selector ){
|
86 | return this.parent().children().not( this ).filter( selector );
|
87 | },
|
88 |
|
89 | isParent: function(){
|
90 | let ele = this[0];
|
91 |
|
92 | if( ele ){
|
93 | return ele.isNode() && ele._private.children.length !== 0;
|
94 | }
|
95 | },
|
96 |
|
97 | isChildless: function(){
|
98 | let ele = this[0];
|
99 |
|
100 | if( ele ){
|
101 | return ele.isNode() && ele._private.children.length === 0;
|
102 | }
|
103 | },
|
104 |
|
105 | isChild: function(){
|
106 | let ele = this[0];
|
107 |
|
108 | if( ele ){
|
109 | return ele.isNode() && ele._private.parent != null;
|
110 | }
|
111 | },
|
112 |
|
113 | isOrphan: function(){
|
114 | let ele = this[0];
|
115 |
|
116 | if( ele ){
|
117 | return ele.isNode() && ele._private.parent == null;
|
118 | }
|
119 | },
|
120 |
|
121 | descendants: function( selector ){
|
122 | let elements = [];
|
123 |
|
124 | function add( eles ){
|
125 | for( let i = 0; i < eles.length; i++ ){
|
126 | let ele = eles[ i ];
|
127 |
|
128 | elements.push( ele );
|
129 |
|
130 | if( ele.children().nonempty() ){
|
131 | add( ele.children() );
|
132 | }
|
133 | }
|
134 | }
|
135 |
|
136 | add( this.children() );
|
137 |
|
138 | return this.spawn( elements, true ).filter( selector );
|
139 | }
|
140 | });
|
141 |
|
142 | function forEachCompound( eles, fn, includeSelf, recursiveStep ){
|
143 | let q = [];
|
144 | let did = new Set();
|
145 | let cy = eles.cy();
|
146 | let hasCompounds = cy.hasCompoundNodes();
|
147 |
|
148 | for( let i = 0; i < eles.length; i++ ){
|
149 | let ele = eles[i];
|
150 |
|
151 | if( includeSelf ){
|
152 | q.push( ele );
|
153 | } else if( hasCompounds ){
|
154 | recursiveStep( q, did, ele );
|
155 | }
|
156 | }
|
157 |
|
158 | while( q.length > 0 ){
|
159 | let ele = q.shift();
|
160 |
|
161 | fn( ele );
|
162 |
|
163 | did.add( ele.id() );
|
164 |
|
165 | if( hasCompounds ){
|
166 | recursiveStep( q, did, ele );
|
167 | }
|
168 | }
|
169 |
|
170 | return eles;
|
171 | }
|
172 |
|
173 | function addChildren( q, did, ele ){
|
174 | if( ele.isParent() ){
|
175 | let children = ele._private.children;
|
176 |
|
177 | for( let i = 0; i < children.length; i++ ){
|
178 | let child = children[i];
|
179 |
|
180 | if( !did.has( child.id() ) ){
|
181 | q.push( child );
|
182 | }
|
183 | }
|
184 | }
|
185 | }
|
186 |
|
187 |
|
188 |
|
189 | elesfn.forEachDown = function( fn, includeSelf = true ){
|
190 | return forEachCompound( this, fn, includeSelf, addChildren );
|
191 | };
|
192 |
|
193 | function addParent( q, did, ele ){
|
194 | if( ele.isChild() ){
|
195 | let parent = ele._private.parent;
|
196 |
|
197 | if( !did.has( parent.id() ) ){
|
198 | q.push( parent );
|
199 | }
|
200 | }
|
201 | }
|
202 |
|
203 | elesfn.forEachUp = function( fn, includeSelf = true ){
|
204 | return forEachCompound( this, fn, includeSelf, addParent );
|
205 | };
|
206 |
|
207 | function addParentAndChildren( q, did, ele ){
|
208 | addParent( q, did, ele );
|
209 | addChildren( q, did, ele );
|
210 | }
|
211 |
|
212 | elesfn.forEachUpAndDown = function( fn, includeSelf = true ){
|
213 | return forEachCompound( this, fn, includeSelf, addParentAndChildren );
|
214 | };
|
215 |
|
216 |
|
217 | elesfn.ancestors = elesfn.parents;
|
218 |
|
219 | export default elesfn;
|