@tmagic/stage 1.1.0-beta.4 → 1.1.0-beta.7

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.
@@ -4,13 +4,13 @@
4
4
  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.TMagicStage = {}, global.EventEmitter, global.utils, global.Moveable, global.MoveableHelper, global.KeyController, global.lodashEs, global.Guides));
5
5
  })(this, (function (exports, EventEmitter, utils, Moveable, MoveableHelper, KeyController, lodashEs, Guides) { 'use strict';
6
6
 
7
- function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
7
+ const _interopDefaultLegacy = e => e && typeof e === 'object' && 'default' in e ? e : { default: e };
8
8
 
9
- var EventEmitter__default = /*#__PURE__*/_interopDefaultLegacy(EventEmitter);
10
- var Moveable__default = /*#__PURE__*/_interopDefaultLegacy(Moveable);
11
- var MoveableHelper__default = /*#__PURE__*/_interopDefaultLegacy(MoveableHelper);
12
- var KeyController__default = /*#__PURE__*/_interopDefaultLegacy(KeyController);
13
- var Guides__default = /*#__PURE__*/_interopDefaultLegacy(Guides);
9
+ const EventEmitter__default = /*#__PURE__*/_interopDefaultLegacy(EventEmitter);
10
+ const Moveable__default = /*#__PURE__*/_interopDefaultLegacy(Moveable);
11
+ const MoveableHelper__default = /*#__PURE__*/_interopDefaultLegacy(MoveableHelper);
12
+ const KeyController__default = /*#__PURE__*/_interopDefaultLegacy(KeyController);
13
+ const Guides__default = /*#__PURE__*/_interopDefaultLegacy(Guides);
14
14
 
15
15
  const GHOST_EL_ID_PREFIX = "ghost_el_";
16
16
  const DRAG_EL_ID_PREFIX = "drag_el_";
@@ -210,14 +210,22 @@
210
210
  };
211
211
 
212
212
  class StageDragResize extends EventEmitter.EventEmitter {
213
+ core;
214
+ mask;
215
+ container;
216
+ target;
217
+ dragEl;
218
+ moveable;
219
+ horizontalGuidelines = [];
220
+ verticalGuidelines = [];
221
+ elementGuidelines = [];
222
+ mode = Mode.ABSOLUTE;
223
+ moveableOptions = {};
224
+ dragStatus = "end" /* END */;
225
+ ghostEl;
226
+ moveableHelper;
213
227
  constructor(config) {
214
228
  super();
215
- this.horizontalGuidelines = [];
216
- this.verticalGuidelines = [];
217
- this.elementGuidelines = [];
218
- this.mode = Mode.ABSOLUTE;
219
- this.moveableOptions = {};
220
- this.dragStatus = "end" /* END */;
221
229
  this.core = config.core;
222
230
  this.container = config.container;
223
231
  this.mask = config.mask;
@@ -227,7 +235,7 @@
227
235
  this.target = el;
228
236
  if (!this.moveable || this.target !== oldTarget) {
229
237
  this.init(el);
230
- this.moveableHelper = MoveableHelper__default["default"].create({
238
+ this.moveableHelper = MoveableHelper__default.default.create({
231
239
  useBeforeRender: true,
232
240
  useRender: false,
233
241
  createAuto: true
@@ -331,7 +339,7 @@
331
339
  }
332
340
  initMoveable() {
333
341
  this.moveable?.destroy();
334
- this.moveable = new Moveable__default["default"](this.container, {
342
+ this.moveable = new Moveable__default.default(this.container, {
335
343
  ...this.moveableOptions
336
344
  });
337
345
  this.bindResizeEvent();
@@ -543,7 +551,7 @@
543
551
  return ghostEl;
544
552
  }
545
553
  setGhostElChildrenId(el) {
546
- for (const child of el.children) {
554
+ for (const child of Array.from(el.children)) {
547
555
  if (child.id) {
548
556
  child.id = `${GHOST_EL_ID_PREFIX}${child.id}`;
549
557
  }
@@ -617,6 +625,11 @@
617
625
  }
618
626
 
619
627
  class TargetCalibrate extends EventEmitter.EventEmitter {
628
+ parent;
629
+ mask;
630
+ dr;
631
+ core;
632
+ operationEl;
620
633
  constructor(config) {
621
634
  super();
622
635
  this.parent = config.parent;
@@ -636,6 +649,7 @@
636
649
  top: ${top}px;
637
650
  width: ${el.clientWidth}px;
638
651
  height: ${el.clientHeight}px;
652
+ z-index: ${ZIndex.DRAG_EL};
639
653
  `;
640
654
  this.operationEl.id = `${prefix}${el.id}`;
641
655
  if (typeof this.core.config.updateDragEl === "function") {
@@ -683,6 +697,11 @@
683
697
  }
684
698
 
685
699
  class StageHighlight extends EventEmitter.EventEmitter {
700
+ core;
701
+ container;
702
+ target;
703
+ moveable;
704
+ calibrationTarget;
686
705
  constructor(config) {
687
706
  super();
688
707
  this.core = config.core;
@@ -699,11 +718,11 @@
699
718
  return;
700
719
  this.target = el;
701
720
  this.moveable?.destroy();
702
- this.moveable = new Moveable__default["default"](this.container, {
721
+ this.moveable = new Moveable__default.default(this.container, {
703
722
  target: this.calibrationTarget.update(el, HIGHLIGHT_EL_ID_PREFIX),
704
723
  origin: false,
705
724
  rootContainer: this.core.container,
706
- zoom: 1
725
+ zoom: 2
707
726
  });
708
727
  }
709
728
  clearHighlight() {
@@ -719,42 +738,15 @@
719
738
  }
720
739
  }
721
740
 
722
- class Rule extends EventEmitter__default["default"] {
741
+ class Rule extends EventEmitter__default.default {
742
+ hGuides;
743
+ vGuides;
744
+ horizontalGuidelines = [];
745
+ verticalGuidelines = [];
746
+ container;
747
+ containerResizeObserver;
723
748
  constructor(container) {
724
749
  super();
725
- this.horizontalGuidelines = [];
726
- this.verticalGuidelines = [];
727
- this.getGuidesStyle = (type) => ({
728
- position: "fixed",
729
- zIndex: 1,
730
- left: type === GuidesType.HORIZONTAL ? 0 : "-30px",
731
- top: type === GuidesType.HORIZONTAL ? "-30px" : 0,
732
- width: type === GuidesType.HORIZONTAL ? "100%" : "30px",
733
- height: type === GuidesType.HORIZONTAL ? "30px" : "100%"
734
- });
735
- this.createGuides = (type, defaultGuides = []) => new Guides__default["default"](this.container, {
736
- type,
737
- defaultGuides,
738
- displayDragPos: true,
739
- backgroundColor: "#fff",
740
- lineColor: "#000",
741
- textColor: "#000",
742
- style: this.getGuidesStyle(type)
743
- });
744
- this.hGuidesChangeGuidesHandler = (e) => {
745
- this.horizontalGuidelines = e.guides;
746
- this.emit("changeGuides", {
747
- type: GuidesType.HORIZONTAL,
748
- guides: this.horizontalGuidelines
749
- });
750
- };
751
- this.vGuidesChangeGuidesHandler = (e) => {
752
- this.verticalGuidelines = e.guides;
753
- this.emit("changeGuides", {
754
- type: GuidesType.VERTICAL,
755
- guides: this.verticalGuidelines
756
- });
757
- };
758
750
  this.container = container;
759
751
  this.hGuides = this.createGuides(GuidesType.HORIZONTAL, this.horizontalGuidelines);
760
752
  this.vGuides = this.createGuides(GuidesType.VERTICAL, this.verticalGuidelines);
@@ -826,6 +818,37 @@
826
818
  this.containerResizeObserver.disconnect();
827
819
  this.removeAllListeners();
828
820
  }
821
+ getGuidesStyle = (type) => ({
822
+ position: "fixed",
823
+ zIndex: 1,
824
+ left: type === GuidesType.HORIZONTAL ? 0 : "-30px",
825
+ top: type === GuidesType.HORIZONTAL ? "-30px" : 0,
826
+ width: type === GuidesType.HORIZONTAL ? "100%" : "30px",
827
+ height: type === GuidesType.HORIZONTAL ? "30px" : "100%"
828
+ });
829
+ createGuides = (type, defaultGuides = []) => new Guides__default.default(this.container, {
830
+ type,
831
+ defaultGuides,
832
+ displayDragPos: true,
833
+ backgroundColor: "#fff",
834
+ lineColor: "#000",
835
+ textColor: "#000",
836
+ style: this.getGuidesStyle(type)
837
+ });
838
+ hGuidesChangeGuidesHandler = (e) => {
839
+ this.horizontalGuidelines = e.guides;
840
+ this.emit("changeGuides", {
841
+ type: GuidesType.HORIZONTAL,
842
+ guides: this.horizontalGuidelines
843
+ });
844
+ };
845
+ vGuidesChangeGuidesHandler = (e) => {
846
+ this.verticalGuidelines = e.guides;
847
+ this.emit("changeGuides", {
848
+ type: GuidesType.VERTICAL,
849
+ guides: this.verticalGuidelines
850
+ });
851
+ };
829
852
  }
830
853
 
831
854
  const wrapperClassName = "editor-mask-wrapper";
@@ -859,74 +882,30 @@
859
882
  return el;
860
883
  };
861
884
  class StageMask extends Rule {
885
+ content = createContent();
886
+ wrapper;
887
+ core;
888
+ page = null;
889
+ pageScrollParent = null;
890
+ scrollTop = 0;
891
+ scrollLeft = 0;
892
+ width = 0;
893
+ height = 0;
894
+ wrapperHeight = 0;
895
+ wrapperWidth = 0;
896
+ maxScrollTop = 0;
897
+ maxScrollLeft = 0;
898
+ intersectionObserver = null;
899
+ isMultiSelectStatus = false;
900
+ mode = Mode.ABSOLUTE;
901
+ pageResizeObserver = null;
902
+ wrapperResizeObserver = null;
903
+ highlightHandler = lodashEs.throttle((event) => {
904
+ this.emit("highlight", event);
905
+ }, throttleTime);
862
906
  constructor(config) {
863
907
  const wrapper = createWrapper();
864
908
  super(wrapper);
865
- this.content = createContent();
866
- this.page = null;
867
- this.pageScrollParent = null;
868
- this.scrollTop = 0;
869
- this.scrollLeft = 0;
870
- this.width = 0;
871
- this.height = 0;
872
- this.wrapperHeight = 0;
873
- this.wrapperWidth = 0;
874
- this.maxScrollTop = 0;
875
- this.maxScrollLeft = 0;
876
- this.intersectionObserver = null;
877
- this.shiftKeyDown = false;
878
- this.mode = Mode.ABSOLUTE;
879
- this.pageResizeObserver = null;
880
- this.wrapperResizeObserver = null;
881
- this.highlightHandler = lodashEs.throttle((event) => {
882
- this.emit("highlight", event);
883
- }, throttleTime);
884
- this.mouseDownHandler = (event) => {
885
- this.emit("clearHighlight");
886
- event.stopImmediatePropagation();
887
- event.stopPropagation();
888
- if (event.button !== MouseButton.LEFT && event.button !== MouseButton.RIGHT)
889
- return;
890
- if (!this.shiftKeyDown && event.target.className.indexOf("moveable-area") !== -1) {
891
- return;
892
- }
893
- if (event.target.className.indexOf("moveable-control") !== -1) {
894
- return;
895
- }
896
- this.content.removeEventListener("mousemove", this.highlightHandler);
897
- if (this.shiftKeyDown) {
898
- this.emit("beforeMultiSelect", event);
899
- } else {
900
- this.emit("beforeSelect", event);
901
- globalThis.document.addEventListener("mouseup", this.mouseUpHandler);
902
- }
903
- };
904
- this.mouseUpHandler = () => {
905
- globalThis.document.removeEventListener("mouseup", this.mouseUpHandler);
906
- this.content.addEventListener("mousemove", this.highlightHandler);
907
- this.emit("select");
908
- };
909
- this.mouseWheelHandler = (event) => {
910
- this.emit("clearHighlight");
911
- if (!this.page)
912
- throw new Error("page \u672A\u521D\u59CB\u5316");
913
- const { deltaY, deltaX } = event;
914
- if (this.page.clientHeight < this.wrapperHeight && deltaY)
915
- return;
916
- if (this.page.clientWidth < this.wrapperWidth && deltaX)
917
- return;
918
- if (this.maxScrollTop > 0) {
919
- this.scrollTop = this.scrollTop + deltaY;
920
- }
921
- if (this.maxScrollLeft > 0) {
922
- this.scrollLeft = this.scrollLeft + deltaX;
923
- }
924
- this.scroll();
925
- this.emit("scroll", event);
926
- };
927
- this.mouseLeaveHandler = () => {
928
- setTimeout(() => this.emit("clearHighlight"), throttleTime);
929
- };
930
909
  this.wrapper = wrapper;
931
910
  this.core = config.core;
932
911
  this.content.addEventListener("mousedown", this.mouseDownHandler);
@@ -934,13 +913,15 @@
934
913
  this.content.addEventListener("wheel", this.mouseWheelHandler);
935
914
  this.content.addEventListener("mousemove", this.highlightHandler);
936
915
  this.content.addEventListener("mouseleave", this.mouseLeaveHandler);
937
- KeyController__default["default"].global.keydown("shift", (e) => {
916
+ const isMac = /mac os x/.test(navigator.userAgent.toLowerCase());
917
+ const ctrl = isMac ? "meta" : "ctrl";
918
+ KeyController__default.default.global.keydown(ctrl, (e) => {
938
919
  e.inputEvent.preventDefault();
939
- this.shiftKeyDown = true;
920
+ this.isMultiSelectStatus = true;
940
921
  });
941
- KeyController__default["default"].global.keyup("shift", (e) => {
922
+ KeyController__default.default.global.keyup(ctrl, (e) => {
942
923
  e.inputEvent.preventDefault();
943
- this.shiftKeyDown = false;
924
+ this.isMultiSelectStatus = false;
944
925
  });
945
926
  }
946
927
  setMode(mode) {
@@ -1070,13 +1051,66 @@
1070
1051
  if (this.maxScrollLeft < this.scrollLeft)
1071
1052
  this.scrollLeft = this.maxScrollLeft;
1072
1053
  }
1054
+ mouseDownHandler = (event) => {
1055
+ this.emit("clearHighlight");
1056
+ event.stopImmediatePropagation();
1057
+ event.stopPropagation();
1058
+ if (event.button !== MouseButton.LEFT && event.button !== MouseButton.RIGHT)
1059
+ return;
1060
+ if (!this.isMultiSelectStatus && event.target.className.indexOf("moveable-area") !== -1) {
1061
+ return;
1062
+ }
1063
+ if (event.target.className.indexOf("moveable-control") !== -1) {
1064
+ return;
1065
+ }
1066
+ this.content.removeEventListener("mousemove", this.highlightHandler);
1067
+ if (this.isMultiSelectStatus) {
1068
+ this.emit("beforeMultiSelect", event);
1069
+ } else {
1070
+ this.emit("beforeSelect", event);
1071
+ }
1072
+ globalThis.document.addEventListener("mouseup", this.mouseUpHandler);
1073
+ };
1074
+ mouseUpHandler = () => {
1075
+ globalThis.document.removeEventListener("mouseup", this.mouseUpHandler);
1076
+ this.content.addEventListener("mousemove", this.highlightHandler);
1077
+ if (!this.isMultiSelectStatus) {
1078
+ this.emit("select");
1079
+ }
1080
+ };
1081
+ mouseWheelHandler = (event) => {
1082
+ this.emit("clearHighlight");
1083
+ if (!this.page)
1084
+ throw new Error("page \u672A\u521D\u59CB\u5316");
1085
+ const { deltaY, deltaX } = event;
1086
+ if (this.page.clientHeight < this.wrapperHeight && deltaY)
1087
+ return;
1088
+ if (this.page.clientWidth < this.wrapperWidth && deltaX)
1089
+ return;
1090
+ if (this.maxScrollTop > 0) {
1091
+ this.scrollTop = this.scrollTop + deltaY;
1092
+ }
1093
+ if (this.maxScrollLeft > 0) {
1094
+ this.scrollLeft = this.scrollLeft + deltaX;
1095
+ }
1096
+ this.scroll();
1097
+ this.emit("scroll", event);
1098
+ };
1099
+ mouseLeaveHandler = () => {
1100
+ setTimeout(() => this.emit("clearHighlight"), throttleTime);
1101
+ };
1073
1102
  }
1074
1103
 
1075
1104
  class StageMultiDragResize extends EventEmitter.EventEmitter {
1105
+ core;
1106
+ mask;
1107
+ container;
1108
+ targetList = [];
1109
+ dragElList = [];
1110
+ moveableForMulti;
1111
+ multiMoveableHelper;
1076
1112
  constructor(config) {
1077
1113
  super();
1078
- this.targetList = [];
1079
- this.dragElList = [];
1080
1114
  this.core = config.core;
1081
1115
  this.container = config.container;
1082
1116
  this.mask = config.mask;
@@ -1097,20 +1131,10 @@
1097
1131
  });
1098
1132
  this.moveableForMulti?.destroy();
1099
1133
  this.multiMoveableHelper?.clear();
1100
- this.moveableForMulti = new Moveable__default["default"](this.container, {
1101
- target: this.dragElList,
1102
- defaultGroupRotate: 0,
1103
- defaultGroupOrigin: "50% 50%",
1104
- draggable: true,
1105
- resizable: true,
1106
- throttleDrag: 0,
1107
- startDragRotate: 0,
1108
- throttleDragRotate: 0,
1109
- zoom: 1,
1110
- origin: true,
1111
- padding: { left: 0, top: 0, right: 0, bottom: 0 }
1112
- });
1113
- this.multiMoveableHelper = MoveableHelper__default["default"].create({
1134
+ this.moveableForMulti = new Moveable__default.default(this.container, this.getOptions({
1135
+ target: this.dragElList
1136
+ }));
1137
+ this.multiMoveableHelper = MoveableHelper__default.default.create({
1114
1138
  useBeforeRender: true,
1115
1139
  useRender: false,
1116
1140
  createAuto: true
@@ -1149,12 +1173,35 @@
1149
1173
  this.update();
1150
1174
  });
1151
1175
  }
1176
+ canSelect(el, stop) {
1177
+ if (el.className.includes(PAGE_CLASS)) {
1178
+ this.core.highlightedDom = void 0;
1179
+ this.core.highlightLayer.clearHighlight();
1180
+ stop();
1181
+ return false;
1182
+ }
1183
+ const currentTargetMode = getMode(el);
1184
+ let selectedDomMode = "";
1185
+ if (this.core.selectedDom?.className.includes(PAGE_CLASS)) {
1186
+ return true;
1187
+ }
1188
+ if (this.targetList.length === 0 && this.core.selectedDom) {
1189
+ selectedDomMode = getMode(this.core.selectedDom);
1190
+ } else if (this.targetList.length > 0) {
1191
+ selectedDomMode = getMode(this.targetList[0]);
1192
+ }
1193
+ if (currentTargetMode !== selectedDomMode) {
1194
+ return false;
1195
+ }
1196
+ return true;
1197
+ }
1152
1198
  clearSelectStatus() {
1153
1199
  if (!this.moveableForMulti)
1154
1200
  return;
1155
1201
  this.destroyDragElList();
1156
1202
  this.moveableForMulti.target = null;
1157
1203
  this.moveableForMulti.updateTarget();
1204
+ this.targetList = [];
1158
1205
  }
1159
1206
  destroy() {
1160
1207
  this.moveableForMulti?.destroy();
@@ -1182,49 +1229,39 @@
1182
1229
  });
1183
1230
  });
1184
1231
  }
1232
+ getOptions(options = {}) {
1233
+ let { multiMoveableOptions = {} } = this.core.config;
1234
+ if (typeof multiMoveableOptions === "function") {
1235
+ multiMoveableOptions = multiMoveableOptions(this.core);
1236
+ }
1237
+ return {
1238
+ defaultGroupRotate: 0,
1239
+ defaultGroupOrigin: "50% 50%",
1240
+ draggable: true,
1241
+ resizable: true,
1242
+ throttleDrag: 0,
1243
+ startDragRotate: 0,
1244
+ throttleDragRotate: 0,
1245
+ zoom: 1,
1246
+ origin: true,
1247
+ padding: { left: 0, top: 0, right: 0, bottom: 0 },
1248
+ ...options,
1249
+ ...multiMoveableOptions
1250
+ };
1251
+ }
1185
1252
  }
1186
1253
 
1187
- 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";
1254
+ 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";
1188
1255
 
1189
1256
  class StageRender extends EventEmitter.EventEmitter {
1257
+ contentWindow = null;
1258
+ runtime = null;
1259
+ iframe;
1260
+ runtimeUrl;
1261
+ core;
1262
+ render;
1190
1263
  constructor({ core }) {
1191
1264
  super();
1192
- this.contentWindow = null;
1193
- this.runtime = null;
1194
- this.getMagicApi = () => ({
1195
- onPageElUpdate: (el) => this.emit("page-el-update", el),
1196
- onRuntimeReady: (runtime) => {
1197
- this.runtime = runtime;
1198
- globalThis.runtime = runtime;
1199
- this.emit("runtime-ready", runtime);
1200
- }
1201
- });
1202
- this.getRuntime = () => {
1203
- if (this.runtime)
1204
- return Promise.resolve(this.runtime);
1205
- return new Promise((resolve) => {
1206
- const listener = (runtime) => {
1207
- this.off("runtime-ready", listener);
1208
- resolve(runtime);
1209
- };
1210
- this.on("runtime-ready", listener);
1211
- });
1212
- };
1213
- this.loadHandler = async () => {
1214
- this.contentWindow = this.iframe?.contentWindow;
1215
- this.contentWindow.magic = this.getMagicApi();
1216
- if (this.render) {
1217
- const el = await this.render(this.core);
1218
- if (el) {
1219
- this.iframe?.contentDocument?.body?.appendChild(el);
1220
- }
1221
- }
1222
- this.emit("onload");
1223
- this.contentWindow.postMessage({
1224
- tmagicRuntimeReady: true
1225
- }, "*");
1226
- utils.injectStyle(this.contentWindow.document, style);
1227
- };
1228
1265
  this.core = core;
1229
1266
  this.runtimeUrl = core.config.runtimeUrl || "";
1230
1267
  this.render = core.config.render;
@@ -1237,20 +1274,39 @@
1237
1274
  `;
1238
1275
  this.iframe.addEventListener("load", this.loadHandler);
1239
1276
  }
1277
+ getMagicApi = () => ({
1278
+ onPageElUpdate: (el) => this.emit("page-el-update", el),
1279
+ onRuntimeReady: (runtime) => {
1280
+ this.runtime = runtime;
1281
+ globalThis.runtime = runtime;
1282
+ this.emit("runtime-ready", runtime);
1283
+ }
1284
+ });
1240
1285
  async mount(el) {
1241
- if (this.iframe) {
1242
- if (!utils.isSameDomain(this.runtimeUrl) && this.runtimeUrl) {
1243
- let html = await fetch(this.runtimeUrl).then((res) => res.text());
1244
- const base = `${location.protocol}//${utils.getHost(this.runtimeUrl)}`;
1245
- html = html.replace("<head>", `<head>
1246
- <base href="${base}">`);
1247
- this.iframe.srcdoc = html;
1248
- }
1249
- el.appendChild(this.iframe);
1250
- } else {
1286
+ if (!this.iframe) {
1251
1287
  throw Error("mount \u5931\u8D25");
1252
1288
  }
1253
- }
1289
+ if (!utils.isSameDomain(this.runtimeUrl) && this.runtimeUrl) {
1290
+ let html = await fetch(this.runtimeUrl).then((res) => res.text());
1291
+ const base = `${location.protocol}//${utils.getHost(this.runtimeUrl)}`;
1292
+ html = html.replace("<head>", `<head>
1293
+ <base href="${base}">`);
1294
+ this.iframe.srcdoc = html;
1295
+ }
1296
+ el.appendChild(this.iframe);
1297
+ this.postTmagicRuntimeReady();
1298
+ }
1299
+ getRuntime = () => {
1300
+ if (this.runtime)
1301
+ return Promise.resolve(this.runtime);
1302
+ return new Promise((resolve) => {
1303
+ const listener = (runtime) => {
1304
+ this.off("runtime-ready", listener);
1305
+ resolve(runtime);
1306
+ };
1307
+ this.on("runtime-ready", listener);
1308
+ });
1309
+ };
1254
1310
  destroy() {
1255
1311
  this.iframe?.removeEventListener("load", this.loadHandler);
1256
1312
  this.contentWindow = null;
@@ -1258,13 +1314,48 @@
1258
1314
  this.iframe = void 0;
1259
1315
  this.removeAllListeners();
1260
1316
  }
1317
+ loadHandler = async () => {
1318
+ if (!this.contentWindow?.magic) {
1319
+ this.postTmagicRuntimeReady();
1320
+ }
1321
+ if (!this.contentWindow)
1322
+ return;
1323
+ if (this.render) {
1324
+ const el = await this.render(this.core);
1325
+ if (el) {
1326
+ this.contentWindow.document?.body?.appendChild(el);
1327
+ }
1328
+ }
1329
+ this.emit("onload");
1330
+ utils.injectStyle(this.contentWindow.document, style);
1331
+ };
1332
+ postTmagicRuntimeReady() {
1333
+ this.contentWindow = this.iframe?.contentWindow;
1334
+ this.contentWindow.magic = this.getMagicApi();
1335
+ this.contentWindow.postMessage({
1336
+ tmagicRuntimeReady: true
1337
+ }, "*");
1338
+ }
1261
1339
  }
1262
1340
 
1263
1341
  class StageCore extends EventEmitter.EventEmitter {
1342
+ container;
1343
+ selectedDom;
1344
+ selectedDomList = [];
1345
+ highlightedDom;
1346
+ renderer;
1347
+ mask;
1348
+ dr;
1349
+ multiDr;
1350
+ highlightLayer;
1351
+ config;
1352
+ zoom = DEFAULT_ZOOM;
1353
+ containerHighlightClassName;
1354
+ containerHighlightDuration;
1355
+ isContainer;
1356
+ canSelect;
1264
1357
  constructor(config) {
1265
1358
  super();
1266
- this.selectedDomList = [];
1267
- this.zoom = DEFAULT_ZOOM;
1268
1359
  this.config = config;
1269
1360
  this.setZoom(config.zoom);
1270
1361
  this.canSelect = config.canSelect || ((el) => !!el.id);
@@ -1294,7 +1385,7 @@
1294
1385
  this.dr.setGuidelines(data.type, data.guides);
1295
1386
  this.emit("changeGuides", data);
1296
1387
  }).on("highlight", async (event) => {
1297
- const el = await this.getElementFromPoint(event, "mousemove");
1388
+ const el = await this.getElementFromPoint(event);
1298
1389
  if (!el)
1299
1390
  return;
1300
1391
  await this.highlight(el);
@@ -1309,9 +1400,6 @@
1309
1400
  const el = await this.getElementFromPoint(event);
1310
1401
  if (!el)
1311
1402
  return;
1312
- if (el.className.includes(PAGE_CLASS))
1313
- return;
1314
- this.clearSelectStatus("select");
1315
1403
  if (this.selectedDom && !this.selectedDom.className.includes(PAGE_CLASS)) {
1316
1404
  this.selectedDomList.push(this.selectedDom);
1317
1405
  this.selectedDom = void 0;
@@ -1322,8 +1410,7 @@
1322
1410
  } else {
1323
1411
  this.selectedDomList.push(el);
1324
1412
  }
1325
- this.multiDr.multiSelect(this.selectedDomList);
1326
- this.emit("multiSelect", this.selectedDomList);
1413
+ this.multiSelect(this.selectedDomList);
1327
1414
  });
1328
1415
  this.dr.on("update", (data) => {
1329
1416
  setTimeout(() => this.emit("update", data));
@@ -1348,22 +1435,29 @@
1348
1435
  }
1349
1436
  return doc?.elementsFromPoint(x / zoom, y / zoom);
1350
1437
  }
1351
- async getElementFromPoint(event, type) {
1438
+ async getElementFromPoint(event) {
1352
1439
  const els = this.getElementsFromPoint(event);
1353
1440
  let stopped = false;
1354
1441
  const stop = () => stopped = true;
1355
1442
  for (const el of els) {
1356
- if (!el.id.startsWith(GHOST_EL_ID_PREFIX) && await this.canSelect(el, event, stop)) {
1443
+ if (!el.id.startsWith(GHOST_EL_ID_PREFIX) && await this.isElCanSelect(el, event, stop)) {
1357
1444
  if (stopped)
1358
1445
  break;
1359
- if (event.type === type) {
1360
- return el;
1361
- }
1362
1446
  return el;
1363
1447
  }
1364
1448
  }
1365
1449
  }
1450
+ async isElCanSelect(el, event, stop) {
1451
+ const canSelectByProp = await this.canSelect(el, event, stop);
1452
+ if (!canSelectByProp)
1453
+ return false;
1454
+ if (this.mask.isMultiSelectStatus) {
1455
+ return this.multiDr.canSelect(el, stop);
1456
+ }
1457
+ return true;
1458
+ }
1366
1459
  async select(idOrEl, event) {
1460
+ this.clearSelectStatus("multiSelect");
1367
1461
  const el = await this.getTargetElement(idOrEl);
1368
1462
  if (el === this.selectedDom)
1369
1463
  return;
@@ -1373,7 +1467,6 @@
1373
1467
  await runtime.beforeSelect(el);
1374
1468
  }
1375
1469
  this.mask.setLayout(el);
1376
- this.multiDr.destroyDragElList();
1377
1470
  this.dr.select(el, event);
1378
1471
  if (this.config.autoScrollIntoView || el.dataset.autoScrollIntoView) {
1379
1472
  this.mask.intersectionObserver?.observe(el);
@@ -1386,6 +1479,12 @@
1386
1479
  }
1387
1480
  }
1388
1481
  }
1482
+ async multiSelect(idOrElList) {
1483
+ this.clearSelectStatus("select");
1484
+ const elList = await Promise.all(idOrElList.map(async (idOrEl) => await this.getTargetElement(idOrEl)));
1485
+ this.multiDr.multiSelect(elList);
1486
+ this.emit("multiSelect", elList);
1487
+ }
1389
1488
  update(data) {
1390
1489
  const { config } = data;
1391
1490
  return this.renderer?.getRuntime().then((runtime) => {
@@ -1498,7 +1597,7 @@
1498
1597
  exports.ZIndex = ZIndex;
1499
1598
  exports.addSelectedClassName = addSelectedClassName;
1500
1599
  exports.calcValueByFontsize = calcValueByFontsize;
1501
- exports["default"] = StageCore;
1600
+ exports.default = StageCore;
1502
1601
  exports.down = down;
1503
1602
  exports.getAbsolutePosition = getAbsolutePosition;
1504
1603
  exports.getMode = getMode;