@easy-editor/plugin-dashboard 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,870 @@
1
+ import { DESIGNER_EVENT, DragObjectType, getConvertedExtraKey } from '@easy-editor/core';
2
+ import { observable, computed, action } from 'mobx';
3
+
4
+ function _applyDecs2311(e, t, n, r, o, i) {
5
+ var a,
6
+ c,
7
+ u,
8
+ s,
9
+ f,
10
+ l,
11
+ p,
12
+ d = Symbol.metadata || Symbol.for("Symbol.metadata"),
13
+ m = Object.defineProperty,
14
+ h = Object.create,
15
+ y = [h(null), h(null)],
16
+ v = t.length;
17
+ function g(t, n, r) {
18
+ return function (o, i) {
19
+ n && (i = o, o = e);
20
+ for (var a = 0; a < t.length; a++) i = t[a].apply(o, r ? [i] : []);
21
+ return r ? i : o;
22
+ };
23
+ }
24
+ function b(e, t, n, r) {
25
+ if ("function" != typeof e && (r || void 0 !== e)) throw new TypeError(t + " must " + (n || "be") + " a function" + (r ? "" : " or undefined"));
26
+ return e;
27
+ }
28
+ function applyDec(e, t, n, r, o, i, u, s, f, l, p) {
29
+ function d(e) {
30
+ if (!p(e)) throw new TypeError("Attempted to access private element on non-instance");
31
+ }
32
+ var h = [].concat(t[0]),
33
+ v = t[3],
34
+ w = !u,
35
+ D = 1 === o,
36
+ S = 3 === o,
37
+ j = 4 === o,
38
+ E = 2 === o;
39
+ function I(t, n, r) {
40
+ return function (o, i) {
41
+ return n && (i = o, o = e), r && r(o), P[t].call(o, i);
42
+ };
43
+ }
44
+ if (!w) {
45
+ var P = {},
46
+ k = [],
47
+ F = S ? "get" : j || D ? "set" : "value";
48
+ if (f ? (l || D ? P = {
49
+ get: _setFunctionName(function () {
50
+ return v(this);
51
+ }, r, "get"),
52
+ set: function (e) {
53
+ t[4](this, e);
54
+ }
55
+ } : P[F] = v, l || _setFunctionName(P[F], r, E ? "" : F)) : l || (P = Object.getOwnPropertyDescriptor(e, r)), !l && !f) {
56
+ if ((c = y[+s][r]) && 7 != (c ^ o)) throw Error("Decorating two elements with the same name (" + P[F].name + ") is not supported yet");
57
+ y[+s][r] = o < 3 ? 1 : o;
58
+ }
59
+ }
60
+ for (var N = e, O = h.length - 1; O >= 0; O -= n ? 2 : 1) {
61
+ var T = b(h[O], "A decorator", "be", !0),
62
+ z = n ? h[O - 1] : void 0,
63
+ A = {},
64
+ H = {
65
+ kind: ["field", "accessor", "method", "getter", "setter", "class"][o],
66
+ name: r,
67
+ metadata: a,
68
+ addInitializer: function (e, t) {
69
+ if (e.v) throw new TypeError("attempted to call addInitializer after decoration was finished");
70
+ b(t, "An initializer", "be", !0), i.push(t);
71
+ }.bind(null, A)
72
+ };
73
+ if (w) c = T.call(z, N, H), A.v = 1, b(c, "class decorators", "return") && (N = c);else if (H.static = s, H.private = f, c = H.access = {
74
+ has: f ? p.bind() : function (e) {
75
+ return r in e;
76
+ }
77
+ }, j || (c.get = f ? E ? function (e) {
78
+ return d(e), P.value;
79
+ } : I("get", 0, d) : function (e) {
80
+ return e[r];
81
+ }), E || S || (c.set = f ? I("set", 0, d) : function (e, t) {
82
+ e[r] = t;
83
+ }), N = T.call(z, D ? {
84
+ get: P.get,
85
+ set: P.set
86
+ } : P[F], H), A.v = 1, D) {
87
+ if ("object" == typeof N && N) (c = b(N.get, "accessor.get")) && (P.get = c), (c = b(N.set, "accessor.set")) && (P.set = c), (c = b(N.init, "accessor.init")) && k.unshift(c);else if (void 0 !== N) throw new TypeError("accessor decorators must return an object with get, set, or init properties or undefined");
88
+ } else b(N, (l ? "field" : "method") + " decorators", "return") && (l ? k.unshift(N) : P[F] = N);
89
+ }
90
+ return o < 2 && u.push(g(k, s, 1), g(i, s, 0)), l || w || (f ? D ? u.splice(-1, 0, I("get", s), I("set", s)) : u.push(E ? P[F] : b.call.bind(P[F])) : m(e, r, P)), N;
91
+ }
92
+ function w(e) {
93
+ return m(e, d, {
94
+ configurable: !0,
95
+ enumerable: !0,
96
+ value: a
97
+ });
98
+ }
99
+ return a = h(null == a ? null : a), f = [], l = function (e) {
100
+ e && f.push(g(e));
101
+ }, p = function (t, r) {
102
+ for (var i = 0; i < n.length; i++) {
103
+ var a = n[i],
104
+ c = a[1],
105
+ l = 7 & c;
106
+ if ((8 & c) == t && !l == r) {
107
+ var p = a[2],
108
+ d = !!a[3],
109
+ m = 16 & c;
110
+ applyDec(t ? e : e.prototype, a, m, d ? "#" + p : _toPropertyKey(p), l, l < 2 ? [] : t ? s = s || [] : u = u || [], f, !!t, d, r, t && d ? function (t) {
111
+ return _checkInRHS(t) === e;
112
+ } : o);
113
+ }
114
+ }
115
+ }, p(8, 0), p(0, 0), p(8, 1), p(0, 1), l(u), l(s), c = f, v || w(e), {
116
+ e: c,
117
+ get c() {
118
+ var n = [];
119
+ return v && [w(e = applyDec(e, [t], r, e.name, 5, n)), g(n, 1)];
120
+ }
121
+ };
122
+ }
123
+ function _checkInRHS(e) {
124
+ if (Object(e) !== e) throw TypeError("right-hand side of 'in' should be an object, got " + (null !== e ? typeof e : "null"));
125
+ return e;
126
+ }
127
+ function _setFunctionName(e, t, n) {
128
+ "symbol" == typeof t && (t = (t = t.description) ? "[" + t + "]" : "");
129
+ try {
130
+ Object.defineProperty(e, "name", {
131
+ configurable: !0,
132
+ value: n ? n + " " + t : t
133
+ });
134
+ } catch (e) {}
135
+ return e;
136
+ }
137
+ function _toPrimitive(t, r) {
138
+ if ("object" != typeof t || !t) return t;
139
+ var e = t[Symbol.toPrimitive];
140
+ if (void 0 !== e) {
141
+ var i = e.call(t, r || "default");
142
+ if ("object" != typeof i) return i;
143
+ throw new TypeError("@@toPrimitive must return a primitive value.");
144
+ }
145
+ return ("string" === r ? String : Number)(t);
146
+ }
147
+ function _toPropertyKey(t) {
148
+ var i = _toPrimitive(t, "string");
149
+ return "symbol" == typeof i ? i : i + "";
150
+ }
151
+
152
+ let _initProto, _init_enabled, _init_extra_enabled, _init_guideLines, _init_extra_guideLines, _init_nodeLineMap, _init_extra_nodeLineMap, _init_adsorptionLines, _init_extra_adsorptionLines;
153
+ class GuideLine {
154
+ static {
155
+ [_init_enabled, _init_extra_enabled, _init_guideLines, _init_extra_guideLines, _init_nodeLineMap, _init_extra_nodeLineMap, _init_adsorptionLines, _init_extra_adsorptionLines, _initProto] = _applyDecs2311(this, [], [[observable, 1, "enabled"], [[observable, observable.shallow], 17, "guideLines"], [computed, 3, "guideLinesMap"], [[observable, observable.shallow], 17, "nodeLineMap"], [observable, 1, "adsorptionLines"], [action, 2, "addGuideLine"], [action, 2, "removeGuideLine"], [action, 2, "updateGuideLine"], [action, 2, "calculateGuideLineInfo"], [action, 2, "getAdsorptionPosition"], [action, 2, "resetAdsorptionLines"]]).e;
156
+ }
157
+ #A = (_initProto(this), _init_enabled(this, true));
158
+ get enabled() {
159
+ return this.#A;
160
+ }
161
+ set enabled(v) {
162
+ this.#A = v;
163
+ }
164
+ #B = (_init_extra_enabled(this), _init_guideLines(this, []));
165
+ get guideLines() {
166
+ return this.#B;
167
+ }
168
+ set guideLines(v) {
169
+ this.#B = v;
170
+ }
171
+ get guideLinesMap() {
172
+ const result = Object.groupBy(this.guideLines, item => item.type);
173
+ return {
174
+ verticalLinesMap: new Map(result.vertical?.map(item => [item.position, item])),
175
+ horizontalLinesMap: new Map(result.horizontal?.map(item => [item.position, item]))
176
+ };
177
+ }
178
+ #C = (_init_extra_guideLines(this), _init_nodeLineMap(this, {
179
+ verticalLinesMap: new Map(),
180
+ horizontalLinesMap: new Map()
181
+ }));
182
+ get nodeLineMap() {
183
+ return this.#C;
184
+ }
185
+ set nodeLineMap(v) {
186
+ this.#C = v;
187
+ }
188
+ #D = (_init_extra_nodeLineMap(this), _init_adsorptionLines(this, {
189
+ verticalLines: new Set(),
190
+ horizontalLines: new Set()
191
+ }));
192
+ get adsorptionLines() {
193
+ return this.#D;
194
+ }
195
+ set adsorptionLines(v) {
196
+ this.#D = v;
197
+ }
198
+ get currentDocument() {
199
+ return this.designer.currentDocument;
200
+ }
201
+ constructor(designer) {
202
+ this.designer = designer;
203
+ this.designer.onEvent(DESIGNER_EVENT.VIEWPORT_MOUNT, ({
204
+ viewport
205
+ }) => {
206
+ this.addGuideLine({
207
+ id: 'viewport-vertical-left',
208
+ type: 'vertical',
209
+ position: 0
210
+ });
211
+ this.addGuideLine({
212
+ id: 'viewport-vertical-middle',
213
+ type: 'vertical',
214
+ position: viewport.width / 2
215
+ });
216
+ this.addGuideLine({
217
+ id: 'viewport-vertical-right',
218
+ type: 'vertical',
219
+ position: viewport.width
220
+ });
221
+ this.addGuideLine({
222
+ id: 'viewport-horizontal-top',
223
+ type: 'horizontal',
224
+ position: 0
225
+ });
226
+ this.addGuideLine({
227
+ id: 'viewport-horizontal-middle',
228
+ type: 'horizontal',
229
+ position: viewport.height / 2
230
+ });
231
+ this.addGuideLine({
232
+ id: 'viewport-horizontal-bottom',
233
+ type: 'horizontal',
234
+ position: viewport.height
235
+ });
236
+ });
237
+ }
238
+ addGuideLine(guideLine) {
239
+ this.guideLines.push(guideLine);
240
+ }
241
+ removeGuideLine(id) {
242
+ const index = this.guideLines.findIndex(item => item.id === id);
243
+ if (index !== -1) {
244
+ this.guideLines.splice(index, 1);
245
+ }
246
+ }
247
+ updateGuideLine(id, guideLine) {
248
+ const index = this.guideLines.findIndex(item => item.id === id);
249
+ if (index !== -1) {
250
+ this.guideLines[index] = guideLine;
251
+ }
252
+ }
253
+ calculateGuideLineInfo() {
254
+ if (!this.enabled) return;
255
+ const verticalLinesMap = new Map();
256
+ const horizontalLinesMap = new Map();
257
+ const nodes = [...this.currentDocument.nodesMap.values()];
258
+ const selected = [];
259
+ for (const node of this.designer.selection.getNodes()) {
260
+ if (node.isGroup) {
261
+ selected.push(...node.getAllNodesInGroup().map(node => node.id));
262
+ } else {
263
+ selected.push(node.id);
264
+ }
265
+ }
266
+ nodes.filter(node => !node.hidden).forEach(node => {
267
+ if (selected.includes(node.id) || node.isRoot || node.isGroup) return;
268
+ const nodeRect = node.getDashboardRect();
269
+ const verticalNodeLines = [nodeRect.left, nodeRect.left + nodeRect.width / 2, nodeRect.right];
270
+ const horizontalNodeLines = [nodeRect.top, nodeRect.top + nodeRect.height / 2, nodeRect.bottom];
271
+ for (const line of verticalNodeLines) {
272
+ const position = Math.round(line);
273
+ verticalLinesMap.set(position, {
274
+ type: 'vertical',
275
+ position
276
+ });
277
+ }
278
+ for (const line of horizontalNodeLines) {
279
+ const position = Math.round(line);
280
+ horizontalLinesMap.set(position, {
281
+ type: 'horizontal',
282
+ position
283
+ });
284
+ }
285
+ });
286
+ this.nodeLineMap.verticalLinesMap = verticalLinesMap;
287
+ this.nodeLineMap.horizontalLinesMap = horizontalLinesMap;
288
+ }
289
+ adsorptionSize = (_init_extra_adsorptionLines(this), 10);
290
+ getAdsorptionPosition(rect, adsorption) {
291
+ if (typeof adsorption === 'number') {
292
+ adsorption = [adsorption];
293
+ }
294
+ this.resetAdsorptionLines();
295
+ const adsorptionVerticalLines = [];
296
+ const adsorptionHorizontalLines = [];
297
+ const currentVerticalLine = [rect.left, rect.left + rect.width / 2, rect.right];
298
+ const currentHorizontalLine = [rect.top, rect.top + rect.height / 2, rect.bottom];
299
+ currentVerticalLine.forEach((item, index) => {
300
+ let minDistance = Number.POSITIVE_INFINITY;
301
+ this.nodeLineMap.verticalLinesMap.forEach((_, pos) => {
302
+ const distance = Math.abs(item - pos);
303
+ if (distance !== 0 && distance < this.adsorptionSize && distance < minDistance) {
304
+ minDistance = pos;
305
+ }
306
+ });
307
+ this.guideLinesMap.verticalLinesMap.forEach((_, pos) => {
308
+ const distance = Math.abs(item - pos);
309
+ if (distance !== 0 && distance < this.adsorptionSize && distance < minDistance) {
310
+ minDistance = pos;
311
+ }
312
+ });
313
+ if (minDistance !== Number.POSITIVE_INFINITY && adsorptionVerticalLines.findIndex(item => item.position === minDistance) === -1) {
314
+ adsorptionVerticalLines.push({
315
+ adsorption: index,
316
+ position: minDistance
317
+ });
318
+ }
319
+ });
320
+ currentHorizontalLine.forEach((item, index) => {
321
+ let minDistance = -1;
322
+ this.nodeLineMap.horizontalLinesMap.forEach((_, pos) => {
323
+ if (Math.abs(item - pos) < this.adsorptionSize) {
324
+ minDistance = pos;
325
+ }
326
+ });
327
+ this.guideLinesMap.horizontalLinesMap.forEach((_, pos) => {
328
+ const distance = Math.abs(item - pos);
329
+ if (distance < this.adsorptionSize && distance < minDistance) {
330
+ minDistance = pos;
331
+ }
332
+ });
333
+ if (minDistance !== -1 && adsorptionHorizontalLines.findIndex(item => item.position === minDistance) === -1) {
334
+ adsorptionHorizontalLines.push({
335
+ adsorption: index,
336
+ position: minDistance
337
+ });
338
+ }
339
+ });
340
+ const isAdsorption = adsorptionVerticalLines.length > 0 || adsorptionHorizontalLines.length > 0;
341
+ const adsorb = {
342
+ x: undefined,
343
+ y: undefined
344
+ };
345
+ if (isAdsorption) {
346
+ adsorptionVerticalLines.forEach(item => this.adsorptionLines.verticalLines.add(item.position));
347
+ adsorptionHorizontalLines.forEach(item => this.adsorptionLines.horizontalLines.add(item.position));
348
+ if (adsorptionVerticalLines.length > 0) {
349
+ if (adsorption) {
350
+ adsorb.x = adsorptionVerticalLines.find(item => adsorption.includes(item.adsorption));
351
+ } else {
352
+ const adsorptionPosition = Math.min(...adsorptionVerticalLines.map(item => item.position));
353
+ adsorb.x = adsorptionVerticalLines.find(item => item.position === adsorptionPosition);
354
+ }
355
+ }
356
+ if (adsorptionHorizontalLines.length > 0) {
357
+ if (adsorption) {
358
+ adsorb.y = adsorptionHorizontalLines.find(item => adsorption.includes(item.adsorption));
359
+ } else {
360
+ const adsorptionPosition = Math.min(...adsorptionHorizontalLines.map(item => item.position));
361
+ adsorb.y = adsorptionHorizontalLines.find(item => item.position === adsorptionPosition);
362
+ }
363
+ }
364
+ }
365
+ return {
366
+ isAdsorption,
367
+ adsorb
368
+ };
369
+ }
370
+ resetAdsorptionLines() {
371
+ this.adsorptionLines.verticalLines.clear();
372
+ this.adsorptionLines.horizontalLines.clear();
373
+ }
374
+ }
375
+
376
+ const Group = props => {
377
+ return (
378
+ /*#__PURE__*/
379
+ // TODO: className 需要调整,需要通用的方式
380
+ React.createElement("div", {
381
+ ref: props.ref,
382
+ className: "relative w-full h-full"
383
+ }, props?.children)
384
+ );
385
+ };
386
+
387
+ const configure = {
388
+ props: [
389
+ ],
390
+ component: {},
391
+ supports: {},
392
+ advanced: {
393
+ view: Group
394
+ }
395
+ };
396
+
397
+ const meta = {
398
+ componentName: 'Group',
399
+ title: '分组',
400
+ category: '内置',
401
+ configure
402
+ };
403
+
404
+ const updateNodeRect = (node, offset = {
405
+ x: 0,
406
+ y: 0
407
+ }) => {
408
+ if (node.isGroup) {
409
+ const nodeRect = node.getDashboardRect();
410
+ const delta = {
411
+ x: offset.x - nodeRect.x,
412
+ y: offset.y - nodeRect.y
413
+ };
414
+ for (const childNode of node.getAllNodesInGroup()) {
415
+ const childRect = childNode.getDashboardRect();
416
+ childNode.updateDashboardRect({
417
+ x: childRect.x + delta.x,
418
+ y: childRect.y + delta.y
419
+ });
420
+ }
421
+ } else {
422
+ node.updateDashboardRect({
423
+ x: offset.x,
424
+ y: offset.y
425
+ });
426
+ }
427
+ };
428
+ const updateNodeRectByDOM = (node, offset = {
429
+ x: 0,
430
+ y: 0
431
+ }) => {
432
+ const domNode = node.getDashboardContainer();
433
+ if (!domNode) {
434
+ return;
435
+ }
436
+ domNode.style.left = `${offset.x}px`;
437
+ domNode.style.top = `${offset.y}px`;
438
+ };
439
+
440
+ const defaultGroupSchema = {
441
+ componentName: 'Group',
442
+ title: '分组',
443
+ isGroup: true
444
+ };
445
+ const DashboardPlugin = options => {
446
+ const {
447
+ group = {}
448
+ } = options || {};
449
+ const {
450
+ schema: groupSchema = defaultGroupSchema
451
+ } = group || {};
452
+ return {
453
+ name: 'DashboardPlugin',
454
+ deps: [],
455
+ init(ctx) {
456
+ const {
457
+ designer,
458
+ simulator,
459
+ componentMetaManager,
460
+ hotkey,
461
+ logger
462
+ } = ctx;
463
+ hotkey.bind('ctrl+d', e => {
464
+ e.preventDefault();
465
+ logger.log('ctrl+d');
466
+ });
467
+ designer.onEvent(DESIGNER_EVENT.INIT, designer => {
468
+ designer.guideline = new GuideLine(designer);
469
+ });
470
+ componentMetaManager.createComponentMeta(meta);
471
+ simulator.addComponent('Group', Group);
472
+ const startOffsetNodeData = {
473
+ x: 0,
474
+ y: 0
475
+ };
476
+ designer.dragon.onDragstart(e => {
477
+ const {
478
+ dragObject
479
+ } = e;
480
+ if (dragObject && dragObject.type === DragObjectType.NodeData) {
481
+ startOffsetNodeData.x = e.globalX - e.target.offsetLeft;
482
+ startOffsetNodeData.y = e.globalY - e.target.offsetTop;
483
+ }
484
+ });
485
+ designer.onEvent(DESIGNER_EVENT.INSERT_NODE_BEFORE, e => {
486
+ const {
487
+ event
488
+ } = e;
489
+ const {
490
+ dragObject
491
+ } = event;
492
+ if (dragObject && dragObject.type === DragObjectType.NodeData) {
493
+ const nodeData = Array.isArray(dragObject.data) ? dragObject.data : [dragObject.data];
494
+ for (const schema of nodeData) {
495
+ if (!schema) continue;
496
+ if (!schema.$dashboard) {
497
+ schema.$dashboard = {};
498
+ }
499
+ if (!schema.$dashboard.rect) {
500
+ schema.$dashboard.rect = {};
501
+ }
502
+ schema.$dashboard.rect.x = event.canvasX - startOffsetNodeData.x;
503
+ schema.$dashboard.rect.y = event.canvasY - startOffsetNodeData.y;
504
+ }
505
+ }
506
+ });
507
+ let startNodes = {};
508
+ let startOffsetNodes = {};
509
+ let lastOffsetNodes = {};
510
+ designer.dragon.onDragstart(e => {
511
+ const {
512
+ dragObject
513
+ } = e;
514
+ if (dragObject && dragObject.type === DragObjectType.Node) {
515
+ designer.guideline.calculateGuideLineInfo();
516
+ for (const node of dragObject.nodes) {
517
+ if (!node) continue;
518
+ const rect = node.getDashboardRect();
519
+ if (rect) {
520
+ startNodes[node.id] = rect;
521
+ startOffsetNodes[node.id] = {
522
+ x: e.canvasX - rect.x,
523
+ y: e.canvasY - rect.y
524
+ };
525
+ }
526
+ }
527
+ const boxRect = calculateDashboardRectBox(dragObject.nodes);
528
+ if (boxRect) {
529
+ startNodes.box = boxRect;
530
+ startOffsetNodes.box = {
531
+ x: e.canvasX - boxRect.x,
532
+ y: e.canvasY - boxRect.y
533
+ };
534
+ }
535
+ }
536
+ });
537
+ designer.dragon.onDrag(e => {
538
+ const {
539
+ dragObject
540
+ } = e;
541
+ if (dragObject && dragObject.type === DragObjectType.Node) {
542
+ const {
543
+ x: boxStartX = 0,
544
+ y: boxStartY = 0,
545
+ width = 0,
546
+ height = 0
547
+ } = startNodes.box;
548
+ const {
549
+ x: boxX = 0,
550
+ y: boxY = 0
551
+ } = startOffsetNodes.box;
552
+ const {
553
+ isAdsorption,
554
+ adsorb
555
+ } = designer.guideline.getAdsorptionPosition(new DOMRect(e.canvasX - boxX, e.canvasY - boxY, width, height));
556
+ let adsorbX = undefined;
557
+ let adsorbY = undefined;
558
+ if (isAdsorption) {
559
+ if (adsorb.x) {
560
+ if (adsorb.x.adsorption === 0) {
561
+ adsorbX = adsorb.x.position;
562
+ } else if (adsorb.x.adsorption === 1) {
563
+ adsorbX = adsorb.x.position - width / 2;
564
+ } else if (adsorb.x.adsorption === 2) {
565
+ adsorbX = adsorb.x.position - width;
566
+ }
567
+ }
568
+ if (adsorb.y) {
569
+ if (adsorb.y.adsorption === 0) {
570
+ adsorbY = adsorb.y.position;
571
+ } else if (adsorb.y.adsorption === 1) {
572
+ adsorbY = adsorb.y.position - height / 2;
573
+ } else if (adsorb.y.adsorption === 2) {
574
+ adsorbY = adsorb.y.position - height;
575
+ }
576
+ }
577
+ }
578
+ for (const node of dragObject.nodes) {
579
+ if (!node) continue;
580
+ const {
581
+ x: nodeStartX = 0,
582
+ y: nodeStartY = 0
583
+ } = startNodes[node.id];
584
+ const {
585
+ x,
586
+ y
587
+ } = startOffsetNodes[node.id];
588
+ let offsetX = e.canvasX - x;
589
+ let offsetY = e.canvasY - y;
590
+ if (isAdsorption) {
591
+ offsetX = adsorbX ? adsorbX + nodeStartX - boxStartX : offsetX;
592
+ offsetY = adsorbY ? adsorbY + nodeStartY - boxStartY : offsetY;
593
+ }
594
+ updateNodeRectByDOM(node, {
595
+ x: offsetX,
596
+ y: offsetY
597
+ });
598
+ lastOffsetNodes[node.id] = {
599
+ x: offsetX,
600
+ y: offsetY
601
+ };
602
+ }
603
+ }
604
+ });
605
+ designer.dragon.onDragend(e => {
606
+ const {
607
+ dragObject,
608
+ esc
609
+ } = e;
610
+ if (dragObject && dragObject.type === DragObjectType.Node) {
611
+ for (const node of dragObject.nodes) {
612
+ if (!node) continue;
613
+ if (esc) {
614
+ simulator.rerender();
615
+ } else {
616
+ const {
617
+ x: lastX = 0,
618
+ y: lastY = 0
619
+ } = lastOffsetNodes[node.id];
620
+ updateNodeRect(node, {
621
+ x: lastX,
622
+ y: lastY
623
+ });
624
+ }
625
+ }
626
+ designer.guideline.resetAdsorptionLines();
627
+ }
628
+ startNodes = {};
629
+ startOffsetNodes = {};
630
+ lastOffsetNodes = {};
631
+ });
632
+ },
633
+ extend({
634
+ extendClass,
635
+ extend
636
+ }) {
637
+ const {
638
+ Node,
639
+ Designer
640
+ } = extendClass;
641
+ const originalInit = Designer.prototype.init;
642
+ extend('Designer', {
643
+ init: {
644
+ value() {
645
+ originalInit.call(this);
646
+ this.guideline = new GuideLine(this);
647
+ }
648
+ }
649
+ });
650
+ extend('Document', {
651
+ group: {
652
+ value(nodeIdList) {
653
+ if (nodeIdList.length === 0) return;
654
+ let nodeList = [];
655
+ if (typeof nodeIdList[0] === 'string') {
656
+ nodeList = nodeIdList.map(id => this.getNode(id));
657
+ }
658
+ const groupNode = this.createNode(groupSchema);
659
+ let maxZIndex = Number.POSITIVE_INFINITY;
660
+ for (const node of nodeList) {
661
+ if (node.index < maxZIndex) {
662
+ maxZIndex = node.index;
663
+ }
664
+ if (node && !node.isRoot) {
665
+ this.migrateNode(node, groupNode);
666
+ }
667
+ }
668
+ this.rootNode?.insert(groupNode, maxZIndex);
669
+ return groupNode;
670
+ }
671
+ },
672
+ ungroup: {
673
+ value(group) {
674
+ let groupNode;
675
+ if (typeof group === 'string') {
676
+ groupNode = this.getNode(group);
677
+ } else {
678
+ groupNode = group;
679
+ }
680
+ if (!groupNode || !groupNode.isGroup || !groupNode.children) return;
681
+ const nodes = groupNode.childrenNodes;
682
+ while (nodes.length > 0) {
683
+ if (groupNode.parent) {
684
+ this.migrateNode(nodes[0], groupNode.parent);
685
+ }
686
+ }
687
+ this.removeNode(groupNode);
688
+ }
689
+ }
690
+ });
691
+ const originalInitProps = Node.prototype.initBuiltinProps;
692
+ extend('Node', {
693
+ getDashboardContainer: {
694
+ value() {
695
+ return document.getElementById(`${this.id}-mask`);
696
+ }
697
+ },
698
+ getDashboardRect: {
699
+ value() {
700
+ if (!this.isGroup) {
701
+ const rect = this.getExtraPropValue('$dashboard.rect');
702
+ return new DOMRect(rect.x ?? 0, rect.y ?? 0, rect.width ?? 0, rect.height ?? 0);
703
+ }
704
+ let [minX, minY, maxX, maxY] = [Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY];
705
+ for (const child of this.childrenNodes) {
706
+ const childRect = child.getDashboardRect();
707
+ minX = Math.min(minX, childRect.x);
708
+ minY = Math.min(minY, childRect.y);
709
+ maxX = Math.max(maxX, childRect.x + childRect.width);
710
+ maxY = Math.max(maxY, childRect.y + childRect.height);
711
+ }
712
+ return new DOMRect(minX, minY, maxX - minX, maxY - minY);
713
+ }
714
+ },
715
+ updateDashboardRect: {
716
+ value(rect) {
717
+ if (this.isGroup) return;
718
+ if (typeof rect.x === 'number') {
719
+ this.setExtraPropValue('$dashboard.rect.x', rect.x);
720
+ }
721
+ if (typeof rect.y === 'number') {
722
+ this.setExtraPropValue('$dashboard.rect.y', rect.y);
723
+ }
724
+ if (typeof rect.width === 'number') {
725
+ this.setExtraPropValue('$dashboard.rect.width', rect.width);
726
+ }
727
+ if (typeof rect.height === 'number') {
728
+ this.setExtraPropValue('$dashboard.rect.height', rect.height);
729
+ }
730
+ }
731
+ },
732
+ isGroup: {
733
+ get() {
734
+ return this.getExtraPropValue('isGroup');
735
+ }
736
+ },
737
+ getCurrentGroup: {
738
+ value() {
739
+ let parent = this.parent;
740
+ while (parent && !parent.isGroup) {
741
+ parent = parent.parent;
742
+ }
743
+ return parent;
744
+ }
745
+ },
746
+ getTopGroup: {
747
+ value() {
748
+ let parent = this.parent;
749
+ let topGroup = null;
750
+ while (parent) {
751
+ if (parent.isGroup) {
752
+ topGroup = parent;
753
+ }
754
+ parent = parent.parent;
755
+ }
756
+ return topGroup;
757
+ }
758
+ },
759
+ getAllGroups: {
760
+ value() {
761
+ const groups = [];
762
+ let parent = this.parent;
763
+ while (parent) {
764
+ if (parent.isGroup) {
765
+ groups.push(parent);
766
+ }
767
+ parent = parent.parent;
768
+ }
769
+ return groups;
770
+ }
771
+ },
772
+ getNodesInGroup: {
773
+ value() {
774
+ if (!this.isGroup) return [];
775
+ const nodes = [];
776
+ for (const node of this.childrenNodes) {
777
+ if (!node.isGroup) {
778
+ nodes.push(node);
779
+ }
780
+ }
781
+ return nodes;
782
+ }
783
+ },
784
+ getAllNodesInGroup: {
785
+ value() {
786
+ if (!this.isGroup) return [];
787
+ const nodes = [];
788
+ for (const node of this.childrenNodes) {
789
+ if (node.isGroup) {
790
+ nodes.push(...node.getAllNodesInGroup());
791
+ } else {
792
+ nodes.push(node);
793
+ }
794
+ }
795
+ return nodes;
796
+ }
797
+ },
798
+ initBuiltinProps: {
799
+ value() {
800
+ originalInitProps.call(this);
801
+ this.props.has(getConvertedExtraKey('isGroup')) || this.props.add(getConvertedExtraKey('isGroup'), false);
802
+ }
803
+ }
804
+ });
805
+ extend('OffsetObserver', {
806
+ computeRect: {
807
+ value() {
808
+ const {
809
+ node,
810
+ instance
811
+ } = this.nodeInstance;
812
+ const host = node.document?.simulator;
813
+ const rect = host.computeComponentInstanceRect(instance);
814
+ const {
815
+ viewport
816
+ } = node.document.simulator;
817
+ const local = viewport.toLocalPoint({
818
+ clientX: rect.x,
819
+ clientY: rect.y
820
+ });
821
+ return new DOMRect(local.clientX, local.clientY, rect.width / viewport.scale, rect.height / viewport.scale);
822
+ }
823
+ },
824
+ height: {
825
+ get() {
826
+ return this.isRoot ? this.viewport.height : this._height;
827
+ }
828
+ },
829
+ width: {
830
+ get() {
831
+ return this.isRoot ? this.viewport.width : this._width;
832
+ }
833
+ },
834
+ top: {
835
+ get() {
836
+ return this.isRoot ? 0 : this._top;
837
+ }
838
+ },
839
+ left: {
840
+ get() {
841
+ return this.isRoot ? 0 : this._left;
842
+ }
843
+ },
844
+ bottom: {
845
+ get() {
846
+ return this.isRoot ? this.viewport.height : this._bottom;
847
+ }
848
+ },
849
+ right: {
850
+ get() {
851
+ return this.isRoot ? this.viewport.width : this._right;
852
+ }
853
+ }
854
+ });
855
+ }
856
+ };
857
+ };
858
+ const calculateDashboardRectBox = nodes => {
859
+ let [minX, minY, maxX, maxY] = [Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY];
860
+ for (const node of nodes) {
861
+ const rect = node.getDashboardRect();
862
+ minX = Math.min(minX, rect.x);
863
+ minY = Math.min(minY, rect.y);
864
+ maxX = Math.max(maxX, rect.x + rect.width);
865
+ maxY = Math.max(maxY, rect.y + rect.height);
866
+ }
867
+ return new DOMRect(minX, minY, maxX - minX, maxY - minY);
868
+ };
869
+
870
+ export { DashboardPlugin as default };