@tmagic/editor 1.5.0-beta.2 → 1.5.0-beta.3

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.
@@ -1012,11 +1012,14 @@ const getMiddleTop = (node, parentNode, stage) => {
1012
1012
  height = 0;
1013
1013
  }
1014
1014
  const { height: parentHeight } = parentNode.style;
1015
- const { scrollTop = 0, wrapperHeight } = stage.mask;
1016
- const wrapperHeightDeal = calcValueByFontsize(stage.renderer.getDocument(), wrapperHeight);
1017
- const scrollTopDeal = calcValueByFontsize(stage.renderer.getDocument(), scrollTop);
1018
- if (isPage(parentNode)) {
1019
- return (wrapperHeightDeal - height) / 2 + scrollTopDeal;
1015
+ let wrapperHeightDeal = parentHeight;
1016
+ if (stage.mask && stage.renderer) {
1017
+ const { scrollTop = 0, wrapperHeight } = stage.mask;
1018
+ wrapperHeightDeal = calcValueByFontsize(stage.renderer.getDocument(), wrapperHeight);
1019
+ const scrollTopDeal = calcValueByFontsize(stage.renderer.getDocument(), scrollTop);
1020
+ if (isPage(parentNode)) {
1021
+ return (wrapperHeightDeal - height) / 2 + scrollTopDeal;
1022
+ }
1020
1023
  }
1021
1024
  return (Math.min(parentHeight, wrapperHeightDeal) - height) / 2;
1022
1025
  };
@@ -1131,7 +1134,7 @@ const fixNodePosition = (config, parent, stage) => {
1131
1134
  return {
1132
1135
  ...config.style || {},
1133
1136
  top: getMiddleTop(config, parent, stage),
1134
- left: fixNodeLeft(config, parent, stage?.renderer.contentWindow?.document)
1137
+ left: fixNodeLeft(config, parent, stage?.renderer?.contentWindow?.document)
1135
1138
  };
1136
1139
  };
1137
1140
  const serializeConfig = (config) => serialize(config, {
@@ -1940,7 +1943,7 @@ class Editor extends BaseService {
1940
1943
  historyService.resetState();
1941
1944
  }
1942
1945
  if (node?.id) {
1943
- this.get("stage")?.renderer.runtime?.getApp?.()?.page?.emit(
1946
+ this.get("stage")?.renderer?.runtime?.getApp?.()?.page?.emit(
1944
1947
  "editor:select",
1945
1948
  {
1946
1949
  node,
@@ -2294,7 +2297,7 @@ class Editor extends BaseService {
2294
2297
  }
2295
2298
  async doPaste(config, position = {}) {
2296
2299
  propsService.clearRelateId();
2297
- const doc = this.get("stage")?.renderer.contentWindow?.document;
2300
+ const doc = this.get("stage")?.renderer?.contentWindow?.document;
2298
2301
  const pasteConfigs = beforePaste(position, cloneDeep(config), doc);
2299
2302
  return pasteConfigs;
2300
2303
  }
@@ -2308,7 +2311,7 @@ class Editor extends BaseService {
2308
2311
  }
2309
2312
  if (!node.style) return config;
2310
2313
  const stage = this.get("stage");
2311
- const doc = stage?.renderer.contentWindow?.document;
2314
+ const doc = stage?.renderer?.contentWindow?.document;
2312
2315
  if (doc) {
2313
2316
  const el = getElById()(doc, node.id);
2314
2317
  const parentEl = layout === Layout.FIXED ? doc.body : el?.offsetParent;
@@ -3881,7 +3884,7 @@ const useStage = (stageOptions) => {
3881
3884
  }
3882
3885
  }
3883
3886
  );
3884
- stage.mask.setGuides([
3887
+ stage.mask?.setGuides([
3885
3888
  getGuideLineFromCache(getGuideLineKey(H_GUIDE_LINE_STORAGE_KEY)),
3886
3889
  getGuideLineFromCache(getGuideLineKey(V_GUIDE_LINE_STORAGE_KEY))
3887
3890
  ]);
@@ -3937,6 +3940,9 @@ const useStage = (stageOptions) => {
3937
3940
  globalThis.localStorage.removeItem(storageKey);
3938
3941
  }
3939
3942
  });
3943
+ onBeforeUnmount(() => {
3944
+ stage.destroy();
3945
+ });
3940
3946
  return stage;
3941
3947
  };
3942
3948
 
@@ -9184,8 +9190,8 @@ const usePasteMenu = (menu) => ({
9184
9190
  const stage = services?.editorService?.get("stage");
9185
9191
  const rect = menu.value.$el.getBoundingClientRect();
9186
9192
  const parentRect = stage?.container?.getBoundingClientRect();
9187
- const initialLeft = calcValueByFontsize(stage?.renderer.getDocument(), (rect.left || 0) - (parentRect?.left || 0)) / services.uiService.get("zoom");
9188
- const initialTop = calcValueByFontsize(stage?.renderer.getDocument(), (rect.top || 0) - (parentRect?.top || 0)) / services.uiService.get("zoom");
9193
+ const initialLeft = calcValueByFontsize(stage?.renderer?.getDocument(), (rect.left || 0) - (parentRect?.left || 0)) / services.uiService.get("zoom");
9194
+ const initialTop = calcValueByFontsize(stage?.renderer?.getDocument(), (rect.top || 0) - (parentRect?.top || 0)) / services.uiService.get("zoom");
9189
9195
  services?.editorService?.paste({ left: initialLeft, top: initialTop });
9190
9196
  } else {
9191
9197
  services?.editorService?.paste();
@@ -9968,7 +9974,7 @@ const _sfc_main$b = /* @__PURE__ */ defineComponent({
9968
9974
  globalThis.clearTimeout(timeout);
9969
9975
  timeout = void 0;
9970
9976
  }
9971
- const doc = stage.value?.renderer.getDocument();
9977
+ const doc = stage.value?.renderer?.getDocument();
9972
9978
  if (doc && stageOptions?.containerHighlightClassName) {
9973
9979
  removeClassNameByClassName(doc, stageOptions.containerHighlightClassName);
9974
9980
  }
@@ -10594,7 +10600,7 @@ const _sfc_main$7 = /* @__PURE__ */ defineComponent({
10594
10600
  if (!stage2) return;
10595
10601
  nextTick(() => unWatch());
10596
10602
  stage2.on("select", (el, event) => {
10597
- const els = stage2.renderer.getElementsFromPoint(event) || [];
10603
+ const els = stage2.renderer?.getElementsFromPoint(event) || [];
10598
10604
  const ids = els.map((el2) => getIdFromEl()(el2)).filter((id) => Boolean(id));
10599
10605
  buttonVisible.value = ids.length > 3;
10600
10606
  filterTextChangeHandler(ids);
@@ -10693,7 +10699,7 @@ const _sfc_main$6 = /* @__PURE__ */ defineComponent({
10693
10699
  watch(stage, (stage2) => {
10694
10700
  if (stage2) {
10695
10701
  stage2.on("dblclick", async (event) => {
10696
- const el = await stage2.actionManager.getElementFromPoint(event);
10702
+ const el = await stage2.actionManager?.getElementFromPoint(event) || null;
10697
10703
  services?.stageOverlayService.openOverlay(el);
10698
10704
  });
10699
10705
  } else {
@@ -10708,7 +10714,7 @@ const _sfc_main$6 = /* @__PURE__ */ defineComponent({
10708
10714
  subStage.mount(stageOverlay2);
10709
10715
  const { mask, renderer } = subStage;
10710
10716
  const { contentWindow } = renderer;
10711
- mask.showRule(false);
10717
+ mask?.showRule(false);
10712
10718
  services?.stageOverlayService.updateOverlay();
10713
10719
  contentWindow?.magic.onRuntimeReady({});
10714
10720
  }
@@ -11021,7 +11027,7 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({
11021
11027
  const config = parseDSL(`(${data})`);
11022
11028
  if (!config || config.dragType !== DragType.COMPONENT_LIST) return;
11023
11029
  e.preventDefault();
11024
- const doc = stage?.renderer.contentWindow?.document;
11030
+ const doc = stage?.renderer?.contentWindow?.document;
11025
11031
  const parentEl = doc?.querySelector(`.${stageOptions?.containerHighlightClassName}`);
11026
11032
  let parent = page.value;
11027
11033
  const parentId = getIdFromEl()(parentEl);
@@ -11964,6 +11970,10 @@ class StageOverlay extends BaseService {
11964
11970
  const subStage = this.get("stage");
11965
11971
  const wrapDiv = this.get("wrapDiv");
11966
11972
  subStage?.destroy();
11973
+ for (let i = 0, l = wrapDiv.children.length; i < l; i++) {
11974
+ const child = wrapDiv.children[i];
11975
+ child.remove();
11976
+ }
11967
11977
  wrapDiv.remove();
11968
11978
  this.set("stage", null);
11969
11979
  this.set("sourceEl", null);
@@ -11989,7 +11999,7 @@ class StageOverlay extends BaseService {
11989
11999
  autoScrollIntoView: false,
11990
12000
  render: async (stage) => {
11991
12001
  this.copyDocumentElement();
11992
- const rootEls = stage.renderer.getDocument()?.body.children;
12002
+ const rootEls = stage.renderer?.getDocument()?.body.children;
11993
12003
  if (rootEls) {
11994
12004
  Array.from(rootEls).forEach((element) => {
11995
12005
  if (["SCRIPT", "STYLE"].includes(element.tagName)) {
@@ -12018,8 +12028,8 @@ class StageOverlay extends BaseService {
12018
12028
  copyDocumentElement() {
12019
12029
  const subStage = this.get("stage");
12020
12030
  const stage = editorService.get("stage");
12021
- const doc = subStage?.renderer.getDocument();
12022
- const documentElement = stage?.renderer.getDocument()?.documentElement;
12031
+ const doc = subStage?.renderer?.getDocument();
12032
+ const documentElement = stage?.renderer?.getDocument()?.documentElement;
12023
12033
  if (doc && documentElement) {
12024
12034
  doc.replaceChild(documentElement.cloneNode(true), doc.documentElement);
12025
12035
  }
@@ -12037,12 +12047,13 @@ class StageOverlay extends BaseService {
12037
12047
  height: ${sourceEl?.scrollHeight}px;
12038
12048
  background-color: #fff;
12039
12049
  `;
12040
- Array.from(wrapDiv.children).forEach((element) => {
12041
- element.remove();
12042
- });
12050
+ for (let i = 0, l = wrapDiv.children.length; i < l; i++) {
12051
+ const child = wrapDiv.children[i];
12052
+ child.remove();
12053
+ }
12043
12054
  wrapDiv.appendChild(contentEl);
12044
12055
  setTimeout(() => {
12045
- subStage?.renderer.contentWindow?.magic.onPageElUpdate(wrapDiv);
12056
+ subStage?.renderer?.contentWindow?.magic.onPageElUpdate(wrapDiv);
12046
12057
  });
12047
12058
  if (await stageOptions?.canSelect?.(contentEl)) {
12048
12059
  const id = getIdFromEl()(contentEl);
@@ -12282,7 +12293,7 @@ const initServiceEvents = (props, emit, { editorService, codeBlockService, dataS
12282
12293
  };
12283
12294
  const getApp = () => {
12284
12295
  const stage = editorService.get("stage");
12285
- return stage?.renderer.runtime?.getApp?.();
12296
+ return stage?.renderer?.runtime?.getApp?.();
12286
12297
  };
12287
12298
  const updateDataSourceSchema = () => {
12288
12299
  const root = editorService.get("root");
@@ -1016,11 +1016,14 @@
1016
1016
  height = 0;
1017
1017
  }
1018
1018
  const { height: parentHeight } = parentNode.style;
1019
- const { scrollTop = 0, wrapperHeight } = stage.mask;
1020
- const wrapperHeightDeal = utils.calcValueByFontsize(stage.renderer.getDocument(), wrapperHeight);
1021
- const scrollTopDeal = utils.calcValueByFontsize(stage.renderer.getDocument(), scrollTop);
1022
- if (utils.isPage(parentNode)) {
1023
- return (wrapperHeightDeal - height) / 2 + scrollTopDeal;
1019
+ let wrapperHeightDeal = parentHeight;
1020
+ if (stage.mask && stage.renderer) {
1021
+ const { scrollTop = 0, wrapperHeight } = stage.mask;
1022
+ wrapperHeightDeal = utils.calcValueByFontsize(stage.renderer.getDocument(), wrapperHeight);
1023
+ const scrollTopDeal = utils.calcValueByFontsize(stage.renderer.getDocument(), scrollTop);
1024
+ if (utils.isPage(parentNode)) {
1025
+ return (wrapperHeightDeal - height) / 2 + scrollTopDeal;
1026
+ }
1024
1027
  }
1025
1028
  return (Math.min(parentHeight, wrapperHeightDeal) - height) / 2;
1026
1029
  };
@@ -1135,7 +1138,7 @@
1135
1138
  return {
1136
1139
  ...config.style || {},
1137
1140
  top: getMiddleTop(config, parent, stage),
1138
- left: fixNodeLeft(config, parent, stage?.renderer.contentWindow?.document)
1141
+ left: fixNodeLeft(config, parent, stage?.renderer?.contentWindow?.document)
1139
1142
  };
1140
1143
  };
1141
1144
  const serializeConfig = (config) => serialize(config, {
@@ -1944,7 +1947,7 @@
1944
1947
  historyService.resetState();
1945
1948
  }
1946
1949
  if (node?.id) {
1947
- this.get("stage")?.renderer.runtime?.getApp?.()?.page?.emit(
1950
+ this.get("stage")?.renderer?.runtime?.getApp?.()?.page?.emit(
1948
1951
  "editor:select",
1949
1952
  {
1950
1953
  node,
@@ -2298,7 +2301,7 @@
2298
2301
  }
2299
2302
  async doPaste(config, position = {}) {
2300
2303
  propsService.clearRelateId();
2301
- const doc = this.get("stage")?.renderer.contentWindow?.document;
2304
+ const doc = this.get("stage")?.renderer?.contentWindow?.document;
2302
2305
  const pasteConfigs = beforePaste(position, lodashEs.cloneDeep(config), doc);
2303
2306
  return pasteConfigs;
2304
2307
  }
@@ -2312,7 +2315,7 @@
2312
2315
  }
2313
2316
  if (!node.style) return config;
2314
2317
  const stage = this.get("stage");
2315
- const doc = stage?.renderer.contentWindow?.document;
2318
+ const doc = stage?.renderer?.contentWindow?.document;
2316
2319
  if (doc) {
2317
2320
  const el = utils.getElById()(doc, node.id);
2318
2321
  const parentEl = layout === Layout.FIXED ? doc.body : el?.offsetParent;
@@ -3885,7 +3888,7 @@
3885
3888
  }
3886
3889
  }
3887
3890
  );
3888
- stage.mask.setGuides([
3891
+ stage.mask?.setGuides([
3889
3892
  getGuideLineFromCache(getGuideLineKey(H_GUIDE_LINE_STORAGE_KEY)),
3890
3893
  getGuideLineFromCache(getGuideLineKey(V_GUIDE_LINE_STORAGE_KEY))
3891
3894
  ]);
@@ -3941,6 +3944,9 @@
3941
3944
  globalThis.localStorage.removeItem(storageKey);
3942
3945
  }
3943
3946
  });
3947
+ vue.onBeforeUnmount(() => {
3948
+ stage.destroy();
3949
+ });
3944
3950
  return stage;
3945
3951
  };
3946
3952
 
@@ -9188,8 +9194,8 @@
9188
9194
  const stage = services?.editorService?.get("stage");
9189
9195
  const rect = menu.value.$el.getBoundingClientRect();
9190
9196
  const parentRect = stage?.container?.getBoundingClientRect();
9191
- const initialLeft = utils.calcValueByFontsize(stage?.renderer.getDocument(), (rect.left || 0) - (parentRect?.left || 0)) / services.uiService.get("zoom");
9192
- const initialTop = utils.calcValueByFontsize(stage?.renderer.getDocument(), (rect.top || 0) - (parentRect?.top || 0)) / services.uiService.get("zoom");
9197
+ const initialLeft = utils.calcValueByFontsize(stage?.renderer?.getDocument(), (rect.left || 0) - (parentRect?.left || 0)) / services.uiService.get("zoom");
9198
+ const initialTop = utils.calcValueByFontsize(stage?.renderer?.getDocument(), (rect.top || 0) - (parentRect?.top || 0)) / services.uiService.get("zoom");
9193
9199
  services?.editorService?.paste({ left: initialLeft, top: initialTop });
9194
9200
  } else {
9195
9201
  services?.editorService?.paste();
@@ -9972,7 +9978,7 @@
9972
9978
  globalThis.clearTimeout(timeout);
9973
9979
  timeout = void 0;
9974
9980
  }
9975
- const doc = stage.value?.renderer.getDocument();
9981
+ const doc = stage.value?.renderer?.getDocument();
9976
9982
  if (doc && stageOptions?.containerHighlightClassName) {
9977
9983
  utils.removeClassNameByClassName(doc, stageOptions.containerHighlightClassName);
9978
9984
  }
@@ -10598,7 +10604,7 @@
10598
10604
  if (!stage2) return;
10599
10605
  vue.nextTick(() => unWatch());
10600
10606
  stage2.on("select", (el, event) => {
10601
- const els = stage2.renderer.getElementsFromPoint(event) || [];
10607
+ const els = stage2.renderer?.getElementsFromPoint(event) || [];
10602
10608
  const ids = els.map((el2) => utils.getIdFromEl()(el2)).filter((id) => Boolean(id));
10603
10609
  buttonVisible.value = ids.length > 3;
10604
10610
  filterTextChangeHandler(ids);
@@ -10697,7 +10703,7 @@
10697
10703
  vue.watch(stage, (stage2) => {
10698
10704
  if (stage2) {
10699
10705
  stage2.on("dblclick", async (event) => {
10700
- const el = await stage2.actionManager.getElementFromPoint(event);
10706
+ const el = await stage2.actionManager?.getElementFromPoint(event) || null;
10701
10707
  services?.stageOverlayService.openOverlay(el);
10702
10708
  });
10703
10709
  } else {
@@ -10712,7 +10718,7 @@
10712
10718
  subStage.mount(stageOverlay2);
10713
10719
  const { mask, renderer } = subStage;
10714
10720
  const { contentWindow } = renderer;
10715
- mask.showRule(false);
10721
+ mask?.showRule(false);
10716
10722
  services?.stageOverlayService.updateOverlay();
10717
10723
  contentWindow?.magic.onRuntimeReady({});
10718
10724
  }
@@ -11025,7 +11031,7 @@
11025
11031
  const config = parseDSL(`(${data})`);
11026
11032
  if (!config || config.dragType !== DragType.COMPONENT_LIST) return;
11027
11033
  e.preventDefault();
11028
- const doc = stage?.renderer.contentWindow?.document;
11034
+ const doc = stage?.renderer?.contentWindow?.document;
11029
11035
  const parentEl = doc?.querySelector(`.${stageOptions?.containerHighlightClassName}`);
11030
11036
  let parent = page.value;
11031
11037
  const parentId = utils.getIdFromEl()(parentEl);
@@ -11968,6 +11974,10 @@
11968
11974
  const subStage = this.get("stage");
11969
11975
  const wrapDiv = this.get("wrapDiv");
11970
11976
  subStage?.destroy();
11977
+ for (let i = 0, l = wrapDiv.children.length; i < l; i++) {
11978
+ const child = wrapDiv.children[i];
11979
+ child.remove();
11980
+ }
11971
11981
  wrapDiv.remove();
11972
11982
  this.set("stage", null);
11973
11983
  this.set("sourceEl", null);
@@ -11993,7 +12003,7 @@
11993
12003
  autoScrollIntoView: false,
11994
12004
  render: async (stage) => {
11995
12005
  this.copyDocumentElement();
11996
- const rootEls = stage.renderer.getDocument()?.body.children;
12006
+ const rootEls = stage.renderer?.getDocument()?.body.children;
11997
12007
  if (rootEls) {
11998
12008
  Array.from(rootEls).forEach((element) => {
11999
12009
  if (["SCRIPT", "STYLE"].includes(element.tagName)) {
@@ -12022,8 +12032,8 @@
12022
12032
  copyDocumentElement() {
12023
12033
  const subStage = this.get("stage");
12024
12034
  const stage = editorService.get("stage");
12025
- const doc = subStage?.renderer.getDocument();
12026
- const documentElement = stage?.renderer.getDocument()?.documentElement;
12035
+ const doc = subStage?.renderer?.getDocument();
12036
+ const documentElement = stage?.renderer?.getDocument()?.documentElement;
12027
12037
  if (doc && documentElement) {
12028
12038
  doc.replaceChild(documentElement.cloneNode(true), doc.documentElement);
12029
12039
  }
@@ -12041,12 +12051,13 @@
12041
12051
  height: ${sourceEl?.scrollHeight}px;
12042
12052
  background-color: #fff;
12043
12053
  `;
12044
- Array.from(wrapDiv.children).forEach((element) => {
12045
- element.remove();
12046
- });
12054
+ for (let i = 0, l = wrapDiv.children.length; i < l; i++) {
12055
+ const child = wrapDiv.children[i];
12056
+ child.remove();
12057
+ }
12047
12058
  wrapDiv.appendChild(contentEl);
12048
12059
  setTimeout(() => {
12049
- subStage?.renderer.contentWindow?.magic.onPageElUpdate(wrapDiv);
12060
+ subStage?.renderer?.contentWindow?.magic.onPageElUpdate(wrapDiv);
12050
12061
  });
12051
12062
  if (await stageOptions?.canSelect?.(contentEl)) {
12052
12063
  const id = utils.getIdFromEl()(contentEl);
@@ -12286,7 +12297,7 @@
12286
12297
  };
12287
12298
  const getApp = () => {
12288
12299
  const stage = editorService.get("stage");
12289
- return stage?.renderer.runtime?.getApp?.();
12300
+ return stage?.renderer?.runtime?.getApp?.();
12290
12301
  };
12291
12302
  const updateDataSourceSchema = () => {
12292
12303
  const root = editorService.get("root");
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.5.0-beta.2",
2
+ "version": "1.5.0-beta.3",
3
3
  "name": "@tmagic/editor",
4
4
  "type": "module",
5
5
  "sideEffects": [
@@ -55,8 +55,8 @@
55
55
  "moveable": "^0.53.0",
56
56
  "serialize-javascript": "^6.0.0",
57
57
  "sortablejs": "^1.15.2",
58
- "@tmagic/dep": "1.5.0-beta.2",
59
- "@tmagic/table": "1.5.0-beta.2"
58
+ "@tmagic/dep": "1.5.0-beta.3",
59
+ "@tmagic/table": "1.5.0-beta.3"
60
60
  },
61
61
  "devDependencies": {
62
62
  "@types/events": "^3.0.0",
@@ -77,12 +77,12 @@
77
77
  "monaco-editor": "^0.48.0",
78
78
  "typescript": "*",
79
79
  "vue": "^3.4.35",
80
- "@tmagic/form": "1.5.0-beta.2",
81
- "@tmagic/schema": "1.5.0-beta.2",
82
- "@tmagic/design": "1.5.0-beta.2",
83
- "@tmagic/stage": "1.5.0-beta.2",
84
- "@tmagic/core": "1.5.0-beta.2",
85
- "@tmagic/utils": "1.5.0-beta.2"
80
+ "@tmagic/form": "1.5.0-beta.3",
81
+ "@tmagic/schema": "1.5.0-beta.3",
82
+ "@tmagic/core": "1.5.0-beta.3",
83
+ "@tmagic/design": "1.5.0-beta.3",
84
+ "@tmagic/stage": "1.5.0-beta.3",
85
+ "@tmagic/utils": "1.5.0-beta.3"
86
86
  },
87
87
  "peerDependenciesMeta": {
88
88
  "typescript": {
@@ -1,4 +1,4 @@
1
- import { computed, watch } from 'vue';
1
+ import { computed, onBeforeUnmount, watch } from 'vue';
2
2
 
3
3
  import type { MNode } from '@tmagic/schema';
4
4
  import StageCore, { GuidesType, RemoveEventData, SortEventData, UpdateEventData } from '@tmagic/stage';
@@ -62,7 +62,7 @@ export const useStage = (stageOptions: StageOptions) => {
62
62
  },
63
63
  );
64
64
 
65
- stage.mask.setGuides([
65
+ stage.mask?.setGuides([
66
66
  getGuideLineFromCache(getGuideLineKey(H_GUIDE_LINE_STORAGE_KEY)),
67
67
  getGuideLineFromCache(getGuideLineKey(V_GUIDE_LINE_STORAGE_KEY)),
68
68
  ]);
@@ -131,5 +131,9 @@ export const useStage = (stageOptions: StageOptions) => {
131
131
  }
132
132
  });
133
133
 
134
+ onBeforeUnmount(() => {
135
+ stage.destroy();
136
+ });
137
+
134
138
  return stage;
135
139
  };
@@ -242,7 +242,7 @@ export const initServiceEvents = (
242
242
 
243
243
  const getApp = () => {
244
244
  const stage = editorService.get('stage');
245
- return stage?.renderer.runtime?.getApp?.();
245
+ return stage?.renderer?.runtime?.getApp?.();
246
246
  };
247
247
 
248
248
  const updateDataSourceSchema = () => {
@@ -111,7 +111,7 @@ const dragendHandler = () => {
111
111
  globalThis.clearTimeout(timeout);
112
112
  timeout = undefined;
113
113
  }
114
- const doc = stage.value?.renderer.getDocument();
114
+ const doc = stage.value?.renderer?.getDocument();
115
115
  if (doc && stageOptions?.containerHighlightClassName) {
116
116
  removeClassNameByClassName(doc, stageOptions.containerHighlightClassName);
117
117
  }
@@ -61,7 +61,7 @@ const unWatch = watch(
61
61
  nextTick(() => unWatch());
62
62
 
63
63
  stage.on('select', (el: HTMLElement, event: MouseEvent) => {
64
- const els = stage.renderer.getElementsFromPoint(event) || [];
64
+ const els = stage.renderer?.getElementsFromPoint(event) || [];
65
65
  const ids = els.map((el) => getIdFromEl()(el)).filter((id) => Boolean(id)) as string[];
66
66
 
67
67
  buttonVisible.value = ids.length > 3;
@@ -196,7 +196,7 @@ const dropHandler = async (e: DragEvent) => {
196
196
 
197
197
  e.preventDefault();
198
198
 
199
- const doc = stage?.renderer.contentWindow?.document;
199
+ const doc = stage?.renderer?.contentWindow?.document;
200
200
  const parentEl: HTMLElement | null | undefined = doc?.querySelector(`.${stageOptions?.containerHighlightClassName}`);
201
201
 
202
202
  let parent: MContainer | undefined | null = page.value;
@@ -209,7 +209,7 @@ const dropHandler = async (e: DragEvent) => {
209
209
  const layout = await services?.editorService.getLayout(parent);
210
210
 
211
211
  const containerRect = stageContainer.value.getBoundingClientRect();
212
- const { scrollTop, scrollLeft } = stage.mask;
212
+ const { scrollTop, scrollLeft } = stage.mask!;
213
213
  const { style = {} } = config.data;
214
214
 
215
215
  let top = 0;
@@ -34,7 +34,7 @@ const style = computed(() => ({
34
34
  watch(stage, (stage) => {
35
35
  if (stage) {
36
36
  stage.on('dblclick', async (event: MouseEvent) => {
37
- const el = await stage.actionManager.getElementFromPoint(event);
37
+ const el = (await stage.actionManager?.getElementFromPoint(event)) || null;
38
38
  services?.stageOverlayService.openOverlay(el);
39
39
  });
40
40
  } else {
@@ -53,8 +53,8 @@ watch(stageOverlay, (stageOverlay) => {
53
53
 
54
54
  const { mask, renderer } = subStage;
55
55
 
56
- const { contentWindow } = renderer;
57
- mask.showRule(false);
56
+ const { contentWindow } = renderer!;
57
+ mask?.showRule(false);
58
58
 
59
59
  services?.stageOverlayService.updateOverlay();
60
60
 
@@ -267,7 +267,7 @@ class Editor extends BaseService {
267
267
 
268
268
  if (node?.id) {
269
269
  this.get('stage')
270
- ?.renderer.runtime?.getApp?.()
270
+ ?.renderer?.runtime?.getApp?.()
271
271
  ?.page?.emit(
272
272
  'editor:select',
273
273
  {
@@ -737,7 +737,7 @@ class Editor extends BaseService {
737
737
 
738
738
  public async doPaste(config: MNode[], position: PastePosition = {}): Promise<MNode[]> {
739
739
  propsService.clearRelateId();
740
- const doc = this.get('stage')?.renderer.contentWindow?.document;
740
+ const doc = this.get('stage')?.renderer?.contentWindow?.document;
741
741
  const pasteConfigs = beforePaste(position, cloneDeep(config), doc);
742
742
  return pasteConfigs;
743
743
  }
@@ -756,7 +756,7 @@ class Editor extends BaseService {
756
756
  if (!node.style) return config;
757
757
 
758
758
  const stage = this.get('stage');
759
- const doc = stage?.renderer.contentWindow?.document;
759
+ const doc = stage?.renderer?.contentWindow?.document;
760
760
 
761
761
  if (doc) {
762
762
  const el = getElById()(doc, node.id);
@@ -64,6 +64,12 @@ class StageOverlay extends BaseService {
64
64
  const subStage = this.get('stage');
65
65
  const wrapDiv = this.get('wrapDiv');
66
66
  subStage?.destroy();
67
+
68
+ for (let i = 0, l = wrapDiv.children.length; i < l; i++) {
69
+ const child = wrapDiv.children[i];
70
+ child.remove();
71
+ }
72
+
67
73
  wrapDiv.remove();
68
74
 
69
75
  this.set('stage', null);
@@ -97,7 +103,7 @@ class StageOverlay extends BaseService {
97
103
  render: async (stage: StageCore) => {
98
104
  this.copyDocumentElement();
99
105
 
100
- const rootEls = stage.renderer.getDocument()?.body.children;
106
+ const rootEls = stage.renderer?.getDocument()?.body.children;
101
107
  if (rootEls) {
102
108
  Array.from(rootEls).forEach((element) => {
103
109
  if (['SCRIPT', 'STYLE'].includes(element.tagName)) {
@@ -135,8 +141,8 @@ class StageOverlay extends BaseService {
135
141
  const subStage = this.get('stage');
136
142
  const stage = editorService.get('stage');
137
143
 
138
- const doc = subStage?.renderer.getDocument();
139
- const documentElement = stage?.renderer.getDocument()?.documentElement;
144
+ const doc = subStage?.renderer?.getDocument();
145
+ const documentElement = stage?.renderer?.getDocument()?.documentElement;
140
146
 
141
147
  if (doc && documentElement) {
142
148
  doc.replaceChild(documentElement.cloneNode(true), doc.documentElement);
@@ -160,13 +166,15 @@ class StageOverlay extends BaseService {
160
166
  background-color: #fff;
161
167
  `;
162
168
 
163
- Array.from(wrapDiv.children).forEach((element) => {
164
- element.remove();
165
- });
169
+ for (let i = 0, l = wrapDiv.children.length; i < l; i++) {
170
+ const child = wrapDiv.children[i];
171
+ child.remove();
172
+ }
173
+
166
174
  wrapDiv.appendChild(contentEl);
167
175
 
168
176
  setTimeout(() => {
169
- subStage?.renderer.contentWindow?.magic.onPageElUpdate(wrapDiv);
177
+ subStage?.renderer?.contentWindow?.magic.onPageElUpdate(wrapDiv);
170
178
  });
171
179
 
172
180
  if (await stageOptions?.canSelect?.(contentEl)) {
@@ -47,10 +47,10 @@ export const usePasteMenu = (menu?: Ref<InstanceType<typeof ContentMenu> | undef
47
47
  const rect = menu.value.$el.getBoundingClientRect();
48
48
  const parentRect = stage?.container?.getBoundingClientRect();
49
49
  const initialLeft =
50
- calcValueByFontsize(stage?.renderer.getDocument(), (rect.left || 0) - (parentRect?.left || 0)) /
50
+ calcValueByFontsize(stage?.renderer?.getDocument(), (rect.left || 0) - (parentRect?.left || 0)) /
51
51
  services.uiService.get('zoom');
52
52
  const initialTop =
53
- calcValueByFontsize(stage?.renderer.getDocument(), (rect.top || 0) - (parentRect?.top || 0)) /
53
+ calcValueByFontsize(stage?.renderer?.getDocument(), (rect.top || 0) - (parentRect?.top || 0)) /
54
54
  services.uiService.get('zoom');
55
55
  services?.editorService?.paste({ left: initialLeft, top: initialTop });
56
56
  } else {
@@ -109,12 +109,16 @@ const getMiddleTop = (node: MNode, parentNode: MNode, stage: StageCore | null) =
109
109
  }
110
110
 
111
111
  const { height: parentHeight } = parentNode.style;
112
- // wrapperHeight 是未 calcValue的高度, 所以要将其calcValueByFontsize一下, 否则在pad or pc端计算的结果有误
113
- const { scrollTop = 0, wrapperHeight } = stage.mask;
114
- const wrapperHeightDeal = calcValueByFontsize(stage.renderer.getDocument()!, wrapperHeight);
115
- const scrollTopDeal = calcValueByFontsize(stage.renderer.getDocument()!, scrollTop);
116
- if (isPage(parentNode)) {
117
- return (wrapperHeightDeal - height) / 2 + scrollTopDeal;
112
+
113
+ let wrapperHeightDeal = parentHeight;
114
+ if (stage.mask && stage.renderer) {
115
+ // wrapperHeight 是未 calcValue的高度, 所以要将其calcValueByFontsize一下, 否则在pad or pc端计算的结果有误
116
+ const { scrollTop = 0, wrapperHeight } = stage.mask;
117
+ wrapperHeightDeal = calcValueByFontsize(stage.renderer.getDocument()!, wrapperHeight);
118
+ const scrollTopDeal = calcValueByFontsize(stage.renderer.getDocument()!, scrollTop);
119
+ if (isPage(parentNode)) {
120
+ return (wrapperHeightDeal - height) / 2 + scrollTopDeal;
121
+ }
118
122
  }
119
123
 
120
124
  // 如果容器的元素高度大于当前视口高度的2倍, 添加的元素居中位置也会看不见, 所以要取最小值计算
@@ -263,7 +267,7 @@ export const fixNodePosition = (config: MNode, parent: MContainer, stage: StageC
263
267
  return {
264
268
  ...(config.style || {}),
265
269
  top: getMiddleTop(config, parent, stage),
266
- left: fixNodeLeft(config, parent, stage?.renderer.contentWindow?.document),
270
+ left: fixNodeLeft(config, parent, stage?.renderer?.contentWindow?.document),
267
271
  };
268
272
  };
269
273