@tmagic/stage 1.0.0-beta.9 → 1.0.0-rc.1

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.
@@ -12,6 +12,8 @@
12
12
  var Guides__default = /*#__PURE__*/_interopDefaultLegacy(Guides);
13
13
 
14
14
  const GHOST_EL_ID_PREFIX = "ghost_el_";
15
+ const DRAG_EL_ID_PREFIX = "drag_el_";
16
+ const HIGHLIGHT_EL_ID_PREFIX = "highlight_el_";
15
17
  const DEFAULT_ZOOM = 1;
16
18
  var GuidesType = /* @__PURE__ */ ((GuidesType2) => {
17
19
  GuidesType2["HORIZONTAL"] = "horizontal";
@@ -169,50 +171,45 @@
169
171
  };
170
172
 
171
173
  class StageDragResize extends EventEmitter.EventEmitter {
172
- core;
173
- container;
174
- target;
175
- dragEl;
176
- moveable;
177
- horizontalGuidelines = [];
178
- verticalGuidelines = [];
179
- moveableOptions = {};
180
- dragStatus = "end" /* END */;
181
- ghostEl;
182
- mode = Mode.ABSOLUTE;
183
- moveableHelper;
184
174
  constructor(config) {
185
175
  super();
176
+ this.horizontalGuidelines = [];
177
+ this.verticalGuidelines = [];
178
+ this.elementGuidelines = [];
179
+ this.mode = Mode.ABSOLUTE;
180
+ this.moveableOptions = {};
181
+ this.dragStatus = "end" /* END */;
186
182
  this.core = config.core;
187
183
  this.container = config.container;
184
+ this.dragEl = globalThis.document.createElement("div");
185
+ this.container.append(this.dragEl);
188
186
  }
189
- async select(el, event) {
187
+ select(el, event) {
188
+ const oldTarget = this.target;
190
189
  this.target = el;
191
- if (/(auto|scroll)/.test(this.target.style.overflow)) {
192
- this.target.style.overflow = "hidden";
190
+ this.init(el);
191
+ if (!this.moveable || this.target !== oldTarget) {
192
+ this.moveableHelper = MoveableHelper__default["default"].create({
193
+ useBeforeRender: true,
194
+ useRender: false,
195
+ createAuto: true
196
+ });
197
+ this.initMoveable();
198
+ } else {
199
+ this.updateMoveable();
193
200
  }
194
- this.mode = getMode(el);
195
- this.destroyDragEl();
196
- this.destroyGhostEl();
197
- this.dragEl = this.generateDragEl(el);
198
- this.moveableOptions = await this.getOptions({
199
- target: this.dragEl || this.target
200
- });
201
- this.moveableHelper = MoveableHelper__default["default"].create({
202
- useBeforeRender: true,
203
- useRender: false,
204
- createAuto: true
205
- });
206
- this.initMoveable();
207
201
  if (event) {
208
202
  this.moveable?.dragStart(event);
209
203
  }
210
204
  }
211
- async refresh() {
205
+ updateMoveable(el = this.target) {
212
206
  if (!this.moveable)
213
207
  throw new Error("\u672A\u521D\u59CB\u5316moveable");
214
- const options = await this.getOptions();
215
- Object.entries(options).forEach(([key, value]) => {
208
+ if (!el)
209
+ throw new Error("\u4E3A\u9009\u4E2D\u4EFB\u4F55\u8282\u70B9");
210
+ this.target = el;
211
+ this.init(el);
212
+ Object.entries(this.moveableOptions).forEach(([key, value]) => {
216
213
  this.moveable[key] = value;
217
214
  });
218
215
  this.moveable.updateTarget();
@@ -220,15 +217,19 @@
220
217
  setGuidelines(type, guidelines) {
221
218
  if (type === GuidesType.HORIZONTAL) {
222
219
  this.horizontalGuidelines = guidelines;
220
+ this.moveableOptions.horizontalGuidelines = guidelines;
223
221
  } else if (type === GuidesType.VERTICAL) {
224
222
  this.verticalGuidelines = guidelines;
223
+ this.moveableOptions.verticalGuidelines = guidelines;
225
224
  }
226
- this.refresh();
225
+ this.updateMoveable();
227
226
  }
228
227
  clearGuides() {
229
- this.verticalGuidelines = [];
230
228
  this.horizontalGuidelines = [];
231
- this.refresh();
229
+ this.verticalGuidelines = [];
230
+ this.moveableOptions.horizontalGuidelines = [];
231
+ this.moveableOptions.verticalGuidelines = [];
232
+ this.updateMoveable();
232
233
  }
233
234
  destroy() {
234
235
  this.moveable?.destroy();
@@ -237,6 +238,17 @@
237
238
  this.dragStatus = "end" /* END */;
238
239
  this.removeAllListeners();
239
240
  }
241
+ init(el) {
242
+ if (/(auto|scroll)/.test(el.style.overflow)) {
243
+ el.style.overflow = "hidden";
244
+ }
245
+ this.mode = getMode(el);
246
+ this.destroyGhostEl();
247
+ this.updateDragEl(el);
248
+ this.moveableOptions = this.getOptions({
249
+ target: this.dragEl
250
+ });
251
+ }
240
252
  initMoveable() {
241
253
  this.moveable?.destroy();
242
254
  this.moveable = new Moveable__default["default"](this.container, {
@@ -281,22 +293,21 @@
281
293
  bindDragEvent() {
282
294
  if (!this.moveable)
283
295
  throw new Error("moveable \u4E3A\u521D\u59CB\u5316");
284
- let offset = {
285
- left: 0,
286
- top: 0
287
- };
296
+ let offset = null;
288
297
  this.moveable.on("dragStart", (e) => {
289
298
  if (!this.target)
290
299
  throw new Error("\u672A\u9009\u4E2D\u7EC4\u4EF6");
291
300
  this.dragStatus = "start" /* START */;
292
301
  this.moveableHelper?.onDragStart(e);
293
- offset = getAbsolutePosition(this.target, { left: 0, top: 0 });
294
302
  if (this.mode === Mode.SORTABLE) {
295
303
  this.ghostEl = this.generateGhostEl(this.target);
296
304
  }
297
305
  }).on("drag", (e) => {
298
306
  if (!this.target || !this.dragEl)
299
307
  return;
308
+ if (!offset) {
309
+ offset = getAbsolutePosition(this.target, { left: 0, top: 0 });
310
+ }
300
311
  this.dragStatus = "ing" /* ING */;
301
312
  const { left, top } = e;
302
313
  if (this.ghostEl) {
@@ -317,17 +328,18 @@
317
328
  this.update();
318
329
  }
319
330
  }
331
+ offset = null;
320
332
  this.dragStatus = "end" /* END */;
321
333
  this.destroyGhostEl();
322
334
  });
323
335
  }
324
- async getSnapElements(el) {
325
- const { renderer } = this.core;
326
- const getSnapElements = (await renderer.getRuntime())?.getSnapElements || (() => {
336
+ getSnapElements(runtime, el) {
337
+ const { renderer, mask } = this.core;
338
+ const getSnapElements = runtime?.getSnapElements || (() => {
327
339
  const doc = renderer.contentWindow?.document;
328
340
  return doc ? Array.from(doc.querySelectorAll("[id]")) : [];
329
341
  });
330
- return getSnapElements(el).filter((element) => element !== this.target && !this.target?.contains(element));
342
+ return getSnapElements(el).filter((element) => element !== this.target && !this.target?.contains(element) && element !== mask.page);
331
343
  }
332
344
  sort() {
333
345
  if (!this.target || !this.ghostEl)
@@ -366,7 +378,7 @@
366
378
  }
367
379
  const ghostEl = el.cloneNode(true);
368
380
  const { top, left } = getAbsolutePosition(el, getOffset(el));
369
- ghostEl.id = `${GHOST_EL_ID_PREFIX}${ghostEl.id}`;
381
+ ghostEl.id = `${GHOST_EL_ID_PREFIX}${el.id}`;
370
382
  ghostEl.style.zIndex = "5";
371
383
  ghostEl.style.opacity = ".5";
372
384
  ghostEl.style.position = "absolute";
@@ -379,44 +391,40 @@
379
391
  this.ghostEl?.remove();
380
392
  this.ghostEl = void 0;
381
393
  }
382
- generateDragEl(el) {
383
- if (this.dragEl) {
384
- this.destroyDragEl();
385
- }
394
+ updateDragEl(el) {
386
395
  const { width, height } = el.getBoundingClientRect();
387
396
  const offset = getOffset(el);
388
- const dragEl = globalThis.document.createElement("div");
389
- dragEl.style.cssText = `
397
+ this.dragEl.style.cssText = `
390
398
  position: absolute;
391
399
  left: ${offset.left}px;
392
400
  top: ${offset.top}px;
393
401
  width: ${width}px;
394
402
  height: ${height}px;
403
+ z-index: 9;
395
404
  `;
396
- this.container.append(dragEl);
397
- return dragEl;
405
+ this.dragEl.id = `${DRAG_EL_ID_PREFIX}${el.id}`;
398
406
  }
399
407
  destroyDragEl() {
400
408
  this.dragEl?.remove();
401
- this.dragEl = void 0;
402
409
  }
403
- async getOptions(options = {}) {
410
+ getOptions(options = {}) {
404
411
  if (!this.target)
405
412
  return {};
406
413
  const isAbsolute = this.mode === Mode.ABSOLUTE;
414
+ const isFixed = this.mode === Mode.FIXED;
407
415
  let { moveableOptions = {} } = this.core.config;
408
416
  if (typeof moveableOptions === "function") {
409
417
  moveableOptions = moveableOptions(this.core);
410
418
  }
411
419
  return {
412
- origin: true,
420
+ origin: false,
413
421
  rootContainer: this.core.container,
414
422
  zoom: 1,
415
423
  dragArea: false,
416
424
  draggable: true,
417
425
  resizable: true,
418
- snappable: isAbsolute,
419
- snapGap: isAbsolute,
426
+ snappable: isAbsolute || isFixed,
427
+ snapGap: isAbsolute || isFixed,
420
428
  snapThreshold: 5,
421
429
  snapDigit: 0,
422
430
  throttleDrag: 0,
@@ -429,8 +437,16 @@
429
437
  center: isAbsolute,
430
438
  middle: isAbsolute
431
439
  },
440
+ elementSnapDirections: {
441
+ top: isAbsolute,
442
+ right: isAbsolute,
443
+ bottom: isAbsolute,
444
+ left: isAbsolute
445
+ },
446
+ isDisplayInnerSnapDigit: true,
432
447
  horizontalGuidelines: this.horizontalGuidelines,
433
448
  verticalGuidelines: this.verticalGuidelines,
449
+ elementGuidelines: this.elementGuidelines,
434
450
  bounds: {
435
451
  top: 0,
436
452
  left: 0,
@@ -499,15 +515,97 @@
499
515
  };
500
516
  };
501
517
 
518
+ class TargetCalibrate extends EventEmitter.EventEmitter {
519
+ constructor(config) {
520
+ super();
521
+ this.parent = config.parent;
522
+ this.mask = config.mask;
523
+ this.dr = config.dr;
524
+ this.operationEl = globalThis.document.createElement("div");
525
+ this.parent.append(this.operationEl);
526
+ }
527
+ update(el, prefix) {
528
+ const { width, height } = el.getBoundingClientRect();
529
+ const { left, top } = this.getOffset(el);
530
+ this.operationEl.style.cssText = `
531
+ position: absolute;
532
+ left: ${left}px;
533
+ top: ${top}px;
534
+ width: ${width}px;
535
+ height: ${height}px;
536
+ `;
537
+ this.operationEl.id = `${prefix}${el.id}`;
538
+ return this.operationEl;
539
+ }
540
+ destroy() {
541
+ this.operationEl?.remove();
542
+ }
543
+ getOffset(el) {
544
+ const { transform } = getComputedStyle(el);
545
+ const { offsetParent } = el;
546
+ let left = el.offsetLeft;
547
+ let top = el.offsetTop;
548
+ if (transform.indexOf("matrix") > -1) {
549
+ let a = 1;
550
+ let b = 1;
551
+ let c = 1;
552
+ let d = 1;
553
+ let e = 0;
554
+ let f = 0;
555
+ transform.replace(/matrix\((.+), (.+), (.+), (.+), (.+), (.+)\)/, ($0, $1, $2, $3, $4, $5, $6) => {
556
+ a = +$1;
557
+ b = +$2;
558
+ c = +$3;
559
+ d = +$4;
560
+ e = +$5;
561
+ f = +$6;
562
+ return transform;
563
+ });
564
+ left = a * left + c * top + e;
565
+ top = b * left + d * top + f;
566
+ }
567
+ if (offsetParent) {
568
+ const parentOffset = this.getOffset(offsetParent);
569
+ return {
570
+ left: left + parentOffset.left,
571
+ top: top + parentOffset.top
572
+ };
573
+ }
574
+ if (this.dr.mode === Mode.FIXED) {
575
+ if (getMode(el) === Mode.FIXED) {
576
+ return {
577
+ left,
578
+ top
579
+ };
580
+ }
581
+ return {
582
+ left: left - this.mask.scrollLeft,
583
+ top: top - this.mask.scrollTop
584
+ };
585
+ }
586
+ if (getMode(el) === Mode.FIXED) {
587
+ return {
588
+ left: left + this.mask.scrollLeft,
589
+ top: top + this.mask.scrollTop
590
+ };
591
+ }
592
+ return {
593
+ left,
594
+ top
595
+ };
596
+ }
597
+ }
598
+
502
599
  class StageHighlight extends EventEmitter.EventEmitter {
503
- core;
504
- container;
505
- target;
506
- moveable;
507
600
  constructor(config) {
508
601
  super();
509
602
  this.core = config.core;
510
603
  this.container = config.container;
604
+ this.calibrationTarget = new TargetCalibrate({
605
+ parent: this.core.mask.content,
606
+ mask: this.core.mask,
607
+ dr: this.core.dr
608
+ });
511
609
  }
512
610
  highlight(el) {
513
611
  if (!el || el === this.target)
@@ -515,29 +613,61 @@
515
613
  this.target = el;
516
614
  this.moveable?.destroy();
517
615
  this.moveable = new Moveable__default["default"](this.container, {
518
- target: this.target
616
+ target: this.calibrationTarget.update(el, HIGHLIGHT_EL_ID_PREFIX),
617
+ origin: false,
618
+ rootContainer: this.core.container,
619
+ zoom: 1
519
620
  });
520
621
  }
521
622
  clearHighlight() {
522
623
  if (!this.moveable)
523
624
  return;
625
+ this.target = void 0;
524
626
  this.moveable.target = null;
525
627
  this.moveable.updateTarget();
526
628
  }
527
629
  destroy() {
528
630
  this.moveable?.destroy();
631
+ this.calibrationTarget.destroy();
529
632
  }
530
633
  }
531
634
 
532
635
  class Rule extends EventEmitter__default["default"] {
533
- hGuides;
534
- vGuides;
535
- horizontalGuidelines = [];
536
- verticalGuidelines = [];
537
- container;
538
- containerResizeObserver;
539
636
  constructor(container) {
540
637
  super();
638
+ this.horizontalGuidelines = [];
639
+ this.verticalGuidelines = [];
640
+ this.getGuidesStyle = (type) => ({
641
+ position: "fixed",
642
+ zIndex: 1,
643
+ left: type === GuidesType.HORIZONTAL ? 0 : "-30px",
644
+ top: type === GuidesType.HORIZONTAL ? "-30px" : 0,
645
+ width: type === GuidesType.HORIZONTAL ? "100%" : "30px",
646
+ height: type === GuidesType.HORIZONTAL ? "30px" : "100%"
647
+ });
648
+ this.createGuides = (type, defaultGuides = []) => new Guides__default["default"](this.container, {
649
+ type,
650
+ defaultGuides,
651
+ displayDragPos: true,
652
+ backgroundColor: "#fff",
653
+ lineColor: "#000",
654
+ textColor: "#000",
655
+ style: this.getGuidesStyle(type)
656
+ });
657
+ this.hGuidesChangeGuidesHandler = (e) => {
658
+ this.horizontalGuidelines = e.guides;
659
+ this.emit("changeGuides", {
660
+ type: GuidesType.HORIZONTAL,
661
+ guides: this.horizontalGuidelines
662
+ });
663
+ };
664
+ this.vGuidesChangeGuidesHandler = (e) => {
665
+ this.verticalGuidelines = e.guides;
666
+ this.emit("changeGuides", {
667
+ type: GuidesType.VERTICAL,
668
+ guides: this.verticalGuidelines
669
+ });
670
+ };
541
671
  this.container = container;
542
672
  this.hGuides = this.createGuides(GuidesType.HORIZONTAL);
543
673
  this.vGuides = this.createGuides(GuidesType.VERTICAL);
@@ -606,37 +736,6 @@
606
736
  this.containerResizeObserver.disconnect();
607
737
  this.removeAllListeners();
608
738
  }
609
- getGuidesStyle = (type) => ({
610
- position: "fixed",
611
- zIndex: 1,
612
- left: type === GuidesType.HORIZONTAL ? 0 : "-30px",
613
- top: type === GuidesType.HORIZONTAL ? "-30px" : 0,
614
- width: type === GuidesType.HORIZONTAL ? "100%" : "30px",
615
- height: type === GuidesType.HORIZONTAL ? "30px" : "100%"
616
- });
617
- createGuides = (type, defaultGuides = []) => new Guides__default["default"](this.container, {
618
- type,
619
- defaultGuides,
620
- displayDragPos: true,
621
- backgroundColor: "#fff",
622
- lineColor: "#000",
623
- textColor: "#000",
624
- style: this.getGuidesStyle(type)
625
- });
626
- hGuidesChangeGuidesHandler = (e) => {
627
- this.horizontalGuidelines = e.guides;
628
- this.emit("changeGuides", {
629
- type: GuidesType.HORIZONTAL,
630
- guides: this.horizontalGuidelines
631
- });
632
- };
633
- vGuidesChangeGuidesHandler = (e) => {
634
- this.verticalGuidelines = e.guides;
635
- this.emit("changeGuides", {
636
- type: GuidesType.VERTICAL,
637
- guides: this.verticalGuidelines
638
- });
639
- };
640
739
  }
641
740
 
642
741
  const wrapperClassName = "editor-mask-wrapper";
@@ -674,32 +773,73 @@
674
773
  return el;
675
774
  };
676
775
  class StageMask extends Rule {
677
- content = createContent();
678
- wrapper;
679
- core;
680
- page = null;
681
- pageScrollParent = null;
682
- scrollTop = 0;
683
- scrollLeft = 0;
684
- width = 0;
685
- height = 0;
686
- wrapperHeight = 0;
687
- wrapperWidth = 0;
688
- mode = Mode.ABSOLUTE;
689
- pageResizeObserver = null;
690
- wrapperResizeObserver = null;
691
- highlightHandler = lodashEs.throttle((event) => {
692
- this.emit("highlight", event);
693
- }, throttleTime);
694
776
  constructor(config) {
695
777
  const wrapper = createWrapper();
696
778
  super(wrapper);
779
+ this.content = createContent();
780
+ this.page = null;
781
+ this.pageScrollParent = null;
782
+ this.scrollTop = 0;
783
+ this.scrollLeft = 0;
784
+ this.width = 0;
785
+ this.height = 0;
786
+ this.wrapperHeight = 0;
787
+ this.wrapperWidth = 0;
788
+ this.maxScrollTop = 0;
789
+ this.maxScrollLeft = 0;
790
+ this.mode = Mode.ABSOLUTE;
791
+ this.pageResizeObserver = null;
792
+ this.wrapperResizeObserver = null;
793
+ this.highlightHandler = lodashEs.throttle((event) => {
794
+ this.emit("highlight", event);
795
+ }, throttleTime);
796
+ this.mouseDownHandler = (event) => {
797
+ this.emit("clearHighlight");
798
+ event.stopImmediatePropagation();
799
+ event.stopPropagation();
800
+ if (event.button !== MouseButton.LEFT && event.button !== MouseButton.RIGHT)
801
+ return;
802
+ if (event.target.className.indexOf("moveable-control") !== -1) {
803
+ return;
804
+ }
805
+ this.content.removeEventListener("mousemove", this.highlightHandler);
806
+ this.emit("beforeSelect", event);
807
+ globalThis.document.addEventListener("mouseup", this.mouseUpHandler);
808
+ };
809
+ this.mouseUpHandler = () => {
810
+ globalThis.document.removeEventListener("mouseup", this.mouseUpHandler);
811
+ this.content.addEventListener("mousemove", this.highlightHandler);
812
+ this.emit("select");
813
+ };
814
+ this.mouseWheelHandler = (event) => {
815
+ this.emit("clearHighlight");
816
+ if (!this.page)
817
+ throw new Error("page \u672A\u521D\u59CB\u5316");
818
+ const { deltaY, deltaX } = event;
819
+ if (this.page.clientHeight < this.wrapperHeight && deltaY)
820
+ return;
821
+ if (this.page.clientWidth < this.wrapperWidth && deltaX)
822
+ return;
823
+ if (this.maxScrollTop > 0) {
824
+ this.scrollTop = this.scrollTop + deltaY;
825
+ }
826
+ if (this.maxScrollLeft > 0) {
827
+ this.scrollLeft = this.scrollLeft + deltaX;
828
+ }
829
+ this.fixScrollValue();
830
+ this.scroll();
831
+ this.emit("scroll", event);
832
+ };
833
+ this.mouseLeaveHandler = () => {
834
+ setTimeout(() => this.emit("clearHighlight"), throttleTime);
835
+ };
697
836
  this.wrapper = wrapper;
698
837
  this.core = config.core;
699
838
  this.content.addEventListener("mousedown", this.mouseDownHandler);
700
839
  this.wrapper.appendChild(this.content);
701
840
  this.content.addEventListener("wheel", this.mouseWheelHandler);
702
841
  this.content.addEventListener("mousemove", this.highlightHandler);
842
+ this.content.addEventListener("mouseleave", this.mouseLeaveHandler);
703
843
  }
704
844
  setMode(mode) {
705
845
  this.mode = mode;
@@ -724,6 +864,9 @@
724
864
  const { clientHeight, clientWidth } = entry.target;
725
865
  this.setHeight(clientHeight);
726
866
  this.setWidth(clientWidth);
867
+ this.fixScrollValue();
868
+ this.scroll();
869
+ this.core.dr.updateMoveable();
727
870
  });
728
871
  this.pageResizeObserver.observe(page);
729
872
  this.wrapperResizeObserver = new ResizeObserver((entries) => {
@@ -731,6 +874,8 @@
731
874
  const { clientHeight, clientWidth } = entry.target;
732
875
  this.wrapperHeight = clientHeight;
733
876
  this.wrapperWidth = clientWidth;
877
+ this.setMaxScrollLeft();
878
+ this.setMaxScrollTop();
734
879
  });
735
880
  this.wrapperResizeObserver.observe(this.wrapper);
736
881
  }
@@ -749,10 +894,17 @@
749
894
  this.pageScrollParent = null;
750
895
  this.pageResizeObserver?.disconnect();
751
896
  this.wrapperResizeObserver?.disconnect();
897
+ this.content.removeEventListener("mouseleave", this.mouseLeaveHandler);
752
898
  super.destroy();
753
899
  }
754
900
  scroll() {
755
901
  let { scrollLeft, scrollTop } = this;
902
+ if (this.pageScrollParent) {
903
+ this.pageScrollParent.scrollTo({
904
+ top: scrollTop,
905
+ left: scrollLeft
906
+ });
907
+ }
756
908
  if (this.mode === Mode.FIXED) {
757
909
  scrollLeft = 0;
758
910
  scrollTop = 0;
@@ -765,74 +917,75 @@
765
917
  }
766
918
  setHeight(height) {
767
919
  this.height = height;
920
+ this.setMaxScrollTop();
768
921
  this.content.style.height = `${height}px`;
769
922
  }
770
923
  setWidth(width) {
771
924
  this.width = width;
925
+ this.setMaxScrollLeft();
772
926
  this.content.style.width = `${width}px`;
773
927
  }
774
- mouseDownHandler = (event) => {
775
- event.stopImmediatePropagation();
776
- event.stopPropagation();
777
- if (event.button !== MouseButton.LEFT && event.button !== MouseButton.RIGHT)
778
- return;
779
- if (event.target.className.indexOf("moveable-control") !== -1) {
780
- return;
781
- }
782
- this.emit("beforeSelect", event);
783
- globalThis.document.addEventListener("mouseup", this.mouseUpHandler);
784
- this.content.removeEventListener("mousemove", this.highlightHandler);
785
- this.emit("clearHighlight");
786
- };
787
- mouseUpHandler = () => {
788
- globalThis.document.removeEventListener("mouseup", this.mouseUpHandler);
789
- this.content.addEventListener("mousemove", this.highlightHandler);
790
- this.emit("select");
791
- };
792
- mouseWheelHandler = (event) => {
793
- if (!this.page)
794
- throw new Error("page \u672A\u521D\u59CB\u5316");
795
- const { deltaY, deltaX } = event;
796
- const { height, wrapperHeight, width, wrapperWidth } = this;
797
- const maxScrollTop = height - wrapperHeight;
798
- const maxScrollLeft = width - wrapperWidth;
799
- if (maxScrollTop > 0) {
800
- if (deltaY > 0) {
801
- this.scrollTop = this.scrollTop + Math.min(maxScrollTop - this.scrollTop, deltaY);
802
- } else {
803
- this.scrollTop = Math.max(this.scrollTop + deltaY, 0);
804
- }
805
- }
806
- if (width > wrapperWidth) {
807
- if (deltaX > 0) {
808
- this.scrollLeft = this.scrollLeft + Math.min(maxScrollLeft - this.scrollLeft, deltaX);
809
- } else {
810
- this.scrollLeft = Math.max(this.scrollLeft + deltaX, 0);
811
- }
812
- }
813
- if (this.mode !== Mode.FIXED) {
814
- this.scrollTo(this.scrollLeft, this.scrollTop);
815
- }
816
- if (this.pageScrollParent) {
817
- this.pageScrollParent.scrollTo({
818
- top: this.scrollTop,
819
- left: this.scrollLeft
820
- });
821
- }
822
- this.scroll();
823
- this.emit("scroll", event);
824
- };
928
+ setMaxScrollLeft() {
929
+ this.maxScrollLeft = this.width - this.wrapperWidth;
930
+ }
931
+ setMaxScrollTop() {
932
+ this.maxScrollTop = this.height - this.wrapperHeight;
933
+ }
934
+ fixScrollValue() {
935
+ if (this.scrollTop < 0)
936
+ this.scrollTop = 0;
937
+ if (this.scrollLeft < 0)
938
+ this.scrollLeft = 0;
939
+ if (this.maxScrollTop < this.scrollTop)
940
+ this.scrollTop = this.maxScrollTop;
941
+ if (this.maxScrollLeft < this.scrollLeft)
942
+ this.scrollLeft = this.maxScrollLeft;
943
+ }
825
944
  }
826
945
 
827
946
  class StageRender extends EventEmitter.EventEmitter {
828
- contentWindow = null;
829
- runtime = null;
830
- iframe;
831
- runtimeUrl;
832
- core;
833
- render;
834
947
  constructor({ core }) {
835
948
  super();
949
+ this.contentWindow = null;
950
+ this.runtime = null;
951
+ this.getMagicApi = () => ({
952
+ onPageElUpdate: (el) => this.emit("page-el-update", el),
953
+ onRuntimeReady: (runtime) => {
954
+ this.runtime = runtime;
955
+ globalThis.runtime = runtime;
956
+ this.emit("runtime-ready", runtime);
957
+ }
958
+ });
959
+ this.getRuntime = () => {
960
+ if (this.runtime)
961
+ return Promise.resolve(this.runtime);
962
+ return new Promise((resolve) => {
963
+ const listener = (runtime) => {
964
+ this.off("runtime-ready", listener);
965
+ resolve(runtime);
966
+ };
967
+ this.on("runtime-ready", listener);
968
+ });
969
+ };
970
+ this.loadHandler = async () => {
971
+ this.emit("onload");
972
+ if (this.render) {
973
+ const el = await this.render(this.core);
974
+ if (el) {
975
+ this.iframe?.contentDocument?.body?.appendChild(el);
976
+ }
977
+ }
978
+ if (this.contentWindow) {
979
+ const style = this.contentWindow.document.createElement("style");
980
+ style.id = "tmagic-stage-render";
981
+ style.innerHTML = `
982
+ .${SELECTED_CLASS}, .${SELECTED_CLASS}-parent {
983
+ z-index: ${ZIndex.SELECTED_EL};
984
+ }
985
+ `;
986
+ this.contentWindow.document.head.appendChild(style);
987
+ }
988
+ };
836
989
  this.core = core;
837
990
  this.runtimeUrl = core.config.runtimeUrl || "";
838
991
  this.render = core.config.render;
@@ -845,14 +998,6 @@
845
998
  `;
846
999
  this.iframe.addEventListener("load", this.loadHandler);
847
1000
  }
848
- getMagicApi = () => ({
849
- onPageElUpdate: (el) => this.emit("page-el-update", el),
850
- onRuntimeReady: (runtime) => {
851
- this.runtime = runtime;
852
- globalThis.runtime = runtime;
853
- this.emit("runtime-ready", runtime);
854
- }
855
- });
856
1001
  async mount(el) {
857
1002
  if (this.iframe) {
858
1003
  if (!isSameDomain(this.runtimeUrl) && this.runtimeUrl) {
@@ -869,17 +1014,6 @@
869
1014
  throw Error("mount \u5931\u8D25");
870
1015
  }
871
1016
  }
872
- getRuntime = () => {
873
- if (this.runtime)
874
- return Promise.resolve(this.runtime);
875
- return new Promise((resolve) => {
876
- const listener = (runtime) => {
877
- this.off("runtime-ready", listener);
878
- resolve(runtime);
879
- };
880
- this.on("runtime-ready", listener);
881
- });
882
- };
883
1017
  destroy() {
884
1018
  this.iframe?.removeEventListener("load", this.loadHandler);
885
1019
  this.contentWindow = null;
@@ -887,49 +1021,25 @@
887
1021
  this.iframe = void 0;
888
1022
  this.removeAllListeners();
889
1023
  }
890
- loadHandler = async () => {
891
- this.emit("onload");
892
- if (this.render) {
893
- const el = await this.render(this.core);
894
- if (el) {
895
- this.iframe?.contentDocument?.body?.appendChild(el);
896
- }
897
- }
898
- if (this.contentWindow) {
899
- const style = this.contentWindow.document.createElement("style");
900
- style.id = "tmagic-stage-render";
901
- style.innerHTML = `
902
- .${SELECTED_CLASS}, .${SELECTED_CLASS}-parent {
903
- z-index: ${ZIndex.SELECTED_EL};
904
- }
905
- `;
906
- this.contentWindow.document.head.appendChild(style);
907
- }
908
- };
909
1024
  }
910
1025
 
911
1026
  class StageCore extends EventEmitter.EventEmitter {
912
- selectedDom;
913
- highlightedDom;
914
- renderer;
915
- mask;
916
- dr;
917
- highlightLayer;
918
- config;
919
- zoom = DEFAULT_ZOOM;
920
- container;
921
- canSelect;
922
1027
  constructor(config) {
923
1028
  super();
1029
+ this.zoom = DEFAULT_ZOOM;
924
1030
  this.config = config;
925
1031
  this.setZoom(config.zoom);
926
1032
  this.canSelect = config.canSelect || ((el) => !!el.id);
927
1033
  this.renderer = new StageRender({ core: this });
928
1034
  this.mask = new StageMask({ core: this });
929
1035
  this.dr = new StageDragResize({ core: this, container: this.mask.content });
930
- this.highlightLayer = new StageHighlight({ core: this, container: this.mask.content });
931
- this.renderer.on("runtime-ready", (runtime) => this.emit("runtime-ready", runtime));
932
- this.renderer.on("page-el-update", (el) => this.mask?.observe(el));
1036
+ this.highlightLayer = new StageHighlight({ core: this, container: this.mask.wrapper });
1037
+ this.renderer.on("runtime-ready", (runtime) => {
1038
+ this.emit("runtime-ready", runtime);
1039
+ });
1040
+ this.renderer.on("page-el-update", (el) => {
1041
+ this.mask?.observe(el);
1042
+ });
933
1043
  this.mask.on("beforeSelect", (event) => {
934
1044
  this.setElementFromPoint(event);
935
1045
  }).on("select", () => {
@@ -939,6 +1049,10 @@
939
1049
  this.emit("changeGuides", data);
940
1050
  }).on("highlight", async (event) => {
941
1051
  await this.setElementFromPoint(event);
1052
+ if (this.highlightedDom === this.selectedDom) {
1053
+ this.highlightLayer.clearHighlight();
1054
+ return;
1055
+ }
942
1056
  this.highlightLayer.highlight(this.highlightedDom);
943
1057
  this.emit("highlight", this.highlightedDom);
944
1058
  }).on("clearHighlight", async () => {
@@ -966,7 +1080,7 @@
966
1080
  let stopped = false;
967
1081
  const stop = () => stopped = true;
968
1082
  for (const el of els) {
969
- if (!el.id.startsWith(GHOST_EL_ID_PREFIX) && await this.canSelect(el, stop)) {
1083
+ if (!el.id.startsWith(GHOST_EL_ID_PREFIX) && await this.canSelect(el, event, stop)) {
970
1084
  if (stopped)
971
1085
  break;
972
1086
  if (event.type === "mousemove") {
@@ -983,11 +1097,12 @@
983
1097
  if (el === this.selectedDom)
984
1098
  return;
985
1099
  const runtime = await this.renderer.getRuntime();
1100
+ await runtime?.select?.(el.id);
986
1101
  if (runtime?.beforeSelect) {
987
1102
  await runtime.beforeSelect(el);
988
1103
  }
989
1104
  this.mask.setLayout(el);
990
- this.dr?.select(el, event);
1105
+ this.dr.select(el, event);
991
1106
  this.selectedDom = el;
992
1107
  if (this.renderer.contentWindow) {
993
1108
  removeSelectedClassName(this.renderer.contentWindow.document);
@@ -998,32 +1113,39 @@
998
1113
  }
999
1114
  update(data) {
1000
1115
  const { config } = data;
1001
- this.renderer?.getRuntime().then((runtime) => {
1116
+ return this.renderer?.getRuntime().then((runtime) => {
1002
1117
  runtime?.update?.(data);
1003
1118
  setTimeout(() => {
1004
1119
  const el = this.renderer.contentWindow?.document.getElementById(`${config.id}`);
1005
- if (el) {
1120
+ if (el && el.id === this.selectedDom?.id) {
1121
+ this.selectedDom = el;
1006
1122
  this.mask.setLayout(el);
1007
- this.dr?.select(el);
1123
+ this.dr.updateMoveable(el);
1008
1124
  }
1009
1125
  }, 0);
1010
1126
  });
1011
1127
  }
1012
1128
  async highlight(idOrEl) {
1013
- const el = await this.getTargetElement(idOrEl);
1129
+ let el;
1130
+ try {
1131
+ el = await this.getTargetElement(idOrEl);
1132
+ } catch (error) {
1133
+ this.highlightLayer.clearHighlight();
1134
+ return;
1135
+ }
1014
1136
  if (el === this.highlightedDom)
1015
1137
  return;
1016
1138
  this.highlightLayer.highlight(el);
1017
1139
  this.highlightedDom = el;
1018
1140
  }
1019
1141
  sortNode(data) {
1020
- this.renderer?.getRuntime().then((runtime) => runtime?.sortNode?.(data));
1142
+ return this.renderer?.getRuntime().then((runtime) => runtime?.sortNode?.(data));
1021
1143
  }
1022
1144
  add(data) {
1023
- this.renderer?.getRuntime().then((runtime) => runtime?.add?.(data));
1145
+ return this.renderer?.getRuntime().then((runtime) => runtime?.add?.(data));
1024
1146
  }
1025
1147
  remove(data) {
1026
- this.renderer?.getRuntime().then((runtime) => runtime?.remove?.(data));
1148
+ return this.renderer?.getRuntime().then((runtime) => runtime?.remove?.(data));
1027
1149
  }
1028
1150
  setZoom(zoom = DEFAULT_ZOOM) {
1029
1151
  this.zoom = zoom;
@@ -1049,16 +1171,13 @@
1049
1171
  this.container = void 0;
1050
1172
  }
1051
1173
  async getTargetElement(idOrEl) {
1052
- let el;
1053
1174
  if (typeof idOrEl === "string" || typeof idOrEl === "number") {
1054
- const runtime = await this.renderer?.getRuntime();
1055
- el = await runtime?.select?.(`${idOrEl}`);
1175
+ const el = this.renderer.contentWindow?.document.getElementById(`${idOrEl}`);
1056
1176
  if (!el)
1057
1177
  throw new Error(`\u4E0D\u5B58\u5728ID\u4E3A${idOrEl}\u7684\u5143\u7D20`);
1058
- } else {
1059
- el = idOrEl;
1178
+ return el;
1060
1179
  }
1061
- return el;
1180
+ return idOrEl;
1062
1181
  }
1063
1182
  }
1064
1183
 
@@ -1067,8 +1186,7 @@
1067
1186
  exports.StageRender = StageRender;
1068
1187
  exports["default"] = StageCore;
1069
1188
 
1070
- Object.defineProperty(exports, '__esModule', { value: true });
1071
- exports[Symbol.toStringTag] = 'Module';
1189
+ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: 'Module' } });
1072
1190
 
1073
1191
  }));
1074
1192
  //# sourceMappingURL=tmagic-stage.umd.js.map