@tmagic/stage 1.2.0-beta.7 → 1.2.0-beta.9

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.
@@ -45,6 +45,77 @@
45
45
  })(Mode || {});
46
46
  const SELECTED_CLASS = "tmagic-stage-selected-area";
47
47
 
48
+ const selectParentAbles = (dr) => ({
49
+ name: "selectParent",
50
+ props: {},
51
+ events: {},
52
+ render(moveable, React) {
53
+ const rect = moveable.getRect();
54
+ const { pos2 } = moveable.state;
55
+ const editableViewer = moveable.useCSS(
56
+ "div",
57
+ `
58
+ {
59
+ position: absolute;
60
+ left: 0px;
61
+ top: 0px;
62
+ will-change: transform;
63
+ transform-origin: 0px 0px;
64
+ display: flex;
65
+ }
66
+ .moveable-button {
67
+ width: 20px;
68
+ height: 20px;
69
+ background: #4af;
70
+ border-radius: 4px;
71
+ appearance: none;
72
+ border: 0;
73
+ color: white;
74
+ font-size: 12px;
75
+ font-weight: bold;
76
+ }
77
+ `
78
+ );
79
+ return React.createElement(
80
+ editableViewer,
81
+ {
82
+ className: "moveable-editable",
83
+ style: {
84
+ transform: `translate(${pos2[0] - 25}px, ${pos2[1] - 30}px) rotate(${rect.rotation}deg) translate(10px)`
85
+ }
86
+ },
87
+ React.createElement(
88
+ "button",
89
+ {
90
+ className: "moveable-button",
91
+ title: "\u9009\u4E2D\u7236\u7EC4\u4EF6",
92
+ onClick: () => {
93
+ dr.emit("select-parent");
94
+ }
95
+ },
96
+ React.createElement(
97
+ "svg",
98
+ {
99
+ width: "1em",
100
+ height: "1em",
101
+ viewBox: "0 0 16 16",
102
+ fill: "none",
103
+ xmlns: "http://www.w3.org/2000/svg",
104
+ style: {
105
+ transform: "rotate(90deg)"
106
+ }
107
+ },
108
+ React.createElement("path", {
109
+ d: "M13.0001 4V10H4.20718L5.85363 8.35355L5.14652 7.64645L2.64652 10.1464C2.45126 10.3417 2.45126 10.6583 2.64652 10.8536L5.14652 13.3536L5.85363 12.6464L4.20718 11H13.0001C13.5524 11 14.0001 10.5523 14.0001 10V4H13.0001Z",
110
+ fill: "currentColor",
111
+ fillOpacity: "0.9"
112
+ })
113
+ )
114
+ )
115
+ );
116
+ }
117
+ });
118
+
48
119
  var ContainerHighlightType = /* @__PURE__ */ ((ContainerHighlightType2) => {
49
120
  ContainerHighlightType2["DEFAULT"] = "default";
50
121
  ContainerHighlightType2["ALT"] = "alt";
@@ -141,6 +212,8 @@
141
212
  return null;
142
213
  for (let parent = element; parent.parentElement; ) {
143
214
  parent = parent.parentElement;
215
+ if (parent.tagName === "HTML")
216
+ return parent;
144
217
  style = getComputedStyle(parent);
145
218
  if (isAbsolute(style) && isStatic(style))
146
219
  continue;
@@ -225,6 +298,7 @@
225
298
  dist: upEls.length && swapIndex > -1 ? upEls[swapIndex].id : target.id
226
299
  };
227
300
  };
301
+ const isMoveableButton = (target) => target.classList.contains("moveable-button") || target.parentElement?.classList.contains("moveable-button");
228
302
 
229
303
  class StageDragResize extends EventEmitter.EventEmitter {
230
304
  core;
@@ -670,6 +744,10 @@
670
744
  bottom: isSortable ? void 0 : this.container.clientHeight,
671
745
  ...moveableOptions.bounds || {}
672
746
  },
747
+ props: {
748
+ selectParent: true
749
+ },
750
+ ables: [selectParentAbles(this)],
673
751
  ...options,
674
752
  ...moveableOptions
675
753
  };
@@ -800,6 +878,7 @@
800
878
  verticalGuidelines = [];
801
879
  container;
802
880
  containerResizeObserver;
881
+ isShowGuides = true;
803
882
  constructor(container) {
804
883
  super();
805
884
  this.container = container;
@@ -813,12 +892,13 @@
813
892
  });
814
893
  this.containerResizeObserver.observe(this.container);
815
894
  }
816
- showGuides(show = true) {
895
+ showGuides(isShowGuides = true) {
896
+ this.isShowGuides = isShowGuides;
817
897
  this.hGuides.setState({
818
- showGuides: show
898
+ showGuides: isShowGuides
819
899
  });
820
900
  this.vGuides.setState({
821
- showGuides: show
901
+ showGuides: isShowGuides
822
902
  });
823
903
  }
824
904
  setGuides([hLines, vLines]) {
@@ -888,7 +968,8 @@
888
968
  backgroundColor: "#fff",
889
969
  lineColor: "#000",
890
970
  textColor: "#000",
891
- style: this.getGuidesStyle(type)
971
+ style: this.getGuidesStyle(type),
972
+ showGuides: this.isShowGuides
892
973
  });
893
974
  hGuidesChangeGuidesHandler = (e) => {
894
975
  this.horizontalGuidelines = e.guides;
@@ -939,9 +1020,7 @@
939
1020
  class StageMask extends Rule {
940
1021
  content = createContent();
941
1022
  wrapper;
942
- core;
943
1023
  page = null;
944
- pageScrollParent = null;
945
1024
  scrollTop = 0;
946
1025
  scrollLeft = 0;
947
1026
  width = 0;
@@ -950,37 +1029,21 @@
950
1029
  wrapperWidth = 0;
951
1030
  maxScrollTop = 0;
952
1031
  maxScrollLeft = 0;
953
- intersectionObserver = null;
954
1032
  isMultiSelectStatus = false;
955
1033
  mode = Mode.ABSOLUTE;
956
- pageResizeObserver = null;
1034
+ pageScrollParent = null;
1035
+ intersectionObserver = null;
957
1036
  wrapperResizeObserver = null;
958
1037
  highlightHandler = lodashEs.throttle((event) => {
959
1038
  this.emit("highlight", event);
960
1039
  }, throttleTime);
961
- constructor(config) {
1040
+ constructor() {
962
1041
  const wrapper = createWrapper();
963
1042
  super(wrapper);
964
1043
  this.wrapper = wrapper;
965
- this.core = config.core;
966
- this.content.addEventListener("mousedown", this.mouseDownHandler);
1044
+ this.initContentEventListener();
967
1045
  this.wrapper.appendChild(this.content);
968
- this.content.addEventListener("wheel", this.mouseWheelHandler);
969
- this.content.addEventListener("mousemove", this.highlightHandler);
970
- this.content.addEventListener("mouseleave", this.mouseLeaveHandler);
971
- const isMac = /mac os x/.test(navigator.userAgent.toLowerCase());
972
- const ctrl = isMac ? "meta" : "ctrl";
973
- KeyController__default.default.global.keydown(ctrl, (e) => {
974
- e.inputEvent.preventDefault();
975
- this.isMultiSelectStatus = true;
976
- });
977
- KeyController__default.default.global.on("blur", () => {
978
- this.isMultiSelectStatus = false;
979
- });
980
- KeyController__default.default.global.keyup(ctrl, (e) => {
981
- e.inputEvent.preventDefault();
982
- this.isMultiSelectStatus = false;
983
- });
1046
+ this.initMultiSelectEvent();
984
1047
  }
985
1048
  setMode(mode) {
986
1049
  this.mode = mode;
@@ -997,9 +1060,66 @@
997
1060
  if (!page)
998
1061
  return;
999
1062
  this.page = page;
1000
- this.pageScrollParent = getScrollParent(page) || this.core.renderer.contentWindow?.document.documentElement || null;
1001
- this.pageResizeObserver?.disconnect();
1063
+ this.initObserverIntersection();
1064
+ this.initObserverWrapper();
1065
+ }
1066
+ pageResize(entries) {
1067
+ const [entry] = entries;
1068
+ const { clientHeight, clientWidth } = entry.target;
1069
+ this.setHeight(clientHeight);
1070
+ this.setWidth(clientWidth);
1071
+ this.scroll();
1072
+ }
1073
+ observerIntersection(el) {
1074
+ this.intersectionObserver?.observe(el);
1075
+ }
1076
+ mount(el) {
1077
+ if (!this.content)
1078
+ throw new Error("content \u4E0D\u5B58\u5728");
1079
+ el.appendChild(this.wrapper);
1080
+ }
1081
+ setLayout(el) {
1082
+ this.setMode(isFixedParent(el) ? Mode.FIXED : Mode.ABSOLUTE);
1083
+ }
1084
+ scrollIntoView(el) {
1085
+ el.scrollIntoView();
1086
+ if (!this.pageScrollParent)
1087
+ return;
1088
+ this.scrollLeft = this.pageScrollParent.scrollLeft;
1089
+ this.scrollTop = this.pageScrollParent.scrollTop;
1090
+ this.scroll();
1091
+ }
1092
+ destroy() {
1093
+ this.content?.remove();
1094
+ this.page = null;
1095
+ this.pageScrollParent = null;
1002
1096
  this.wrapperResizeObserver?.disconnect();
1097
+ this.content.removeEventListener("mouseleave", this.mouseLeaveHandler);
1098
+ super.destroy();
1099
+ }
1100
+ initContentEventListener() {
1101
+ this.content.addEventListener("mousedown", this.mouseDownHandler);
1102
+ this.content.addEventListener("wheel", this.mouseWheelHandler);
1103
+ this.content.addEventListener("mousemove", this.highlightHandler);
1104
+ this.content.addEventListener("mouseleave", this.mouseLeaveHandler);
1105
+ }
1106
+ initMultiSelectEvent() {
1107
+ const isMac = /mac os x/.test(navigator.userAgent.toLowerCase());
1108
+ const ctrl = isMac ? "meta" : "ctrl";
1109
+ KeyController__default.default.global.keydown(ctrl, (e) => {
1110
+ e.inputEvent.preventDefault();
1111
+ this.isMultiSelectStatus = true;
1112
+ });
1113
+ KeyController__default.default.global.on("blur", () => {
1114
+ this.isMultiSelectStatus = false;
1115
+ });
1116
+ KeyController__default.default.global.keyup(ctrl, (e) => {
1117
+ e.inputEvent.preventDefault();
1118
+ this.isMultiSelectStatus = false;
1119
+ });
1120
+ }
1121
+ initObserverIntersection() {
1122
+ this.pageScrollParent = getScrollParent(this.page) || null;
1003
1123
  this.intersectionObserver?.disconnect();
1004
1124
  if (typeof IntersectionObserver !== "undefined") {
1005
1125
  this.intersectionObserver = new IntersectionObserver(
@@ -1019,18 +1139,10 @@
1019
1139
  }
1020
1140
  );
1021
1141
  }
1142
+ }
1143
+ initObserverWrapper() {
1144
+ this.wrapperResizeObserver?.disconnect();
1022
1145
  if (typeof ResizeObserver !== "undefined") {
1023
- this.pageResizeObserver = new ResizeObserver((entries) => {
1024
- const [entry] = entries;
1025
- const { clientHeight, clientWidth } = entry.target;
1026
- this.setHeight(clientHeight);
1027
- this.setWidth(clientWidth);
1028
- this.scroll();
1029
- if (this.core.dr.moveable) {
1030
- this.core.dr.updateMoveable();
1031
- }
1032
- });
1033
- this.pageResizeObserver.observe(page);
1034
1146
  this.wrapperResizeObserver = new ResizeObserver((entries) => {
1035
1147
  const [entry] = entries;
1036
1148
  const { clientHeight, clientWidth } = entry.target;
@@ -1042,31 +1154,6 @@
1042
1154
  this.wrapperResizeObserver.observe(this.wrapper);
1043
1155
  }
1044
1156
  }
1045
- mount(el) {
1046
- if (!this.content)
1047
- throw new Error("content \u4E0D\u5B58\u5728");
1048
- el.appendChild(this.wrapper);
1049
- }
1050
- setLayout(el) {
1051
- this.setMode(isFixedParent(el) ? Mode.FIXED : Mode.ABSOLUTE);
1052
- }
1053
- scrollIntoView(el) {
1054
- el.scrollIntoView();
1055
- if (!this.pageScrollParent)
1056
- return;
1057
- this.scrollLeft = this.pageScrollParent.scrollLeft;
1058
- this.scrollTop = this.pageScrollParent.scrollTop;
1059
- this.scroll();
1060
- }
1061
- destroy() {
1062
- this.content?.remove();
1063
- this.page = null;
1064
- this.pageScrollParent = null;
1065
- this.pageResizeObserver?.disconnect();
1066
- this.wrapperResizeObserver?.disconnect();
1067
- this.content.removeEventListener("mouseleave", this.mouseLeaveHandler);
1068
- super.destroy();
1069
- }
1070
1157
  scroll() {
1071
1158
  this.fixScrollValue();
1072
1159
  let { scrollLeft, scrollTop } = this;
@@ -1118,10 +1205,13 @@
1118
1205
  event.stopPropagation();
1119
1206
  if (event.button !== MouseButton.LEFT && event.button !== MouseButton.RIGHT)
1120
1207
  return;
1121
- if (!this.isMultiSelectStatus && event.target.className.indexOf("moveable-area") !== -1) {
1208
+ if (!event.target)
1209
+ return;
1210
+ const targetClassList = event.target.classList;
1211
+ if (!this.isMultiSelectStatus && targetClassList.contains("moveable-area")) {
1122
1212
  return;
1123
1213
  }
1124
- if (event.target.className.indexOf("moveable-control") !== -1) {
1214
+ if (targetClassList.contains("moveable-control") || isMoveableButton(event.target)) {
1125
1215
  return;
1126
1216
  }
1127
1217
  this.content.removeEventListener("mousemove", this.highlightHandler);
@@ -1383,13 +1473,11 @@
1383
1473
  runtime = null;
1384
1474
  iframe;
1385
1475
  runtimeUrl;
1386
- core;
1387
1476
  render;
1388
- constructor({ core }) {
1477
+ constructor({ runtimeUrl, render }) {
1389
1478
  super();
1390
- this.core = core;
1391
- this.runtimeUrl = core.config.runtimeUrl || "";
1392
- this.render = core.config.render;
1479
+ this.runtimeUrl = runtimeUrl || "";
1480
+ this.render = render;
1393
1481
  this.iframe = globalThis.document.createElement("iframe");
1394
1482
  this.iframe.src = utils.isSameDomain(this.runtimeUrl) ? this.runtimeUrl : "";
1395
1483
  this.iframe.style.cssText = `
@@ -1432,6 +1520,9 @@
1432
1520
  this.on("runtime-ready", listener);
1433
1521
  });
1434
1522
  };
1523
+ getDocument() {
1524
+ return this.contentWindow?.document;
1525
+ }
1435
1526
  destroy() {
1436
1527
  this.iframe?.removeEventListener("load", this.loadHandler);
1437
1528
  this.contentWindow = null;
@@ -1446,7 +1537,7 @@
1446
1537
  if (!this.contentWindow)
1447
1538
  return;
1448
1539
  if (this.render) {
1449
- const el = await this.render(this.core);
1540
+ const el = await this.render();
1450
1541
  if (el) {
1451
1542
  this.contentWindow.document?.body?.appendChild(el);
1452
1543
  }
@@ -1483,6 +1574,7 @@
1483
1574
  containerHighlightType;
1484
1575
  isContainer;
1485
1576
  canSelect;
1577
+ pageResizeObserver = null;
1486
1578
  constructor(config) {
1487
1579
  super();
1488
1580
  this.config = config;
@@ -1492,8 +1584,8 @@
1492
1584
  this.containerHighlightClassName = config.containerHighlightClassName || CONTAINER_HIGHLIGHT_CLASS;
1493
1585
  this.containerHighlightDuration = config.containerHighlightDuration || 800;
1494
1586
  this.containerHighlightType = config.containerHighlightType;
1495
- this.renderer = new StageRender({ core: this });
1496
- this.mask = new StageMask({ core: this });
1587
+ this.renderer = new StageRender({ runtimeUrl: config.runtimeUrl, render: this.render.bind(this) });
1588
+ this.mask = new StageMask();
1497
1589
  this.dr = new StageDragResize({ core: this, container: this.mask.content, mask: this.mask });
1498
1590
  this.multiDr = new StageMultiDragResize({ core: this, container: this.mask.content, mask: this.mask });
1499
1591
  this.highlightLayer = new StageHighlight({ core: this, container: this.mask.wrapper });
@@ -1502,6 +1594,7 @@
1502
1594
  });
1503
1595
  this.renderer.on("page-el-update", (el) => {
1504
1596
  this.mask?.observe(el);
1597
+ this.observePageResize(el);
1505
1598
  });
1506
1599
  this.mask.on("beforeSelect", async (event) => {
1507
1600
  this.clearSelectStatus("multiSelect");
@@ -1549,6 +1642,8 @@
1549
1642
  setTimeout(() => this.emit("update", data));
1550
1643
  }).on("sort", (data) => {
1551
1644
  setTimeout(() => this.emit("sort", data));
1645
+ }).on("select-parent", () => {
1646
+ this.emit("select-parent");
1552
1647
  });
1553
1648
  this.multiDr.on("update", (data) => {
1554
1649
  setTimeout(() => this.emit("update", data));
@@ -1560,7 +1655,6 @@
1560
1655
  }
1561
1656
  getElementsFromPoint(event) {
1562
1657
  const { renderer, zoom } = this;
1563
- const doc = renderer.contentWindow?.document;
1564
1658
  let x = event.clientX;
1565
1659
  let y = event.clientY;
1566
1660
  if (renderer.iframe) {
@@ -1570,7 +1664,7 @@
1570
1664
  y = y - rect.top;
1571
1665
  }
1572
1666
  }
1573
- return doc?.elementsFromPoint(x / zoom, y / zoom);
1667
+ return renderer.getDocument()?.elementsFromPoint(x / zoom, y / zoom);
1574
1668
  }
1575
1669
  async getElementFromPoint(event) {
1576
1670
  const els = this.getElementsFromPoint(event);
@@ -1606,13 +1700,14 @@
1606
1700
  this.mask.setLayout(el);
1607
1701
  this.dr.select(el, event);
1608
1702
  if (this.config.autoScrollIntoView || el.dataset.autoScrollIntoView) {
1609
- this.mask.intersectionObserver?.observe(el);
1703
+ this.mask.observerIntersection(el);
1610
1704
  }
1611
1705
  this.selectedDom = el;
1612
- if (this.renderer.contentWindow) {
1613
- removeSelectedClassName(this.renderer.contentWindow.document);
1706
+ const doc = this.renderer.getDocument();
1707
+ if (doc) {
1708
+ removeSelectedClassName(doc);
1614
1709
  if (this.selectedDom) {
1615
- addSelectedClassName(this.selectedDom, this.renderer.contentWindow.document);
1710
+ addSelectedClassName(this.selectedDom, doc);
1616
1711
  }
1617
1712
  }
1618
1713
  }
@@ -1626,7 +1721,7 @@
1626
1721
  return this.renderer?.getRuntime().then((runtime) => {
1627
1722
  runtime?.update?.(data);
1628
1723
  setTimeout(() => {
1629
- const el = this.renderer.contentWindow?.document.getElementById(`${config.id}`);
1724
+ const el = this.renderer.getDocument()?.getElementById(`${config.id}`);
1630
1725
  if (el && el.id === this.selectedDom?.id) {
1631
1726
  this.selectedDom = el;
1632
1727
  this.mask.setLayout(el);
@@ -1682,7 +1777,7 @@
1682
1777
  async addContainerHighlightClassName(event, exclude) {
1683
1778
  const els = this.getElementsFromPoint(event);
1684
1779
  const { renderer } = this;
1685
- const doc = renderer.contentWindow?.document;
1780
+ const doc = renderer.getDocument();
1686
1781
  if (!doc)
1687
1782
  return;
1688
1783
  for (const el of els) {
@@ -1698,17 +1793,35 @@
1698
1793
  }, this.containerHighlightDuration);
1699
1794
  }
1700
1795
  destroy() {
1701
- const { mask, renderer, dr, highlightLayer } = this;
1796
+ const { mask, renderer, dr, highlightLayer, pageResizeObserver } = this;
1702
1797
  renderer.destroy();
1703
1798
  mask.destroy();
1704
1799
  dr.destroy();
1705
1800
  highlightLayer.destroy();
1801
+ pageResizeObserver?.disconnect();
1706
1802
  this.removeAllListeners();
1707
1803
  this.container = void 0;
1708
1804
  }
1805
+ observePageResize(page) {
1806
+ if (typeof ResizeObserver !== "undefined") {
1807
+ this.pageResizeObserver = new ResizeObserver((entries) => {
1808
+ this.mask.pageResize(entries);
1809
+ if (this.dr.moveable) {
1810
+ this.dr.updateMoveable();
1811
+ }
1812
+ });
1813
+ this.pageResizeObserver.observe(page);
1814
+ }
1815
+ }
1816
+ async render() {
1817
+ if (this.config?.render) {
1818
+ return await this.config.render(this);
1819
+ }
1820
+ return null;
1821
+ }
1709
1822
  async getTargetElement(idOrEl) {
1710
1823
  if (typeof idOrEl === "string" || typeof idOrEl === "number") {
1711
- const el = this.renderer.contentWindow?.document.getElementById(`${idOrEl}`);
1824
+ const el = this.renderer.getDocument()?.getElementById(`${idOrEl}`);
1712
1825
  if (!el)
1713
1826
  throw new Error(`\u4E0D\u5B58\u5728ID\u4E3A${idOrEl}\u7684\u5143\u7D20`);
1714
1827
  return el;
@@ -1745,6 +1858,7 @@
1745
1858
  exports.isAbsolute = isAbsolute;
1746
1859
  exports.isFixed = isFixed;
1747
1860
  exports.isFixedParent = isFixedParent;
1861
+ exports.isMoveableButton = isMoveableButton;
1748
1862
  exports.isRelative = isRelative;
1749
1863
  exports.isStatic = isStatic;
1750
1864
  exports.removeSelectedClassName = removeSelectedClassName;