1 | import * as util from '../util';
|
2 | import * as is from '../is';
|
3 | import Map from '../map';
|
4 | import Set from '../set';
|
5 |
|
6 | import Element from './element';
|
7 | import algorithms from './algorithms';
|
8 | import animation from './animation';
|
9 | import classNames from './class';
|
10 | import comparators from './comparators';
|
11 | import compounds from './compounds';
|
12 | import data from './data';
|
13 | import degree from './degree';
|
14 | import dimensions from './dimensions';
|
15 | import events from './events';
|
16 | import filter from './filter';
|
17 | import group from './group';
|
18 | import iteration from './iteration';
|
19 | import layout from './layout';
|
20 | import style from './style';
|
21 | import switchFunctions from './switch-functions';
|
22 | import traversing from './traversing';
|
23 |
|
24 |
|
25 | let Collection = function( cy, elements, unique = false, removed = false ){
|
26 | if( cy === undefined ){
|
27 | util.error( 'A collection must have a reference to the core' );
|
28 | return;
|
29 | }
|
30 |
|
31 | let map = new Map();
|
32 | let createdElements = false;
|
33 |
|
34 | if( !elements ){
|
35 | elements = [];
|
36 | } else if( elements.length > 0 && is.plainObject( elements[0] ) && !is.element( elements[0] ) ){
|
37 | createdElements = true;
|
38 |
|
39 |
|
40 | let eles = [];
|
41 | let elesIds = new Set();
|
42 |
|
43 | for( let i = 0, l = elements.length; i < l; i++ ){
|
44 | let json = elements[ i ];
|
45 |
|
46 | if( json.data == null ){
|
47 | json.data = {};
|
48 | }
|
49 |
|
50 | let data = json.data;
|
51 |
|
52 |
|
53 | if( data.id == null ){
|
54 | data.id = util.uuid();
|
55 | } else if( cy.hasElementWithId( data.id ) || elesIds.has( data.id ) ){
|
56 | continue;
|
57 | }
|
58 |
|
59 | let ele = new Element( cy, json, false );
|
60 | eles.push( ele );
|
61 | elesIds.add( data.id );
|
62 | }
|
63 |
|
64 | elements = eles;
|
65 | }
|
66 |
|
67 | this.length = 0;
|
68 |
|
69 | for( let i = 0, l = elements.length; i < l; i++ ){
|
70 | let element = elements[i][0];
|
71 | if( element == null ){ continue; }
|
72 |
|
73 | let id = element._private.data.id;
|
74 |
|
75 | if( !unique || !map.has(id) ){
|
76 | if( unique ){
|
77 | map.set( id, {
|
78 | index: this.length,
|
79 | ele: element
|
80 | } );
|
81 | }
|
82 |
|
83 | this[ this.length ] = element;
|
84 | this.length++;
|
85 | }
|
86 | }
|
87 |
|
88 | this._private = {
|
89 | eles: this,
|
90 | cy: cy,
|
91 | get map(){
|
92 | if( this.lazyMap == null ){
|
93 | this.rebuildMap();
|
94 | }
|
95 |
|
96 | return this.lazyMap;
|
97 | },
|
98 | set map(m){
|
99 | this.lazyMap = m;
|
100 | },
|
101 | rebuildMap(){
|
102 | const m = this.lazyMap = new Map();
|
103 | const eles = this.eles;
|
104 |
|
105 | for( let i = 0; i < eles.length; i++ ){
|
106 | const ele = eles[i];
|
107 |
|
108 | m.set(ele.id(), { index: i, ele });
|
109 | }
|
110 | }
|
111 | };
|
112 |
|
113 | if( unique ){
|
114 | this._private.map = map;
|
115 | }
|
116 |
|
117 |
|
118 | if( createdElements && !removed ){
|
119 | this.restore();
|
120 | }
|
121 | };
|
122 |
|
123 |
|
124 |
|
125 |
|
126 |
|
127 |
|
128 | let elesfn = Element.prototype = Collection.prototype = Object.create(Array.prototype);
|
129 |
|
130 | elesfn.instanceString = function(){
|
131 | return 'collection';
|
132 | };
|
133 |
|
134 | elesfn.spawn = function( eles, unique ){
|
135 | return new Collection( this.cy(), eles, unique );
|
136 | };
|
137 |
|
138 | elesfn.spawnSelf = function(){
|
139 | return this.spawn( this );
|
140 | };
|
141 |
|
142 | elesfn.cy = function(){
|
143 | return this._private.cy;
|
144 | };
|
145 |
|
146 | elesfn.renderer = function(){
|
147 | return this._private.cy.renderer();
|
148 | };
|
149 |
|
150 | elesfn.element = function(){
|
151 | return this[0];
|
152 | };
|
153 |
|
154 | elesfn.collection = function(){
|
155 | if( is.collection( this ) ){
|
156 | return this;
|
157 | } else {
|
158 | return new Collection( this._private.cy, [ this ] );
|
159 | }
|
160 | };
|
161 |
|
162 | elesfn.unique = function(){
|
163 | return new Collection( this._private.cy, this, true );
|
164 | };
|
165 |
|
166 | elesfn.hasElementWithId = function( id ){
|
167 | id = '' + id;
|
168 |
|
169 | return this._private.map.has( id );
|
170 | };
|
171 |
|
172 | elesfn.getElementById = function( id ){
|
173 | id = '' + id;
|
174 |
|
175 | let cy = this._private.cy;
|
176 | let entry = this._private.map.get( id );
|
177 |
|
178 | return entry ? entry.ele : new Collection( cy );
|
179 | };
|
180 |
|
181 | elesfn.$id = elesfn.getElementById;
|
182 |
|
183 | elesfn.poolIndex = function(){
|
184 | let cy = this._private.cy;
|
185 | let eles = cy._private.elements;
|
186 | let id = this[0]._private.data.id;
|
187 |
|
188 | return eles._private.map.get( id ).index;
|
189 | };
|
190 |
|
191 | elesfn.indexOf = function( ele ){
|
192 | let id = ele[0]._private.data.id;
|
193 |
|
194 | return this._private.map.get( id ).index;
|
195 | };
|
196 |
|
197 | elesfn.indexOfId = function( id ){
|
198 | id = '' + id;
|
199 |
|
200 | return this._private.map.get( id ).index;
|
201 | };
|
202 |
|
203 | elesfn.json = function( obj ){
|
204 | let ele = this.element();
|
205 | let cy = this.cy();
|
206 |
|
207 | if( ele == null && obj ){ return this; }
|
208 |
|
209 | if( ele == null ){ return undefined; }
|
210 |
|
211 | let p = ele._private;
|
212 |
|
213 | if( is.plainObject( obj ) ){
|
214 |
|
215 | cy.startBatch();
|
216 |
|
217 | if( obj.data ){
|
218 | ele.data( obj.data );
|
219 |
|
220 | let data = p.data;
|
221 |
|
222 | if( ele.isEdge() ){
|
223 | let move = false;
|
224 | let spec = {};
|
225 | let src = obj.data.source;
|
226 | let tgt = obj.data.target;
|
227 |
|
228 | if( src != null && src != data.source ){
|
229 | spec.source = '' + src;
|
230 | move = true;
|
231 | }
|
232 |
|
233 | if( tgt != null && tgt != data.target ){
|
234 | spec.target = '' + tgt;
|
235 | move = true;
|
236 | }
|
237 |
|
238 | if( move ){
|
239 | ele = ele.move(spec);
|
240 | }
|
241 | } else {
|
242 | let newParentValSpecd = 'parent' in obj.data;
|
243 | let parent = obj.data.parent;
|
244 |
|
245 | if( newParentValSpecd && (parent != null || data.parent != null) && parent != data.parent ){
|
246 | if( parent === undefined ){
|
247 | parent = null;
|
248 | }
|
249 |
|
250 | if( parent != null ){
|
251 | parent = '' + parent;
|
252 | }
|
253 |
|
254 | ele = ele.move({ parent });
|
255 | }
|
256 | }
|
257 | }
|
258 |
|
259 | if( obj.position ){
|
260 | ele.position( obj.position );
|
261 | }
|
262 |
|
263 |
|
264 |
|
265 | let checkSwitch = function( k, trueFnName, falseFnName ){
|
266 | let obj_k = obj[ k ];
|
267 |
|
268 | if( obj_k != null && obj_k !== p[ k ] ){
|
269 | if( obj_k ){
|
270 | ele[ trueFnName ]();
|
271 | } else {
|
272 | ele[ falseFnName ]();
|
273 | }
|
274 | }
|
275 | };
|
276 |
|
277 | checkSwitch( 'removed', 'remove', 'restore' );
|
278 |
|
279 | checkSwitch( 'selected', 'select', 'unselect' );
|
280 |
|
281 | checkSwitch( 'selectable', 'selectify', 'unselectify' );
|
282 |
|
283 | checkSwitch( 'locked', 'lock', 'unlock' );
|
284 |
|
285 | checkSwitch( 'grabbable', 'grabify', 'ungrabify' );
|
286 |
|
287 | checkSwitch( 'pannable', 'panify', 'unpanify' );
|
288 |
|
289 | if( obj.classes != null ){
|
290 | ele.classes( obj.classes );
|
291 | }
|
292 |
|
293 | cy.endBatch();
|
294 |
|
295 | return this;
|
296 |
|
297 | } else if( obj === undefined ){
|
298 |
|
299 | let json = {
|
300 | data: util.copy( p.data ),
|
301 | position: util.copy( p.position ),
|
302 | group: p.group,
|
303 | removed: p.removed,
|
304 | selected: p.selected,
|
305 | selectable: p.selectable,
|
306 | locked: p.locked,
|
307 | grabbable: p.grabbable,
|
308 | pannable: p.pannable,
|
309 | classes: null
|
310 | };
|
311 |
|
312 | json.classes = '';
|
313 |
|
314 | let i = 0;
|
315 | p.classes.forEach( cls => json.classes += ( i++ === 0 ? cls : ' ' + cls ) );
|
316 |
|
317 | return json;
|
318 | }
|
319 | };
|
320 |
|
321 | elesfn.jsons = function(){
|
322 | let jsons = [];
|
323 |
|
324 | for( let i = 0; i < this.length; i++ ){
|
325 | let ele = this[ i ];
|
326 | let json = ele.json();
|
327 |
|
328 | jsons.push( json );
|
329 | }
|
330 |
|
331 | return jsons;
|
332 | };
|
333 |
|
334 | elesfn.clone = function(){
|
335 | let cy = this.cy();
|
336 | let elesArr = [];
|
337 |
|
338 | for( let i = 0; i < this.length; i++ ){
|
339 | let ele = this[ i ];
|
340 | let json = ele.json();
|
341 | let clone = new Element( cy, json, false );
|
342 |
|
343 | elesArr.push( clone );
|
344 | }
|
345 |
|
346 | return new Collection( cy, elesArr );
|
347 | };
|
348 | elesfn.copy = elesfn.clone;
|
349 |
|
350 | elesfn.restore = function( notifyRenderer = true, addToPool = true ){
|
351 | let self = this;
|
352 | let cy = self.cy();
|
353 | let cy_p = cy._private;
|
354 |
|
355 |
|
356 |
|
357 | let nodes = [];
|
358 | let edges = [];
|
359 | let elements;
|
360 | for( let i = 0, l = self.length; i < l; i++ ){
|
361 | let ele = self[ i ];
|
362 |
|
363 | if( addToPool && !ele.removed() ){
|
364 |
|
365 | continue;
|
366 | }
|
367 |
|
368 |
|
369 | if( ele.isNode() ){
|
370 | nodes.push( ele );
|
371 | } else {
|
372 | edges.push( ele );
|
373 | }
|
374 | }
|
375 |
|
376 | elements = nodes.concat( edges );
|
377 |
|
378 | let i;
|
379 | let removeFromElements = function(){
|
380 | elements.splice( i, 1 );
|
381 | i--;
|
382 | };
|
383 |
|
384 |
|
385 | for( i = 0; i < elements.length; i++ ){
|
386 | let ele = elements[ i ];
|
387 |
|
388 | let _private = ele._private;
|
389 | let data = _private.data;
|
390 |
|
391 |
|
392 | ele.clearTraversalCache();
|
393 |
|
394 |
|
395 | if( !addToPool && !_private.removed ){
|
396 |
|
397 |
|
398 | } else if( data.id === undefined ){
|
399 | data.id = util.uuid();
|
400 |
|
401 | } else if( is.number( data.id ) ){
|
402 | data.id = '' + data.id;
|
403 |
|
404 | } else if( is.emptyString( data.id ) || !is.string( data.id ) ){
|
405 | util.error( 'Can not create element with invalid string ID `' + data.id + '`' );
|
406 |
|
407 |
|
408 | removeFromElements();
|
409 | continue;
|
410 | } else if( cy.hasElementWithId( data.id ) ){
|
411 | util.error( 'Can not create second element with ID `' + data.id + '`' );
|
412 |
|
413 |
|
414 | removeFromElements();
|
415 | continue;
|
416 | }
|
417 |
|
418 | let id = data.id;
|
419 |
|
420 | if( ele.isNode() ){
|
421 | let pos = _private.position;
|
422 |
|
423 |
|
424 |
|
425 | if( pos.x == null ){
|
426 | pos.x = 0;
|
427 | }
|
428 |
|
429 | if( pos.y == null ){
|
430 | pos.y = 0;
|
431 | }
|
432 | }
|
433 |
|
434 | if( ele.isEdge() ){
|
435 |
|
436 | let edge = ele;
|
437 | let fields = [ 'source', 'target' ];
|
438 | let fieldsLength = fields.length;
|
439 | let badSourceOrTarget = false;
|
440 | for( let j = 0; j < fieldsLength; j++ ){
|
441 |
|
442 | let field = fields[ j ];
|
443 | let val = data[ field ];
|
444 |
|
445 | if( is.number( val ) ){
|
446 | val = data[ field ] = '' + data[ field ];
|
447 | }
|
448 |
|
449 | if( val == null || val === '' ){
|
450 |
|
451 | util.error( 'Can not create edge `' + id + '` with unspecified ' + field );
|
452 | badSourceOrTarget = true;
|
453 | } else if( !cy.hasElementWithId( val ) ){
|
454 |
|
455 | util.error( 'Can not create edge `' + id + '` with nonexistant ' + field + ' `' + val + '`' );
|
456 | badSourceOrTarget = true;
|
457 | }
|
458 | }
|
459 |
|
460 | if( badSourceOrTarget ){ removeFromElements(); continue; }
|
461 |
|
462 | let src = cy.getElementById( data.source );
|
463 | let tgt = cy.getElementById( data.target );
|
464 |
|
465 |
|
466 | if (src.same(tgt)) {
|
467 | src._private.edges.push( edge );
|
468 | } else {
|
469 | src._private.edges.push( edge );
|
470 | tgt._private.edges.push( edge );
|
471 | }
|
472 |
|
473 | edge._private.source = src;
|
474 | edge._private.target = tgt;
|
475 | }
|
476 |
|
477 |
|
478 | _private.map = new Map();
|
479 | _private.map.set( id, { ele: ele, index: 0 } );
|
480 |
|
481 | _private.removed = false;
|
482 |
|
483 | if( addToPool ){
|
484 | cy.addToPool( ele );
|
485 | }
|
486 | }
|
487 |
|
488 |
|
489 | for( let i = 0; i < nodes.length; i++ ){
|
490 | let node = nodes[ i ];
|
491 | let data = node._private.data;
|
492 |
|
493 | if( is.number( data.parent ) ){
|
494 | data.parent = '' + data.parent;
|
495 | }
|
496 |
|
497 | let parentId = data.parent;
|
498 |
|
499 | let specifiedParent = parentId != null;
|
500 |
|
501 | if( specifiedParent || node._private.parent ){
|
502 |
|
503 | let parent = node._private.parent ? cy.collection().merge(node._private.parent) : cy.getElementById( parentId );
|
504 |
|
505 | if( parent.empty() ){
|
506 |
|
507 | data.parent = undefined;
|
508 | } else if( parent[0].removed() ) {
|
509 | util.warn('Node added with missing parent, reference to parent removed');
|
510 | data.parent = undefined;
|
511 | node._private.parent = null;
|
512 | } else {
|
513 | let selfAsParent = false;
|
514 | let ancestor = parent;
|
515 | while( !ancestor.empty() ){
|
516 | if( node.same( ancestor ) ){
|
517 |
|
518 | selfAsParent = true;
|
519 | data.parent = undefined;
|
520 |
|
521 |
|
522 | break;
|
523 | }
|
524 |
|
525 | ancestor = ancestor.parent();
|
526 | }
|
527 |
|
528 | if( !selfAsParent ){
|
529 |
|
530 | parent[0]._private.children.push( node );
|
531 | node._private.parent = parent[0];
|
532 |
|
533 |
|
534 | cy_p.hasCompoundNodes = true;
|
535 | }
|
536 | }
|
537 | }
|
538 | }
|
539 |
|
540 | if( elements.length > 0 ){
|
541 | let restored = elements.length === self.length ? self : new Collection( cy, elements );
|
542 |
|
543 | for( let i = 0; i < restored.length; i++ ){
|
544 | let ele = restored[i];
|
545 |
|
546 | if( ele.isNode() ){ continue; }
|
547 |
|
548 |
|
549 | ele.parallelEdges().clearTraversalCache();
|
550 |
|
551 |
|
552 | ele.source().clearTraversalCache();
|
553 | ele.target().clearTraversalCache();
|
554 | }
|
555 |
|
556 | let toUpdateStyle;
|
557 |
|
558 | if( cy_p.hasCompoundNodes ){
|
559 | toUpdateStyle = cy.collection().merge( restored ).merge( restored.connectedNodes() ).merge( restored.parent() );
|
560 | } else {
|
561 | toUpdateStyle = restored;
|
562 | }
|
563 |
|
564 | toUpdateStyle.dirtyCompoundBoundsCache().dirtyBoundingBoxCache().updateStyle( notifyRenderer );
|
565 |
|
566 | if( notifyRenderer ){
|
567 | restored.emitAndNotify( 'add' );
|
568 | } else if( addToPool ){
|
569 | restored.emit( 'add' );
|
570 | }
|
571 | }
|
572 |
|
573 | return self;
|
574 | };
|
575 |
|
576 | elesfn.removed = function(){
|
577 | let ele = this[0];
|
578 | return ele && ele._private.removed;
|
579 | };
|
580 |
|
581 | elesfn.inside = function(){
|
582 | let ele = this[0];
|
583 | return ele && !ele._private.removed;
|
584 | };
|
585 |
|
586 | elesfn.remove = function( notifyRenderer = true, removeFromPool = true ){
|
587 | let self = this;
|
588 | let elesToRemove = [];
|
589 | let elesToRemoveIds = {};
|
590 | let cy = self._private.cy;
|
591 |
|
592 |
|
593 | function addConnectedEdges( node ){
|
594 | let edges = node._private.edges;
|
595 | for( let i = 0; i < edges.length; i++ ){
|
596 | add( edges[ i ] );
|
597 | }
|
598 | }
|
599 |
|
600 |
|
601 | function addChildren( node ){
|
602 | let children = node._private.children;
|
603 |
|
604 | for( let i = 0; i < children.length; i++ ){
|
605 | add( children[ i ] );
|
606 | }
|
607 | }
|
608 |
|
609 | function add( ele ){
|
610 | let alreadyAdded = elesToRemoveIds[ ele.id() ];
|
611 | if( (removeFromPool && ele.removed()) || alreadyAdded ){
|
612 | return;
|
613 | } else {
|
614 | elesToRemoveIds[ ele.id() ] = true;
|
615 | }
|
616 |
|
617 | if( ele.isNode() ){
|
618 | elesToRemove.push( ele );
|
619 |
|
620 | addConnectedEdges( ele );
|
621 | addChildren( ele );
|
622 | } else {
|
623 | elesToRemove.unshift( ele );
|
624 | }
|
625 | }
|
626 |
|
627 |
|
628 |
|
629 |
|
630 | for( let i = 0, l = self.length; i < l; i++ ){
|
631 | let ele = self[ i ];
|
632 |
|
633 | add( ele );
|
634 | }
|
635 |
|
636 | function removeEdgeRef( node, edge ){
|
637 | let connectedEdges = node._private.edges;
|
638 |
|
639 | util.removeFromArray( connectedEdges, edge );
|
640 |
|
641 |
|
642 | node.clearTraversalCache();
|
643 | }
|
644 |
|
645 | function removeParallelRef( pllEdge ){
|
646 |
|
647 | pllEdge.clearTraversalCache();
|
648 | }
|
649 |
|
650 | let alteredParents = [];
|
651 | alteredParents.ids = {};
|
652 |
|
653 | function removeChildRef( parent, ele ){
|
654 | ele = ele[0];
|
655 | parent = parent[0];
|
656 |
|
657 | let children = parent._private.children;
|
658 | let pid = parent.id();
|
659 |
|
660 | util.removeFromArray( children, ele );
|
661 |
|
662 | ele._private.parent = null;
|
663 |
|
664 | if( !alteredParents.ids[ pid ] ){
|
665 | alteredParents.ids[ pid ] = true;
|
666 | alteredParents.push( parent );
|
667 | }
|
668 | }
|
669 |
|
670 | self.dirtyCompoundBoundsCache();
|
671 |
|
672 | if( removeFromPool ){
|
673 | cy.removeFromPool( elesToRemove );
|
674 | }
|
675 |
|
676 | for( let i = 0; i < elesToRemove.length; i++ ){
|
677 | let ele = elesToRemove[ i ];
|
678 |
|
679 | if( ele.isEdge() ){
|
680 | let src = ele.source()[0];
|
681 | let tgt = ele.target()[0];
|
682 |
|
683 | removeEdgeRef( src, ele );
|
684 | removeEdgeRef( tgt, ele );
|
685 |
|
686 | let pllEdges = ele.parallelEdges();
|
687 |
|
688 | for( let j = 0; j < pllEdges.length; j++ ){
|
689 | let pllEdge = pllEdges[j];
|
690 |
|
691 | removeParallelRef(pllEdge);
|
692 |
|
693 | if( pllEdge.isBundledBezier() ){
|
694 | pllEdge.dirtyBoundingBoxCache();
|
695 | }
|
696 | }
|
697 |
|
698 | } else {
|
699 | let parent = ele.parent();
|
700 |
|
701 | if( parent.length !== 0 ){
|
702 | removeChildRef( parent, ele );
|
703 | }
|
704 | }
|
705 |
|
706 | if( removeFromPool ){
|
707 |
|
708 | ele._private.removed = true;
|
709 | }
|
710 | }
|
711 |
|
712 |
|
713 | let elesStillInside = cy._private.elements;
|
714 | cy._private.hasCompoundNodes = false;
|
715 | for( let i = 0; i < elesStillInside.length; i++ ){
|
716 | let ele = elesStillInside[ i ];
|
717 |
|
718 | if( ele.isParent() ){
|
719 | cy._private.hasCompoundNodes = true;
|
720 | break;
|
721 | }
|
722 | }
|
723 |
|
724 | let removedElements = new Collection( this.cy(), elesToRemove );
|
725 |
|
726 | if( removedElements.size() > 0 ){
|
727 |
|
728 |
|
729 | if( notifyRenderer ){
|
730 | removedElements.emitAndNotify('remove');
|
731 | } else if( removeFromPool ){
|
732 | removedElements.emit('remove');
|
733 | }
|
734 | }
|
735 |
|
736 |
|
737 | for( let i = 0; i < alteredParents.length; i++ ){
|
738 | let ele = alteredParents[ i ];
|
739 |
|
740 | if( !removeFromPool || !ele.removed() ){
|
741 | ele.updateStyle();
|
742 | }
|
743 | }
|
744 |
|
745 | return removedElements;
|
746 | };
|
747 |
|
748 | elesfn.move = function( struct ){
|
749 | let cy = this._private.cy;
|
750 | let eles = this;
|
751 |
|
752 |
|
753 |
|
754 | let notifyRenderer = false;
|
755 | let modifyPool = false;
|
756 |
|
757 | let toString = id => id == null ? id : '' + id;
|
758 |
|
759 | if( struct.source !== undefined || struct.target !== undefined ){
|
760 | let srcId = toString(struct.source);
|
761 | let tgtId = toString(struct.target);
|
762 | let srcExists = srcId != null && cy.hasElementWithId( srcId );
|
763 | let tgtExists = tgtId != null && cy.hasElementWithId( tgtId );
|
764 |
|
765 | if( srcExists || tgtExists ){
|
766 | cy.batch(() => {
|
767 | eles.remove( notifyRenderer, modifyPool );
|
768 | eles.emitAndNotify('moveout');
|
769 |
|
770 | for( let i = 0; i < eles.length; i++ ){
|
771 | let ele = eles[i];
|
772 | let data = ele._private.data;
|
773 |
|
774 | if( ele.isEdge() ){
|
775 | if( srcExists ){ data.source = srcId; }
|
776 |
|
777 | if( tgtExists ){ data.target = tgtId; }
|
778 | }
|
779 | }
|
780 |
|
781 | eles.restore( notifyRenderer, modifyPool );
|
782 | });
|
783 |
|
784 | eles.emitAndNotify('move');
|
785 | }
|
786 |
|
787 | } else if( struct.parent !== undefined ){
|
788 | let parentId = toString(struct.parent);
|
789 | let parentExists = parentId === null || cy.hasElementWithId( parentId );
|
790 |
|
791 | if( parentExists ){
|
792 | let pidToAssign = parentId === null ? undefined : parentId;
|
793 |
|
794 | cy.batch(() => {
|
795 | let updated = eles.remove( notifyRenderer, modifyPool );
|
796 | updated.emitAndNotify('moveout');
|
797 |
|
798 | for( let i = 0; i < eles.length; i++ ){
|
799 | let ele = eles[i];
|
800 | let data = ele._private.data;
|
801 |
|
802 | if( ele.isNode() ){
|
803 | data.parent = pidToAssign;
|
804 | }
|
805 | }
|
806 |
|
807 | updated.restore( notifyRenderer, modifyPool );
|
808 | });
|
809 |
|
810 | eles.emitAndNotify('move');
|
811 | }
|
812 | }
|
813 |
|
814 | return this;
|
815 | };
|
816 |
|
817 | [
|
818 | algorithms,
|
819 | animation,
|
820 | classNames,
|
821 | comparators,
|
822 | compounds,
|
823 | data,
|
824 | degree,
|
825 | dimensions,
|
826 | events,
|
827 | filter,
|
828 | group,
|
829 | iteration,
|
830 | layout,
|
831 | style,
|
832 | switchFunctions,
|
833 | traversing
|
834 | ].forEach( function( props ){
|
835 | util.extend( elesfn, props );
|
836 | } );
|
837 |
|
838 | export default Collection;
|