@@ -4,52 +4,6 @@ import { GroupArrayChild, GroupSingleChild } from "./groups";
4
4
import { GroupChild , TargetGroupsObject , TargetGroupsType , TargetList } from "./types" ;
5
5
6
6
7
- function createGroupChildren (
8
- targetGroups : TargetGroupsObject ,
9
- parent : GroupArrayChild ,
10
- ) {
11
- const {
12
- value,
13
- map,
14
- } = parent ;
15
- targetGroups . forEach ( child => {
16
- if ( "groupId" in child ) {
17
- const group = new GroupArrayChild ( parent ) ;
18
-
19
- group . id = child . groupId ;
20
- group . depth = parent . depth + 1 ;
21
- value . push ( group ) ;
22
-
23
- createGroupChildren ( child . children , group ) ;
24
- } else if ( isArray ( child ) ) {
25
- const group = new GroupArrayChild ( parent ) ;
26
-
27
- group . depth = parent . depth + 1 ;
28
- value . push ( group ) ;
29
-
30
- createGroupChildren ( child , group ) ;
31
- } else {
32
- const element = "current" in child ? child . current : child ;
33
- const single = new GroupSingleChild ( parent , element ! ) ;
34
-
35
- single . depth = parent . depth + 1 ;
36
- value . push ( single ) ;
37
- map . set ( element ! , single ) ;
38
- }
39
- } ) ;
40
-
41
- value . forEach ( child => {
42
- if ( child . type === "single" ) {
43
- map . set ( child . value , child ) ;
44
- } else {
45
- child . map . forEach ( ( nextChild , element ) => {
46
- map . set ( element , nextChild ) ;
47
- } ) ;
48
- }
49
- } ) ;
50
- return parent ;
51
- }
52
-
53
7
export function toTargetList ( raw : GroupChild [ ] ) : TargetList {
54
8
function targets ( childs : GroupChild [ ] = [ ] ) {
55
9
const arr : TargetGroupsType = [ ] ;
@@ -78,6 +32,8 @@ export function toTargetList(raw: GroupChild[]): TargetList {
78
32
79
33
export class GroupManager extends GroupArrayChild {
80
34
public type = "root" as const ;
35
+ private _targets : Array < HTMLElement | SVGElement > = [ ] ;
36
+
81
37
constructor (
82
38
targetGroups : TargetGroupsType ,
83
39
targets ?: Array < HTMLElement | SVGElement > ,
@@ -95,8 +51,7 @@ export class GroupManager extends GroupArrayChild {
95
51
const map = this . map ;
96
52
const value = this . value ;
97
53
98
- createGroupChildren ( targetGroups , this ) ;
99
-
54
+ this . add ( targetGroups ) ;
100
55
targets . forEach ( target => {
101
56
if ( map . has ( target ) ) {
102
57
return ;
@@ -107,6 +62,7 @@ export class GroupManager extends GroupArrayChild {
107
62
value . push ( single ) ;
108
63
map . set ( target , single ) ;
109
64
} ) ;
65
+ this . _targets = targets ;
110
66
}
111
67
public selectSubChilds ( targets : TargetGroupsType , target : HTMLElement | SVGElement ) {
112
68
const root = this ;
@@ -300,6 +256,62 @@ export class GroupManager extends GroupArrayChild {
300
256
301
257
return value ;
302
258
}
259
+ public group ( targets : TargetGroupsType , flatten ?: boolean ) : TargetGroupsType | null {
260
+ const commonParent = this . findCommonParent ( targets ) ;
261
+ const groupChilds = targets . map ( target => {
262
+ if ( isArray ( target ) ) {
263
+ return this . findArrayChild ( target ) ;
264
+ }
265
+ return this . toSingleChild ( target ) ;
266
+ } ) ;
267
+ const isGroupable = groupChilds . every ( child => child ?. parent === commonParent ) ;
268
+
269
+ if ( ! isGroupable ) {
270
+ return null ;
271
+ }
272
+ const group = new GroupArrayChild ( commonParent ) ;
273
+ const nextChilds = commonParent . value . filter ( target => groupChilds . indexOf ( target ) === - 1 ) ;
274
+
275
+ nextChilds . unshift ( group ) ;
276
+
277
+ group . add ( flatten ? deepFlat ( targets ) : targets ) ;
278
+ commonParent . value = nextChilds ;
279
+
280
+ this . set ( this . toTargetGroups ( ) , this . _targets ) ;
281
+
282
+ return group . toTargetGroups ( ) ;
283
+ }
284
+ public ungroup ( targets : TargetGroupsType ) {
285
+ if ( targets . length === 1 && isArray ( targets [ 0 ] ) ) {
286
+ targets = targets [ 0 ] ;
287
+ }
288
+ const commonParent = this . findCommonParent ( targets ) ;
289
+ const groupChilds = targets . map ( target => {
290
+ if ( isArray ( target ) ) {
291
+ return this . findArrayChild ( target ) ;
292
+ }
293
+ return this . toSingleChild ( target ) ;
294
+ } ) ;
295
+ const isGroupable = commonParent . value . every ( child => groupChilds . indexOf ( child ) > - 1 ) ;
296
+
297
+ if ( ! isGroupable || commonParent === this ) {
298
+ // has no group
299
+ return null ;
300
+ }
301
+
302
+ const parent = commonParent . parent ;
303
+
304
+ if ( ! parent ) {
305
+ return null ;
306
+ }
307
+ const nextChilds = parent . value . filter ( target => target !== commonParent ) ;
308
+
309
+ nextChilds . push ( ...commonParent . value ) ;
310
+ parent . value = nextChilds ;
311
+
312
+ this . set ( this . toTargetGroups ( ) , this . _targets ) ;
313
+ return commonParent . toTargetGroups ( ) ;
314
+ }
303
315
protected _findParentGroup (
304
316
element : HTMLElement | SVGElement ,
305
317
range : Array < HTMLElement | SVGElement > ,
0 commit comments