@tmagic/stage 1.1.0-beta.3 → 1.1.0-beta.6
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 → tmagic-stage.mjs} +327 -234
- package/dist/tmagic-stage.mjs.map +1 -0
- package/dist/tmagic-stage.umd.js +341 -246
- package/dist/tmagic-stage.umd.js.map +1 -1
- package/package.json +13 -11
- package/src/StageCore.ts +27 -12
- package/src/StageDragResize.ts +4 -74
- package/src/StageHighlight.ts +1 -1
- package/src/StageMask.ts +10 -8
- package/src/StageMultiDragResize.ts +62 -16
- package/src/StageRender.ts +28 -18
- package/src/TargetCalibrate.ts +2 -1
- package/src/style.css +1 -0
- package/src/types.ts +1 -1
- package/src/util.ts +72 -2
- package/tsconfig.build.json +13 -0
- package/{dist/types/src → types}/Rule.d.ts +0 -0
- package/{dist/types/src → types}/StageCore.d.ts +8 -1
- package/{dist/types/src → types}/StageDragResize.d.ts +1 -15
- package/{dist/types/src → types}/StageHighlight.d.ts +0 -0
- package/{dist/types/src → types}/StageMask.d.ts +1 -1
- package/{dist/types/src → types}/StageMultiDragResize.d.ts +7 -0
- package/{dist/types/src → types}/StageRender.d.ts +1 -0
- package/{dist/types/src → types}/TargetCalibrate.d.ts +0 -0
- package/{dist/types/src → types}/const.d.ts +0 -0
- package/{dist/types/src → types}/index.d.ts +0 -0
- package/types/logger.d.ts +5 -0
- package/{dist/types/src → types}/types.d.ts +1 -1
- package/{dist/types/src → types}/util.d.ts +15 -1
- package/dist/tmagic-stage.es.js.map +0 -1
- package/dist/types/src/vite-env.d.ts +0 -1
- package/src/vite-env.d.ts +0 -1
|
@@ -156,16 +156,70 @@ const calcValueByFontsize = (doc, value) => {
|
|
|
156
156
|
}
|
|
157
157
|
return value;
|
|
158
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
|
+
};
|
|
159
205
|
|
|
160
206
|
class StageDragResize extends EventEmitter {
|
|
207
|
+
core;
|
|
208
|
+
mask;
|
|
209
|
+
container;
|
|
210
|
+
target;
|
|
211
|
+
dragEl;
|
|
212
|
+
moveable;
|
|
213
|
+
horizontalGuidelines = [];
|
|
214
|
+
verticalGuidelines = [];
|
|
215
|
+
elementGuidelines = [];
|
|
216
|
+
mode = Mode.ABSOLUTE;
|
|
217
|
+
moveableOptions = {};
|
|
218
|
+
dragStatus = "end" /* END */;
|
|
219
|
+
ghostEl;
|
|
220
|
+
moveableHelper;
|
|
161
221
|
constructor(config) {
|
|
162
222
|
super();
|
|
163
|
-
this.horizontalGuidelines = [];
|
|
164
|
-
this.verticalGuidelines = [];
|
|
165
|
-
this.elementGuidelines = [];
|
|
166
|
-
this.mode = Mode.ABSOLUTE;
|
|
167
|
-
this.moveableOptions = {};
|
|
168
|
-
this.dragStatus = "end" /* END */;
|
|
169
223
|
this.core = config.core;
|
|
170
224
|
this.container = config.container;
|
|
171
225
|
this.mask = config.mask;
|
|
@@ -491,7 +545,7 @@ class StageDragResize extends EventEmitter {
|
|
|
491
545
|
return ghostEl;
|
|
492
546
|
}
|
|
493
547
|
setGhostElChildrenId(el) {
|
|
494
|
-
for (const child of el.children) {
|
|
548
|
+
for (const child of Array.from(el.children)) {
|
|
495
549
|
if (child.id) {
|
|
496
550
|
child.id = `${GHOST_EL_ID_PREFIX}${child.id}`;
|
|
497
551
|
}
|
|
@@ -554,7 +608,7 @@ class StageDragResize extends EventEmitter {
|
|
|
554
608
|
bounds: {
|
|
555
609
|
top: 0,
|
|
556
610
|
left: -1,
|
|
557
|
-
right: this.container.clientWidth,
|
|
611
|
+
right: this.container.clientWidth - 1,
|
|
558
612
|
bottom: this.container.clientHeight,
|
|
559
613
|
...moveableOptions.bounds || {}
|
|
560
614
|
},
|
|
@@ -563,54 +617,13 @@ class StageDragResize extends EventEmitter {
|
|
|
563
617
|
};
|
|
564
618
|
}
|
|
565
619
|
}
|
|
566
|
-
const down = (deltaTop, target) => {
|
|
567
|
-
let swapIndex = 0;
|
|
568
|
-
let addUpH = target.clientHeight;
|
|
569
|
-
const brothers = Array.from(target.parentNode?.children || []).filter((node) => !node.id.startsWith(GHOST_EL_ID_PREFIX));
|
|
570
|
-
const index = brothers.indexOf(target);
|
|
571
|
-
const downEls = brothers.slice(index + 1);
|
|
572
|
-
for (let i = 0; i < downEls.length; i++) {
|
|
573
|
-
const ele = downEls[i];
|
|
574
|
-
if (ele.style?.position === "fixed") {
|
|
575
|
-
continue;
|
|
576
|
-
}
|
|
577
|
-
addUpH += ele.clientHeight / 2;
|
|
578
|
-
if (deltaTop <= addUpH) {
|
|
579
|
-
break;
|
|
580
|
-
}
|
|
581
|
-
addUpH += ele.clientHeight / 2;
|
|
582
|
-
swapIndex = i;
|
|
583
|
-
}
|
|
584
|
-
return {
|
|
585
|
-
src: target.id,
|
|
586
|
-
dist: downEls.length && swapIndex > -1 ? downEls[swapIndex].id : target.id
|
|
587
|
-
};
|
|
588
|
-
};
|
|
589
|
-
const up = (deltaTop, target) => {
|
|
590
|
-
const brothers = Array.from(target.parentNode?.children || []).filter((node) => !node.id.startsWith(GHOST_EL_ID_PREFIX));
|
|
591
|
-
const index = brothers.indexOf(target);
|
|
592
|
-
const upEls = brothers.slice(0, index);
|
|
593
|
-
let addUpH = target.clientHeight;
|
|
594
|
-
let swapIndex = upEls.length - 1;
|
|
595
|
-
for (let i = upEls.length - 1; i >= 0; i--) {
|
|
596
|
-
const ele = upEls[i];
|
|
597
|
-
if (!ele)
|
|
598
|
-
continue;
|
|
599
|
-
if (ele.style.position === "fixed")
|
|
600
|
-
continue;
|
|
601
|
-
addUpH += ele.clientHeight / 2;
|
|
602
|
-
if (-deltaTop <= addUpH)
|
|
603
|
-
break;
|
|
604
|
-
addUpH += ele.clientHeight / 2;
|
|
605
|
-
swapIndex = i;
|
|
606
|
-
}
|
|
607
|
-
return {
|
|
608
|
-
src: target.id,
|
|
609
|
-
dist: upEls.length && swapIndex > -1 ? upEls[swapIndex].id : target.id
|
|
610
|
-
};
|
|
611
|
-
};
|
|
612
620
|
|
|
613
621
|
class TargetCalibrate extends EventEmitter {
|
|
622
|
+
parent;
|
|
623
|
+
mask;
|
|
624
|
+
dr;
|
|
625
|
+
core;
|
|
626
|
+
operationEl;
|
|
614
627
|
constructor(config) {
|
|
615
628
|
super();
|
|
616
629
|
this.parent = config.parent;
|
|
@@ -630,6 +643,7 @@ class TargetCalibrate extends EventEmitter {
|
|
|
630
643
|
top: ${top}px;
|
|
631
644
|
width: ${el.clientWidth}px;
|
|
632
645
|
height: ${el.clientHeight}px;
|
|
646
|
+
z-index: ${ZIndex.DRAG_EL};
|
|
633
647
|
`;
|
|
634
648
|
this.operationEl.id = `${prefix}${el.id}`;
|
|
635
649
|
if (typeof this.core.config.updateDragEl === "function") {
|
|
@@ -677,6 +691,11 @@ class TargetCalibrate extends EventEmitter {
|
|
|
677
691
|
}
|
|
678
692
|
|
|
679
693
|
class StageHighlight extends EventEmitter {
|
|
694
|
+
core;
|
|
695
|
+
container;
|
|
696
|
+
target;
|
|
697
|
+
moveable;
|
|
698
|
+
calibrationTarget;
|
|
680
699
|
constructor(config) {
|
|
681
700
|
super();
|
|
682
701
|
this.core = config.core;
|
|
@@ -697,7 +716,7 @@ class StageHighlight extends EventEmitter {
|
|
|
697
716
|
target: this.calibrationTarget.update(el, HIGHLIGHT_EL_ID_PREFIX),
|
|
698
717
|
origin: false,
|
|
699
718
|
rootContainer: this.core.container,
|
|
700
|
-
zoom:
|
|
719
|
+
zoom: 2
|
|
701
720
|
});
|
|
702
721
|
}
|
|
703
722
|
clearHighlight() {
|
|
@@ -714,41 +733,14 @@ class StageHighlight extends EventEmitter {
|
|
|
714
733
|
}
|
|
715
734
|
|
|
716
735
|
class Rule extends EventEmitter$1 {
|
|
736
|
+
hGuides;
|
|
737
|
+
vGuides;
|
|
738
|
+
horizontalGuidelines = [];
|
|
739
|
+
verticalGuidelines = [];
|
|
740
|
+
container;
|
|
741
|
+
containerResizeObserver;
|
|
717
742
|
constructor(container) {
|
|
718
743
|
super();
|
|
719
|
-
this.horizontalGuidelines = [];
|
|
720
|
-
this.verticalGuidelines = [];
|
|
721
|
-
this.getGuidesStyle = (type) => ({
|
|
722
|
-
position: "fixed",
|
|
723
|
-
zIndex: 1,
|
|
724
|
-
left: type === GuidesType.HORIZONTAL ? 0 : "-30px",
|
|
725
|
-
top: type === GuidesType.HORIZONTAL ? "-30px" : 0,
|
|
726
|
-
width: type === GuidesType.HORIZONTAL ? "100%" : "30px",
|
|
727
|
-
height: type === GuidesType.HORIZONTAL ? "30px" : "100%"
|
|
728
|
-
});
|
|
729
|
-
this.createGuides = (type, defaultGuides = []) => new Guides(this.container, {
|
|
730
|
-
type,
|
|
731
|
-
defaultGuides,
|
|
732
|
-
displayDragPos: true,
|
|
733
|
-
backgroundColor: "#fff",
|
|
734
|
-
lineColor: "#000",
|
|
735
|
-
textColor: "#000",
|
|
736
|
-
style: this.getGuidesStyle(type)
|
|
737
|
-
});
|
|
738
|
-
this.hGuidesChangeGuidesHandler = (e) => {
|
|
739
|
-
this.horizontalGuidelines = e.guides;
|
|
740
|
-
this.emit("changeGuides", {
|
|
741
|
-
type: GuidesType.HORIZONTAL,
|
|
742
|
-
guides: this.horizontalGuidelines
|
|
743
|
-
});
|
|
744
|
-
};
|
|
745
|
-
this.vGuidesChangeGuidesHandler = (e) => {
|
|
746
|
-
this.verticalGuidelines = e.guides;
|
|
747
|
-
this.emit("changeGuides", {
|
|
748
|
-
type: GuidesType.VERTICAL,
|
|
749
|
-
guides: this.verticalGuidelines
|
|
750
|
-
});
|
|
751
|
-
};
|
|
752
744
|
this.container = container;
|
|
753
745
|
this.hGuides = this.createGuides(GuidesType.HORIZONTAL, this.horizontalGuidelines);
|
|
754
746
|
this.vGuides = this.createGuides(GuidesType.VERTICAL, this.verticalGuidelines);
|
|
@@ -820,6 +812,37 @@ class Rule extends EventEmitter$1 {
|
|
|
820
812
|
this.containerResizeObserver.disconnect();
|
|
821
813
|
this.removeAllListeners();
|
|
822
814
|
}
|
|
815
|
+
getGuidesStyle = (type) => ({
|
|
816
|
+
position: "fixed",
|
|
817
|
+
zIndex: 1,
|
|
818
|
+
left: type === GuidesType.HORIZONTAL ? 0 : "-30px",
|
|
819
|
+
top: type === GuidesType.HORIZONTAL ? "-30px" : 0,
|
|
820
|
+
width: type === GuidesType.HORIZONTAL ? "100%" : "30px",
|
|
821
|
+
height: type === GuidesType.HORIZONTAL ? "30px" : "100%"
|
|
822
|
+
});
|
|
823
|
+
createGuides = (type, defaultGuides = []) => new Guides(this.container, {
|
|
824
|
+
type,
|
|
825
|
+
defaultGuides,
|
|
826
|
+
displayDragPos: true,
|
|
827
|
+
backgroundColor: "#fff",
|
|
828
|
+
lineColor: "#000",
|
|
829
|
+
textColor: "#000",
|
|
830
|
+
style: this.getGuidesStyle(type)
|
|
831
|
+
});
|
|
832
|
+
hGuidesChangeGuidesHandler = (e) => {
|
|
833
|
+
this.horizontalGuidelines = e.guides;
|
|
834
|
+
this.emit("changeGuides", {
|
|
835
|
+
type: GuidesType.HORIZONTAL,
|
|
836
|
+
guides: this.horizontalGuidelines
|
|
837
|
+
});
|
|
838
|
+
};
|
|
839
|
+
vGuidesChangeGuidesHandler = (e) => {
|
|
840
|
+
this.verticalGuidelines = e.guides;
|
|
841
|
+
this.emit("changeGuides", {
|
|
842
|
+
type: GuidesType.VERTICAL,
|
|
843
|
+
guides: this.verticalGuidelines
|
|
844
|
+
});
|
|
845
|
+
};
|
|
823
846
|
}
|
|
824
847
|
|
|
825
848
|
const wrapperClassName = "editor-mask-wrapper";
|
|
@@ -853,74 +876,30 @@ const createWrapper = () => {
|
|
|
853
876
|
return el;
|
|
854
877
|
};
|
|
855
878
|
class StageMask extends Rule {
|
|
879
|
+
content = createContent();
|
|
880
|
+
wrapper;
|
|
881
|
+
core;
|
|
882
|
+
page = null;
|
|
883
|
+
pageScrollParent = null;
|
|
884
|
+
scrollTop = 0;
|
|
885
|
+
scrollLeft = 0;
|
|
886
|
+
width = 0;
|
|
887
|
+
height = 0;
|
|
888
|
+
wrapperHeight = 0;
|
|
889
|
+
wrapperWidth = 0;
|
|
890
|
+
maxScrollTop = 0;
|
|
891
|
+
maxScrollLeft = 0;
|
|
892
|
+
intersectionObserver = null;
|
|
893
|
+
isMultiSelectStatus = false;
|
|
894
|
+
mode = Mode.ABSOLUTE;
|
|
895
|
+
pageResizeObserver = null;
|
|
896
|
+
wrapperResizeObserver = null;
|
|
897
|
+
highlightHandler = throttle((event) => {
|
|
898
|
+
this.emit("highlight", event);
|
|
899
|
+
}, throttleTime);
|
|
856
900
|
constructor(config) {
|
|
857
901
|
const wrapper = createWrapper();
|
|
858
902
|
super(wrapper);
|
|
859
|
-
this.content = createContent();
|
|
860
|
-
this.page = null;
|
|
861
|
-
this.pageScrollParent = null;
|
|
862
|
-
this.scrollTop = 0;
|
|
863
|
-
this.scrollLeft = 0;
|
|
864
|
-
this.width = 0;
|
|
865
|
-
this.height = 0;
|
|
866
|
-
this.wrapperHeight = 0;
|
|
867
|
-
this.wrapperWidth = 0;
|
|
868
|
-
this.maxScrollTop = 0;
|
|
869
|
-
this.maxScrollLeft = 0;
|
|
870
|
-
this.intersectionObserver = null;
|
|
871
|
-
this.shiftKeyDown = false;
|
|
872
|
-
this.mode = Mode.ABSOLUTE;
|
|
873
|
-
this.pageResizeObserver = null;
|
|
874
|
-
this.wrapperResizeObserver = null;
|
|
875
|
-
this.highlightHandler = throttle((event) => {
|
|
876
|
-
this.emit("highlight", event);
|
|
877
|
-
}, throttleTime);
|
|
878
|
-
this.mouseDownHandler = (event) => {
|
|
879
|
-
this.emit("clearHighlight");
|
|
880
|
-
event.stopImmediatePropagation();
|
|
881
|
-
event.stopPropagation();
|
|
882
|
-
if (event.button !== MouseButton.LEFT && event.button !== MouseButton.RIGHT)
|
|
883
|
-
return;
|
|
884
|
-
if (!this.shiftKeyDown && event.target.className.indexOf("moveable-area") !== -1) {
|
|
885
|
-
return;
|
|
886
|
-
}
|
|
887
|
-
if (event.target.className.indexOf("moveable-control") !== -1) {
|
|
888
|
-
return;
|
|
889
|
-
}
|
|
890
|
-
this.content.removeEventListener("mousemove", this.highlightHandler);
|
|
891
|
-
if (this.shiftKeyDown) {
|
|
892
|
-
this.emit("beforeMultiSelect", event);
|
|
893
|
-
} else {
|
|
894
|
-
this.emit("beforeSelect", event);
|
|
895
|
-
globalThis.document.addEventListener("mouseup", this.mouseUpHandler);
|
|
896
|
-
}
|
|
897
|
-
};
|
|
898
|
-
this.mouseUpHandler = () => {
|
|
899
|
-
globalThis.document.removeEventListener("mouseup", this.mouseUpHandler);
|
|
900
|
-
this.content.addEventListener("mousemove", this.highlightHandler);
|
|
901
|
-
this.emit("select");
|
|
902
|
-
};
|
|
903
|
-
this.mouseWheelHandler = (event) => {
|
|
904
|
-
this.emit("clearHighlight");
|
|
905
|
-
if (!this.page)
|
|
906
|
-
throw new Error("page \u672A\u521D\u59CB\u5316");
|
|
907
|
-
const { deltaY, deltaX } = event;
|
|
908
|
-
if (this.page.clientHeight < this.wrapperHeight && deltaY)
|
|
909
|
-
return;
|
|
910
|
-
if (this.page.clientWidth < this.wrapperWidth && deltaX)
|
|
911
|
-
return;
|
|
912
|
-
if (this.maxScrollTop > 0) {
|
|
913
|
-
this.scrollTop = this.scrollTop + deltaY;
|
|
914
|
-
}
|
|
915
|
-
if (this.maxScrollLeft > 0) {
|
|
916
|
-
this.scrollLeft = this.scrollLeft + deltaX;
|
|
917
|
-
}
|
|
918
|
-
this.scroll();
|
|
919
|
-
this.emit("scroll", event);
|
|
920
|
-
};
|
|
921
|
-
this.mouseLeaveHandler = () => {
|
|
922
|
-
setTimeout(() => this.emit("clearHighlight"), throttleTime);
|
|
923
|
-
};
|
|
924
903
|
this.wrapper = wrapper;
|
|
925
904
|
this.core = config.core;
|
|
926
905
|
this.content.addEventListener("mousedown", this.mouseDownHandler);
|
|
@@ -930,11 +909,11 @@ class StageMask extends Rule {
|
|
|
930
909
|
this.content.addEventListener("mouseleave", this.mouseLeaveHandler);
|
|
931
910
|
KeyController.global.keydown("shift", (e) => {
|
|
932
911
|
e.inputEvent.preventDefault();
|
|
933
|
-
this.
|
|
912
|
+
this.isMultiSelectStatus = true;
|
|
934
913
|
});
|
|
935
914
|
KeyController.global.keyup("shift", (e) => {
|
|
936
915
|
e.inputEvent.preventDefault();
|
|
937
|
-
this.
|
|
916
|
+
this.isMultiSelectStatus = false;
|
|
938
917
|
});
|
|
939
918
|
}
|
|
940
919
|
setMode(mode) {
|
|
@@ -1064,13 +1043,66 @@ class StageMask extends Rule {
|
|
|
1064
1043
|
if (this.maxScrollLeft < this.scrollLeft)
|
|
1065
1044
|
this.scrollLeft = this.maxScrollLeft;
|
|
1066
1045
|
}
|
|
1046
|
+
mouseDownHandler = (event) => {
|
|
1047
|
+
this.emit("clearHighlight");
|
|
1048
|
+
event.stopImmediatePropagation();
|
|
1049
|
+
event.stopPropagation();
|
|
1050
|
+
if (event.button !== MouseButton.LEFT && event.button !== MouseButton.RIGHT)
|
|
1051
|
+
return;
|
|
1052
|
+
if (!this.isMultiSelectStatus && event.target.className.indexOf("moveable-area") !== -1) {
|
|
1053
|
+
return;
|
|
1054
|
+
}
|
|
1055
|
+
if (event.target.className.indexOf("moveable-control") !== -1) {
|
|
1056
|
+
return;
|
|
1057
|
+
}
|
|
1058
|
+
this.content.removeEventListener("mousemove", this.highlightHandler);
|
|
1059
|
+
if (this.isMultiSelectStatus) {
|
|
1060
|
+
this.emit("beforeMultiSelect", event);
|
|
1061
|
+
} else {
|
|
1062
|
+
this.emit("beforeSelect", event);
|
|
1063
|
+
}
|
|
1064
|
+
globalThis.document.addEventListener("mouseup", this.mouseUpHandler);
|
|
1065
|
+
};
|
|
1066
|
+
mouseUpHandler = () => {
|
|
1067
|
+
globalThis.document.removeEventListener("mouseup", this.mouseUpHandler);
|
|
1068
|
+
this.content.addEventListener("mousemove", this.highlightHandler);
|
|
1069
|
+
if (!this.isMultiSelectStatus) {
|
|
1070
|
+
this.emit("select");
|
|
1071
|
+
}
|
|
1072
|
+
};
|
|
1073
|
+
mouseWheelHandler = (event) => {
|
|
1074
|
+
this.emit("clearHighlight");
|
|
1075
|
+
if (!this.page)
|
|
1076
|
+
throw new Error("page \u672A\u521D\u59CB\u5316");
|
|
1077
|
+
const { deltaY, deltaX } = event;
|
|
1078
|
+
if (this.page.clientHeight < this.wrapperHeight && deltaY)
|
|
1079
|
+
return;
|
|
1080
|
+
if (this.page.clientWidth < this.wrapperWidth && deltaX)
|
|
1081
|
+
return;
|
|
1082
|
+
if (this.maxScrollTop > 0) {
|
|
1083
|
+
this.scrollTop = this.scrollTop + deltaY;
|
|
1084
|
+
}
|
|
1085
|
+
if (this.maxScrollLeft > 0) {
|
|
1086
|
+
this.scrollLeft = this.scrollLeft + deltaX;
|
|
1087
|
+
}
|
|
1088
|
+
this.scroll();
|
|
1089
|
+
this.emit("scroll", event);
|
|
1090
|
+
};
|
|
1091
|
+
mouseLeaveHandler = () => {
|
|
1092
|
+
setTimeout(() => this.emit("clearHighlight"), throttleTime);
|
|
1093
|
+
};
|
|
1067
1094
|
}
|
|
1068
1095
|
|
|
1069
1096
|
class StageMultiDragResize extends EventEmitter {
|
|
1097
|
+
core;
|
|
1098
|
+
mask;
|
|
1099
|
+
container;
|
|
1100
|
+
targetList = [];
|
|
1101
|
+
dragElList = [];
|
|
1102
|
+
moveableForMulti;
|
|
1103
|
+
multiMoveableHelper;
|
|
1070
1104
|
constructor(config) {
|
|
1071
1105
|
super();
|
|
1072
|
-
this.targetList = [];
|
|
1073
|
-
this.dragElList = [];
|
|
1074
1106
|
this.core = config.core;
|
|
1075
1107
|
this.container = config.container;
|
|
1076
1108
|
this.mask = config.mask;
|
|
@@ -1091,19 +1123,9 @@ class StageMultiDragResize extends EventEmitter {
|
|
|
1091
1123
|
});
|
|
1092
1124
|
this.moveableForMulti?.destroy();
|
|
1093
1125
|
this.multiMoveableHelper?.clear();
|
|
1094
|
-
this.moveableForMulti = new Moveable(this.container, {
|
|
1095
|
-
target: this.dragElList
|
|
1096
|
-
|
|
1097
|
-
defaultGroupOrigin: "50% 50%",
|
|
1098
|
-
draggable: true,
|
|
1099
|
-
resizable: true,
|
|
1100
|
-
throttleDrag: 0,
|
|
1101
|
-
startDragRotate: 0,
|
|
1102
|
-
throttleDragRotate: 0,
|
|
1103
|
-
zoom: 1,
|
|
1104
|
-
origin: true,
|
|
1105
|
-
padding: { left: 0, top: 0, right: 0, bottom: 0 }
|
|
1106
|
-
});
|
|
1126
|
+
this.moveableForMulti = new Moveable(this.container, this.getOptions({
|
|
1127
|
+
target: this.dragElList
|
|
1128
|
+
}));
|
|
1107
1129
|
this.multiMoveableHelper = MoveableHelper.create({
|
|
1108
1130
|
useBeforeRender: true,
|
|
1109
1131
|
useRender: false,
|
|
@@ -1143,12 +1165,31 @@ class StageMultiDragResize extends EventEmitter {
|
|
|
1143
1165
|
this.update();
|
|
1144
1166
|
});
|
|
1145
1167
|
}
|
|
1168
|
+
canSelect(el) {
|
|
1169
|
+
if (el.className.includes(PAGE_CLASS)) {
|
|
1170
|
+
this.core.highlightedDom = void 0;
|
|
1171
|
+
this.core.highlightLayer.clearHighlight();
|
|
1172
|
+
return false;
|
|
1173
|
+
}
|
|
1174
|
+
const currentTargetMode = getMode(el);
|
|
1175
|
+
let selectedDomMode = "";
|
|
1176
|
+
if (this.targetList.length === 0 && this.core.selectedDom) {
|
|
1177
|
+
selectedDomMode = getMode(this.core.selectedDom);
|
|
1178
|
+
} else if (this.targetList.length > 0) {
|
|
1179
|
+
selectedDomMode = getMode(this.targetList[0]);
|
|
1180
|
+
}
|
|
1181
|
+
if (currentTargetMode !== selectedDomMode) {
|
|
1182
|
+
return false;
|
|
1183
|
+
}
|
|
1184
|
+
return true;
|
|
1185
|
+
}
|
|
1146
1186
|
clearSelectStatus() {
|
|
1147
1187
|
if (!this.moveableForMulti)
|
|
1148
1188
|
return;
|
|
1149
1189
|
this.destroyDragElList();
|
|
1150
1190
|
this.moveableForMulti.target = null;
|
|
1151
1191
|
this.moveableForMulti.updateTarget();
|
|
1192
|
+
this.targetList = [];
|
|
1152
1193
|
}
|
|
1153
1194
|
destroy() {
|
|
1154
1195
|
this.moveableForMulti?.destroy();
|
|
@@ -1176,49 +1217,39 @@ class StageMultiDragResize extends EventEmitter {
|
|
|
1176
1217
|
});
|
|
1177
1218
|
});
|
|
1178
1219
|
}
|
|
1220
|
+
getOptions(options = {}) {
|
|
1221
|
+
let { multiMoveableOptions = {} } = this.core.config;
|
|
1222
|
+
if (typeof multiMoveableOptions === "function") {
|
|
1223
|
+
multiMoveableOptions = multiMoveableOptions(this.core);
|
|
1224
|
+
}
|
|
1225
|
+
return {
|
|
1226
|
+
defaultGroupRotate: 0,
|
|
1227
|
+
defaultGroupOrigin: "50% 50%",
|
|
1228
|
+
draggable: true,
|
|
1229
|
+
resizable: true,
|
|
1230
|
+
throttleDrag: 0,
|
|
1231
|
+
startDragRotate: 0,
|
|
1232
|
+
throttleDragRotate: 0,
|
|
1233
|
+
zoom: 1,
|
|
1234
|
+
origin: true,
|
|
1235
|
+
padding: { left: 0, top: 0, right: 0, bottom: 0 },
|
|
1236
|
+
...options,
|
|
1237
|
+
...multiMoveableOptions
|
|
1238
|
+
};
|
|
1239
|
+
}
|
|
1179
1240
|
}
|
|
1180
1241
|
|
|
1181
|
-
|
|
1242
|
+
const 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";
|
|
1182
1243
|
|
|
1183
1244
|
class StageRender extends EventEmitter {
|
|
1245
|
+
contentWindow = null;
|
|
1246
|
+
runtime = null;
|
|
1247
|
+
iframe;
|
|
1248
|
+
runtimeUrl;
|
|
1249
|
+
core;
|
|
1250
|
+
render;
|
|
1184
1251
|
constructor({ core }) {
|
|
1185
1252
|
super();
|
|
1186
|
-
this.contentWindow = null;
|
|
1187
|
-
this.runtime = null;
|
|
1188
|
-
this.getMagicApi = () => ({
|
|
1189
|
-
onPageElUpdate: (el) => this.emit("page-el-update", el),
|
|
1190
|
-
onRuntimeReady: (runtime) => {
|
|
1191
|
-
this.runtime = runtime;
|
|
1192
|
-
globalThis.runtime = runtime;
|
|
1193
|
-
this.emit("runtime-ready", runtime);
|
|
1194
|
-
}
|
|
1195
|
-
});
|
|
1196
|
-
this.getRuntime = () => {
|
|
1197
|
-
if (this.runtime)
|
|
1198
|
-
return Promise.resolve(this.runtime);
|
|
1199
|
-
return new Promise((resolve) => {
|
|
1200
|
-
const listener = (runtime) => {
|
|
1201
|
-
this.off("runtime-ready", listener);
|
|
1202
|
-
resolve(runtime);
|
|
1203
|
-
};
|
|
1204
|
-
this.on("runtime-ready", listener);
|
|
1205
|
-
});
|
|
1206
|
-
};
|
|
1207
|
-
this.loadHandler = async () => {
|
|
1208
|
-
this.contentWindow = this.iframe?.contentWindow;
|
|
1209
|
-
this.contentWindow.magic = this.getMagicApi();
|
|
1210
|
-
if (this.render) {
|
|
1211
|
-
const el = await this.render(this.core);
|
|
1212
|
-
if (el) {
|
|
1213
|
-
this.iframe?.contentDocument?.body?.appendChild(el);
|
|
1214
|
-
}
|
|
1215
|
-
}
|
|
1216
|
-
this.emit("onload");
|
|
1217
|
-
this.contentWindow.postMessage({
|
|
1218
|
-
tmagicRuntimeReady: true
|
|
1219
|
-
}, "*");
|
|
1220
|
-
injectStyle(this.contentWindow.document, style);
|
|
1221
|
-
};
|
|
1222
1253
|
this.core = core;
|
|
1223
1254
|
this.runtimeUrl = core.config.runtimeUrl || "";
|
|
1224
1255
|
this.render = core.config.render;
|
|
@@ -1231,20 +1262,39 @@ class StageRender extends EventEmitter {
|
|
|
1231
1262
|
`;
|
|
1232
1263
|
this.iframe.addEventListener("load", this.loadHandler);
|
|
1233
1264
|
}
|
|
1265
|
+
getMagicApi = () => ({
|
|
1266
|
+
onPageElUpdate: (el) => this.emit("page-el-update", el),
|
|
1267
|
+
onRuntimeReady: (runtime) => {
|
|
1268
|
+
this.runtime = runtime;
|
|
1269
|
+
globalThis.runtime = runtime;
|
|
1270
|
+
this.emit("runtime-ready", runtime);
|
|
1271
|
+
}
|
|
1272
|
+
});
|
|
1234
1273
|
async mount(el) {
|
|
1235
|
-
if (this.iframe) {
|
|
1236
|
-
if (!isSameDomain(this.runtimeUrl) && this.runtimeUrl) {
|
|
1237
|
-
let html = await fetch(this.runtimeUrl).then((res) => res.text());
|
|
1238
|
-
const base = `${location.protocol}//${getHost(this.runtimeUrl)}`;
|
|
1239
|
-
html = html.replace("<head>", `<head>
|
|
1240
|
-
<base href="${base}">`);
|
|
1241
|
-
this.iframe.srcdoc = html;
|
|
1242
|
-
}
|
|
1243
|
-
el.appendChild(this.iframe);
|
|
1244
|
-
} else {
|
|
1274
|
+
if (!this.iframe) {
|
|
1245
1275
|
throw Error("mount \u5931\u8D25");
|
|
1246
1276
|
}
|
|
1247
|
-
|
|
1277
|
+
if (!isSameDomain(this.runtimeUrl) && this.runtimeUrl) {
|
|
1278
|
+
let html = await fetch(this.runtimeUrl).then((res) => res.text());
|
|
1279
|
+
const base = `${location.protocol}//${getHost(this.runtimeUrl)}`;
|
|
1280
|
+
html = html.replace("<head>", `<head>
|
|
1281
|
+
<base href="${base}">`);
|
|
1282
|
+
this.iframe.srcdoc = html;
|
|
1283
|
+
}
|
|
1284
|
+
el.appendChild(this.iframe);
|
|
1285
|
+
this.postTmagicRuntimeReady();
|
|
1286
|
+
}
|
|
1287
|
+
getRuntime = () => {
|
|
1288
|
+
if (this.runtime)
|
|
1289
|
+
return Promise.resolve(this.runtime);
|
|
1290
|
+
return new Promise((resolve) => {
|
|
1291
|
+
const listener = (runtime) => {
|
|
1292
|
+
this.off("runtime-ready", listener);
|
|
1293
|
+
resolve(runtime);
|
|
1294
|
+
};
|
|
1295
|
+
this.on("runtime-ready", listener);
|
|
1296
|
+
});
|
|
1297
|
+
};
|
|
1248
1298
|
destroy() {
|
|
1249
1299
|
this.iframe?.removeEventListener("load", this.loadHandler);
|
|
1250
1300
|
this.contentWindow = null;
|
|
@@ -1252,13 +1302,48 @@ class StageRender extends EventEmitter {
|
|
|
1252
1302
|
this.iframe = void 0;
|
|
1253
1303
|
this.removeAllListeners();
|
|
1254
1304
|
}
|
|
1305
|
+
loadHandler = async () => {
|
|
1306
|
+
if (!this.contentWindow?.magic) {
|
|
1307
|
+
this.postTmagicRuntimeReady();
|
|
1308
|
+
}
|
|
1309
|
+
if (!this.contentWindow)
|
|
1310
|
+
return;
|
|
1311
|
+
if (this.render) {
|
|
1312
|
+
const el = await this.render(this.core);
|
|
1313
|
+
if (el) {
|
|
1314
|
+
this.contentWindow.document?.body?.appendChild(el);
|
|
1315
|
+
}
|
|
1316
|
+
}
|
|
1317
|
+
this.emit("onload");
|
|
1318
|
+
injectStyle(this.contentWindow.document, style);
|
|
1319
|
+
};
|
|
1320
|
+
postTmagicRuntimeReady() {
|
|
1321
|
+
this.contentWindow = this.iframe?.contentWindow;
|
|
1322
|
+
this.contentWindow.magic = this.getMagicApi();
|
|
1323
|
+
this.contentWindow.postMessage({
|
|
1324
|
+
tmagicRuntimeReady: true
|
|
1325
|
+
}, "*");
|
|
1326
|
+
}
|
|
1255
1327
|
}
|
|
1256
1328
|
|
|
1257
1329
|
class StageCore extends EventEmitter {
|
|
1330
|
+
container;
|
|
1331
|
+
selectedDom;
|
|
1332
|
+
selectedDomList = [];
|
|
1333
|
+
highlightedDom;
|
|
1334
|
+
renderer;
|
|
1335
|
+
mask;
|
|
1336
|
+
dr;
|
|
1337
|
+
multiDr;
|
|
1338
|
+
highlightLayer;
|
|
1339
|
+
config;
|
|
1340
|
+
zoom = DEFAULT_ZOOM;
|
|
1341
|
+
containerHighlightClassName;
|
|
1342
|
+
containerHighlightDuration;
|
|
1343
|
+
isContainer;
|
|
1344
|
+
canSelect;
|
|
1258
1345
|
constructor(config) {
|
|
1259
1346
|
super();
|
|
1260
|
-
this.selectedDomList = [];
|
|
1261
|
-
this.zoom = DEFAULT_ZOOM;
|
|
1262
1347
|
this.config = config;
|
|
1263
1348
|
this.setZoom(config.zoom);
|
|
1264
1349
|
this.canSelect = config.canSelect || ((el) => !!el.id);
|
|
@@ -1288,7 +1373,7 @@ class StageCore extends EventEmitter {
|
|
|
1288
1373
|
this.dr.setGuidelines(data.type, data.guides);
|
|
1289
1374
|
this.emit("changeGuides", data);
|
|
1290
1375
|
}).on("highlight", async (event) => {
|
|
1291
|
-
const el = await this.getElementFromPoint(event
|
|
1376
|
+
const el = await this.getElementFromPoint(event);
|
|
1292
1377
|
if (!el)
|
|
1293
1378
|
return;
|
|
1294
1379
|
await this.highlight(el);
|
|
@@ -1303,9 +1388,6 @@ class StageCore extends EventEmitter {
|
|
|
1303
1388
|
const el = await this.getElementFromPoint(event);
|
|
1304
1389
|
if (!el)
|
|
1305
1390
|
return;
|
|
1306
|
-
if (el.className.includes(PAGE_CLASS))
|
|
1307
|
-
return;
|
|
1308
|
-
this.clearSelectStatus("select");
|
|
1309
1391
|
if (this.selectedDom && !this.selectedDom.className.includes(PAGE_CLASS)) {
|
|
1310
1392
|
this.selectedDomList.push(this.selectedDom);
|
|
1311
1393
|
this.selectedDom = void 0;
|
|
@@ -1316,8 +1398,7 @@ class StageCore extends EventEmitter {
|
|
|
1316
1398
|
} else {
|
|
1317
1399
|
this.selectedDomList.push(el);
|
|
1318
1400
|
}
|
|
1319
|
-
this.
|
|
1320
|
-
this.emit("multiSelect", this.selectedDomList);
|
|
1401
|
+
this.multiSelect(this.selectedDomList);
|
|
1321
1402
|
});
|
|
1322
1403
|
this.dr.on("update", (data) => {
|
|
1323
1404
|
setTimeout(() => this.emit("update", data));
|
|
@@ -1342,22 +1423,29 @@ class StageCore extends EventEmitter {
|
|
|
1342
1423
|
}
|
|
1343
1424
|
return doc?.elementsFromPoint(x / zoom, y / zoom);
|
|
1344
1425
|
}
|
|
1345
|
-
async getElementFromPoint(event
|
|
1426
|
+
async getElementFromPoint(event) {
|
|
1346
1427
|
const els = this.getElementsFromPoint(event);
|
|
1347
1428
|
let stopped = false;
|
|
1348
1429
|
const stop = () => stopped = true;
|
|
1349
1430
|
for (const el of els) {
|
|
1350
|
-
if (!el.id.startsWith(GHOST_EL_ID_PREFIX) && await this.
|
|
1431
|
+
if (!el.id.startsWith(GHOST_EL_ID_PREFIX) && await this.isElCanSelect(el, event, stop)) {
|
|
1351
1432
|
if (stopped)
|
|
1352
1433
|
break;
|
|
1353
|
-
if (event.type === type) {
|
|
1354
|
-
return el;
|
|
1355
|
-
}
|
|
1356
1434
|
return el;
|
|
1357
1435
|
}
|
|
1358
1436
|
}
|
|
1359
1437
|
}
|
|
1438
|
+
async isElCanSelect(el, event, stop) {
|
|
1439
|
+
const canSelectByProp = await this.canSelect(el, event, stop);
|
|
1440
|
+
if (!canSelectByProp)
|
|
1441
|
+
return false;
|
|
1442
|
+
if (this.mask.isMultiSelectStatus) {
|
|
1443
|
+
return this.multiDr.canSelect(el);
|
|
1444
|
+
}
|
|
1445
|
+
return true;
|
|
1446
|
+
}
|
|
1360
1447
|
async select(idOrEl, event) {
|
|
1448
|
+
this.clearSelectStatus("multiSelect");
|
|
1361
1449
|
const el = await this.getTargetElement(idOrEl);
|
|
1362
1450
|
if (el === this.selectedDom)
|
|
1363
1451
|
return;
|
|
@@ -1367,7 +1455,6 @@ class StageCore extends EventEmitter {
|
|
|
1367
1455
|
await runtime.beforeSelect(el);
|
|
1368
1456
|
}
|
|
1369
1457
|
this.mask.setLayout(el);
|
|
1370
|
-
this.multiDr.destroyDragElList();
|
|
1371
1458
|
this.dr.select(el, event);
|
|
1372
1459
|
if (this.config.autoScrollIntoView || el.dataset.autoScrollIntoView) {
|
|
1373
1460
|
this.mask.intersectionObserver?.observe(el);
|
|
@@ -1380,6 +1467,12 @@ class StageCore extends EventEmitter {
|
|
|
1380
1467
|
}
|
|
1381
1468
|
}
|
|
1382
1469
|
}
|
|
1470
|
+
async multiSelect(idOrElList) {
|
|
1471
|
+
this.clearSelectStatus("select");
|
|
1472
|
+
const elList = await Promise.all(idOrElList.map(async (idOrEl) => await this.getTargetElement(idOrEl)));
|
|
1473
|
+
this.multiDr.multiSelect(elList);
|
|
1474
|
+
this.emit("multiSelect", elList);
|
|
1475
|
+
}
|
|
1383
1476
|
update(data) {
|
|
1384
1477
|
const { config } = data;
|
|
1385
1478
|
return this.renderer?.getRuntime().then((runtime) => {
|
|
@@ -1476,5 +1569,5 @@ class StageCore extends EventEmitter {
|
|
|
1476
1569
|
}
|
|
1477
1570
|
}
|
|
1478
1571
|
|
|
1479
|
-
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, getAbsolutePosition, getMode, getOffset, getScrollParent, getTargetElStyle, isAbsolute, isFixed, isFixedParent, isRelative, isStatic, removeSelectedClassName };
|
|
1480
|
-
//# sourceMappingURL=tmagic-stage.
|
|
1572
|
+
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 };
|
|
1573
|
+
//# sourceMappingURL=tmagic-stage.mjs.map
|