@tmagic/stage 1.2.0-beta.1 → 1.2.0-beta.11

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;
@@ -499,10 +573,14 @@
499
573
  this.dragStatus = StageDragStatus.END;
500
574
  const frame = this.moveableHelper?.getFrame(e.target);
501
575
  this.emit("update", {
502
- el: this.target,
503
- style: {
504
- transform: frame?.get("transform")
505
- }
576
+ data: [
577
+ {
578
+ el: this.target,
579
+ style: {
580
+ transform: frame?.get("transform")
581
+ }
582
+ }
583
+ ]
506
584
  });
507
585
  });
508
586
  }
@@ -523,10 +601,14 @@
523
601
  this.dragStatus = StageDragStatus.END;
524
602
  const frame = this.moveableHelper?.getFrame(e.target);
525
603
  this.emit("update", {
526
- el: this.target,
527
- style: {
528
- transform: frame?.get("transform")
529
- }
604
+ data: [
605
+ {
606
+ el: this.target,
607
+ style: {
608
+ transform: frame?.get("transform")
609
+ }
610
+ }
611
+ ]
530
612
  });
531
613
  });
532
614
  }
@@ -631,7 +713,7 @@
631
713
  resizable: true,
632
714
  scalable: false,
633
715
  rotatable: false,
634
- snappable: isAbsolute || isFixed,
716
+ snappable: true,
635
717
  snapGap: isAbsolute || isFixed,
636
718
  snapThreshold: 5,
637
719
  snapDigit: 0,
@@ -662,6 +744,10 @@
662
744
  bottom: isSortable ? void 0 : this.container.clientHeight,
663
745
  ...moveableOptions.bounds || {}
664
746
  },
747
+ props: {
748
+ selectParent: true
749
+ },
750
+ ables: [selectParentAbles(this)],
665
751
  ...options,
666
752
  ...moveableOptions
667
753
  };
@@ -792,6 +878,7 @@
792
878
  verticalGuidelines = [];
793
879
  container;
794
880
  containerResizeObserver;
881
+ isShowGuides = true;
795
882
  constructor(container) {
796
883
  super();
797
884
  this.container = container;
@@ -805,12 +892,13 @@
805
892
  });
806
893
  this.containerResizeObserver.observe(this.container);
807
894
  }
808
- showGuides(show = true) {
895
+ showGuides(isShowGuides = true) {
896
+ this.isShowGuides = isShowGuides;
809
897
  this.hGuides.setState({
810
- showGuides: show
898
+ showGuides: isShowGuides
811
899
  });
812
900
  this.vGuides.setState({
813
- showGuides: show
901
+ showGuides: isShowGuides
814
902
  });
815
903
  }
816
904
  setGuides([hLines, vLines]) {
@@ -880,7 +968,8 @@
880
968
  backgroundColor: "#fff",
881
969
  lineColor: "#000",
882
970
  textColor: "#000",
883
- style: this.getGuidesStyle(type)
971
+ style: this.getGuidesStyle(type),
972
+ showGuides: this.isShowGuides
884
973
  });
885
974
  hGuidesChangeGuidesHandler = (e) => {
886
975
  this.horizontalGuidelines = e.guides;
@@ -931,9 +1020,7 @@
931
1020
  class StageMask extends Rule {
932
1021
  content = createContent();
933
1022
  wrapper;
934
- core;
935
1023
  page = null;
936
- pageScrollParent = null;
937
1024
  scrollTop = 0;
938
1025
  scrollLeft = 0;
939
1026
  width = 0;
@@ -942,37 +1029,21 @@
942
1029
  wrapperWidth = 0;
943
1030
  maxScrollTop = 0;
944
1031
  maxScrollLeft = 0;
945
- intersectionObserver = null;
946
1032
  isMultiSelectStatus = false;
947
1033
  mode = Mode.ABSOLUTE;
948
- pageResizeObserver = null;
1034
+ pageScrollParent = null;
1035
+ intersectionObserver = null;
949
1036
  wrapperResizeObserver = null;
950
1037
  highlightHandler = lodashEs.throttle((event) => {
951
1038
  this.emit("highlight", event);
952
1039
  }, throttleTime);
953
- constructor(config) {
1040
+ constructor() {
954
1041
  const wrapper = createWrapper();
955
1042
  super(wrapper);
956
1043
  this.wrapper = wrapper;
957
- this.core = config.core;
958
- this.content.addEventListener("mousedown", this.mouseDownHandler);
1044
+ this.initContentEventListener();
959
1045
  this.wrapper.appendChild(this.content);
960
- this.content.addEventListener("wheel", this.mouseWheelHandler);
961
- this.content.addEventListener("mousemove", this.highlightHandler);
962
- this.content.addEventListener("mouseleave", this.mouseLeaveHandler);
963
- const isMac = /mac os x/.test(navigator.userAgent.toLowerCase());
964
- const ctrl = isMac ? "meta" : "ctrl";
965
- KeyController__default.default.global.keydown(ctrl, (e) => {
966
- e.inputEvent.preventDefault();
967
- this.isMultiSelectStatus = true;
968
- });
969
- KeyController__default.default.global.on("blur", () => {
970
- this.isMultiSelectStatus = false;
971
- });
972
- KeyController__default.default.global.keyup(ctrl, (e) => {
973
- e.inputEvent.preventDefault();
974
- this.isMultiSelectStatus = false;
975
- });
1046
+ this.initMultiSelectEvent();
976
1047
  }
977
1048
  setMode(mode) {
978
1049
  this.mode = mode;
@@ -989,9 +1060,66 @@
989
1060
  if (!page)
990
1061
  return;
991
1062
  this.page = page;
992
- this.pageScrollParent = getScrollParent(page) || this.core.renderer.contentWindow?.document.documentElement || null;
993
- 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;
994
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;
995
1123
  this.intersectionObserver?.disconnect();
996
1124
  if (typeof IntersectionObserver !== "undefined") {
997
1125
  this.intersectionObserver = new IntersectionObserver(
@@ -1011,18 +1139,10 @@
1011
1139
  }
1012
1140
  );
1013
1141
  }
1142
+ }
1143
+ initObserverWrapper() {
1144
+ this.wrapperResizeObserver?.disconnect();
1014
1145
  if (typeof ResizeObserver !== "undefined") {
1015
- this.pageResizeObserver = new ResizeObserver((entries) => {
1016
- const [entry] = entries;
1017
- const { clientHeight, clientWidth } = entry.target;
1018
- this.setHeight(clientHeight);
1019
- this.setWidth(clientWidth);
1020
- this.scroll();
1021
- if (this.core.dr.moveable) {
1022
- this.core.dr.updateMoveable();
1023
- }
1024
- });
1025
- this.pageResizeObserver.observe(page);
1026
1146
  this.wrapperResizeObserver = new ResizeObserver((entries) => {
1027
1147
  const [entry] = entries;
1028
1148
  const { clientHeight, clientWidth } = entry.target;
@@ -1034,31 +1154,6 @@
1034
1154
  this.wrapperResizeObserver.observe(this.wrapper);
1035
1155
  }
1036
1156
  }
1037
- mount(el) {
1038
- if (!this.content)
1039
- throw new Error("content \u4E0D\u5B58\u5728");
1040
- el.appendChild(this.wrapper);
1041
- }
1042
- setLayout(el) {
1043
- this.setMode(isFixedParent(el) ? Mode.FIXED : Mode.ABSOLUTE);
1044
- }
1045
- scrollIntoView(el) {
1046
- el.scrollIntoView();
1047
- if (!this.pageScrollParent)
1048
- return;
1049
- this.scrollLeft = this.pageScrollParent.scrollLeft;
1050
- this.scrollTop = this.pageScrollParent.scrollTop;
1051
- this.scroll();
1052
- }
1053
- destroy() {
1054
- this.content?.remove();
1055
- this.page = null;
1056
- this.pageScrollParent = null;
1057
- this.pageResizeObserver?.disconnect();
1058
- this.wrapperResizeObserver?.disconnect();
1059
- this.content.removeEventListener("mouseleave", this.mouseLeaveHandler);
1060
- super.destroy();
1061
- }
1062
1157
  scroll() {
1063
1158
  this.fixScrollValue();
1064
1159
  let { scrollLeft, scrollTop } = this;
@@ -1110,10 +1205,13 @@
1110
1205
  event.stopPropagation();
1111
1206
  if (event.button !== MouseButton.LEFT && event.button !== MouseButton.RIGHT)
1112
1207
  return;
1113
- 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")) {
1114
1212
  return;
1115
1213
  }
1116
- if (event.target.className.indexOf("moveable-control") !== -1) {
1214
+ if (targetClassList.contains("moveable-control") || isMoveableButton(event.target)) {
1117
1215
  return;
1118
1216
  }
1119
1217
  this.content.removeEventListener("mousemove", this.highlightHandler);
@@ -1375,13 +1473,11 @@
1375
1473
  runtime = null;
1376
1474
  iframe;
1377
1475
  runtimeUrl;
1378
- core;
1379
1476
  render;
1380
- constructor({ core }) {
1477
+ constructor({ runtimeUrl, render }) {
1381
1478
  super();
1382
- this.core = core;
1383
- this.runtimeUrl = core.config.runtimeUrl || "";
1384
- this.render = core.config.render;
1479
+ this.runtimeUrl = runtimeUrl || "";
1480
+ this.render = render;
1385
1481
  this.iframe = globalThis.document.createElement("iframe");
1386
1482
  this.iframe.src = utils.isSameDomain(this.runtimeUrl) ? this.runtimeUrl : "";
1387
1483
  this.iframe.style.cssText = `
@@ -1424,6 +1520,9 @@
1424
1520
  this.on("runtime-ready", listener);
1425
1521
  });
1426
1522
  };
1523
+ getDocument() {
1524
+ return this.contentWindow?.document;
1525
+ }
1427
1526
  destroy() {
1428
1527
  this.iframe?.removeEventListener("load", this.loadHandler);
1429
1528
  this.contentWindow = null;
@@ -1438,7 +1537,7 @@
1438
1537
  if (!this.contentWindow)
1439
1538
  return;
1440
1539
  if (this.render) {
1441
- const el = await this.render(this.core);
1540
+ const el = await this.render();
1442
1541
  if (el) {
1443
1542
  this.contentWindow.document?.body?.appendChild(el);
1444
1543
  }
@@ -1475,6 +1574,7 @@
1475
1574
  containerHighlightType;
1476
1575
  isContainer;
1477
1576
  canSelect;
1577
+ pageResizeObserver = null;
1478
1578
  constructor(config) {
1479
1579
  super();
1480
1580
  this.config = config;
@@ -1484,8 +1584,8 @@
1484
1584
  this.containerHighlightClassName = config.containerHighlightClassName || CONTAINER_HIGHLIGHT_CLASS;
1485
1585
  this.containerHighlightDuration = config.containerHighlightDuration || 800;
1486
1586
  this.containerHighlightType = config.containerHighlightType;
1487
- this.renderer = new StageRender({ core: this });
1488
- this.mask = new StageMask({ core: this });
1587
+ this.renderer = new StageRender({ runtimeUrl: config.runtimeUrl, render: this.render.bind(this) });
1588
+ this.mask = new StageMask();
1489
1589
  this.dr = new StageDragResize({ core: this, container: this.mask.content, mask: this.mask });
1490
1590
  this.multiDr = new StageMultiDragResize({ core: this, container: this.mask.content, mask: this.mask });
1491
1591
  this.highlightLayer = new StageHighlight({ core: this, container: this.mask.wrapper });
@@ -1494,6 +1594,7 @@
1494
1594
  });
1495
1595
  this.renderer.on("page-el-update", (el) => {
1496
1596
  this.mask?.observe(el);
1597
+ this.observePageResize(el);
1497
1598
  });
1498
1599
  this.mask.on("beforeSelect", async (event) => {
1499
1600
  this.clearSelectStatus("multiSelect");
@@ -1535,11 +1636,14 @@
1535
1636
  this.selectedDomList.push(el);
1536
1637
  }
1537
1638
  this.multiSelect(this.selectedDomList);
1639
+ this.emit("multiSelect", this.selectedDomList);
1538
1640
  });
1539
1641
  this.dr.on("update", (data) => {
1540
1642
  setTimeout(() => this.emit("update", data));
1541
1643
  }).on("sort", (data) => {
1542
1644
  setTimeout(() => this.emit("sort", data));
1645
+ }).on("select-parent", () => {
1646
+ this.emit("select-parent");
1543
1647
  });
1544
1648
  this.multiDr.on("update", (data) => {
1545
1649
  setTimeout(() => this.emit("update", data));
@@ -1551,7 +1655,6 @@
1551
1655
  }
1552
1656
  getElementsFromPoint(event) {
1553
1657
  const { renderer, zoom } = this;
1554
- const doc = renderer.contentWindow?.document;
1555
1658
  let x = event.clientX;
1556
1659
  let y = event.clientY;
1557
1660
  if (renderer.iframe) {
@@ -1561,7 +1664,7 @@
1561
1664
  y = y - rect.top;
1562
1665
  }
1563
1666
  }
1564
- return doc?.elementsFromPoint(x / zoom, y / zoom);
1667
+ return renderer.getDocument()?.elementsFromPoint(x / zoom, y / zoom);
1565
1668
  }
1566
1669
  async getElementFromPoint(event) {
1567
1670
  const els = this.getElementsFromPoint(event);
@@ -1597,28 +1700,28 @@
1597
1700
  this.mask.setLayout(el);
1598
1701
  this.dr.select(el, event);
1599
1702
  if (this.config.autoScrollIntoView || el.dataset.autoScrollIntoView) {
1600
- this.mask.intersectionObserver?.observe(el);
1703
+ this.mask.observerIntersection(el);
1601
1704
  }
1602
1705
  this.selectedDom = el;
1603
- if (this.renderer.contentWindow) {
1604
- removeSelectedClassName(this.renderer.contentWindow.document);
1706
+ const doc = this.renderer.getDocument();
1707
+ if (doc) {
1708
+ removeSelectedClassName(doc);
1605
1709
  if (this.selectedDom) {
1606
- addSelectedClassName(this.selectedDom, this.renderer.contentWindow.document);
1710
+ addSelectedClassName(this.selectedDom, doc);
1607
1711
  }
1608
1712
  }
1609
1713
  }
1610
1714
  async multiSelect(idOrElList) {
1611
1715
  this.clearSelectStatus("select");
1612
- const elList = await Promise.all(idOrElList.map(async (idOrEl) => await this.getTargetElement(idOrEl)));
1613
- this.multiDr.multiSelect(elList);
1614
- this.emit("multiSelect", elList);
1716
+ this.selectedDomList = await Promise.all(idOrElList.map(async (idOrEl) => await this.getTargetElement(idOrEl)));
1717
+ this.multiDr.multiSelect(this.selectedDomList);
1615
1718
  }
1616
1719
  update(data) {
1617
1720
  const { config } = data;
1618
1721
  return this.renderer?.getRuntime().then((runtime) => {
1619
1722
  runtime?.update?.(data);
1620
1723
  setTimeout(() => {
1621
- const el = this.renderer.contentWindow?.document.getElementById(`${config.id}`);
1724
+ const el = this.renderer.getDocument()?.getElementById(`${config.id}`);
1622
1725
  if (el && el.id === this.selectedDom?.id) {
1623
1726
  this.selectedDom = el;
1624
1727
  this.mask.setLayout(el);
@@ -1674,7 +1777,7 @@
1674
1777
  async addContainerHighlightClassName(event, exclude) {
1675
1778
  const els = this.getElementsFromPoint(event);
1676
1779
  const { renderer } = this;
1677
- const doc = renderer.contentWindow?.document;
1780
+ const doc = renderer.getDocument();
1678
1781
  if (!doc)
1679
1782
  return;
1680
1783
  for (const el of els) {
@@ -1690,17 +1793,35 @@
1690
1793
  }, this.containerHighlightDuration);
1691
1794
  }
1692
1795
  destroy() {
1693
- const { mask, renderer, dr, highlightLayer } = this;
1796
+ const { mask, renderer, dr, highlightLayer, pageResizeObserver } = this;
1694
1797
  renderer.destroy();
1695
1798
  mask.destroy();
1696
1799
  dr.destroy();
1697
1800
  highlightLayer.destroy();
1801
+ pageResizeObserver?.disconnect();
1698
1802
  this.removeAllListeners();
1699
1803
  this.container = void 0;
1700
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
+ }
1701
1822
  async getTargetElement(idOrEl) {
1702
1823
  if (typeof idOrEl === "string" || typeof idOrEl === "number") {
1703
- const el = this.renderer.contentWindow?.document.getElementById(`${idOrEl}`);
1824
+ const el = this.renderer.getDocument()?.getElementById(`${idOrEl}`);
1704
1825
  if (!el)
1705
1826
  throw new Error(`\u4E0D\u5B58\u5728ID\u4E3A${idOrEl}\u7684\u5143\u7D20`);
1706
1827
  return el;
@@ -1737,6 +1858,7 @@
1737
1858
  exports.isAbsolute = isAbsolute;
1738
1859
  exports.isFixed = isFixed;
1739
1860
  exports.isFixedParent = isFixedParent;
1861
+ exports.isMoveableButton = isMoveableButton;
1740
1862
  exports.isRelative = isRelative;
1741
1863
  exports.isStatic = isStatic;
1742
1864
  exports.removeSelectedClassName = removeSelectedClassName;