@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.
@@ -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: 1
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.shiftKeyDown = true;
912
+ this.isMultiSelectStatus = true;
934
913
  });
935
914
  KeyController.global.keyup("shift", (e) => {
936
915
  e.inputEvent.preventDefault();
937
- this.shiftKeyDown = false;
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
- defaultGroupRotate: 0,
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
- 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}\n";
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, "mousemove");
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.multiDr.multiSelect(this.selectedDomList);
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, type) {
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.canSelect(el, event, stop)) {
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.es.js.map
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