@tmagic/editor 1.3.11 → 1.3.12

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.
@@ -1855,6 +1855,197 @@
1855
1855
  }
1856
1856
  const depService = new Dep();
1857
1857
 
1858
+ class Props extends BaseService {
1859
+ state = vue.reactive({
1860
+ propsConfigMap: {},
1861
+ propsValueMap: {},
1862
+ relateIdMap: {}
1863
+ });
1864
+ constructor() {
1865
+ super([
1866
+ { name: "setPropsConfig", isAsync: true },
1867
+ { name: "getPropsConfig", isAsync: true },
1868
+ { name: "setPropsValue", isAsync: true },
1869
+ { name: "getPropsValue", isAsync: true },
1870
+ { name: "createId", isAsync: false },
1871
+ { name: "setNewItemId", isAsync: true },
1872
+ { name: "fillConfig", isAsync: true },
1873
+ { name: "getDefaultPropsValue", isAsync: true }
1874
+ ]);
1875
+ }
1876
+ setPropsConfigs(configs) {
1877
+ Object.keys(configs).forEach((type) => {
1878
+ this.setPropsConfig(utils.toLine(type), configs[type]);
1879
+ });
1880
+ this.emit("props-configs-change");
1881
+ }
1882
+ async fillConfig(config) {
1883
+ return fillConfig(config);
1884
+ }
1885
+ /**
1886
+ * 为指定类型组件设置组件属性表单配置
1887
+ * @param type 组件类型
1888
+ * @param config 组件属性表单配置
1889
+ */
1890
+ async setPropsConfig(type, config) {
1891
+ this.state.propsConfigMap[type] = await this.fillConfig(Array.isArray(config) ? config : [config]);
1892
+ }
1893
+ /**
1894
+ * 获取指点类型的组件属性表单配置
1895
+ * @param type 组件类型
1896
+ * @returns 组件属性表单配置
1897
+ */
1898
+ async getPropsConfig(type) {
1899
+ if (type === "area") {
1900
+ return await this.getPropsConfig("button");
1901
+ }
1902
+ return lodashEs.cloneDeep(this.state.propsConfigMap[type] || await this.fillConfig([]));
1903
+ }
1904
+ setPropsValues(values) {
1905
+ Object.keys(values).forEach((type) => {
1906
+ this.setPropsValue(utils.toLine(type), values[type]);
1907
+ });
1908
+ }
1909
+ /**
1910
+ * 为指点类型组件设置组件初始值
1911
+ * @param type 组件类型
1912
+ * @param value 组件初始值
1913
+ */
1914
+ async setPropsValue(type, value) {
1915
+ this.state.propsValueMap[type] = value;
1916
+ }
1917
+ /**
1918
+ * 获取指定类型的组件初始值
1919
+ * @param type 组件类型
1920
+ * @returns 组件初始值
1921
+ */
1922
+ async getPropsValue(type, { inputEvent, ...defaultValue } = {}) {
1923
+ if (type === "area") {
1924
+ const value = await this.getPropsValue("button");
1925
+ value.className = "action-area";
1926
+ value.text = "";
1927
+ if (value.style) {
1928
+ value.style.backgroundColor = "rgba(255, 255, 255, 0)";
1929
+ }
1930
+ return value;
1931
+ }
1932
+ const [id, defaultPropsValue, data] = await Promise.all([
1933
+ this.createId(type),
1934
+ this.getDefaultPropsValue(type),
1935
+ this.setNewItemId(
1936
+ lodashEs.cloneDeep({
1937
+ type,
1938
+ ...defaultValue
1939
+ })
1940
+ )
1941
+ ]);
1942
+ return {
1943
+ id,
1944
+ ...defaultPropsValue,
1945
+ ...lodashEs.mergeWith({}, lodashEs.cloneDeep(this.state.propsValueMap[type] || {}), data)
1946
+ };
1947
+ }
1948
+ async createId(type) {
1949
+ return `${type}_${utils.guid()}`;
1950
+ }
1951
+ /**
1952
+ * 将组件与组件的子元素配置中的id都设置成一个新的ID
1953
+ * 如果没有相同ID并且force为false则保持不变
1954
+ * @param {Object} config 组件配置
1955
+ * @param {Boolean} force 是否强制设置新的ID
1956
+ */
1957
+ /* eslint no-param-reassign: ["error", { "props": false }] */
1958
+ async setNewItemId(config, force = true) {
1959
+ if (force || editorService.getNodeById(config.id)) {
1960
+ const newId = await this.createId(config.type || "component");
1961
+ this.setRelateId(config.id, newId);
1962
+ config.id = newId;
1963
+ }
1964
+ if (config.items && Array.isArray(config.items)) {
1965
+ for (const item of config.items) {
1966
+ await this.setNewItemId(item);
1967
+ }
1968
+ }
1969
+ return config;
1970
+ }
1971
+ /**
1972
+ * 获取默认属性配置
1973
+ * @param type 组件类型
1974
+ * @returns Object
1975
+ */
1976
+ async getDefaultPropsValue(type) {
1977
+ return ["page", "container"].includes(type) ? {
1978
+ type,
1979
+ layout: "absolute",
1980
+ style: {},
1981
+ name: type,
1982
+ items: []
1983
+ } : {
1984
+ type,
1985
+ style: {},
1986
+ name: type
1987
+ };
1988
+ }
1989
+ resetState() {
1990
+ this.state.propsConfigMap = {};
1991
+ this.state.propsValueMap = {};
1992
+ }
1993
+ /**
1994
+ * 替换关联ID
1995
+ * @param originConfigs 原组件配置
1996
+ * @param targetConfigs 待替换的组件配置
1997
+ */
1998
+ replaceRelateId(originConfigs, targetConfigs) {
1999
+ const relateIdMap = this.getRelateIdMap();
2000
+ if (Object.keys(relateIdMap).length === 0)
2001
+ return;
2002
+ const target = depService.getTarget(dep.DepTargetType.RELATED_COMP_WHEN_COPY, dep.DepTargetType.RELATED_COMP_WHEN_COPY);
2003
+ if (!target)
2004
+ return;
2005
+ originConfigs.forEach((config) => {
2006
+ const newId = relateIdMap[config.id];
2007
+ const targetConfig = targetConfigs.find((targetConfig2) => targetConfig2.id === newId);
2008
+ if (!targetConfig)
2009
+ return;
2010
+ target.deps[config.id]?.keys?.forEach((fullKey) => {
2011
+ const relateOriginId = utils.getValueByKeyPath(fullKey, config);
2012
+ const relateTargetId = relateIdMap[relateOriginId];
2013
+ if (!relateTargetId)
2014
+ return;
2015
+ utils.setValueByKeyPath(fullKey, relateTargetId, targetConfig);
2016
+ });
2017
+ });
2018
+ }
2019
+ /**
2020
+ * 清除setNewItemId前后映射关系
2021
+ */
2022
+ clearRelateId() {
2023
+ this.state.relateIdMap = {};
2024
+ }
2025
+ destroy() {
2026
+ this.resetState();
2027
+ this.removeAllListeners();
2028
+ this.removeAllPlugins();
2029
+ }
2030
+ /**
2031
+ * 获取setNewItemId前后映射关系
2032
+ * @param oldId 原组件ID
2033
+ * @returns 新旧ID映射
2034
+ */
2035
+ getRelateIdMap() {
2036
+ return this.state.relateIdMap;
2037
+ }
2038
+ /**
2039
+ * 记录setNewItemId前后映射关系
2040
+ * @param oldId 原组件ID
2041
+ * @param newId 分配的新ID
2042
+ */
2043
+ setRelateId(oldId, newId) {
2044
+ this.state.relateIdMap[oldId] = newId;
2045
+ }
2046
+ }
2047
+ const propsService = new Props();
2048
+
1858
2049
  class UndoRedo {
1859
2050
  elementList;
1860
2051
  listCursor;
@@ -2109,197 +2300,6 @@
2109
2300
  }
2110
2301
  const storageService = new WebStorage();
2111
2302
 
2112
- class Props extends BaseService {
2113
- state = vue.reactive({
2114
- propsConfigMap: {},
2115
- propsValueMap: {},
2116
- relateIdMap: {}
2117
- });
2118
- constructor() {
2119
- super([
2120
- { name: "setPropsConfig", isAsync: true },
2121
- { name: "getPropsConfig", isAsync: true },
2122
- { name: "setPropsValue", isAsync: true },
2123
- { name: "getPropsValue", isAsync: true },
2124
- { name: "createId", isAsync: false },
2125
- { name: "setNewItemId", isAsync: true },
2126
- { name: "fillConfig", isAsync: true },
2127
- { name: "getDefaultPropsValue", isAsync: true }
2128
- ]);
2129
- }
2130
- setPropsConfigs(configs) {
2131
- Object.keys(configs).forEach((type) => {
2132
- this.setPropsConfig(utils.toLine(type), configs[type]);
2133
- });
2134
- this.emit("props-configs-change");
2135
- }
2136
- async fillConfig(config) {
2137
- return fillConfig(config);
2138
- }
2139
- /**
2140
- * 为指定类型组件设置组件属性表单配置
2141
- * @param type 组件类型
2142
- * @param config 组件属性表单配置
2143
- */
2144
- async setPropsConfig(type, config) {
2145
- this.state.propsConfigMap[type] = await this.fillConfig(Array.isArray(config) ? config : [config]);
2146
- }
2147
- /**
2148
- * 获取指点类型的组件属性表单配置
2149
- * @param type 组件类型
2150
- * @returns 组件属性表单配置
2151
- */
2152
- async getPropsConfig(type) {
2153
- if (type === "area") {
2154
- return await this.getPropsConfig("button");
2155
- }
2156
- return lodashEs.cloneDeep(this.state.propsConfigMap[type] || await this.fillConfig([]));
2157
- }
2158
- setPropsValues(values) {
2159
- Object.keys(values).forEach((type) => {
2160
- this.setPropsValue(utils.toLine(type), values[type]);
2161
- });
2162
- }
2163
- /**
2164
- * 为指点类型组件设置组件初始值
2165
- * @param type 组件类型
2166
- * @param value 组件初始值
2167
- */
2168
- async setPropsValue(type, value) {
2169
- this.state.propsValueMap[type] = value;
2170
- }
2171
- /**
2172
- * 获取指定类型的组件初始值
2173
- * @param type 组件类型
2174
- * @returns 组件初始值
2175
- */
2176
- async getPropsValue(type, { inputEvent, ...defaultValue } = {}) {
2177
- if (type === "area") {
2178
- const value = await this.getPropsValue("button");
2179
- value.className = "action-area";
2180
- value.text = "";
2181
- if (value.style) {
2182
- value.style.backgroundColor = "rgba(255, 255, 255, 0)";
2183
- }
2184
- return value;
2185
- }
2186
- const [id, defaultPropsValue, data] = await Promise.all([
2187
- this.createId(type),
2188
- this.getDefaultPropsValue(type),
2189
- this.setNewItemId(
2190
- lodashEs.cloneDeep({
2191
- type,
2192
- ...defaultValue
2193
- })
2194
- )
2195
- ]);
2196
- return {
2197
- id,
2198
- ...defaultPropsValue,
2199
- ...lodashEs.mergeWith({}, lodashEs.cloneDeep(this.state.propsValueMap[type] || {}), data)
2200
- };
2201
- }
2202
- async createId(type) {
2203
- return `${type}_${utils.guid()}`;
2204
- }
2205
- /**
2206
- * 将组件与组件的子元素配置中的id都设置成一个新的ID
2207
- * 如果没有相同ID并且force为false则保持不变
2208
- * @param {Object} config 组件配置
2209
- * @param {Boolean} force 是否强制设置新的ID
2210
- */
2211
- /* eslint no-param-reassign: ["error", { "props": false }] */
2212
- async setNewItemId(config, force = true) {
2213
- if (force || editorService.getNodeById(config.id)) {
2214
- const newId = await this.createId(config.type || "component");
2215
- this.setRelateId(config.id, newId);
2216
- config.id = newId;
2217
- }
2218
- if (config.items && Array.isArray(config.items)) {
2219
- for (const item of config.items) {
2220
- await this.setNewItemId(item);
2221
- }
2222
- }
2223
- return config;
2224
- }
2225
- /**
2226
- * 获取默认属性配置
2227
- * @param type 组件类型
2228
- * @returns Object
2229
- */
2230
- async getDefaultPropsValue(type) {
2231
- return ["page", "container"].includes(type) ? {
2232
- type,
2233
- layout: "absolute",
2234
- style: {},
2235
- name: type,
2236
- items: []
2237
- } : {
2238
- type,
2239
- style: {},
2240
- name: type
2241
- };
2242
- }
2243
- resetState() {
2244
- this.state.propsConfigMap = {};
2245
- this.state.propsValueMap = {};
2246
- }
2247
- /**
2248
- * 替换关联ID
2249
- * @param originConfigs 原组件配置
2250
- * @param targetConfigs 待替换的组件配置
2251
- */
2252
- replaceRelateId(originConfigs, targetConfigs) {
2253
- const relateIdMap = this.getRelateIdMap();
2254
- if (Object.keys(relateIdMap).length === 0)
2255
- return;
2256
- const target = depService.getTarget(dep.DepTargetType.RELATED_COMP_WHEN_COPY, dep.DepTargetType.RELATED_COMP_WHEN_COPY);
2257
- if (!target)
2258
- return;
2259
- originConfigs.forEach((config) => {
2260
- const newId = relateIdMap[config.id];
2261
- const targetConfig = targetConfigs.find((targetConfig2) => targetConfig2.id === newId);
2262
- if (!targetConfig)
2263
- return;
2264
- target.deps[config.id]?.keys?.forEach((fullKey) => {
2265
- const relateOriginId = utils.getValueByKeyPath(fullKey, config);
2266
- const relateTargetId = relateIdMap[relateOriginId];
2267
- if (!relateTargetId)
2268
- return;
2269
- utils.setValueByKeyPath(fullKey, relateTargetId, targetConfig);
2270
- });
2271
- });
2272
- }
2273
- /**
2274
- * 清除setNewItemId前后映射关系
2275
- */
2276
- clearRelateId() {
2277
- this.state.relateIdMap = {};
2278
- }
2279
- destroy() {
2280
- this.resetState();
2281
- this.removeAllListeners();
2282
- this.removeAllPlugins();
2283
- }
2284
- /**
2285
- * 获取setNewItemId前后映射关系
2286
- * @param oldId 原组件ID
2287
- * @returns 新旧ID映射
2288
- */
2289
- getRelateIdMap() {
2290
- return this.state.relateIdMap;
2291
- }
2292
- /**
2293
- * 记录setNewItemId前后映射关系
2294
- * @param oldId 原组件ID
2295
- * @param newId 分配的新ID
2296
- */
2297
- setRelateId(oldId, newId) {
2298
- this.state.relateIdMap[oldId] = newId;
2299
- }
2300
- }
2301
- const propsService = new Props();
2302
-
2303
2303
  class Editor extends BaseService {
2304
2304
  state = vue.reactive({
2305
2305
  root: null,
@@ -2935,14 +2935,14 @@
2935
2935
  * @param targetId 容器ID
2936
2936
  */
2937
2937
  async moveToContainer(config, targetId) {
2938
- const root = lodashEs.cloneDeep(this.get("root"));
2938
+ const root = this.get("root");
2939
2939
  const { node, parent } = this.getNodeInfo(config.id, false);
2940
2940
  const target = this.getNodeById(targetId, false);
2941
2941
  const stage = this.get("stage");
2942
2942
  if (root && node && parent && stage) {
2943
2943
  const index = getNodeIndex(node.id, parent);
2944
2944
  parent.items?.splice(index, 1);
2945
- await stage.remove({ id: node.id, parentId: parent.id, root });
2945
+ await stage.remove({ id: node.id, parentId: parent.id, root: lodashEs.cloneDeep(root) });
2946
2946
  const layout = await this.getLayout(target);
2947
2947
  const newConfig = lodashEs.mergeWith(lodashEs.cloneDeep(node), config, (objValue, srcValue) => {
2948
2948
  if (Array.isArray(srcValue)) {
@@ -2953,7 +2953,7 @@
2953
2953
  target.items.push(newConfig);
2954
2954
  await stage.select(targetId);
2955
2955
  const targetParent = this.getParentById(target.id);
2956
- await stage.update({ config: lodashEs.cloneDeep(target), parentId: targetParent?.id, root });
2956
+ await stage.update({ config: lodashEs.cloneDeep(target), parentId: targetParent?.id, root: lodashEs.cloneDeep(root) });
2957
2957
  await this.select(newConfig);
2958
2958
  stage.select(newConfig.id);
2959
2959
  this.addModifiedNodeId(target.id);
@@ -5370,7 +5370,7 @@
5370
5370
 
5371
5371
  const _sfc_main$z = /* @__PURE__ */ vue.defineComponent({
5372
5372
  ...{
5373
- name: "MEditorLayout"
5373
+ name: "MEditorSplitView"
5374
5374
  },
5375
5375
  __name: "SplitView",
5376
5376
  props: {
@@ -8473,8 +8473,8 @@
8473
8473
  globalThis.clearTimeout(timeout);
8474
8474
  timeout = void 0;
8475
8475
  }
8476
- const doc = stage.value?.renderer.contentWindow?.document;
8477
- if (doc && stageOptions) {
8476
+ const doc = stage.value?.renderer.getDocument();
8477
+ if (doc && stageOptions?.containerHighlightClassName) {
8478
8478
  utils.removeClassNameByClassName(doc, stageOptions.containerHighlightClassName);
8479
8479
  }
8480
8480
  clientX = 0;
@@ -9282,7 +9282,9 @@
9282
9282
  disabledDragStart: stageOptions.disabledDragStart,
9283
9283
  renderType: stageOptions.renderType,
9284
9284
  canSelect: (el, event, stop) => {
9285
- const elCanSelect = stageOptions.canSelect(el);
9285
+ if (!stageOptions.canSelect)
9286
+ return true;
9287
+ const elCanSelect = stageOptions.canSelect?.(el);
9286
9288
  if (uiSelectMode.value && elCanSelect && event.type === "mousedown") {
9287
9289
  document.dispatchEvent(new CustomEvent(UI_SELECT_MODE_EVENT_NAME, { detail: el }));
9288
9290
  return stop();
@@ -9577,152 +9579,71 @@
9577
9579
  }
9578
9580
  });
9579
9581
 
9580
- const useStageOverlay = () => {
9581
- const services = vue.inject("services");
9582
- const stageOptions = vue.inject("stageOptions");
9583
- const wrapWidth = vue.ref(0);
9584
- const wrapHeight = vue.ref(0);
9585
- const stageOverlayVisible = vue.ref(false);
9586
- const stageOverlay = vue.ref();
9587
- const stage = vue.computed(() => services?.editorService.get("stage"));
9588
- let subStage = null;
9589
- const div = document.createElement("div");
9590
- let selectEl = null;
9591
- const render = () => {
9592
- if (!selectEl)
9593
- return;
9594
- const content = selectEl.cloneNode(true);
9595
- content.style.position = "static";
9596
- Array.from(div.children).forEach((element) => {
9597
- element.remove();
9598
- });
9599
- div.appendChild(content);
9600
- subStage?.renderer.contentWindow?.magic.onPageElUpdate(div);
9601
- subStage?.select(content);
9602
- };
9603
- const copyDocumentElement = () => {
9604
- const doc = subStage?.renderer.getDocument();
9605
- const documentElement = stage.value?.renderer.getDocument()?.documentElement;
9606
- if (doc && documentElement) {
9607
- doc.replaceChild(documentElement.cloneNode(true), doc.documentElement);
9608
- }
9609
- };
9610
- const updateOverlay = () => {
9611
- if (!selectEl)
9612
- return;
9613
- const { scrollWidth, scrollHeight } = selectEl;
9614
- stageOverlay.value.style.width = `${scrollWidth}px`;
9615
- stageOverlay.value.style.height = `${scrollHeight}px`;
9616
- wrapWidth.value = scrollWidth;
9617
- wrapHeight.value = scrollHeight;
9618
- };
9619
- const updateHandler = () => {
9620
- render();
9621
- updateOverlay();
9622
- };
9623
- const addHandler = () => {
9624
- render();
9625
- updateOverlay();
9626
- };
9627
- const removeHandler = () => {
9628
- render();
9629
- updateOverlay();
9630
- };
9631
- const openOverlay = async (el) => {
9632
- selectEl = el;
9633
- stageOverlayVisible.value = true;
9634
- if (!stageOverlay.value) {
9635
- await vue.nextTick();
9636
- }
9637
- if (!stageOptions) {
9638
- return;
9639
- }
9640
- subStage = useStage({
9641
- ...stageOptions,
9642
- runtimeUrl: "",
9643
- autoScrollIntoView: false,
9644
- render(stage2) {
9645
- copyDocumentElement();
9646
- const rootEl = stage2.renderer.getDocument()?.getElementById("app");
9647
- if (rootEl) {
9648
- rootEl.remove();
9649
- }
9650
- div.style.cssText = `
9651
- width: ${el.scrollWidth}px;
9652
- height: ${el.scrollHeight}px;
9653
- background-color: #fff;
9654
- `;
9655
- render();
9656
- return div;
9657
- }
9658
- });
9659
- subStage.mount(stageOverlay.value);
9660
- const { mask, renderer } = subStage;
9661
- const { contentWindow } = renderer;
9662
- mask.showRule(false);
9663
- updateOverlay();
9664
- contentWindow?.magic.onRuntimeReady({});
9665
- services?.editorService.on("update", updateHandler);
9666
- services?.editorService.on("add", addHandler);
9667
- services?.editorService.on("remove", removeHandler);
9668
- };
9669
- const closeOverlay = () => {
9670
- stageOverlayVisible.value = false;
9671
- subStage?.destroy();
9672
- subStage = null;
9673
- services?.editorService.off("update", updateHandler);
9674
- services?.editorService.off("add", addHandler);
9675
- services?.editorService.off("remove", removeHandler);
9676
- };
9677
- vue.watch(stage, (stage2) => {
9678
- if (stage2) {
9679
- stage2.on("dblclick", async (event) => {
9680
- const el = await stage2.actionManager.getElementFromPoint(event);
9681
- if (el) {
9682
- openOverlay(el);
9683
- }
9684
- });
9685
- } else if (subStage) {
9686
- closeOverlay();
9687
- }
9688
- });
9689
- return {
9690
- wrapWidth,
9691
- wrapHeight,
9692
- stageOverlayVisible,
9693
- stageOverlay,
9694
- closeOverlay
9695
- };
9696
- };
9697
-
9698
9582
  const _sfc_main$6 = /* @__PURE__ */ vue.defineComponent({
9699
9583
  __name: "StageOverlay",
9700
9584
  setup(__props) {
9701
- const { stageOverlayVisible, stageOverlay, closeOverlay } = useStageOverlay();
9585
+ const services = vue.inject("services");
9586
+ const stageOptions = vue.inject("stageOptions");
9587
+ const stageOverlay = vue.ref();
9588
+ const stageOverlayVisible = vue.computed(() => services?.stageOverlayService.get("stageOverlayVisible"));
9589
+ const wrapWidth = vue.computed(() => services?.stageOverlayService.get("wrapWidth") || 0);
9590
+ const wrapHeight = vue.computed(() => services?.stageOverlayService.get("wrapHeight") || 0);
9591
+ const stage = vue.computed(() => services?.editorService.get("stage"));
9592
+ const style = vue.computed(() => ({
9593
+ width: `${wrapWidth.value}px`,
9594
+ height: `${wrapHeight.value}px`
9595
+ }));
9596
+ vue.watch(stage, (stage2) => {
9597
+ if (stage2) {
9598
+ stage2.on("dblclick", async (event) => {
9599
+ const el = await stage2.actionManager.getElementFromPoint(event);
9600
+ services?.stageOverlayService.openOverlay(el);
9601
+ });
9602
+ } else {
9603
+ services?.stageOverlayService.closeOverlay();
9604
+ }
9605
+ });
9606
+ vue.watch(stageOverlay, (stageOverlay2) => {
9607
+ if (!services)
9608
+ return;
9609
+ const subStage = services.stageOverlayService.createStage(stageOptions);
9610
+ services?.stageOverlayService.set("stage", subStage);
9611
+ if (stageOverlay2 && subStage) {
9612
+ subStage.mount(stageOverlay2);
9613
+ const { mask, renderer } = subStage;
9614
+ const { contentWindow } = renderer;
9615
+ mask.showRule(false);
9616
+ services?.stageOverlayService.updateOverlay();
9617
+ contentWindow?.magic.onRuntimeReady({});
9618
+ }
9619
+ });
9620
+ const closeOverlayHandler = () => {
9621
+ services?.stageOverlayService.closeOverlay();
9622
+ };
9702
9623
  return (_ctx, _cache) => {
9703
- return vue.unref(stageOverlayVisible) ? (vue.openBlock(), vue.createElementBlock("div", {
9624
+ return stageOverlayVisible.value ? (vue.openBlock(), vue.createElementBlock("div", {
9704
9625
  key: 0,
9705
9626
  class: "m-editor-stage-overlay",
9706
- onClick: _cache[1] || (_cache[1] = //@ts-ignore
9707
- (...args) => vue.unref(closeOverlay) && vue.unref(closeOverlay)(...args))
9627
+ onClick: closeOverlayHandler
9708
9628
  }, [
9709
9629
  vue.createVNode(vue.unref(design.TMagicIcon), {
9710
9630
  class: "m-editor-stage-overlay-close",
9711
9631
  size: 20,
9712
- onClick: vue.unref(closeOverlay)
9632
+ onClick: closeOverlayHandler
9713
9633
  }, {
9714
9634
  default: vue.withCtx(() => [
9715
9635
  vue.createVNode(vue.unref(iconsVue.CloseBold))
9716
9636
  ]),
9717
9637
  _: 1
9718
- }, 8, ["onClick"]),
9638
+ }),
9719
9639
  vue.createElementVNode("div", {
9720
9640
  ref_key: "stageOverlay",
9721
9641
  ref: stageOverlay,
9722
9642
  class: "m-editor-stage-overlay-container",
9643
+ style: vue.normalizeStyle(style.value),
9723
9644
  onClick: _cache[0] || (_cache[0] = vue.withModifiers(() => {
9724
9645
  }, ["stop"]))
9725
- }, null, 512)
9646
+ }, null, 4)
9726
9647
  ])) : vue.createCommentVNode("", true);
9727
9648
  };
9728
9649
  }
@@ -9909,7 +9830,8 @@
9909
9830
  __name: "Stage",
9910
9831
  props: {
9911
9832
  stageContentMenu: {},
9912
- customContentMenu: { type: Function }
9833
+ disabledStageOverlay: { type: Boolean, default: false },
9834
+ customContentMenu: {}
9913
9835
  },
9914
9836
  setup(__props) {
9915
9837
  let stage = null;
@@ -10070,7 +9992,7 @@
10070
9992
  onClick: _cache[0] || (_cache[0] = ($event) => stageWrap.value?.container?.focus())
10071
9993
  }, {
10072
9994
  content: vue.withCtx(() => [
10073
- vue.createVNode(_sfc_main$6),
9995
+ !_ctx.disabledStageOverlay ? (vue.openBlock(), vue.createBlock(_sfc_main$6, { key: 0 })) : vue.createCommentVNode("", true),
10074
9996
  (vue.openBlock(), vue.createBlock(vue.Teleport, { to: "body" }, [
10075
9997
  vue.createVNode(_sfc_main$4, {
10076
9998
  ref_key: "menu",
@@ -10152,7 +10074,8 @@
10152
10074
  __name: "Workspace",
10153
10075
  props: {
10154
10076
  stageContentMenu: {},
10155
- customContentMenu: { type: Function }
10077
+ disabledStageOverlay: { type: Boolean, default: false },
10078
+ customContentMenu: {}
10156
10079
  },
10157
10080
  setup(__props) {
10158
10081
  const services = vue.inject("services");
@@ -10163,9 +10086,10 @@
10163
10086
  vue.renderSlot(_ctx.$slots, "stage", {}, () => [
10164
10087
  page.value ? (vue.openBlock(), vue.createBlock(_sfc_main$3, {
10165
10088
  key: 0,
10089
+ "disabled-stage-overlay": _ctx.disabledStageOverlay,
10166
10090
  "stage-content-menu": _ctx.stageContentMenu,
10167
10091
  "custom-content-menu": _ctx.customContentMenu
10168
- }, null, 8, ["stage-content-menu", "custom-content-menu"])) : vue.createCommentVNode("", true)
10092
+ }, null, 8, ["disabled-stage-overlay", "stage-content-menu", "custom-content-menu"])) : vue.createCommentVNode("", true)
10169
10093
  ]),
10170
10094
  vue.renderSlot(_ctx.$slots, "workspace-content")
10171
10095
  ]);
@@ -10624,7 +10548,152 @@
10624
10548
  }
10625
10549
  const keybindingService = new Keybinding();
10626
10550
 
10551
+ class StageOverlay extends BaseService {
10552
+ state = vue.reactive({
10553
+ wrapDiv: document.createElement("div"),
10554
+ sourceEl: null,
10555
+ contentEl: null,
10556
+ stage: null,
10557
+ stageOptions: null,
10558
+ wrapWidth: 0,
10559
+ wrapHeight: 0,
10560
+ stageOverlayVisible: false
10561
+ });
10562
+ constructor() {
10563
+ super([
10564
+ { name: "openOverlay", isAsync: false },
10565
+ { name: "closeOverlay", isAsync: false },
10566
+ { name: "updateOverlay", isAsync: false },
10567
+ { name: "createStage", isAsync: false }
10568
+ ]);
10569
+ this.get("wrapDiv").classList.add("tmagic-editor-sub-stage-wrap");
10570
+ }
10571
+ get(name) {
10572
+ return this.state[name];
10573
+ }
10574
+ set(name, value) {
10575
+ this.state[name] = value;
10576
+ }
10577
+ openOverlay(el) {
10578
+ const stageOptions = this.get("stageOptions");
10579
+ if (!el || !stageOptions)
10580
+ return;
10581
+ this.set("sourceEl", el);
10582
+ this.createContentEl();
10583
+ this.set("stageOverlayVisible", true);
10584
+ editorService.on("update", this.updateHandler);
10585
+ editorService.on("add", this.addHandler);
10586
+ editorService.on("remove", this.removeHandler);
10587
+ }
10588
+ closeOverlay() {
10589
+ this.set("stageOverlayVisible", false);
10590
+ const subStage = this.get("stage");
10591
+ const wrapDiv = this.get("wrapDiv");
10592
+ subStage?.destroy();
10593
+ wrapDiv.remove();
10594
+ this.set("stage", null);
10595
+ this.set("sourceEl", null);
10596
+ this.set("contentEl", null);
10597
+ editorService.off("update", this.updateHandler);
10598
+ editorService.off("add", this.addHandler);
10599
+ editorService.off("remove", this.removeHandler);
10600
+ }
10601
+ updateOverlay() {
10602
+ const sourceEl = this.get("sourceEl");
10603
+ if (!sourceEl)
10604
+ return;
10605
+ const { scrollWidth, scrollHeight } = sourceEl;
10606
+ this.set("wrapWidth", scrollWidth);
10607
+ this.set("wrapHeight", scrollHeight);
10608
+ }
10609
+ createStage(stageOptions = {}) {
10610
+ return useStage({
10611
+ ...stageOptions,
10612
+ runtimeUrl: "",
10613
+ autoScrollIntoView: false,
10614
+ render: async (stage) => {
10615
+ this.copyDocumentElement();
10616
+ const rootEls = stage.renderer.getDocument()?.body.children;
10617
+ if (rootEls) {
10618
+ Array.from(rootEls).forEach((element) => {
10619
+ if (["SCRIPT", "STYLE"].includes(element.tagName)) {
10620
+ return;
10621
+ }
10622
+ element.remove();
10623
+ });
10624
+ }
10625
+ const wrapDiv = this.get("wrapDiv");
10626
+ const sourceEl = this.get("sourceEl");
10627
+ wrapDiv.style.cssText = `
10628
+ width: ${sourceEl?.scrollWidth}px;
10629
+ height: ${sourceEl?.scrollHeight}px;
10630
+ background-color: #fff;
10631
+ `;
10632
+ await this.render();
10633
+ return wrapDiv;
10634
+ }
10635
+ });
10636
+ }
10637
+ createContentEl() {
10638
+ const sourceEl = this.get("sourceEl");
10639
+ if (!sourceEl)
10640
+ return;
10641
+ const contentEl = sourceEl.cloneNode(true);
10642
+ this.set("contentEl", contentEl);
10643
+ contentEl.style.position = "static";
10644
+ contentEl.style.overflow = "visible";
10645
+ }
10646
+ copyDocumentElement() {
10647
+ const subStage = this.get("stage");
10648
+ const stage = editorService.get("stage");
10649
+ const doc = subStage?.renderer.getDocument();
10650
+ const documentElement = stage?.renderer.getDocument()?.documentElement;
10651
+ if (doc && documentElement) {
10652
+ doc.replaceChild(documentElement.cloneNode(true), doc.documentElement);
10653
+ }
10654
+ }
10655
+ async render() {
10656
+ this.createContentEl();
10657
+ const contentEl = this.get("contentEl");
10658
+ const wrapDiv = this.get("wrapDiv");
10659
+ const subStage = this.get("stage");
10660
+ const stageOptions = this.get("stageOptions");
10661
+ if (!contentEl)
10662
+ return;
10663
+ Array.from(wrapDiv.children).forEach((element) => {
10664
+ element.remove();
10665
+ });
10666
+ wrapDiv.appendChild(contentEl);
10667
+ setTimeout(() => {
10668
+ subStage?.renderer.contentWindow?.magic.onPageElUpdate(wrapDiv);
10669
+ });
10670
+ if (await stageOptions?.canSelect?.(contentEl)) {
10671
+ subStage?.select(contentEl);
10672
+ }
10673
+ }
10674
+ updateHandler = () => {
10675
+ this.render();
10676
+ this.updateOverlay();
10677
+ };
10678
+ addHandler = () => {
10679
+ this.render();
10680
+ this.updateOverlay();
10681
+ };
10682
+ removeHandler = () => {
10683
+ this.render();
10684
+ this.updateOverlay();
10685
+ };
10686
+ }
10687
+ const stageOverlayService = new StageOverlay();
10688
+
10627
10689
  const defaultEditorProps = {
10690
+ renderType: StageCore.RenderType.IFRAME,
10691
+ disabledMultiSelect: false,
10692
+ disabledPageFragment: false,
10693
+ disabledStageOverlay: false,
10694
+ containerHighlightClassName: StageCore.CONTAINER_HIGHLIGHT_CLASS_NAME,
10695
+ containerHighlightDuration: 800,
10696
+ containerHighlightType: StageCore.ContainerHighlightType.DEFAULT,
10628
10697
  componentGroupList: () => [],
10629
10698
  datasourceList: () => [],
10630
10699
  menu: () => ({ left: [], right: [] }),
@@ -10637,13 +10706,7 @@
10637
10706
  datasourceConfigs: () => ({}),
10638
10707
  canSelect: (el) => Boolean(el.id),
10639
10708
  isContainer: (el) => el.classList.contains("magic-ui-container"),
10640
- containerHighlightClassName: StageCore.CONTAINER_HIGHLIGHT_CLASS_NAME,
10641
- containerHighlightDuration: 800,
10642
- containerHighlightType: StageCore.ContainerHighlightType.DEFAULT,
10643
- codeOptions: () => ({}),
10644
- renderType: StageCore.RenderType.IFRAME,
10645
- disabledMultiSelect: false,
10646
- disabledPageFragment: false
10709
+ codeOptions: () => ({})
10647
10710
  };
10648
10711
 
10649
10712
  const initServiceState = (props, {
@@ -10990,7 +11053,6 @@
10990
11053
  menu: {},
10991
11054
  layerContentMenu: {},
10992
11055
  stageContentMenu: {},
10993
- render: { type: Function },
10994
11056
  runtimeUrl: {},
10995
11057
  renderType: {},
10996
11058
  autoScrollIntoView: { type: Boolean },
@@ -11002,21 +11064,23 @@
11002
11064
  datasourceEventMethodList: {},
11003
11065
  moveableOptions: { type: Function },
11004
11066
  defaultSelected: {},
11005
- canSelect: { type: Function },
11006
- isContainer: { type: Function },
11007
11067
  containerHighlightClassName: {},
11008
11068
  containerHighlightDuration: {},
11009
11069
  containerHighlightType: {},
11010
11070
  stageRect: {},
11011
11071
  codeOptions: {},
11012
- updateDragEl: { type: Function },
11013
11072
  disabledDragStart: { type: Boolean },
11014
- extendFormState: { type: Function },
11015
11073
  collectorOptions: {},
11016
11074
  guidesOptions: {},
11017
11075
  disabledMultiSelect: { type: Boolean },
11018
11076
  disabledPageFragment: { type: Boolean },
11019
- customContentMenu: { type: Function }
11077
+ disabledStageOverlay: { type: Boolean },
11078
+ render: { type: Function },
11079
+ updateDragEl: { type: Function },
11080
+ canSelect: { type: Function },
11081
+ isContainer: { type: Function },
11082
+ customContentMenu: { type: Function },
11083
+ extendFormState: { type: Function }
11020
11084
  }, defaultEditorProps),
11021
11085
  emits: ["props-panel-mounted", "update:modelValue", "props-form-error", "props-submit-error"],
11022
11086
  setup(__props, { expose: __expose, emit: __emit }) {
@@ -11033,33 +11097,33 @@
11033
11097
  codeBlockService,
11034
11098
  depService,
11035
11099
  dataSourceService,
11036
- keybindingService
11100
+ keybindingService,
11101
+ stageOverlayService
11037
11102
  };
11038
11103
  initServiceEvents(props, emit, services);
11039
11104
  initServiceState(props, services);
11040
11105
  keybindingService.register(keybindingConfig);
11041
11106
  keybindingService.registerEl("global");
11107
+ const stageOptions = {
11108
+ runtimeUrl: props.runtimeUrl,
11109
+ autoScrollIntoView: props.autoScrollIntoView,
11110
+ render: props.render,
11111
+ moveableOptions: props.moveableOptions,
11112
+ canSelect: props.canSelect,
11113
+ updateDragEl: props.updateDragEl,
11114
+ isContainer: props.isContainer,
11115
+ containerHighlightClassName: props.containerHighlightClassName,
11116
+ containerHighlightDuration: props.containerHighlightDuration,
11117
+ containerHighlightType: props.containerHighlightType,
11118
+ disabledDragStart: props.disabledDragStart,
11119
+ renderType: props.renderType,
11120
+ guidesOptions: props.guidesOptions,
11121
+ disabledMultiSelect: props.disabledMultiSelect
11122
+ };
11123
+ stageOverlayService.set("stageOptions", stageOptions);
11042
11124
  vue.provide("services", services);
11043
11125
  vue.provide("codeOptions", props.codeOptions);
11044
- vue.provide(
11045
- "stageOptions",
11046
- vue.reactive({
11047
- runtimeUrl: props.runtimeUrl,
11048
- autoScrollIntoView: props.autoScrollIntoView,
11049
- render: props.render,
11050
- moveableOptions: props.moveableOptions,
11051
- canSelect: props.canSelect,
11052
- updateDragEl: props.updateDragEl,
11053
- isContainer: props.isContainer,
11054
- containerHighlightClassName: props.containerHighlightClassName,
11055
- containerHighlightDuration: props.containerHighlightDuration,
11056
- containerHighlightType: props.containerHighlightType,
11057
- disabledDragStart: props.disabledDragStart,
11058
- renderType: props.renderType,
11059
- guidesOptions: props.guidesOptions,
11060
- disabledMultiSelect: props.disabledMultiSelect
11061
- })
11062
- );
11126
+ vue.provide("stageOptions", stageOptions);
11063
11127
  __expose(services);
11064
11128
  return (_ctx, _cache) => {
11065
11129
  return vue.openBlock(), vue.createBlock(_sfc_main$s, { "disabled-page-fragment": _ctx.disabledPageFragment }, {
@@ -11121,6 +11185,7 @@
11121
11185
  workspace: vue.withCtx(() => [
11122
11186
  vue.renderSlot(_ctx.$slots, "workspace", { editorService: vue.unref(editorService) }, () => [
11123
11187
  vue.createVNode(_sfc_main$1, {
11188
+ "disabled-stage-overlay": _ctx.disabledStageOverlay,
11124
11189
  "stage-content-menu": _ctx.stageContentMenu,
11125
11190
  "custom-content-menu": _ctx.customContentMenu
11126
11191
  }, {
@@ -11131,7 +11196,7 @@
11131
11196
  vue.renderSlot(_ctx.$slots, "workspace-content", { editorService: vue.unref(editorService) })
11132
11197
  ]),
11133
11198
  _: 3
11134
- }, 8, ["stage-content-menu", "custom-content-menu"])
11199
+ }, 8, ["disabled-stage-overlay", "stage-content-menu", "custom-content-menu"])
11135
11200
  ])
11136
11201
  ]),
11137
11202
  "props-panel": vue.withCtx(() => [
@@ -11286,6 +11351,7 @@
11286
11351
  exports.setChildrenLayout = setChildrenLayout;
11287
11352
  exports.setConfig = setConfig;
11288
11353
  exports.setLayout = setLayout;
11354
+ exports.stageOverlayService = stageOverlayService;
11289
11355
  exports.storageService = storageService;
11290
11356
  exports.styleTabConfig = styleTabConfig;
11291
11357
  exports.traverseNode = traverseNode;