@tmagic/stage 1.0.3 → 1.1.0-beta.0

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.
@@ -1,8 +1,8 @@
1
1
  (function (global, factory) {
2
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('events'), require('moveable'), require('moveable-helper'), require('lodash-es'), require('@scena/guides')) :
3
- typeof define === 'function' && define.amd ? define(['exports', 'events', 'moveable', 'moveable-helper', 'lodash-es', '@scena/guides'], factory) :
4
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.TMagicStage = {}, global.EventEmitter, global.Moveable, global.MoveableHelper, global.lodashEs, global.Guides));
5
- })(this, (function (exports, EventEmitter, Moveable, MoveableHelper, lodashEs, Guides) { 'use strict';
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('events'), require('moveable'), require('moveable-helper'), require('@tmagic/utils'), require('lodash-es'), require('@scena/guides')) :
3
+ typeof define === 'function' && define.amd ? define(['exports', 'events', 'moveable', 'moveable-helper', '@tmagic/utils', 'lodash-es', '@scena/guides'], factory) :
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.TMagicStage = {}, global.EventEmitter, global.Moveable, global.MoveableHelper, global.utils, global.lodashEs, global.Guides));
5
+ })(this, (function (exports, EventEmitter, Moveable, MoveableHelper, utils, lodashEs, Guides) { 'use strict';
6
6
 
7
7
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
8
8
 
@@ -14,6 +14,7 @@
14
14
  const GHOST_EL_ID_PREFIX = "ghost_el_";
15
15
  const DRAG_EL_ID_PREFIX = "drag_el_";
16
16
  const HIGHLIGHT_EL_ID_PREFIX = "highlight_el_";
17
+ const CONTAINER_HIGHLIGHT_CLASS = "tmagic-stage-container-highlight";
17
18
  const DEFAULT_ZOOM = 1;
18
19
  var GuidesType = /* @__PURE__ */ ((GuidesType2) => {
19
20
  GuidesType2["HORIZONTAL"] = "horizontal";
@@ -77,13 +78,6 @@
77
78
  }
78
79
  return { left, top };
79
80
  };
80
- const getHost = (targetUrl) => targetUrl.match(/\/\/([^/]+)/)?.[1];
81
- const isSameDomain = (targetUrl = "", source = globalThis.location.host) => {
82
- const isHttpUrl = /^(http[s]?:)?\/\//.test(targetUrl);
83
- if (!isHttpUrl)
84
- return true;
85
- return getHost(targetUrl) === source;
86
- };
87
81
  const isAbsolute = (style) => style.position === "absolute";
88
82
  const isRelative = (style) => style.position === "relative";
89
83
  const isStatic = (style) => style.position === "static";
@@ -127,19 +121,14 @@
127
121
  }
128
122
  return null;
129
123
  };
130
- const createDiv = ({ className, cssText }) => {
131
- const el = globalThis.document.createElement("div");
132
- el.className = className;
133
- el.style.cssText = cssText;
134
- return el;
135
- };
136
124
  const removeSelectedClassName = (doc) => {
137
125
  const oldEl = doc.querySelector(`.${SELECTED_CLASS}`);
138
126
  if (oldEl) {
139
- oldEl.classList.remove(SELECTED_CLASS);
140
- oldEl.parentNode?.classList.remove(`${SELECTED_CLASS}-parent`);
127
+ utils.removeClassName(oldEl, SELECTED_CLASS);
128
+ if (oldEl.parentNode)
129
+ utils.removeClassName(oldEl.parentNode, `${SELECTED_CLASS}-parent`);
141
130
  doc.querySelectorAll(`.${SELECTED_CLASS}-parents`).forEach((item) => {
142
- item.classList.remove(`${SELECTED_CLASS}-parents`);
131
+ utils.removeClassName(item, `${SELECTED_CLASS}-parents`);
143
132
  });
144
133
  }
145
134
  };
@@ -150,6 +139,14 @@
150
139
  item.classList.add(`${SELECTED_CLASS}-parents`);
151
140
  });
152
141
  };
142
+ const calcValueByFontsize = (doc, value) => {
143
+ const { fontSize } = doc.documentElement.style;
144
+ if (fontSize) {
145
+ const times = globalThis.parseFloat(fontSize) / 100;
146
+ return Number((value / times).toFixed(2));
147
+ }
148
+ return value;
149
+ };
153
150
 
154
151
  class StageDragResize extends EventEmitter.EventEmitter {
155
152
  constructor(config) {
@@ -238,19 +235,22 @@
238
235
  });
239
236
  this.elementGuidelines = [];
240
237
  if (this.mode === Mode.ABSOLUTE) {
241
- const frame = document.createDocumentFragment();
242
- for (const node of nodes) {
243
- const { width, height } = node.getBoundingClientRect();
244
- if (node === this.target)
245
- continue;
246
- const { left, top } = getOffset(node);
247
- const elementGuideline = document.createElement("div");
248
- elementGuideline.style.cssText = `position: absolute;width: ${width}px;height: ${height}px;top: ${top}px;left: ${left}px`;
249
- this.elementGuidelines.push(elementGuideline);
250
- frame.append(elementGuideline);
251
- }
252
- this.container.append(frame);
238
+ this.container.append(this.createGuidelineElements(nodes));
239
+ }
240
+ }
241
+ createGuidelineElements(nodes) {
242
+ const frame = globalThis.document.createDocumentFragment();
243
+ for (const node of nodes) {
244
+ const { width, height } = node.getBoundingClientRect();
245
+ if (node === this.target)
246
+ continue;
247
+ const { left, top } = getOffset(node);
248
+ const elementGuideline = globalThis.document.createElement("div");
249
+ elementGuideline.style.cssText = `position: absolute;width: ${width}px;height: ${height}px;top: ${top}px;left: ${left}px`;
250
+ this.elementGuidelines.push(elementGuideline);
251
+ frame.append(elementGuideline);
253
252
  }
253
+ return frame;
254
254
  }
255
255
  initMoveable() {
256
256
  this.moveable?.destroy();
@@ -303,6 +303,9 @@
303
303
  left: 0,
304
304
  top: 0
305
305
  };
306
+ let timeout;
307
+ const { contentWindow } = this.core.renderer;
308
+ const doc = contentWindow?.document;
306
309
  this.moveable.on("dragStart", (e) => {
307
310
  if (!this.target)
308
311
  throw new Error("\u672A\u9009\u4E2D\u7EC4\u4EF6");
@@ -316,6 +319,19 @@
316
319
  }).on("drag", (e) => {
317
320
  if (!this.target || !this.dragEl)
318
321
  return;
322
+ if (timeout) {
323
+ globalThis.clearTimeout(timeout);
324
+ timeout = void 0;
325
+ }
326
+ timeout = globalThis.setTimeout(async () => {
327
+ const els = this.core.getElementsFromPoint(e.inputEvent);
328
+ for (const el of els) {
329
+ if (doc && !el.id.startsWith(GHOST_EL_ID_PREFIX) && el !== this.target && await this.core.isContainer(el)) {
330
+ utils.addClassName(el, doc, this.core.containerHighlightClassName);
331
+ break;
332
+ }
333
+ }
334
+ }, this.core.containerHighlightDuration);
319
335
  this.dragStatus = "ing" /* ING */;
320
336
  if (this.ghostEl) {
321
337
  this.ghostEl.style.top = `${frame.top + e.beforeTranslate[1]}px`;
@@ -325,13 +341,25 @@
325
341
  this.target.style.left = `${frame.left + e.beforeTranslate[0]}px`;
326
342
  this.target.style.top = `${frame.top + e.beforeTranslate[1]}px`;
327
343
  }).on("dragEnd", () => {
344
+ if (timeout) {
345
+ globalThis.clearTimeout(timeout);
346
+ timeout = void 0;
347
+ }
348
+ let parentEl = null;
349
+ if (doc) {
350
+ parentEl = utils.removeClassNameByClassName(doc, this.core.containerHighlightClassName);
351
+ }
328
352
  if (this.dragStatus === "ing" /* ING */) {
329
- switch (this.mode) {
330
- case Mode.SORTABLE:
331
- this.sort();
332
- break;
333
- default:
334
- this.update();
353
+ if (parentEl) {
354
+ this.update(false, parentEl);
355
+ } else {
356
+ switch (this.mode) {
357
+ case Mode.SORTABLE:
358
+ this.sort();
359
+ break;
360
+ default:
361
+ this.update();
362
+ }
335
363
  }
336
364
  }
337
365
  this.dragStatus = "end" /* END */;
@@ -405,16 +433,27 @@
405
433
  });
406
434
  }
407
435
  }
408
- update(isResize = false) {
436
+ update(isResize = false, parentEl = null) {
409
437
  if (!this.target)
410
438
  return;
439
+ const { contentWindow } = this.core.renderer;
440
+ const doc = contentWindow?.document;
441
+ if (!doc)
442
+ return;
411
443
  const offset = this.mode === Mode.SORTABLE ? { left: 0, top: 0 } : { left: this.target.offsetLeft, top: this.target.offsetTop };
412
- const left = this.calcValueByFontsize(offset.left);
413
- const top = this.calcValueByFontsize(offset.top);
414
- const width = this.calcValueByFontsize(this.target.clientWidth);
415
- const height = this.calcValueByFontsize(this.target.clientHeight);
444
+ let left = calcValueByFontsize(doc, offset.left);
445
+ let top = calcValueByFontsize(doc, offset.top);
446
+ const width = calcValueByFontsize(doc, this.target.clientWidth);
447
+ const height = calcValueByFontsize(doc, this.target.clientHeight);
448
+ if (parentEl && this.mode === Mode.ABSOLUTE && this.dragEl) {
449
+ const [translateX, translateY] = this.moveableHelper?.getFrame(this.dragEl).properties.transform.translate.value;
450
+ const { left: parentLeft, top: parentTop } = getOffset(parentEl);
451
+ left = calcValueByFontsize(doc, this.dragEl.offsetLeft) + parseFloat(translateX) - calcValueByFontsize(doc, parentLeft);
452
+ top = calcValueByFontsize(doc, this.dragEl.offsetTop) + parseFloat(translateY) - calcValueByFontsize(doc, parentTop);
453
+ }
416
454
  this.emit("update", {
417
455
  el: this.target,
456
+ parentEl,
418
457
  style: isResize ? { left, top, width, height } : { left, top }
419
458
  });
420
459
  }
@@ -515,15 +554,6 @@
515
554
  ...moveableOptions
516
555
  };
517
556
  }
518
- calcValueByFontsize(value) {
519
- const { contentWindow } = this.core.renderer;
520
- const fontSize = contentWindow?.document.documentElement.style.fontSize;
521
- if (fontSize) {
522
- const times = globalThis.parseFloat(fontSize) / 100;
523
- return (value / times).toFixed(2);
524
- }
525
- return value;
526
- }
527
557
  }
528
558
  const down = (deltaTop, target) => {
529
559
  let swapIndex = 0;
@@ -787,13 +817,9 @@
787
817
  const wrapperClassName = "editor-mask-wrapper";
788
818
  const throttleTime = 100;
789
819
  const hideScrollbar = () => {
790
- const style = globalThis.document.createElement("style");
791
- style.innerHTML = `
792
- .${wrapperClassName}::-webkit-scrollbar { width: 0 !important; display: none }
793
- `;
794
- globalThis.document.head.appendChild(style);
820
+ utils.injectStyle(globalThis.document, `.${wrapperClassName}::-webkit-scrollbar { width: 0 !important; display: none }`);
795
821
  };
796
- const createContent = () => createDiv({
822
+ const createContent = () => utils.createDiv({
797
823
  className: "editor-mask",
798
824
  cssText: `
799
825
  position: absolute;
@@ -803,7 +829,7 @@
803
829
  `
804
830
  });
805
831
  const createWrapper = () => {
806
- const el = createDiv({
832
+ const el = utils.createDiv({
807
833
  className: wrapperClassName,
808
834
  cssText: `
809
835
  position: absolute;
@@ -1016,6 +1042,8 @@
1016
1042
  }
1017
1043
  }
1018
1044
 
1045
+ var style = ".tmagic-stage-container-highlight::after {\n content: '';\n position: absolute;\n width: 100%;\n height: 100%;\n top: 0;\n left: 0;\n background-color: #000;\n opacity: .1;\n}\n";
1046
+
1019
1047
  class StageRender extends EventEmitter.EventEmitter {
1020
1048
  constructor({ core }) {
1021
1049
  super();
@@ -1053,12 +1081,13 @@
1053
1081
  this.contentWindow.postMessage({
1054
1082
  tmagicRuntimeReady: true
1055
1083
  }, "*");
1084
+ utils.injectStyle(this.contentWindow.document, style);
1056
1085
  };
1057
1086
  this.core = core;
1058
1087
  this.runtimeUrl = core.config.runtimeUrl || "";
1059
1088
  this.render = core.config.render;
1060
1089
  this.iframe = globalThis.document.createElement("iframe");
1061
- this.iframe.src = isSameDomain(this.runtimeUrl) ? this.runtimeUrl : "";
1090
+ this.iframe.src = utils.isSameDomain(this.runtimeUrl) ? this.runtimeUrl : "";
1062
1091
  this.iframe.style.cssText = `
1063
1092
  border: 0;
1064
1093
  width: 100%;
@@ -1068,9 +1097,9 @@
1068
1097
  }
1069
1098
  async mount(el) {
1070
1099
  if (this.iframe) {
1071
- if (!isSameDomain(this.runtimeUrl) && this.runtimeUrl) {
1100
+ if (!utils.isSameDomain(this.runtimeUrl) && this.runtimeUrl) {
1072
1101
  let html = await fetch(this.runtimeUrl).then((res) => res.text());
1073
- const base = `${location.protocol}//${getHost(this.runtimeUrl)}`;
1102
+ const base = `${location.protocol}//${utils.getHost(this.runtimeUrl)}`;
1074
1103
  html = html.replace("<head>", `<head>
1075
1104
  <base href="${base}">`);
1076
1105
  this.iframe.srcdoc = html;
@@ -1096,6 +1125,9 @@
1096
1125
  this.config = config;
1097
1126
  this.setZoom(config.zoom);
1098
1127
  this.canSelect = config.canSelect || ((el) => !!el.id);
1128
+ this.isContainer = config.isContainer;
1129
+ this.containerHighlightClassName = config.containerHighlightClassName;
1130
+ this.containerHighlightDuration = config.containerHighlightDuration;
1099
1131
  this.renderer = new StageRender({ core: this });
1100
1132
  this.mask = new StageMask({ core: this });
1101
1133
  this.dr = new StageDragResize({ core: this, container: this.mask.content });
@@ -1130,7 +1162,7 @@
1130
1162
  setTimeout(() => this.emit("sort", data));
1131
1163
  });
1132
1164
  }
1133
- async setElementFromPoint(event) {
1165
+ getElementsFromPoint(event) {
1134
1166
  const { renderer, zoom } = this;
1135
1167
  const doc = renderer.contentWindow?.document;
1136
1168
  let x = event.clientX;
@@ -1142,7 +1174,10 @@
1142
1174
  y = y - rect.top;
1143
1175
  }
1144
1176
  }
1145
- const els = doc?.elementsFromPoint(x / zoom, y / zoom);
1177
+ return doc?.elementsFromPoint(x / zoom, y / zoom);
1178
+ }
1179
+ async setElementFromPoint(event) {
1180
+ const els = this.getElementsFromPoint(event);
1146
1181
  let stopped = false;
1147
1182
  const stop = () => stopped = true;
1148
1183
  for (const el of els) {
@@ -1250,6 +1285,7 @@
1250
1285
  }
1251
1286
  }
1252
1287
 
1288
+ exports.CONTAINER_HIGHLIGHT_CLASS = CONTAINER_HIGHLIGHT_CLASS;
1253
1289
  exports.DEFAULT_ZOOM = DEFAULT_ZOOM;
1254
1290
  exports.DRAG_EL_ID_PREFIX = DRAG_EL_ID_PREFIX;
1255
1291
  exports.GHOST_EL_ID_PREFIX = GHOST_EL_ID_PREFIX;
@@ -1262,7 +1298,19 @@
1262
1298
  exports.StageMask = StageMask;
1263
1299
  exports.StageRender = StageRender;
1264
1300
  exports.ZIndex = ZIndex;
1301
+ exports.addSelectedClassName = addSelectedClassName;
1302
+ exports.calcValueByFontsize = calcValueByFontsize;
1265
1303
  exports["default"] = StageCore;
1304
+ exports.getAbsolutePosition = getAbsolutePosition;
1305
+ exports.getMode = getMode;
1306
+ exports.getOffset = getOffset;
1307
+ exports.getScrollParent = getScrollParent;
1308
+ exports.isAbsolute = isAbsolute;
1309
+ exports.isFixed = isFixed;
1310
+ exports.isFixedParent = isFixedParent;
1311
+ exports.isRelative = isRelative;
1312
+ exports.isStatic = isStatic;
1313
+ exports.removeSelectedClassName = removeSelectedClassName;
1266
1314
 
1267
1315
  Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: 'Module' } });
1268
1316