@tmagic/stage 1.1.0-beta.2 → 1.1.0-beta.5
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/tmagic-stage.es.js +352 -114
- package/dist/tmagic-stage.es.js.map +1 -1
- package/dist/tmagic-stage.umd.js +358 -116
- package/dist/tmagic-stage.umd.js.map +1 -1
- package/dist/types/src/StageCore.d.ts +13 -2
- package/dist/types/src/StageDragResize.d.ts +7 -18
- package/dist/types/src/StageMask.d.ts +1 -0
- package/dist/types/src/StageMultiDragResize.d.ts +49 -0
- package/dist/types/src/StageRender.d.ts +1 -0
- package/dist/types/src/const.d.ts +1 -0
- package/dist/types/src/types.d.ts +3 -1
- package/dist/types/src/util.d.ts +16 -1
- package/package.json +5 -4
- package/src/StageCore.ts +92 -18
- package/src/StageDragResize.ts +40 -118
- package/src/StageHighlight.ts +1 -1
- package/src/StageMask.ts +21 -4
- package/src/StageMultiDragResize.ts +231 -0
- package/src/StageRender.ts +28 -18
- package/src/TargetCalibrate.ts +2 -1
- package/src/const.ts +2 -0
- package/src/style.css +1 -0
- package/src/types.ts +3 -1
- package/src/util.ts +87 -2
package/dist/tmagic-stage.es.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import EventEmitter$1, { EventEmitter } from 'events';
|
|
2
|
+
import { removeClassName, removeClassNameByClassName, createDiv, injectStyle, isSameDomain, getHost, addClassName } from '@tmagic/utils';
|
|
2
3
|
import Moveable from 'moveable';
|
|
3
4
|
import MoveableHelper from 'moveable-helper';
|
|
4
|
-
import
|
|
5
|
+
import KeyController from 'keycon';
|
|
5
6
|
import { throttle } from 'lodash-es';
|
|
6
7
|
import Guides from '@scena/guides';
|
|
7
8
|
|
|
@@ -9,6 +10,7 @@ const GHOST_EL_ID_PREFIX = "ghost_el_";
|
|
|
9
10
|
const DRAG_EL_ID_PREFIX = "drag_el_";
|
|
10
11
|
const HIGHLIGHT_EL_ID_PREFIX = "highlight_el_";
|
|
11
12
|
const CONTAINER_HIGHLIGHT_CLASS = "tmagic-stage-container-highlight";
|
|
13
|
+
const PAGE_CLASS = "magic-ui-page";
|
|
12
14
|
const DEFAULT_ZOOM = 1;
|
|
13
15
|
var GuidesType = /* @__PURE__ */ ((GuidesType2) => {
|
|
14
16
|
GuidesType2["HORIZONTAL"] = "horizontal";
|
|
@@ -61,6 +63,19 @@ const getOffset = (el) => {
|
|
|
61
63
|
top
|
|
62
64
|
};
|
|
63
65
|
};
|
|
66
|
+
const getTargetElStyle = (el) => {
|
|
67
|
+
const offset = getOffset(el);
|
|
68
|
+
const { transform } = getComputedStyle(el);
|
|
69
|
+
return `
|
|
70
|
+
position: absolute;
|
|
71
|
+
transform: ${transform};
|
|
72
|
+
left: ${offset.left}px;
|
|
73
|
+
top: ${offset.top}px;
|
|
74
|
+
width: ${el.clientWidth}px;
|
|
75
|
+
height: ${el.clientHeight}px;
|
|
76
|
+
z-index: ${ZIndex.DRAG_EL};
|
|
77
|
+
`;
|
|
78
|
+
};
|
|
64
79
|
const getAbsolutePosition = (el, { top, left }) => {
|
|
65
80
|
const { offsetParent } = el;
|
|
66
81
|
if (offsetParent) {
|
|
@@ -141,6 +156,52 @@ const calcValueByFontsize = (doc, value) => {
|
|
|
141
156
|
}
|
|
142
157
|
return value;
|
|
143
158
|
};
|
|
159
|
+
const down = (deltaTop, target) => {
|
|
160
|
+
let swapIndex = 0;
|
|
161
|
+
let addUpH = target.clientHeight;
|
|
162
|
+
const brothers = Array.from(target.parentNode?.children || []).filter((node) => !node.id.startsWith(GHOST_EL_ID_PREFIX));
|
|
163
|
+
const index = brothers.indexOf(target);
|
|
164
|
+
const downEls = brothers.slice(index + 1);
|
|
165
|
+
for (let i = 0; i < downEls.length; i++) {
|
|
166
|
+
const ele = downEls[i];
|
|
167
|
+
if (ele.style?.position === "fixed") {
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
addUpH += ele.clientHeight / 2;
|
|
171
|
+
if (deltaTop <= addUpH) {
|
|
172
|
+
break;
|
|
173
|
+
}
|
|
174
|
+
addUpH += ele.clientHeight / 2;
|
|
175
|
+
swapIndex = i;
|
|
176
|
+
}
|
|
177
|
+
return {
|
|
178
|
+
src: target.id,
|
|
179
|
+
dist: downEls.length && swapIndex > -1 ? downEls[swapIndex].id : target.id
|
|
180
|
+
};
|
|
181
|
+
};
|
|
182
|
+
const up = (deltaTop, target) => {
|
|
183
|
+
const brothers = Array.from(target.parentNode?.children || []).filter((node) => !node.id.startsWith(GHOST_EL_ID_PREFIX));
|
|
184
|
+
const index = brothers.indexOf(target);
|
|
185
|
+
const upEls = brothers.slice(0, index);
|
|
186
|
+
let addUpH = target.clientHeight;
|
|
187
|
+
let swapIndex = upEls.length - 1;
|
|
188
|
+
for (let i = upEls.length - 1; i >= 0; i--) {
|
|
189
|
+
const ele = upEls[i];
|
|
190
|
+
if (!ele)
|
|
191
|
+
continue;
|
|
192
|
+
if (ele.style.position === "fixed")
|
|
193
|
+
continue;
|
|
194
|
+
addUpH += ele.clientHeight / 2;
|
|
195
|
+
if (-deltaTop <= addUpH)
|
|
196
|
+
break;
|
|
197
|
+
addUpH += ele.clientHeight / 2;
|
|
198
|
+
swapIndex = i;
|
|
199
|
+
}
|
|
200
|
+
return {
|
|
201
|
+
src: target.id,
|
|
202
|
+
dist: upEls.length && swapIndex > -1 ? upEls[swapIndex].id : target.id
|
|
203
|
+
};
|
|
204
|
+
};
|
|
144
205
|
|
|
145
206
|
class StageDragResize extends EventEmitter {
|
|
146
207
|
constructor(config) {
|
|
@@ -153,8 +214,7 @@ class StageDragResize extends EventEmitter {
|
|
|
153
214
|
this.dragStatus = "end" /* END */;
|
|
154
215
|
this.core = config.core;
|
|
155
216
|
this.container = config.container;
|
|
156
|
-
this.
|
|
157
|
-
this.container.append(this.dragEl);
|
|
217
|
+
this.mask = config.mask;
|
|
158
218
|
}
|
|
159
219
|
select(el, event) {
|
|
160
220
|
const oldTarget = this.target;
|
|
@@ -205,6 +265,16 @@ class StageDragResize extends EventEmitter {
|
|
|
205
265
|
this.moveableOptions.verticalGuidelines = [];
|
|
206
266
|
this.updateMoveable();
|
|
207
267
|
}
|
|
268
|
+
clearSelectStatus() {
|
|
269
|
+
if (!this.moveable)
|
|
270
|
+
return;
|
|
271
|
+
this.destroyDragEl();
|
|
272
|
+
this.moveable.target = null;
|
|
273
|
+
this.moveable.updateTarget();
|
|
274
|
+
}
|
|
275
|
+
destroyDragEl() {
|
|
276
|
+
this.dragEl?.remove();
|
|
277
|
+
}
|
|
208
278
|
destroy() {
|
|
209
279
|
this.moveable?.destroy();
|
|
210
280
|
this.destroyGhostEl();
|
|
@@ -218,7 +288,14 @@ class StageDragResize extends EventEmitter {
|
|
|
218
288
|
}
|
|
219
289
|
this.mode = getMode(el);
|
|
220
290
|
this.destroyGhostEl();
|
|
221
|
-
this.
|
|
291
|
+
this.destroyDragEl();
|
|
292
|
+
this.dragEl = globalThis.document.createElement("div");
|
|
293
|
+
this.container.append(this.dragEl);
|
|
294
|
+
this.dragEl.style.cssText = getTargetElStyle(el);
|
|
295
|
+
this.dragEl.id = `${DRAG_EL_ID_PREFIX}${el.id}`;
|
|
296
|
+
if (typeof this.core.config.updateDragEl === "function") {
|
|
297
|
+
this.core.config.updateDragEl(this.dragEl, el);
|
|
298
|
+
}
|
|
222
299
|
this.moveableOptions = this.getOptions({
|
|
223
300
|
target: this.dragEl
|
|
224
301
|
});
|
|
@@ -317,15 +394,7 @@ class StageDragResize extends EventEmitter {
|
|
|
317
394
|
globalThis.clearTimeout(timeout);
|
|
318
395
|
timeout = void 0;
|
|
319
396
|
}
|
|
320
|
-
timeout =
|
|
321
|
-
const els = this.core.getElementsFromPoint(e.inputEvent);
|
|
322
|
-
for (const el of els) {
|
|
323
|
-
if (doc && !el.id.startsWith(GHOST_EL_ID_PREFIX) && el !== this.target && await this.core.isContainer(el)) {
|
|
324
|
-
addClassName(el, doc, this.core.containerHighlightClassName);
|
|
325
|
-
break;
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
}, this.core.containerHighlightDuration);
|
|
397
|
+
timeout = this.core.getAddContainerHighlightClassNameTimeout(e.inputEvent, [this.target]);
|
|
329
398
|
this.dragStatus = "ing" /* ING */;
|
|
330
399
|
if (this.ghostEl) {
|
|
331
400
|
this.ghostEl.style.top = `${frame.top + e.beforeTranslate[1]}px`;
|
|
@@ -456,6 +525,7 @@ class StageDragResize extends EventEmitter {
|
|
|
456
525
|
this.destroyGhostEl();
|
|
457
526
|
}
|
|
458
527
|
const ghostEl = el.cloneNode(true);
|
|
528
|
+
this.setGhostElChildrenId(ghostEl);
|
|
459
529
|
const { top, left } = getAbsolutePosition(el, getOffset(el));
|
|
460
530
|
ghostEl.id = `${GHOST_EL_ID_PREFIX}${el.id}`;
|
|
461
531
|
ghostEl.style.zIndex = ZIndex.GHOST_EL;
|
|
@@ -466,30 +536,20 @@ class StageDragResize extends EventEmitter {
|
|
|
466
536
|
el.after(ghostEl);
|
|
467
537
|
return ghostEl;
|
|
468
538
|
}
|
|
539
|
+
setGhostElChildrenId(el) {
|
|
540
|
+
for (const child of el.children) {
|
|
541
|
+
if (child.id) {
|
|
542
|
+
child.id = `${GHOST_EL_ID_PREFIX}${child.id}`;
|
|
543
|
+
}
|
|
544
|
+
if (child.children.length) {
|
|
545
|
+
this.setGhostElChildrenId(child);
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
}
|
|
469
549
|
destroyGhostEl() {
|
|
470
550
|
this.ghostEl?.remove();
|
|
471
551
|
this.ghostEl = void 0;
|
|
472
552
|
}
|
|
473
|
-
updateDragEl(el) {
|
|
474
|
-
const offset = getOffset(el);
|
|
475
|
-
const { transform } = getComputedStyle(el);
|
|
476
|
-
this.dragEl.style.cssText = `
|
|
477
|
-
position: absolute;
|
|
478
|
-
transform: ${transform};
|
|
479
|
-
left: ${offset.left}px;
|
|
480
|
-
top: ${offset.top}px;
|
|
481
|
-
width: ${el.clientWidth}px;
|
|
482
|
-
height: ${el.clientHeight}px;
|
|
483
|
-
z-index: ${ZIndex.DRAG_EL};
|
|
484
|
-
`;
|
|
485
|
-
this.dragEl.id = `${DRAG_EL_ID_PREFIX}${el.id}`;
|
|
486
|
-
if (typeof this.core.config.updateDragEl === "function") {
|
|
487
|
-
this.core.config.updateDragEl(this.dragEl, el);
|
|
488
|
-
}
|
|
489
|
-
}
|
|
490
|
-
destroyDragEl() {
|
|
491
|
-
this.dragEl?.remove();
|
|
492
|
-
}
|
|
493
553
|
getOptions(options = {}) {
|
|
494
554
|
if (!this.target)
|
|
495
555
|
return {};
|
|
@@ -540,7 +600,7 @@ class StageDragResize extends EventEmitter {
|
|
|
540
600
|
bounds: {
|
|
541
601
|
top: 0,
|
|
542
602
|
left: -1,
|
|
543
|
-
right: this.container.clientWidth,
|
|
603
|
+
right: this.container.clientWidth - 1,
|
|
544
604
|
bottom: this.container.clientHeight,
|
|
545
605
|
...moveableOptions.bounds || {}
|
|
546
606
|
},
|
|
@@ -549,52 +609,6 @@ class StageDragResize extends EventEmitter {
|
|
|
549
609
|
};
|
|
550
610
|
}
|
|
551
611
|
}
|
|
552
|
-
const down = (deltaTop, target) => {
|
|
553
|
-
let swapIndex = 0;
|
|
554
|
-
let addUpH = target.clientHeight;
|
|
555
|
-
const brothers = Array.from(target.parentNode?.children || []).filter((node) => !node.id.startsWith(GHOST_EL_ID_PREFIX));
|
|
556
|
-
const index = brothers.indexOf(target);
|
|
557
|
-
const downEls = brothers.slice(index + 1);
|
|
558
|
-
for (let i = 0; i < downEls.length; i++) {
|
|
559
|
-
const ele = downEls[i];
|
|
560
|
-
if (ele.style?.position === "fixed") {
|
|
561
|
-
continue;
|
|
562
|
-
}
|
|
563
|
-
addUpH += ele.clientHeight / 2;
|
|
564
|
-
if (deltaTop <= addUpH) {
|
|
565
|
-
break;
|
|
566
|
-
}
|
|
567
|
-
addUpH += ele.clientHeight / 2;
|
|
568
|
-
swapIndex = i;
|
|
569
|
-
}
|
|
570
|
-
return {
|
|
571
|
-
src: target.id,
|
|
572
|
-
dist: downEls.length && swapIndex > -1 ? downEls[swapIndex].id : target.id
|
|
573
|
-
};
|
|
574
|
-
};
|
|
575
|
-
const up = (deltaTop, target) => {
|
|
576
|
-
const brothers = Array.from(target.parentNode?.children || []).filter((node) => !node.id.startsWith(GHOST_EL_ID_PREFIX));
|
|
577
|
-
const index = brothers.indexOf(target);
|
|
578
|
-
const upEls = brothers.slice(0, index);
|
|
579
|
-
let addUpH = target.clientHeight;
|
|
580
|
-
let swapIndex = upEls.length - 1;
|
|
581
|
-
for (let i = upEls.length - 1; i >= 0; i--) {
|
|
582
|
-
const ele = upEls[i];
|
|
583
|
-
if (!ele)
|
|
584
|
-
continue;
|
|
585
|
-
if (ele.style.position === "fixed")
|
|
586
|
-
continue;
|
|
587
|
-
addUpH += ele.clientHeight / 2;
|
|
588
|
-
if (-deltaTop <= addUpH)
|
|
589
|
-
break;
|
|
590
|
-
addUpH += ele.clientHeight / 2;
|
|
591
|
-
swapIndex = i;
|
|
592
|
-
}
|
|
593
|
-
return {
|
|
594
|
-
src: target.id,
|
|
595
|
-
dist: upEls.length && swapIndex > -1 ? upEls[swapIndex].id : target.id
|
|
596
|
-
};
|
|
597
|
-
};
|
|
598
612
|
|
|
599
613
|
class TargetCalibrate extends EventEmitter {
|
|
600
614
|
constructor(config) {
|
|
@@ -616,6 +630,7 @@ class TargetCalibrate extends EventEmitter {
|
|
|
616
630
|
top: ${top}px;
|
|
617
631
|
width: ${el.clientWidth}px;
|
|
618
632
|
height: ${el.clientHeight}px;
|
|
633
|
+
z-index: ${ZIndex.DRAG_EL};
|
|
619
634
|
`;
|
|
620
635
|
this.operationEl.id = `${prefix}${el.id}`;
|
|
621
636
|
if (typeof this.core.config.updateDragEl === "function") {
|
|
@@ -683,7 +698,7 @@ class StageHighlight extends EventEmitter {
|
|
|
683
698
|
target: this.calibrationTarget.update(el, HIGHLIGHT_EL_ID_PREFIX),
|
|
684
699
|
origin: false,
|
|
685
700
|
rootContainer: this.core.container,
|
|
686
|
-
zoom:
|
|
701
|
+
zoom: 2
|
|
687
702
|
});
|
|
688
703
|
}
|
|
689
704
|
clearHighlight() {
|
|
@@ -854,6 +869,7 @@ class StageMask extends Rule {
|
|
|
854
869
|
this.maxScrollTop = 0;
|
|
855
870
|
this.maxScrollLeft = 0;
|
|
856
871
|
this.intersectionObserver = null;
|
|
872
|
+
this.isMultiSelectStatus = false;
|
|
857
873
|
this.mode = Mode.ABSOLUTE;
|
|
858
874
|
this.pageResizeObserver = null;
|
|
859
875
|
this.wrapperResizeObserver = null;
|
|
@@ -866,11 +882,18 @@ class StageMask extends Rule {
|
|
|
866
882
|
event.stopPropagation();
|
|
867
883
|
if (event.button !== MouseButton.LEFT && event.button !== MouseButton.RIGHT)
|
|
868
884
|
return;
|
|
885
|
+
if (!this.isMultiSelectStatus && event.target.className.indexOf("moveable-area") !== -1) {
|
|
886
|
+
return;
|
|
887
|
+
}
|
|
869
888
|
if (event.target.className.indexOf("moveable-control") !== -1) {
|
|
870
889
|
return;
|
|
871
890
|
}
|
|
872
891
|
this.content.removeEventListener("mousemove", this.highlightHandler);
|
|
873
|
-
this.
|
|
892
|
+
if (this.isMultiSelectStatus) {
|
|
893
|
+
this.emit("beforeMultiSelect", event);
|
|
894
|
+
} else {
|
|
895
|
+
this.emit("beforeSelect", event);
|
|
896
|
+
}
|
|
874
897
|
globalThis.document.addEventListener("mouseup", this.mouseUpHandler);
|
|
875
898
|
};
|
|
876
899
|
this.mouseUpHandler = () => {
|
|
@@ -906,6 +929,14 @@ class StageMask extends Rule {
|
|
|
906
929
|
this.content.addEventListener("wheel", this.mouseWheelHandler);
|
|
907
930
|
this.content.addEventListener("mousemove", this.highlightHandler);
|
|
908
931
|
this.content.addEventListener("mouseleave", this.mouseLeaveHandler);
|
|
932
|
+
KeyController.global.keydown("shift", (e) => {
|
|
933
|
+
e.inputEvent.preventDefault();
|
|
934
|
+
this.isMultiSelectStatus = true;
|
|
935
|
+
});
|
|
936
|
+
KeyController.global.keyup("shift", (e) => {
|
|
937
|
+
e.inputEvent.preventDefault();
|
|
938
|
+
this.isMultiSelectStatus = false;
|
|
939
|
+
});
|
|
909
940
|
}
|
|
910
941
|
setMode(mode) {
|
|
911
942
|
this.mode = mode;
|
|
@@ -1036,7 +1067,148 @@ class StageMask extends Rule {
|
|
|
1036
1067
|
}
|
|
1037
1068
|
}
|
|
1038
1069
|
|
|
1039
|
-
|
|
1070
|
+
class StageMultiDragResize extends EventEmitter {
|
|
1071
|
+
constructor(config) {
|
|
1072
|
+
super();
|
|
1073
|
+
this.targetList = [];
|
|
1074
|
+
this.dragElList = [];
|
|
1075
|
+
this.core = config.core;
|
|
1076
|
+
this.container = config.container;
|
|
1077
|
+
this.mask = config.mask;
|
|
1078
|
+
}
|
|
1079
|
+
multiSelect(els) {
|
|
1080
|
+
this.targetList = els;
|
|
1081
|
+
this.core.dr.destroyDragEl();
|
|
1082
|
+
this.destroyDragElList();
|
|
1083
|
+
this.dragElList = els.map((elItem) => {
|
|
1084
|
+
const dragElDiv = globalThis.document.createElement("div");
|
|
1085
|
+
this.container.append(dragElDiv);
|
|
1086
|
+
dragElDiv.style.cssText = getTargetElStyle(elItem);
|
|
1087
|
+
dragElDiv.id = `${DRAG_EL_ID_PREFIX}${elItem.id}`;
|
|
1088
|
+
if (typeof this.core.config.updateDragEl === "function") {
|
|
1089
|
+
this.core.config.updateDragEl(dragElDiv, elItem);
|
|
1090
|
+
}
|
|
1091
|
+
return dragElDiv;
|
|
1092
|
+
});
|
|
1093
|
+
this.moveableForMulti?.destroy();
|
|
1094
|
+
this.multiMoveableHelper?.clear();
|
|
1095
|
+
this.moveableForMulti = new Moveable(this.container, this.getOptions({
|
|
1096
|
+
target: this.dragElList
|
|
1097
|
+
}));
|
|
1098
|
+
this.multiMoveableHelper = MoveableHelper.create({
|
|
1099
|
+
useBeforeRender: true,
|
|
1100
|
+
useRender: false,
|
|
1101
|
+
createAuto: true
|
|
1102
|
+
});
|
|
1103
|
+
const frames = [];
|
|
1104
|
+
this.moveableForMulti.on("dragGroupStart", (params) => {
|
|
1105
|
+
const { events } = params;
|
|
1106
|
+
this.multiMoveableHelper?.onDragGroupStart(params);
|
|
1107
|
+
events.forEach((ev) => {
|
|
1108
|
+
const matchEventTarget = this.targetList.find((targetItem) => targetItem.id === ev.target.id.replace(DRAG_EL_ID_PREFIX, ""));
|
|
1109
|
+
if (!matchEventTarget)
|
|
1110
|
+
return;
|
|
1111
|
+
frames.push({
|
|
1112
|
+
left: matchEventTarget.offsetLeft,
|
|
1113
|
+
top: matchEventTarget.offsetTop,
|
|
1114
|
+
id: matchEventTarget.id
|
|
1115
|
+
});
|
|
1116
|
+
});
|
|
1117
|
+
}).on("dragGroup", (params) => {
|
|
1118
|
+
const { events } = params;
|
|
1119
|
+
events.forEach((ev) => {
|
|
1120
|
+
const frameSnapShot = frames.find((frameItem) => frameItem.id === ev.target.id.replace(DRAG_EL_ID_PREFIX, ""));
|
|
1121
|
+
if (!frameSnapShot)
|
|
1122
|
+
return;
|
|
1123
|
+
const targeEl = this.targetList.find((targetItem) => targetItem.id === ev.target.id.replace(DRAG_EL_ID_PREFIX, ""));
|
|
1124
|
+
if (!targeEl)
|
|
1125
|
+
return;
|
|
1126
|
+
const isParentIncluded = this.targetList.find((targetItem) => targetItem.id === targeEl.parentElement?.id);
|
|
1127
|
+
if (!isParentIncluded) {
|
|
1128
|
+
targeEl.style.left = `${frameSnapShot.left + ev.beforeTranslate[0]}px`;
|
|
1129
|
+
targeEl.style.top = `${frameSnapShot.top + ev.beforeTranslate[1]}px`;
|
|
1130
|
+
}
|
|
1131
|
+
});
|
|
1132
|
+
this.multiMoveableHelper?.onDragGroup(params);
|
|
1133
|
+
}).on("dragGroupEnd", () => {
|
|
1134
|
+
this.update();
|
|
1135
|
+
});
|
|
1136
|
+
}
|
|
1137
|
+
canSelect(el) {
|
|
1138
|
+
if (el.className.includes(PAGE_CLASS)) {
|
|
1139
|
+
this.core.highlightedDom = void 0;
|
|
1140
|
+
this.core.highlightLayer.clearHighlight();
|
|
1141
|
+
return false;
|
|
1142
|
+
}
|
|
1143
|
+
const currentTargetMode = getMode(el);
|
|
1144
|
+
let selectedDomMode = "";
|
|
1145
|
+
if (this.targetList.length === 0 && this.core.selectedDom) {
|
|
1146
|
+
selectedDomMode = getMode(this.core.selectedDom);
|
|
1147
|
+
} else if (this.targetList.length > 0) {
|
|
1148
|
+
selectedDomMode = getMode(this.targetList[0]);
|
|
1149
|
+
}
|
|
1150
|
+
if (currentTargetMode !== selectedDomMode) {
|
|
1151
|
+
return false;
|
|
1152
|
+
}
|
|
1153
|
+
return true;
|
|
1154
|
+
}
|
|
1155
|
+
clearSelectStatus() {
|
|
1156
|
+
if (!this.moveableForMulti)
|
|
1157
|
+
return;
|
|
1158
|
+
this.destroyDragElList();
|
|
1159
|
+
this.moveableForMulti.target = null;
|
|
1160
|
+
this.moveableForMulti.updateTarget();
|
|
1161
|
+
this.targetList = [];
|
|
1162
|
+
}
|
|
1163
|
+
destroy() {
|
|
1164
|
+
this.moveableForMulti?.destroy();
|
|
1165
|
+
this.destroyDragElList();
|
|
1166
|
+
}
|
|
1167
|
+
destroyDragElList() {
|
|
1168
|
+
this.dragElList.forEach((dragElItem) => dragElItem?.remove());
|
|
1169
|
+
}
|
|
1170
|
+
update(isResize = false) {
|
|
1171
|
+
if (this.targetList.length === 0)
|
|
1172
|
+
return;
|
|
1173
|
+
const { contentWindow } = this.core.renderer;
|
|
1174
|
+
const doc = contentWindow?.document;
|
|
1175
|
+
if (!doc)
|
|
1176
|
+
return;
|
|
1177
|
+
this.targetList.forEach((targetItem) => {
|
|
1178
|
+
const offset = { left: targetItem.offsetLeft, top: targetItem.offsetTop };
|
|
1179
|
+
const left = calcValueByFontsize(doc, offset.left);
|
|
1180
|
+
const top = calcValueByFontsize(doc, offset.top);
|
|
1181
|
+
const width = calcValueByFontsize(doc, targetItem.clientWidth);
|
|
1182
|
+
const height = calcValueByFontsize(doc, targetItem.clientHeight);
|
|
1183
|
+
this.emit("update", {
|
|
1184
|
+
el: targetItem,
|
|
1185
|
+
style: isResize ? { left, top, width, height } : { left, top }
|
|
1186
|
+
});
|
|
1187
|
+
});
|
|
1188
|
+
}
|
|
1189
|
+
getOptions(options = {}) {
|
|
1190
|
+
let { moveableOptions = {} } = this.core.config;
|
|
1191
|
+
if (typeof moveableOptions === "function") {
|
|
1192
|
+
moveableOptions = moveableOptions(this.core);
|
|
1193
|
+
}
|
|
1194
|
+
return {
|
|
1195
|
+
defaultGroupRotate: 0,
|
|
1196
|
+
defaultGroupOrigin: "50% 50%",
|
|
1197
|
+
draggable: true,
|
|
1198
|
+
resizable: true,
|
|
1199
|
+
throttleDrag: 0,
|
|
1200
|
+
startDragRotate: 0,
|
|
1201
|
+
throttleDragRotate: 0,
|
|
1202
|
+
zoom: 1,
|
|
1203
|
+
origin: true,
|
|
1204
|
+
padding: { left: 0, top: 0, right: 0, bottom: 0 },
|
|
1205
|
+
...options,
|
|
1206
|
+
...moveableOptions
|
|
1207
|
+
};
|
|
1208
|
+
}
|
|
1209
|
+
}
|
|
1210
|
+
|
|
1211
|
+
var style = ".tmagic-stage-container-highlight::after {\n content: '';\n position: absolute;\n width: 100%;\n height: 100%;\n top: 0;\n left: 0;\n background-color: #000;\n opacity: .1;\n pointer-events: none;\n}\n";
|
|
1040
1212
|
|
|
1041
1213
|
class StageRender extends EventEmitter {
|
|
1042
1214
|
constructor({ core }) {
|
|
@@ -1063,18 +1235,18 @@ class StageRender extends EventEmitter {
|
|
|
1063
1235
|
});
|
|
1064
1236
|
};
|
|
1065
1237
|
this.loadHandler = async () => {
|
|
1066
|
-
this.contentWindow
|
|
1067
|
-
|
|
1238
|
+
if (!this.contentWindow?.magic) {
|
|
1239
|
+
this.postTmagicRuntimeReady();
|
|
1240
|
+
}
|
|
1241
|
+
if (!this.contentWindow)
|
|
1242
|
+
return;
|
|
1068
1243
|
if (this.render) {
|
|
1069
1244
|
const el = await this.render(this.core);
|
|
1070
1245
|
if (el) {
|
|
1071
|
-
this.
|
|
1246
|
+
this.contentWindow.document?.body?.appendChild(el);
|
|
1072
1247
|
}
|
|
1073
1248
|
}
|
|
1074
1249
|
this.emit("onload");
|
|
1075
|
-
this.contentWindow.postMessage({
|
|
1076
|
-
tmagicRuntimeReady: true
|
|
1077
|
-
}, "*");
|
|
1078
1250
|
injectStyle(this.contentWindow.document, style);
|
|
1079
1251
|
};
|
|
1080
1252
|
this.core = core;
|
|
@@ -1090,18 +1262,18 @@ class StageRender extends EventEmitter {
|
|
|
1090
1262
|
this.iframe.addEventListener("load", this.loadHandler);
|
|
1091
1263
|
}
|
|
1092
1264
|
async mount(el) {
|
|
1093
|
-
if (this.iframe) {
|
|
1094
|
-
if (!isSameDomain(this.runtimeUrl) && this.runtimeUrl) {
|
|
1095
|
-
let html = await fetch(this.runtimeUrl).then((res) => res.text());
|
|
1096
|
-
const base = `${location.protocol}//${getHost(this.runtimeUrl)}`;
|
|
1097
|
-
html = html.replace("<head>", `<head>
|
|
1098
|
-
<base href="${base}">`);
|
|
1099
|
-
this.iframe.srcdoc = html;
|
|
1100
|
-
}
|
|
1101
|
-
el.appendChild(this.iframe);
|
|
1102
|
-
} else {
|
|
1265
|
+
if (!this.iframe) {
|
|
1103
1266
|
throw Error("mount \u5931\u8D25");
|
|
1104
1267
|
}
|
|
1268
|
+
if (!isSameDomain(this.runtimeUrl) && this.runtimeUrl) {
|
|
1269
|
+
let html = await fetch(this.runtimeUrl).then((res) => res.text());
|
|
1270
|
+
const base = `${location.protocol}//${getHost(this.runtimeUrl)}`;
|
|
1271
|
+
html = html.replace("<head>", `<head>
|
|
1272
|
+
<base href="${base}">`);
|
|
1273
|
+
this.iframe.srcdoc = html;
|
|
1274
|
+
}
|
|
1275
|
+
el.appendChild(this.iframe);
|
|
1276
|
+
this.postTmagicRuntimeReady();
|
|
1105
1277
|
}
|
|
1106
1278
|
destroy() {
|
|
1107
1279
|
this.iframe?.removeEventListener("load", this.loadHandler);
|
|
@@ -1110,11 +1282,19 @@ class StageRender extends EventEmitter {
|
|
|
1110
1282
|
this.iframe = void 0;
|
|
1111
1283
|
this.removeAllListeners();
|
|
1112
1284
|
}
|
|
1285
|
+
postTmagicRuntimeReady() {
|
|
1286
|
+
this.contentWindow = this.iframe?.contentWindow;
|
|
1287
|
+
this.contentWindow.magic = this.getMagicApi();
|
|
1288
|
+
this.contentWindow.postMessage({
|
|
1289
|
+
tmagicRuntimeReady: true
|
|
1290
|
+
}, "*");
|
|
1291
|
+
}
|
|
1113
1292
|
}
|
|
1114
1293
|
|
|
1115
1294
|
class StageCore extends EventEmitter {
|
|
1116
1295
|
constructor(config) {
|
|
1117
1296
|
super();
|
|
1297
|
+
this.selectedDomList = [];
|
|
1118
1298
|
this.zoom = DEFAULT_ZOOM;
|
|
1119
1299
|
this.config = config;
|
|
1120
1300
|
this.setZoom(config.zoom);
|
|
@@ -1124,7 +1304,8 @@ class StageCore extends EventEmitter {
|
|
|
1124
1304
|
this.containerHighlightDuration = config.containerHighlightDuration;
|
|
1125
1305
|
this.renderer = new StageRender({ core: this });
|
|
1126
1306
|
this.mask = new StageMask({ core: this });
|
|
1127
|
-
this.dr = new StageDragResize({ core: this, container: this.mask.content });
|
|
1307
|
+
this.dr = new StageDragResize({ core: this, container: this.mask.content, mask: this.mask });
|
|
1308
|
+
this.multiDr = new StageMultiDragResize({ core: this, container: this.mask.content, mask: this.mask });
|
|
1128
1309
|
this.highlightLayer = new StageHighlight({ core: this, container: this.mask.wrapper });
|
|
1129
1310
|
this.renderer.on("runtime-ready", (runtime) => {
|
|
1130
1311
|
this.emit("runtime-ready", runtime);
|
|
@@ -1132,29 +1313,55 @@ class StageCore extends EventEmitter {
|
|
|
1132
1313
|
this.renderer.on("page-el-update", (el) => {
|
|
1133
1314
|
this.mask?.observe(el);
|
|
1134
1315
|
});
|
|
1135
|
-
this.mask.on("beforeSelect", (event) => {
|
|
1136
|
-
this.
|
|
1316
|
+
this.mask.on("beforeSelect", async (event) => {
|
|
1317
|
+
this.clearSelectStatus("multiSelect");
|
|
1318
|
+
const el = await this.getElementFromPoint(event);
|
|
1319
|
+
if (!el)
|
|
1320
|
+
return;
|
|
1321
|
+
this.select(el, event);
|
|
1137
1322
|
}).on("select", () => {
|
|
1138
1323
|
this.emit("select", this.selectedDom);
|
|
1139
1324
|
}).on("changeGuides", (data) => {
|
|
1140
1325
|
this.dr.setGuidelines(data.type, data.guides);
|
|
1141
1326
|
this.emit("changeGuides", data);
|
|
1142
1327
|
}).on("highlight", async (event) => {
|
|
1143
|
-
await this.
|
|
1328
|
+
const el = await this.getElementFromPoint(event);
|
|
1329
|
+
if (!el)
|
|
1330
|
+
return;
|
|
1331
|
+
await this.highlight(el);
|
|
1144
1332
|
if (this.highlightedDom === this.selectedDom) {
|
|
1145
1333
|
this.highlightLayer.clearHighlight();
|
|
1146
1334
|
return;
|
|
1147
1335
|
}
|
|
1148
|
-
this.highlightLayer.highlight(this.highlightedDom);
|
|
1149
1336
|
this.emit("highlight", this.highlightedDom);
|
|
1150
1337
|
}).on("clearHighlight", async () => {
|
|
1151
1338
|
this.highlightLayer.clearHighlight();
|
|
1339
|
+
}).on("beforeMultiSelect", async (event) => {
|
|
1340
|
+
const el = await this.getElementFromPoint(event);
|
|
1341
|
+
if (!el)
|
|
1342
|
+
return;
|
|
1343
|
+
this.clearSelectStatus("select");
|
|
1344
|
+
if (this.selectedDom && !this.selectedDom.className.includes(PAGE_CLASS)) {
|
|
1345
|
+
this.selectedDomList.push(this.selectedDom);
|
|
1346
|
+
this.selectedDom = void 0;
|
|
1347
|
+
}
|
|
1348
|
+
const existIndex = this.selectedDomList.findIndex((selectedDom) => selectedDom.id === el.id);
|
|
1349
|
+
if (existIndex !== -1) {
|
|
1350
|
+
this.selectedDomList.splice(existIndex, 1);
|
|
1351
|
+
} else {
|
|
1352
|
+
this.selectedDomList.push(el);
|
|
1353
|
+
}
|
|
1354
|
+
this.multiDr.multiSelect(this.selectedDomList);
|
|
1355
|
+
this.emit("multiSelect", this.selectedDomList);
|
|
1152
1356
|
});
|
|
1153
1357
|
this.dr.on("update", (data) => {
|
|
1154
1358
|
setTimeout(() => this.emit("update", data));
|
|
1155
1359
|
}).on("sort", (data) => {
|
|
1156
1360
|
setTimeout(() => this.emit("sort", data));
|
|
1157
1361
|
});
|
|
1362
|
+
this.multiDr.on("update", (data) => {
|
|
1363
|
+
setTimeout(() => this.emit("update", data));
|
|
1364
|
+
});
|
|
1158
1365
|
}
|
|
1159
1366
|
getElementsFromPoint(event) {
|
|
1160
1367
|
const { renderer, zoom } = this;
|
|
@@ -1170,24 +1377,29 @@ class StageCore extends EventEmitter {
|
|
|
1170
1377
|
}
|
|
1171
1378
|
return doc?.elementsFromPoint(x / zoom, y / zoom);
|
|
1172
1379
|
}
|
|
1173
|
-
async
|
|
1380
|
+
async getElementFromPoint(event) {
|
|
1174
1381
|
const els = this.getElementsFromPoint(event);
|
|
1175
1382
|
let stopped = false;
|
|
1176
1383
|
const stop = () => stopped = true;
|
|
1177
1384
|
for (const el of els) {
|
|
1178
|
-
if (!el.id.startsWith(GHOST_EL_ID_PREFIX) && await this.
|
|
1385
|
+
if (!el.id.startsWith(GHOST_EL_ID_PREFIX) && await this.isElCanSelect(el, event, stop)) {
|
|
1179
1386
|
if (stopped)
|
|
1180
1387
|
break;
|
|
1181
|
-
|
|
1182
|
-
this.highlight(el);
|
|
1183
|
-
break;
|
|
1184
|
-
}
|
|
1185
|
-
this.select(el, event);
|
|
1186
|
-
break;
|
|
1388
|
+
return el;
|
|
1187
1389
|
}
|
|
1188
1390
|
}
|
|
1189
1391
|
}
|
|
1392
|
+
async isElCanSelect(el, event, stop) {
|
|
1393
|
+
const canSelectByProp = await this.canSelect(el, event, stop);
|
|
1394
|
+
if (!canSelectByProp)
|
|
1395
|
+
return false;
|
|
1396
|
+
if (this.mask.isMultiSelectStatus) {
|
|
1397
|
+
return this.multiDr.canSelect(el);
|
|
1398
|
+
}
|
|
1399
|
+
return true;
|
|
1400
|
+
}
|
|
1190
1401
|
async select(idOrEl, event) {
|
|
1402
|
+
this.clearSelectStatus("multiSelect");
|
|
1191
1403
|
const el = await this.getTargetElement(idOrEl);
|
|
1192
1404
|
if (el === this.selectedDom)
|
|
1193
1405
|
return;
|
|
@@ -1231,7 +1443,7 @@ class StageCore extends EventEmitter {
|
|
|
1231
1443
|
this.highlightLayer.clearHighlight();
|
|
1232
1444
|
return;
|
|
1233
1445
|
}
|
|
1234
|
-
if (el === this.highlightedDom)
|
|
1446
|
+
if (el === this.highlightedDom || !el)
|
|
1235
1447
|
return;
|
|
1236
1448
|
this.highlightLayer.highlight(el);
|
|
1237
1449
|
this.highlightedDom = el;
|
|
@@ -1248,6 +1460,14 @@ class StageCore extends EventEmitter {
|
|
|
1248
1460
|
setZoom(zoom = DEFAULT_ZOOM) {
|
|
1249
1461
|
this.zoom = zoom;
|
|
1250
1462
|
}
|
|
1463
|
+
clearSelectStatus(selectType) {
|
|
1464
|
+
if (selectType === "multiSelect") {
|
|
1465
|
+
this.multiDr.clearSelectStatus();
|
|
1466
|
+
this.selectedDomList = [];
|
|
1467
|
+
} else {
|
|
1468
|
+
this.dr.clearSelectStatus();
|
|
1469
|
+
}
|
|
1470
|
+
}
|
|
1251
1471
|
async mount(el) {
|
|
1252
1472
|
this.container = el;
|
|
1253
1473
|
const { mask, renderer } = this;
|
|
@@ -1259,6 +1479,24 @@ class StageCore extends EventEmitter {
|
|
|
1259
1479
|
this.mask.clearGuides();
|
|
1260
1480
|
this.dr.clearGuides();
|
|
1261
1481
|
}
|
|
1482
|
+
async addContainerHighlightClassName(event, exclude) {
|
|
1483
|
+
const els = this.getElementsFromPoint(event);
|
|
1484
|
+
const { renderer } = this;
|
|
1485
|
+
const doc = renderer.contentWindow?.document;
|
|
1486
|
+
if (!doc)
|
|
1487
|
+
return;
|
|
1488
|
+
for (const el of els) {
|
|
1489
|
+
if (!el.id.startsWith(GHOST_EL_ID_PREFIX) && await this.isContainer(el) && !exclude.includes(el)) {
|
|
1490
|
+
addClassName(el, doc, this.containerHighlightClassName);
|
|
1491
|
+
break;
|
|
1492
|
+
}
|
|
1493
|
+
}
|
|
1494
|
+
}
|
|
1495
|
+
getAddContainerHighlightClassNameTimeout(event, exclude = []) {
|
|
1496
|
+
return globalThis.setTimeout(() => {
|
|
1497
|
+
this.addContainerHighlightClassName(event, exclude);
|
|
1498
|
+
}, this.containerHighlightDuration);
|
|
1499
|
+
}
|
|
1262
1500
|
destroy() {
|
|
1263
1501
|
const { mask, renderer, dr, highlightLayer } = this;
|
|
1264
1502
|
renderer.destroy();
|
|
@@ -1279,5 +1517,5 @@ class StageCore extends EventEmitter {
|
|
|
1279
1517
|
}
|
|
1280
1518
|
}
|
|
1281
1519
|
|
|
1282
|
-
export { CONTAINER_HIGHLIGHT_CLASS, DEFAULT_ZOOM, DRAG_EL_ID_PREFIX, GHOST_EL_ID_PREFIX, GuidesType, HIGHLIGHT_EL_ID_PREFIX, Mode, MouseButton, SELECTED_CLASS, StageDragResize, StageMask, StageRender, ZIndex, addSelectedClassName, calcValueByFontsize, StageCore as default, getAbsolutePosition, getMode, getOffset, getScrollParent, isAbsolute, isFixed, isFixedParent, isRelative, isStatic, removeSelectedClassName };
|
|
1520
|
+
export { CONTAINER_HIGHLIGHT_CLASS, DEFAULT_ZOOM, DRAG_EL_ID_PREFIX, GHOST_EL_ID_PREFIX, GuidesType, HIGHLIGHT_EL_ID_PREFIX, Mode, MouseButton, PAGE_CLASS, SELECTED_CLASS, StageDragResize, StageMask, StageRender, ZIndex, addSelectedClassName, calcValueByFontsize, StageCore as default, down, getAbsolutePosition, getMode, getOffset, getScrollParent, getTargetElStyle, isAbsolute, isFixed, isFixedParent, isRelative, isStatic, removeSelectedClassName, up };
|
|
1283
1521
|
//# sourceMappingURL=tmagic-stage.es.js.map
|