@tmagic/stage 1.2.0-beta.2 → 1.2.0-beta.20

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,15 +1,16 @@
1
- import EventEmitter$1, { EventEmitter } from 'events';
2
- import { removeClassName, removeClassNameByClassName, createDiv, injectStyle, isSameDomain, getHost, addClassName } from '@tmagic/utils';
1
+ import EventEmitter, { EventEmitter as EventEmitter$1 } from 'events';
3
2
  import KeyController from 'keycon';
3
+ import { merge, throttle } from 'lodash-es';
4
+ import { Env } from '@tmagic/core';
5
+ import { removeClassName, addClassName, removeClassNameByClassName, getDocument, createDiv, injectStyle, isSameDomain, getHost } from '@tmagic/utils';
4
6
  import Moveable from 'moveable';
5
7
  import MoveableHelper from 'moveable-helper';
6
- import { throttle } from 'lodash-es';
7
8
  import Guides from '@scena/guides';
8
9
 
9
10
  const GHOST_EL_ID_PREFIX = "ghost_el_";
10
11
  const DRAG_EL_ID_PREFIX = "drag_el_";
11
12
  const HIGHLIGHT_EL_ID_PREFIX = "highlight_el_";
12
- const CONTAINER_HIGHLIGHT_CLASS = "tmagic-stage-container-highlight";
13
+ const CONTAINER_HIGHLIGHT_CLASS_NAME = "tmagic-stage-container-highlight";
13
14
  const PAGE_CLASS = "magic-ui-page";
14
15
  const DEFAULT_ZOOM = 1;
15
16
  var GuidesType = /* @__PURE__ */ ((GuidesType2) => {
@@ -39,18 +40,6 @@ var Mode = /* @__PURE__ */ ((Mode2) => {
39
40
  })(Mode || {});
40
41
  const SELECTED_CLASS = "tmagic-stage-selected-area";
41
42
 
42
- var ContainerHighlightType = /* @__PURE__ */ ((ContainerHighlightType2) => {
43
- ContainerHighlightType2["DEFAULT"] = "default";
44
- ContainerHighlightType2["ALT"] = "alt";
45
- return ContainerHighlightType2;
46
- })(ContainerHighlightType || {});
47
- var StageDragStatus = /* @__PURE__ */ ((StageDragStatus2) => {
48
- StageDragStatus2["START"] = "start";
49
- StageDragStatus2["ING"] = "ing";
50
- StageDragStatus2["END"] = "end";
51
- return StageDragStatus2;
52
- })(StageDragStatus || {});
53
-
54
43
  const getParents = (el, relative) => {
55
44
  let cur = el.parentElement;
56
45
  const parents = [];
@@ -61,9 +50,10 @@ const getParents = (el, relative) => {
61
50
  return parents;
62
51
  };
63
52
  const getOffset = (el) => {
64
- const { offsetParent } = el;
65
- const left = el.offsetLeft;
66
- const top = el.offsetTop;
53
+ const htmlEl = el;
54
+ const { offsetParent } = htmlEl;
55
+ const left = htmlEl.offsetLeft || 0;
56
+ const top = htmlEl.offsetTop || 0;
67
57
  if (offsetParent) {
68
58
  const parentOffset = getOffset(offsetParent);
69
59
  return {
@@ -76,7 +66,7 @@ const getOffset = (el) => {
76
66
  top
77
67
  };
78
68
  };
79
- const getTargetElStyle = (el) => {
69
+ const getTargetElStyle = (el, zIndex) => {
80
70
  const offset = getOffset(el);
81
71
  const { transform } = getComputedStyle(el);
82
72
  return `
@@ -86,7 +76,7 @@ const getTargetElStyle = (el) => {
86
76
  top: ${offset.top}px;
87
77
  width: ${el.clientWidth}px;
88
78
  height: ${el.clientHeight}px;
89
- z-index: ${ZIndex.DRAG_EL};
79
+ ${typeof zIndex !== "undefined" ? `z-index: ${zIndex};` : ""}
90
80
  `;
91
81
  };
92
82
  const getAbsolutePosition = (el, { top, left }) => {
@@ -135,6 +125,8 @@ const getScrollParent = (element, includeHidden = false) => {
135
125
  return null;
136
126
  for (let parent = element; parent.parentElement; ) {
137
127
  parent = parent.parentElement;
128
+ if (parent.tagName === "HTML")
129
+ return parent;
138
130
  style = getComputedStyle(parent);
139
131
  if (isAbsolute(style) && isStatic(style))
140
132
  continue;
@@ -219,144 +211,500 @@ const up = (deltaTop, target) => {
219
211
  dist: upEls.length && swapIndex > -1 ? upEls[swapIndex].id : target.id
220
212
  };
221
213
  };
214
+ const isMoveableButton = (target) => target.classList.contains("moveable-button") || target.parentElement?.classList.contains("moveable-button");
222
215
 
223
- class StageDragResize extends EventEmitter {
224
- core;
225
- mask;
216
+ class TargetShadow {
217
+ el;
218
+ els = [];
219
+ idPrefix = "target_calibrate_";
226
220
  container;
221
+ scrollLeft = 0;
222
+ scrollTop = 0;
223
+ zIndex;
224
+ updateDragEl;
225
+ constructor(config) {
226
+ this.container = config.container;
227
+ if (config.updateDragEl) {
228
+ this.updateDragEl = config.updateDragEl;
229
+ }
230
+ if (typeof config.zIndex !== "undefined") {
231
+ this.zIndex = config.zIndex;
232
+ }
233
+ if (config.idPrefix) {
234
+ this.idPrefix = config.idPrefix;
235
+ }
236
+ this.container.addEventListener("customScroll", this.scrollHandler);
237
+ }
238
+ update(target) {
239
+ this.el = this.updateEl(target, this.el);
240
+ return this.el;
241
+ }
242
+ updateGroup(targetGroup) {
243
+ if (this.els.length > targetGroup.length) {
244
+ this.els.slice(targetGroup.length - 1).forEach((el) => {
245
+ el.remove();
246
+ });
247
+ }
248
+ this.els = targetGroup.map((target, index) => this.updateEl(target, this.els[index]));
249
+ return this.els;
250
+ }
251
+ destroyEl() {
252
+ this.el?.remove();
253
+ this.el = void 0;
254
+ }
255
+ destroyEls() {
256
+ this.els.forEach((el) => {
257
+ el.remove();
258
+ });
259
+ this.els = [];
260
+ }
261
+ destroy() {
262
+ this.container.removeEventListener("customScroll", this.scrollHandler);
263
+ this.destroyEl();
264
+ this.destroyEls();
265
+ }
266
+ updateEl(target, src) {
267
+ const el = src || globalThis.document.createElement("div");
268
+ el.id = `${this.idPrefix}${target.id}`;
269
+ el.style.cssText = getTargetElStyle(target, this.zIndex);
270
+ if (typeof this.updateDragEl === "function") {
271
+ this.updateDragEl(el, target);
272
+ }
273
+ const isFixed = isFixedParent(target);
274
+ const mode = this.container.dataset.mode || Mode.ABSOLUTE;
275
+ if (isFixed && mode !== Mode.FIXED) {
276
+ el.style.transform = `translate3d(${this.scrollLeft}px, ${this.scrollTop}px, 0)`;
277
+ } else if (!isFixed && mode === Mode.FIXED) {
278
+ el.style.transform = `translate3d(${-this.scrollLeft}px, ${-this.scrollTop}px, 0)`;
279
+ }
280
+ if (!globalThis.document.getElementById(el.id)) {
281
+ this.container.append(el);
282
+ }
283
+ return el;
284
+ }
285
+ scrollHandler = (e) => {
286
+ this.scrollLeft = e.detail.scrollLeft;
287
+ this.scrollTop = e.detail.scrollTop;
288
+ };
289
+ }
290
+
291
+ class DragResizeHelper {
292
+ targetShadow;
227
293
  target;
228
- dragEl;
229
- moveable;
230
- horizontalGuidelines = [];
231
- verticalGuidelines = [];
232
- elementGuidelines = [];
233
- mode = Mode.ABSOLUTE;
234
- moveableOptions = {};
235
- dragStatus = StageDragStatus.END;
236
- ghostEl;
294
+ targetList = [];
237
295
  moveableHelper;
238
- isContainerHighlight = false;
296
+ ghostEl;
297
+ frameSnapShot = {
298
+ left: 0,
299
+ top: 0
300
+ };
301
+ framesSnapShot = [];
302
+ mode = Mode.ABSOLUTE;
239
303
  constructor(config) {
240
- super();
241
- this.core = config.core;
242
- this.container = config.container;
243
- this.mask = config.mask;
244
- KeyController.global.keydown("alt", (e) => {
245
- e.inputEvent.preventDefault();
246
- this.isContainerHighlight = true;
304
+ this.moveableHelper = MoveableHelper.create({
305
+ useBeforeRender: true,
306
+ useRender: false,
307
+ createAuto: true
247
308
  });
248
- KeyController.global.keyup("alt", (e) => {
249
- e.inputEvent.preventDefault();
250
- const doc = this.core.renderer.contentWindow?.document;
251
- if (doc && this.canContainerHighlight()) {
252
- removeClassNameByClassName(doc, this.core.containerHighlightClassName);
253
- }
254
- this.isContainerHighlight = false;
309
+ this.targetShadow = new TargetShadow({
310
+ container: config.container,
311
+ updateDragEl: config.updateDragEl,
312
+ zIndex: ZIndex.DRAG_EL,
313
+ idPrefix: DRAG_EL_ID_PREFIX
255
314
  });
256
315
  }
257
- select(el, event) {
258
- const oldTarget = this.target;
316
+ destroy() {
317
+ this.targetShadow.destroy();
318
+ this.destroyGhostEl();
319
+ this.moveableHelper.clear();
320
+ }
321
+ destroyShadowEl() {
322
+ this.targetShadow.destroyEl();
323
+ }
324
+ getShadowEl() {
325
+ return this.targetShadow.el;
326
+ }
327
+ updateShadowEl(el) {
328
+ this.destroyGhostEl();
259
329
  this.target = el;
260
- if (!this.dragEl) {
261
- this.dragEl = globalThis.document.createElement("div");
262
- this.container.append(this.dragEl);
263
- }
264
- if (!this.moveable || this.target !== oldTarget) {
265
- this.init(el);
266
- this.moveableHelper = MoveableHelper.create({
267
- useBeforeRender: true,
268
- useRender: false,
269
- createAuto: true
270
- });
271
- this.initMoveable();
330
+ this.targetShadow.update(el);
331
+ }
332
+ setMode(mode) {
333
+ this.mode = mode;
334
+ }
335
+ onResizeStart(e) {
336
+ this.moveableHelper.onResizeStart(e);
337
+ this.frameSnapShot.top = this.target.offsetTop;
338
+ this.frameSnapShot.left = this.target.offsetLeft;
339
+ }
340
+ onResize(e) {
341
+ const { width, height, drag } = e;
342
+ const { beforeTranslate } = drag;
343
+ if (this.mode === Mode.SORTABLE) {
344
+ this.target.style.top = "0px";
345
+ if (this.targetShadow.el) {
346
+ this.targetShadow.el.style.width = `${width}px`;
347
+ this.targetShadow.el.style.height = `${height}px`;
348
+ }
272
349
  } else {
273
- this.updateMoveable();
350
+ this.moveableHelper.onResize(e);
351
+ this.target.style.left = `${this.frameSnapShot.left + beforeTranslate[0]}px`;
352
+ this.target.style.top = `${this.frameSnapShot.top + beforeTranslate[1]}px`;
274
353
  }
275
- if (event) {
276
- this.moveable?.dragStart(event);
354
+ this.target.style.width = `${width}px`;
355
+ this.target.style.height = `${height}px`;
356
+ }
357
+ onDragStart(e) {
358
+ this.moveableHelper.onDragStart(e);
359
+ if (this.mode === Mode.SORTABLE) {
360
+ this.ghostEl = this.generateGhostEl(this.target);
277
361
  }
362
+ this.frameSnapShot.top = this.target.offsetTop;
363
+ this.frameSnapShot.left = this.target.offsetLeft;
278
364
  }
279
- updateMoveable(el = this.target) {
280
- if (!this.moveable)
281
- throw new Error("\u672A\u521D\u59CB\u5316moveable");
282
- if (!el)
283
- throw new Error("\u672A\u9009\u4E2D\u4EFB\u4F55\u8282\u70B9");
284
- this.target = el;
285
- this.init(el);
286
- Object.entries(this.moveableOptions).forEach(([key, value]) => {
287
- this.moveable[key] = value;
365
+ onDrag(e) {
366
+ if (this.ghostEl) {
367
+ this.ghostEl.style.top = `${this.frameSnapShot.top + e.beforeTranslate[1]}px`;
368
+ return;
369
+ }
370
+ this.moveableHelper.onDrag(e);
371
+ this.target.style.left = `${this.frameSnapShot.left + e.beforeTranslate[0]}px`;
372
+ this.target.style.top = `${this.frameSnapShot.top + e.beforeTranslate[1]}px`;
373
+ }
374
+ onRotateStart(e) {
375
+ this.moveableHelper.onRotateStart(e);
376
+ }
377
+ onRotate(e) {
378
+ this.moveableHelper.onRotate(e);
379
+ const frame = this.moveableHelper.getFrame(e.target);
380
+ this.target.style.transform = frame?.toCSSObject().transform || "";
381
+ }
382
+ onScaleStart(e) {
383
+ this.moveableHelper.onScaleStart(e);
384
+ }
385
+ onScale(e) {
386
+ this.moveableHelper.onScale(e);
387
+ const frame = this.moveableHelper.getFrame(e.target);
388
+ this.target.style.transform = frame?.toCSSObject().transform || "";
389
+ }
390
+ getGhostEl() {
391
+ return this.ghostEl;
392
+ }
393
+ destroyGhostEl() {
394
+ this.ghostEl?.remove();
395
+ this.ghostEl = void 0;
396
+ }
397
+ clear() {
398
+ this.moveableHelper.clear();
399
+ }
400
+ getFrame(el) {
401
+ return this.moveableHelper.getFrame(el);
402
+ }
403
+ getShadowEls() {
404
+ return this.targetShadow.els;
405
+ }
406
+ updateGroup(els) {
407
+ this.targetList = els;
408
+ this.framesSnapShot = [];
409
+ this.targetShadow.updateGroup(els);
410
+ }
411
+ setTargetList(targetList) {
412
+ this.targetList = targetList;
413
+ }
414
+ clearMultiSelectStatus() {
415
+ this.targetList = [];
416
+ this.targetShadow.destroyEls();
417
+ }
418
+ onResizeGroupStart(e) {
419
+ const { events } = e;
420
+ this.moveableHelper.onResizeGroupStart(e);
421
+ this.setFramesSnapShot(events);
422
+ }
423
+ onResizeGroup(e) {
424
+ const { events } = e;
425
+ events.forEach((ev) => {
426
+ const { width, height, beforeTranslate } = ev.drag;
427
+ const frameSnapShot = this.framesSnapShot.find(
428
+ (frameItem) => frameItem.id === ev.target.id.replace(DRAG_EL_ID_PREFIX, "")
429
+ );
430
+ if (!frameSnapShot)
431
+ return;
432
+ const targeEl = this.targetList.find(
433
+ (targetItem) => targetItem.id === ev.target.id.replace(DRAG_EL_ID_PREFIX, "")
434
+ );
435
+ if (!targeEl)
436
+ return;
437
+ const isParentIncluded = this.targetList.find((targetItem) => targetItem.id === targeEl.parentElement?.id);
438
+ if (!isParentIncluded) {
439
+ targeEl.style.left = `${frameSnapShot.left + beforeTranslate[0]}px`;
440
+ targeEl.style.top = `${frameSnapShot.top + beforeTranslate[1]}px`;
441
+ }
442
+ targeEl.style.width = `${width}px`;
443
+ targeEl.style.height = `${height}px`;
288
444
  });
289
- this.moveable.updateTarget();
445
+ this.moveableHelper.onResizeGroup(e);
446
+ }
447
+ onDragGroupStart(e) {
448
+ const { events } = e;
449
+ this.moveableHelper.onDragGroupStart(e);
450
+ this.setFramesSnapShot(events);
451
+ }
452
+ onDragGroup(e) {
453
+ const { events } = e;
454
+ events.forEach((ev) => {
455
+ const frameSnapShot = this.framesSnapShot.find(
456
+ (frameItem) => frameItem.id === ev.target.id.replace(DRAG_EL_ID_PREFIX, "")
457
+ );
458
+ if (!frameSnapShot)
459
+ return;
460
+ const targeEl = this.targetList.find(
461
+ (targetItem) => targetItem.id === ev.target.id.replace(DRAG_EL_ID_PREFIX, "")
462
+ );
463
+ if (!targeEl)
464
+ return;
465
+ const isParentIncluded = this.targetList.find((targetItem) => targetItem.id === targeEl.parentElement?.id);
466
+ if (!isParentIncluded) {
467
+ targeEl.style.left = `${frameSnapShot.left + ev.beforeTranslate[0]}px`;
468
+ targeEl.style.top = `${frameSnapShot.top + ev.beforeTranslate[1]}px`;
469
+ }
470
+ });
471
+ this.moveableHelper.onDragGroup(e);
472
+ }
473
+ setFramesSnapShot(events) {
474
+ if (this.framesSnapShot.length > 0)
475
+ return;
476
+ events.forEach((ev) => {
477
+ const matchEventTarget = this.targetList.find(
478
+ (targetItem) => targetItem.id === ev.target.id.replace(DRAG_EL_ID_PREFIX, "")
479
+ );
480
+ if (!matchEventTarget)
481
+ return;
482
+ this.framesSnapShot.push({
483
+ left: matchEventTarget.offsetLeft,
484
+ top: matchEventTarget.offsetTop,
485
+ id: matchEventTarget.id
486
+ });
487
+ });
488
+ }
489
+ generateGhostEl(el) {
490
+ if (this.ghostEl) {
491
+ this.destroyGhostEl();
492
+ }
493
+ const ghostEl = el.cloneNode(true);
494
+ this.setGhostElChildrenId(ghostEl);
495
+ const { top, left } = getAbsolutePosition(el, getOffset(el));
496
+ ghostEl.id = `${GHOST_EL_ID_PREFIX}${el.id}`;
497
+ ghostEl.style.zIndex = ZIndex.GHOST_EL;
498
+ ghostEl.style.opacity = ".5";
499
+ ghostEl.style.position = "absolute";
500
+ ghostEl.style.left = `${left}px`;
501
+ ghostEl.style.top = `${top}px`;
502
+ el.after(ghostEl);
503
+ return ghostEl;
504
+ }
505
+ setGhostElChildrenId(el) {
506
+ for (const child of Array.from(el.children)) {
507
+ if (child.id) {
508
+ child.id = `${GHOST_EL_ID_PREFIX}${child.id}`;
509
+ }
510
+ if (child.children.length) {
511
+ this.setGhostElChildrenId(child);
512
+ }
513
+ }
514
+ }
515
+ }
516
+
517
+ const selectParentAbles = (selectParentHandler) => ({
518
+ name: "select-parent",
519
+ props: {},
520
+ events: {},
521
+ render(moveable, React) {
522
+ const rect = moveable.getRect();
523
+ const { pos2 } = moveable.state;
524
+ const editableViewer = moveable.useCSS(
525
+ "div",
526
+ `
527
+ {
528
+ position: absolute;
529
+ left: 0px;
530
+ top: 0px;
531
+ will-change: transform;
532
+ transform-origin: 0px 0px;
533
+ display: flex;
534
+ }
535
+ .moveable-button {
536
+ width: 20px;
537
+ height: 20px;
538
+ background: #4af;
539
+ border-radius: 4px;
540
+ appearance: none;
541
+ border: 0;
542
+ color: white;
543
+ font-size: 12px;
544
+ font-weight: bold;
545
+ }
546
+ `
547
+ );
548
+ return React.createElement(
549
+ editableViewer,
550
+ {
551
+ className: "moveable-editable",
552
+ style: {
553
+ transform: `translate(${pos2[0] - 25}px, ${pos2[1] - 30}px) rotate(${rect.rotation}deg) translate(10px)`
554
+ }
555
+ },
556
+ React.createElement(
557
+ "button",
558
+ {
559
+ className: "moveable-button",
560
+ title: "\u9009\u4E2D\u7236\u7EC4\u4EF6",
561
+ onClick: () => {
562
+ selectParentHandler();
563
+ }
564
+ },
565
+ React.createElement(
566
+ "svg",
567
+ {
568
+ width: "1em",
569
+ height: "1em",
570
+ viewBox: "0 0 16 16",
571
+ fill: "none",
572
+ xmlns: "http://www.w3.org/2000/svg",
573
+ style: {
574
+ transform: "rotate(90deg)"
575
+ }
576
+ },
577
+ React.createElement("path", {
578
+ 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",
579
+ fill: "currentColor",
580
+ fillOpacity: "0.9"
581
+ })
582
+ )
583
+ )
584
+ );
585
+ }
586
+ });
587
+
588
+ class MoveableOptionsManager extends EventEmitter {
589
+ mode = Mode.ABSOLUTE;
590
+ container;
591
+ horizontalGuidelines = [];
592
+ verticalGuidelines = [];
593
+ elementGuidelines = [];
594
+ customizedOptions;
595
+ getRootContainer;
596
+ constructor(config) {
597
+ super();
598
+ this.customizedOptions = config.moveableOptions;
599
+ this.container = config.container;
600
+ this.getRootContainer = config.getRootContainer;
290
601
  }
291
602
  setGuidelines(type, guidelines) {
292
603
  if (type === GuidesType.HORIZONTAL) {
293
604
  this.horizontalGuidelines = guidelines;
294
- this.moveableOptions.horizontalGuidelines = guidelines;
295
605
  } else if (type === GuidesType.VERTICAL) {
296
606
  this.verticalGuidelines = guidelines;
297
- this.moveableOptions.verticalGuidelines = guidelines;
298
- }
299
- if (this.moveable) {
300
- this.updateMoveable();
301
607
  }
608
+ this.emit("update-moveable");
302
609
  }
303
610
  clearGuides() {
304
611
  this.horizontalGuidelines = [];
305
612
  this.verticalGuidelines = [];
306
- this.moveableOptions.horizontalGuidelines = [];
307
- this.moveableOptions.verticalGuidelines = [];
308
- this.updateMoveable();
309
- }
310
- clearSelectStatus() {
311
- if (!this.moveable)
312
- return;
313
- this.destroyDragEl();
314
- this.dragEl = void 0;
315
- this.moveable.target = null;
316
- this.moveable.updateTarget();
317
- }
318
- destroyDragEl() {
319
- this.dragEl?.remove();
320
- }
321
- destroy() {
322
- this.moveable?.destroy();
323
- this.destroyGhostEl();
324
- this.destroyDragEl();
325
- this.dragStatus = StageDragStatus.END;
326
- this.removeAllListeners();
327
- }
328
- init(el) {
329
- if (/(auto|scroll)/.test(el.style.overflow)) {
330
- el.style.overflow = "hidden";
331
- }
332
- this.mode = getMode(el);
333
- this.destroyGhostEl();
334
- if (!this.dragEl) {
335
- return;
336
- }
337
- this.dragEl.style.cssText = getTargetElStyle(el);
338
- this.dragEl.id = `${DRAG_EL_ID_PREFIX}${el.id}`;
339
- if (typeof this.core.config.updateDragEl === "function") {
340
- this.core.config.updateDragEl(this.dragEl, el);
341
- }
342
- this.moveableOptions = this.getOptions({
343
- target: this.dragEl
344
- });
613
+ this.emit("update-moveable");
345
614
  }
346
- setElementGuidelines(nodes) {
615
+ setElementGuidelines(selectedElList, allElList) {
347
616
  this.elementGuidelines.forEach((node) => {
348
617
  node.remove();
349
618
  });
350
619
  this.elementGuidelines = [];
351
620
  if (this.mode === Mode.ABSOLUTE) {
352
- this.container.append(this.createGuidelineElements(nodes));
621
+ this.container.append(this.createGuidelineElements(selectedElList, allElList));
622
+ }
623
+ }
624
+ getOptions(isMultiSelect, runtimeOptions = {}) {
625
+ const defaultOptions = this.getDefaultOptions(isMultiSelect);
626
+ const customizedOptions = this.getCustomizeOptions();
627
+ return merge(defaultOptions, customizedOptions, runtimeOptions);
628
+ }
629
+ getDefaultOptions(isMultiSelect) {
630
+ const isSortable = this.mode === Mode.SORTABLE;
631
+ const commonOptions = {
632
+ draggable: true,
633
+ resizable: true,
634
+ rootContainer: this.getRootContainer(),
635
+ zoom: 1,
636
+ throttleDrag: 0,
637
+ snappable: true,
638
+ horizontalGuidelines: this.horizontalGuidelines,
639
+ verticalGuidelines: this.verticalGuidelines,
640
+ elementGuidelines: this.elementGuidelines,
641
+ bounds: {
642
+ top: 0,
643
+ left: -1,
644
+ right: this.container.clientWidth - 1,
645
+ bottom: isSortable ? void 0 : this.container.clientHeight
646
+ }
647
+ };
648
+ const differenceOptions = isMultiSelect ? this.getMultiOptions() : this.getSingleOptions();
649
+ return merge(commonOptions, differenceOptions);
650
+ }
651
+ getSingleOptions() {
652
+ const isAbsolute = this.mode === Mode.ABSOLUTE;
653
+ const isFixed = this.mode === Mode.FIXED;
654
+ return {
655
+ origin: false,
656
+ dragArea: false,
657
+ scalable: false,
658
+ rotatable: false,
659
+ snapGap: isAbsolute || isFixed,
660
+ snapThreshold: 5,
661
+ snapDigit: 0,
662
+ isDisplaySnapDigit: isAbsolute,
663
+ snapDirections: {
664
+ top: isAbsolute,
665
+ right: isAbsolute,
666
+ bottom: isAbsolute,
667
+ left: isAbsolute,
668
+ center: isAbsolute,
669
+ middle: isAbsolute
670
+ },
671
+ elementSnapDirections: {
672
+ top: isAbsolute,
673
+ right: isAbsolute,
674
+ bottom: isAbsolute,
675
+ left: isAbsolute
676
+ },
677
+ isDisplayInnerSnapDigit: true,
678
+ props: {
679
+ selectParent: true
680
+ },
681
+ ables: [selectParentAbles(this.selectParentHandler.bind(this))]
682
+ };
683
+ }
684
+ getMultiOptions() {
685
+ return {
686
+ defaultGroupRotate: 0,
687
+ defaultGroupOrigin: "50% 50%",
688
+ startDragRotate: 0,
689
+ throttleDragRotate: 0,
690
+ origin: true,
691
+ padding: { left: 0, top: 0, right: 0, bottom: 0 }
692
+ };
693
+ }
694
+ getCustomizeOptions() {
695
+ if (typeof this.customizedOptions === "function") {
696
+ return this.customizedOptions();
353
697
  }
698
+ return this.customizedOptions;
354
699
  }
355
- createGuidelineElements(nodes) {
700
+ selectParentHandler() {
701
+ this.emit("select-parent");
702
+ }
703
+ createGuidelineElements(selectedElList, allElList) {
356
704
  const frame = globalThis.document.createDocumentFragment();
357
- for (const node of nodes) {
705
+ for (const node of allElList) {
358
706
  const { width, height } = node.getBoundingClientRect();
359
- if (node === this.target)
707
+ if (this.isInElementList(node, selectedElList))
360
708
  continue;
361
709
  const { left, top } = getOffset(node);
362
710
  const elementGuideline = globalThis.document.createElement("div");
@@ -366,10 +714,109 @@ class StageDragResize extends EventEmitter {
366
714
  }
367
715
  return frame;
368
716
  }
369
- initMoveable() {
370
- this.moveable?.destroy();
717
+ isInElementList(ele, eleList) {
718
+ for (const eleItem of eleList) {
719
+ if (ele === eleItem)
720
+ return true;
721
+ }
722
+ return false;
723
+ }
724
+ }
725
+
726
+ var ContainerHighlightType = /* @__PURE__ */ ((ContainerHighlightType2) => {
727
+ ContainerHighlightType2["DEFAULT"] = "default";
728
+ ContainerHighlightType2["ALT"] = "alt";
729
+ return ContainerHighlightType2;
730
+ })(ContainerHighlightType || {});
731
+ var SelectStatus = /* @__PURE__ */ ((SelectStatus2) => {
732
+ SelectStatus2["SELECT"] = "select";
733
+ SelectStatus2["MULTI_SELECT"] = "multiSelect";
734
+ return SelectStatus2;
735
+ })(SelectStatus || {});
736
+ var StageDragStatus = /* @__PURE__ */ ((StageDragStatus2) => {
737
+ StageDragStatus2["START"] = "start";
738
+ StageDragStatus2["ING"] = "ing";
739
+ StageDragStatus2["END"] = "end";
740
+ return StageDragStatus2;
741
+ })(StageDragStatus || {});
742
+
743
+ class StageDragResize extends MoveableOptionsManager {
744
+ target;
745
+ moveable;
746
+ dragStatus = StageDragStatus.END;
747
+ dragResizeHelper;
748
+ getRenderDocument;
749
+ markContainerEnd;
750
+ delayedMarkContainer;
751
+ constructor(config) {
752
+ super(config);
753
+ this.getRenderDocument = config.getRenderDocument;
754
+ this.markContainerEnd = config.markContainerEnd;
755
+ this.delayedMarkContainer = config.delayedMarkContainer;
756
+ this.dragResizeHelper = new DragResizeHelper({
757
+ container: config.container,
758
+ updateDragEl: config.updateDragEl
759
+ });
760
+ this.on("update-moveable", () => {
761
+ if (this.moveable) {
762
+ this.updateMoveable();
763
+ }
764
+ });
765
+ }
766
+ select(el, event) {
767
+ if (!this.moveable || el !== this.target) {
768
+ this.initMoveable(el);
769
+ } else {
770
+ this.updateMoveable(el);
771
+ }
772
+ if (event) {
773
+ this.moveable?.dragStart(event);
774
+ }
775
+ }
776
+ updateMoveable(el = this.target) {
777
+ if (!this.moveable)
778
+ return;
779
+ if (!el)
780
+ throw new Error("\u672A\u9009\u4E2D\u4EFB\u4F55\u8282\u70B9");
781
+ const options = this.init(el);
782
+ Object.entries(options).forEach(([key, value]) => {
783
+ this.moveable[key] = value;
784
+ });
785
+ this.moveable.updateTarget();
786
+ }
787
+ clearSelectStatus() {
788
+ if (!this.moveable)
789
+ return;
790
+ this.dragResizeHelper.destroyShadowEl();
791
+ this.moveable.target = null;
792
+ this.moveable.updateTarget();
793
+ }
794
+ destroy() {
795
+ this.moveable?.destroy();
796
+ this.dragResizeHelper.destroy();
797
+ this.dragStatus = StageDragStatus.END;
798
+ this.removeAllListeners();
799
+ }
800
+ init(el) {
801
+ if (/(auto|scroll)/.test(el.style.overflow)) {
802
+ el.style.overflow = "hidden";
803
+ }
804
+ this.target = el;
805
+ this.mode = getMode(el);
806
+ this.dragResizeHelper.updateShadowEl(el);
807
+ this.dragResizeHelper.setMode(this.mode);
808
+ const elementGuidelines = Array.prototype.slice.call(this.target?.parentElement?.children) || [];
809
+ this.setElementGuidelines([this.target], elementGuidelines);
810
+ return this.getOptions(false, {
811
+ target: this.dragResizeHelper.getShadowEl()
812
+ });
813
+ }
814
+ initMoveable(el) {
815
+ const options = this.init(el);
816
+ this.dragResizeHelper.clear();
817
+ this.moveable?.destroy();
371
818
  this.moveable = new Moveable(this.container, {
372
- ...this.moveableOptions
819
+ ...options
373
820
  });
374
821
  this.bindResizeEvent();
375
822
  this.bindDragEvent();
@@ -379,34 +826,16 @@ class StageDragResize extends EventEmitter {
379
826
  bindResizeEvent() {
380
827
  if (!this.moveable)
381
828
  throw new Error("moveable \u672A\u521D\u59CB\u5316");
382
- const frame = {
383
- left: 0,
384
- top: 0
385
- };
386
829
  this.moveable.on("resizeStart", (e) => {
387
830
  if (!this.target)
388
831
  return;
389
832
  this.dragStatus = StageDragStatus.START;
390
- this.moveableHelper?.onResizeStart(e);
391
- frame.top = this.target.offsetTop;
392
- frame.left = this.target.offsetLeft;
833
+ this.dragResizeHelper.onResizeStart(e);
393
834
  }).on("resize", (e) => {
394
- const { width, height, drag } = e;
395
- if (!this.moveable || !this.target || !this.dragEl)
835
+ if (!this.moveable || !this.target || !this.dragResizeHelper.getShadowEl())
396
836
  return;
397
- const { beforeTranslate } = drag;
398
837
  this.dragStatus = StageDragStatus.ING;
399
- if (this.mode === Mode.SORTABLE) {
400
- this.target.style.top = "0px";
401
- this.dragEl.style.width = `${width}px`;
402
- this.dragEl.style.height = `${height}px`;
403
- } else {
404
- this.moveableHelper?.onResize(e);
405
- this.target.style.left = `${frame.left + beforeTranslate[0]}px`;
406
- this.target.style.top = `${frame.top + beforeTranslate[1]}px`;
407
- }
408
- this.target.style.width = `${width}px`;
409
- this.target.style.height = `${height}px`;
838
+ this.dragResizeHelper.onResize(e);
410
839
  }).on("resizeEnd", () => {
411
840
  this.dragStatus = StageDragStatus.END;
412
841
  this.update(true);
@@ -415,50 +844,28 @@ class StageDragResize extends EventEmitter {
415
844
  bindDragEvent() {
416
845
  if (!this.moveable)
417
846
  throw new Error("moveable \u672A\u521D\u59CB\u5316");
418
- const frame = {
419
- left: 0,
420
- top: 0
421
- };
422
847
  let timeout;
423
- const { contentWindow } = this.core.renderer;
424
- const doc = contentWindow?.document;
425
848
  this.moveable.on("dragStart", (e) => {
426
849
  if (!this.target)
427
850
  throw new Error("\u672A\u9009\u4E2D\u7EC4\u4EF6");
428
851
  this.dragStatus = StageDragStatus.START;
429
- this.moveableHelper?.onDragStart(e);
430
- if (this.mode === Mode.SORTABLE) {
431
- this.ghostEl = this.generateGhostEl(this.target);
432
- }
433
- frame.top = this.target.offsetTop;
434
- frame.left = this.target.offsetLeft;
852
+ this.dragResizeHelper.onDragStart(e);
435
853
  }).on("drag", (e) => {
436
- if (!this.target || !this.dragEl)
854
+ if (!this.target || !this.dragResizeHelper.getShadowEl())
437
855
  return;
438
856
  if (timeout) {
439
857
  globalThis.clearTimeout(timeout);
440
858
  timeout = void 0;
441
859
  }
442
- if (this.canContainerHighlight()) {
443
- timeout = this.core.getAddContainerHighlightClassNameTimeout(e.inputEvent, [this.target]);
444
- }
860
+ timeout = this.delayedMarkContainer(e.inputEvent, [this.target]);
445
861
  this.dragStatus = StageDragStatus.ING;
446
- if (this.ghostEl) {
447
- this.ghostEl.style.top = `${frame.top + e.beforeTranslate[1]}px`;
448
- return;
449
- }
450
- this.moveableHelper?.onDrag(e);
451
- this.target.style.left = `${frame.left + e.beforeTranslate[0]}px`;
452
- this.target.style.top = `${frame.top + e.beforeTranslate[1]}px`;
862
+ this.dragResizeHelper.onDrag(e);
453
863
  }).on("dragEnd", () => {
454
864
  if (timeout) {
455
865
  globalThis.clearTimeout(timeout);
456
866
  timeout = void 0;
457
867
  }
458
- let parentEl = null;
459
- if (doc && this.canContainerHighlight()) {
460
- parentEl = removeClassNameByClassName(doc, this.core.containerHighlightClassName);
461
- }
868
+ const parentEl = this.markContainerEnd();
462
869
  if (this.dragStatus === StageDragStatus.ING) {
463
870
  if (parentEl) {
464
871
  this.update(false, parentEl);
@@ -473,7 +880,7 @@ class StageDragResize extends EventEmitter {
473
880
  }
474
881
  }
475
882
  this.dragStatus = StageDragStatus.END;
476
- this.destroyGhostEl();
883
+ this.dragResizeHelper.destroyGhostEl();
477
884
  });
478
885
  }
479
886
  bindRotateEvent() {
@@ -481,17 +888,15 @@ class StageDragResize extends EventEmitter {
481
888
  throw new Error("moveable \u672A\u521D\u59CB\u5316");
482
889
  this.moveable.on("rotateStart", (e) => {
483
890
  this.dragStatus = StageDragStatus.START;
484
- this.moveableHelper?.onRotateStart(e);
891
+ this.dragResizeHelper.onRotateStart(e);
485
892
  }).on("rotate", (e) => {
486
- if (!this.target || !this.dragEl)
893
+ if (!this.target || !this.dragResizeHelper.getShadowEl())
487
894
  return;
488
895
  this.dragStatus = StageDragStatus.ING;
489
- this.moveableHelper?.onRotate(e);
490
- const frame = this.moveableHelper?.getFrame(e.target);
491
- this.target.style.transform = frame?.toCSSObject().transform || "";
896
+ this.dragResizeHelper.onRotate(e);
492
897
  }).on("rotateEnd", (e) => {
493
898
  this.dragStatus = StageDragStatus.END;
494
- const frame = this.moveableHelper?.getFrame(e.target);
899
+ const frame = this.dragResizeHelper?.getFrame(e.target);
495
900
  this.emit("update", {
496
901
  data: [
497
902
  {
@@ -509,17 +914,15 @@ class StageDragResize extends EventEmitter {
509
914
  throw new Error("moveable \u672A\u521D\u59CB\u5316");
510
915
  this.moveable.on("scaleStart", (e) => {
511
916
  this.dragStatus = StageDragStatus.START;
512
- this.moveableHelper?.onScaleStart(e);
917
+ this.dragResizeHelper.onScaleStart(e);
513
918
  }).on("scale", (e) => {
514
- if (!this.target || !this.dragEl)
919
+ if (!this.target || !this.dragResizeHelper.getShadowEl())
515
920
  return;
516
921
  this.dragStatus = StageDragStatus.ING;
517
- this.moveableHelper?.onScale(e);
518
- const frame = this.moveableHelper?.getFrame(e.target);
519
- this.target.style.transform = frame?.toCSSObject().transform || "";
922
+ this.dragResizeHelper.onScale(e);
520
923
  }).on("scaleEnd", (e) => {
521
924
  this.dragStatus = StageDragStatus.END;
522
- const frame = this.moveableHelper?.getFrame(e.target);
925
+ const frame = this.dragResizeHelper.getFrame(e.target);
523
926
  this.emit("update", {
524
927
  data: [
525
928
  {
@@ -533,9 +936,9 @@ class StageDragResize extends EventEmitter {
533
936
  });
534
937
  }
535
938
  sort() {
536
- if (!this.target || !this.ghostEl)
939
+ if (!this.target || !this.dragResizeHelper.getGhostEl())
537
940
  throw new Error("\u672A\u77E5\u9519\u8BEF");
538
- const { top } = this.ghostEl.getBoundingClientRect();
941
+ const { top } = this.dragResizeHelper.getGhostEl().getBoundingClientRect();
539
942
  const { top: oriTop } = this.target.getBoundingClientRect();
540
943
  const deltaTop = top - oriTop;
541
944
  if (Math.abs(deltaTop) >= this.target.clientHeight / 2) {
@@ -554,8 +957,7 @@ class StageDragResize extends EventEmitter {
554
957
  update(isResize = false, parentEl = null) {
555
958
  if (!this.target)
556
959
  return;
557
- const { contentWindow } = this.core.renderer;
558
- const doc = contentWindow?.document;
960
+ const doc = this.getRenderDocument();
559
961
  if (!doc)
560
962
  return;
561
963
  const offset = this.mode === Mode.SORTABLE ? { left: 0, top: 0 } : { left: this.target.offsetLeft, top: this.target.offsetTop };
@@ -563,11 +965,16 @@ class StageDragResize extends EventEmitter {
563
965
  let top = calcValueByFontsize(doc, offset.top);
564
966
  const width = calcValueByFontsize(doc, this.target.clientWidth);
565
967
  const height = calcValueByFontsize(doc, this.target.clientHeight);
566
- if (parentEl && this.mode === Mode.ABSOLUTE && this.dragEl) {
567
- const [translateX, translateY] = this.moveableHelper?.getFrame(this.dragEl).properties.transform.translate.value;
968
+ const shadowEl = this.dragResizeHelper.getShadowEl();
969
+ if (parentEl && this.mode === Mode.ABSOLUTE && shadowEl) {
970
+ const targetShadowHtmlEl = shadowEl;
971
+ const targetShadowElOffsetLeft = targetShadowHtmlEl.offsetLeft || 0;
972
+ const targetShadowElOffsetTop = targetShadowHtmlEl.offsetTop || 0;
973
+ const frame = this.dragResizeHelper.getFrame(shadowEl);
974
+ const [translateX, translateY] = frame?.properties.transform.translate.value;
568
975
  const { left: parentLeft, top: parentTop } = getOffset(parentEl);
569
- left = calcValueByFontsize(doc, this.dragEl.offsetLeft) + parseFloat(translateX) - calcValueByFontsize(doc, parentLeft);
570
- top = calcValueByFontsize(doc, this.dragEl.offsetTop) + parseFloat(translateY) - calcValueByFontsize(doc, parentTop);
976
+ left = calcValueByFontsize(doc, targetShadowElOffsetLeft) + parseFloat(translateX) - calcValueByFontsize(doc, parentLeft);
977
+ top = calcValueByFontsize(doc, targetShadowElOffsetTop) + parseFloat(translateY) - calcValueByFontsize(doc, parentTop);
571
978
  }
572
979
  this.emit("update", {
573
980
  data: [
@@ -579,187 +986,23 @@ class StageDragResize extends EventEmitter {
579
986
  parentEl
580
987
  });
581
988
  }
582
- generateGhostEl(el) {
583
- if (this.ghostEl) {
584
- this.destroyGhostEl();
585
- }
586
- const ghostEl = el.cloneNode(true);
587
- this.setGhostElChildrenId(ghostEl);
588
- const { top, left } = getAbsolutePosition(el, getOffset(el));
589
- ghostEl.id = `${GHOST_EL_ID_PREFIX}${el.id}`;
590
- ghostEl.style.zIndex = ZIndex.GHOST_EL;
591
- ghostEl.style.opacity = ".5";
592
- ghostEl.style.position = "absolute";
593
- ghostEl.style.left = `${left}px`;
594
- ghostEl.style.top = `${top}px`;
595
- el.after(ghostEl);
596
- return ghostEl;
597
- }
598
- setGhostElChildrenId(el) {
599
- for (const child of Array.from(el.children)) {
600
- if (child.id) {
601
- child.id = `${GHOST_EL_ID_PREFIX}${child.id}`;
602
- }
603
- if (child.children.length) {
604
- this.setGhostElChildrenId(child);
605
- }
606
- }
607
- }
608
- destroyGhostEl() {
609
- this.ghostEl?.remove();
610
- this.ghostEl = void 0;
611
- }
612
- getOptions(options = {}) {
613
- if (!this.target)
614
- return {};
615
- const isAbsolute = this.mode === Mode.ABSOLUTE;
616
- const isFixed = this.mode === Mode.FIXED;
617
- const isSortable = this.mode === Mode.SORTABLE;
618
- let { moveableOptions = {} } = this.core.config;
619
- if (typeof moveableOptions === "function") {
620
- moveableOptions = moveableOptions(this.core);
621
- }
622
- const elementGuidelines = moveableOptions.elementGuidelines || this.target.parentElement?.children || [];
623
- this.setElementGuidelines(elementGuidelines);
624
- if (moveableOptions.elementGuidelines) {
625
- delete moveableOptions.elementGuidelines;
626
- }
627
- return {
628
- origin: false,
629
- rootContainer: this.core.container,
630
- zoom: 1,
631
- dragArea: false,
632
- draggable: true,
633
- resizable: true,
634
- scalable: false,
635
- rotatable: false,
636
- snappable: isAbsolute || isFixed,
637
- snapGap: isAbsolute || isFixed,
638
- snapThreshold: 5,
639
- snapDigit: 0,
640
- throttleDrag: 0,
641
- isDisplaySnapDigit: isAbsolute,
642
- snapDirections: {
643
- top: isAbsolute,
644
- right: isAbsolute,
645
- bottom: isAbsolute,
646
- left: isAbsolute,
647
- center: isAbsolute,
648
- middle: isAbsolute
649
- },
650
- elementSnapDirections: {
651
- top: isAbsolute,
652
- right: isAbsolute,
653
- bottom: isAbsolute,
654
- left: isAbsolute
655
- },
656
- isDisplayInnerSnapDigit: true,
657
- horizontalGuidelines: this.horizontalGuidelines,
658
- verticalGuidelines: this.verticalGuidelines,
659
- elementGuidelines: this.elementGuidelines,
660
- bounds: {
661
- top: 0,
662
- left: -1,
663
- right: this.container.clientWidth - 1,
664
- bottom: isSortable ? void 0 : this.container.clientHeight,
665
- ...moveableOptions.bounds || {}
666
- },
667
- ...options,
668
- ...moveableOptions
669
- };
670
- }
671
- canContainerHighlight() {
672
- return this.core.containerHighlightType === ContainerHighlightType.DEFAULT || this.core.containerHighlightType === ContainerHighlightType.ALT && this.isContainerHighlight;
673
- }
674
- }
675
-
676
- class TargetCalibrate extends EventEmitter {
677
- parent;
678
- mask;
679
- dr;
680
- core;
681
- operationEl;
682
- constructor(config) {
683
- super();
684
- this.parent = config.parent;
685
- this.mask = config.mask;
686
- this.dr = config.dr;
687
- this.core = config.core;
688
- this.operationEl = globalThis.document.createElement("div");
689
- this.parent.append(this.operationEl);
690
- }
691
- update(el, prefix) {
692
- const { left, top } = this.getOffset(el);
693
- const { transform } = getComputedStyle(el);
694
- this.operationEl.style.cssText = `
695
- position: absolute;
696
- transform: ${transform};
697
- left: ${left}px;
698
- top: ${top}px;
699
- width: ${el.clientWidth}px;
700
- height: ${el.clientHeight}px;
701
- z-index: ${ZIndex.HIGHLIGHT_EL};
702
- `;
703
- this.operationEl.id = `${prefix}${el.id}`;
704
- if (typeof this.core.config.updateDragEl === "function") {
705
- this.core.config.updateDragEl(this.operationEl, el);
706
- }
707
- return this.operationEl;
708
- }
709
- destroy() {
710
- this.operationEl?.remove();
711
- }
712
- getOffset(el) {
713
- const { offsetParent } = el;
714
- const left = el.offsetLeft;
715
- const top = el.offsetTop;
716
- if (offsetParent) {
717
- const parentOffset = this.getOffset(offsetParent);
718
- return {
719
- left: left + parentOffset.left,
720
- top: top + parentOffset.top
721
- };
722
- }
723
- if (this.dr.mode === Mode.FIXED) {
724
- if (getMode(el) === Mode.FIXED) {
725
- return {
726
- left,
727
- top
728
- };
729
- }
730
- return {
731
- left: left - this.mask.scrollLeft,
732
- top: top - this.mask.scrollTop
733
- };
734
- }
735
- if (getMode(el) === Mode.FIXED) {
736
- return {
737
- left: left + this.mask.scrollLeft,
738
- top: top + this.mask.scrollTop
739
- };
740
- }
741
- return {
742
- left,
743
- top
744
- };
745
- }
746
989
  }
747
990
 
748
- class StageHighlight extends EventEmitter {
749
- core;
991
+ class StageHighlight extends EventEmitter$1 {
750
992
  container;
751
993
  target;
752
994
  moveable;
753
- calibrationTarget;
995
+ targetShadow;
996
+ getRootContainer;
754
997
  constructor(config) {
755
998
  super();
756
- this.core = config.core;
757
999
  this.container = config.container;
758
- this.calibrationTarget = new TargetCalibrate({
759
- parent: this.core.mask.content,
760
- mask: this.core.mask,
761
- dr: this.core.dr,
762
- core: this.core
1000
+ this.getRootContainer = config.getRootContainer;
1001
+ this.targetShadow = new TargetShadow({
1002
+ container: config.container,
1003
+ updateDragEl: config.updateDragEl,
1004
+ zIndex: ZIndex.HIGHLIGHT_EL,
1005
+ idPrefix: HIGHLIGHT_EL_ID_PREFIX
763
1006
  });
764
1007
  }
765
1008
  highlight(el) {
@@ -768,14 +1011,14 @@ class StageHighlight extends EventEmitter {
768
1011
  this.target = el;
769
1012
  this.moveable?.destroy();
770
1013
  this.moveable = new Moveable(this.container, {
771
- target: this.calibrationTarget.update(el, HIGHLIGHT_EL_ID_PREFIX),
1014
+ target: this.targetShadow.update(el),
772
1015
  origin: false,
773
- rootContainer: this.core.container,
1016
+ rootContainer: this.getRootContainer(),
774
1017
  zoom: 2
775
1018
  });
776
1019
  }
777
1020
  clearHighlight() {
778
- if (!this.moveable)
1021
+ if (!this.moveable || !this.target)
779
1022
  return;
780
1023
  this.target = void 0;
781
1024
  this.moveable.target = null;
@@ -783,64 +1026,531 @@ class StageHighlight extends EventEmitter {
783
1026
  }
784
1027
  destroy() {
785
1028
  this.moveable?.destroy();
786
- this.calibrationTarget.destroy();
1029
+ this.targetShadow.destroy();
787
1030
  }
788
1031
  }
789
1032
 
790
- class Rule extends EventEmitter$1 {
791
- hGuides;
792
- vGuides;
793
- horizontalGuidelines = [];
794
- verticalGuidelines = [];
1033
+ class StageMultiDragResize extends MoveableOptionsManager {
795
1034
  container;
796
- containerResizeObserver;
797
- constructor(container) {
798
- super();
799
- this.container = container;
800
- this.hGuides = this.createGuides(GuidesType.HORIZONTAL, this.horizontalGuidelines);
801
- this.vGuides = this.createGuides(GuidesType.VERTICAL, this.verticalGuidelines);
802
- this.hGuides.on("changeGuides", this.hGuidesChangeGuidesHandler);
803
- this.vGuides.on("changeGuides", this.vGuidesChangeGuidesHandler);
804
- this.containerResizeObserver = new ResizeObserver(() => {
805
- this.vGuides.resize();
806
- this.hGuides.resize();
807
- });
808
- this.containerResizeObserver.observe(this.container);
809
- }
810
- showGuides(show = true) {
811
- this.hGuides.setState({
812
- showGuides: show
1035
+ targetList = [];
1036
+ moveableForMulti;
1037
+ dragStatus = StageDragStatus.END;
1038
+ dragResizeHelper;
1039
+ getRenderDocument;
1040
+ constructor(config) {
1041
+ const moveableOptionsManagerConfig = {
1042
+ container: config.container,
1043
+ moveableOptions: config.multiMoveableOptions,
1044
+ getRootContainer: config.getRootContainer
1045
+ };
1046
+ super(moveableOptionsManagerConfig);
1047
+ this.container = config.container;
1048
+ this.getRenderDocument = config.getRenderDocument;
1049
+ this.dragResizeHelper = new DragResizeHelper({
1050
+ container: config.container,
1051
+ updateDragEl: config.updateDragEl
813
1052
  });
814
- this.vGuides.setState({
815
- showGuides: show
1053
+ this.on("update-moveable", () => {
1054
+ if (this.moveableForMulti) {
1055
+ this.updateMoveable();
1056
+ }
816
1057
  });
817
1058
  }
818
- setGuides([hLines, vLines]) {
819
- this.horizontalGuidelines = hLines;
820
- this.verticalGuidelines = vLines;
821
- this.hGuides.setState({
822
- defaultGuides: hLines
823
- });
824
- this.vGuides.setState({
825
- defaultGuides: vLines
1059
+ multiSelect(els) {
1060
+ if (els.length === 0) {
1061
+ return;
1062
+ }
1063
+ this.mode = getMode(els[0]);
1064
+ this.targetList = els;
1065
+ this.dragResizeHelper.updateGroup(els);
1066
+ const elementGuidelines = Array.prototype.slice.call(this.targetList[0].parentElement?.children) || [];
1067
+ this.setElementGuidelines(this.targetList, elementGuidelines);
1068
+ this.moveableForMulti?.destroy();
1069
+ this.dragResizeHelper.clear();
1070
+ this.moveableForMulti = new Moveable(
1071
+ this.container,
1072
+ this.getOptions(true, {
1073
+ target: this.dragResizeHelper.getShadowEls()
1074
+ })
1075
+ );
1076
+ this.moveableForMulti.on("resizeGroupStart", (e) => {
1077
+ this.dragResizeHelper.onResizeGroupStart(e);
1078
+ this.dragStatus = StageDragStatus.START;
1079
+ }).on("resizeGroup", (e) => {
1080
+ this.dragResizeHelper.onResizeGroup(e);
1081
+ this.dragStatus = StageDragStatus.ING;
1082
+ }).on("resizeGroupEnd", () => {
1083
+ this.update(true);
1084
+ this.dragStatus = StageDragStatus.END;
1085
+ }).on("dragGroupStart", (e) => {
1086
+ this.dragResizeHelper.onDragGroupStart(e);
1087
+ this.dragStatus = StageDragStatus.START;
1088
+ }).on("dragGroup", (e) => {
1089
+ this.dragResizeHelper.onDragGroup(e);
1090
+ this.dragStatus = StageDragStatus.ING;
1091
+ }).on("dragGroupEnd", () => {
1092
+ this.update();
1093
+ this.dragStatus = StageDragStatus.END;
1094
+ }).on("clickGroup", (e) => {
1095
+ const { inputTarget, targets } = e;
1096
+ if (targets.length > 1 && targets.includes(inputTarget)) {
1097
+ this.emit("change-to-select", inputTarget.id.replace(DRAG_EL_ID_PREFIX, ""));
1098
+ }
826
1099
  });
827
- this.emit("changeGuides", {
828
- type: GuidesType.HORIZONTAL,
829
- guides: hLines
1100
+ }
1101
+ canSelect(el, selectedEl) {
1102
+ const currentTargetMode = getMode(el);
1103
+ let selectedElMode = "";
1104
+ if (currentTargetMode === Mode.SORTABLE) {
1105
+ return false;
1106
+ }
1107
+ if (this.targetList.length === 0 && selectedEl) {
1108
+ selectedElMode = getMode(selectedEl);
1109
+ } else if (this.targetList.length > 0) {
1110
+ selectedElMode = getMode(this.targetList[0]);
1111
+ }
1112
+ if (currentTargetMode !== selectedElMode) {
1113
+ return false;
1114
+ }
1115
+ return true;
1116
+ }
1117
+ updateMoveable(eleList = this.targetList) {
1118
+ if (!this.moveableForMulti)
1119
+ return;
1120
+ if (!eleList)
1121
+ throw new Error("\u672A\u9009\u4E2D\u4EFB\u4F55\u8282\u70B9");
1122
+ this.targetList = eleList;
1123
+ this.dragResizeHelper.setTargetList(eleList);
1124
+ const options = this.getOptions(true, {
1125
+ target: this.dragResizeHelper.getShadowEls()
830
1126
  });
831
- this.emit("changeGuides", {
832
- type: GuidesType.VERTICAL,
833
- guides: vLines
1127
+ Object.entries(options).forEach(([key, value]) => {
1128
+ this.moveableForMulti[key] = value;
834
1129
  });
1130
+ this.moveableForMulti.updateTarget();
835
1131
  }
836
- clearGuides() {
837
- this.setGuides([[], []]);
1132
+ clearSelectStatus() {
1133
+ if (!this.moveableForMulti)
1134
+ return;
1135
+ this.dragResizeHelper.clearMultiSelectStatus();
1136
+ this.moveableForMulti.target = null;
1137
+ this.moveableForMulti.updateTarget();
1138
+ this.targetList = [];
838
1139
  }
839
- showRule(show = true) {
840
- if (show) {
841
- this.hGuides.destroy();
842
- this.hGuides = this.createGuides(GuidesType.HORIZONTAL, this.horizontalGuidelines);
843
- this.vGuides.destroy();
1140
+ destroy() {
1141
+ this.moveableForMulti?.destroy();
1142
+ this.dragResizeHelper.destroy();
1143
+ }
1144
+ update(isResize = false) {
1145
+ if (this.targetList.length === 0)
1146
+ return;
1147
+ const doc = this.getRenderDocument();
1148
+ if (!doc)
1149
+ return;
1150
+ const data = this.targetList.map((targetItem) => {
1151
+ const left = calcValueByFontsize(doc, targetItem.offsetLeft);
1152
+ const top = calcValueByFontsize(doc, targetItem.offsetTop);
1153
+ const width = calcValueByFontsize(doc, targetItem.clientWidth);
1154
+ const height = calcValueByFontsize(doc, targetItem.clientHeight);
1155
+ return {
1156
+ el: targetItem,
1157
+ style: isResize ? { left, top, width, height } : { left, top }
1158
+ };
1159
+ });
1160
+ this.emit("update", data, null);
1161
+ }
1162
+ }
1163
+
1164
+ const throttleTime = 100;
1165
+ const defaultContainerHighlightDuration = 800;
1166
+ class ActionManager extends EventEmitter {
1167
+ dr;
1168
+ multiDr;
1169
+ highlightLayer;
1170
+ container;
1171
+ selectedEl;
1172
+ selectedElList = [];
1173
+ highlightedEl;
1174
+ isMultiSelectStatus = false;
1175
+ containerHighlightClassName;
1176
+ containerHighlightDuration;
1177
+ containerHighlightType;
1178
+ isAltKeydown = false;
1179
+ getTargetElement;
1180
+ getElementsFromPoint;
1181
+ canSelect;
1182
+ isContainer;
1183
+ getRenderDocument;
1184
+ mouseMoveHandler = throttle(async (event) => {
1185
+ const el = await this.getElementFromPoint(event);
1186
+ if (!el) {
1187
+ this.clearHighlight();
1188
+ return;
1189
+ }
1190
+ this.highlight(el);
1191
+ }, throttleTime);
1192
+ constructor(config) {
1193
+ super();
1194
+ this.container = config.container;
1195
+ this.containerHighlightClassName = config.containerHighlightClassName || CONTAINER_HIGHLIGHT_CLASS_NAME;
1196
+ this.containerHighlightDuration = config.containerHighlightDuration || defaultContainerHighlightDuration;
1197
+ this.containerHighlightType = config.containerHighlightType;
1198
+ this.getTargetElement = config.getTargetElement;
1199
+ this.getElementsFromPoint = config.getElementsFromPoint;
1200
+ this.canSelect = config.canSelect || ((el) => !!el.id);
1201
+ this.getRenderDocument = config.getRenderDocument;
1202
+ this.isContainer = config.isContainer;
1203
+ this.dr = new StageDragResize({
1204
+ container: config.container,
1205
+ getRootContainer: config.getRootContainer,
1206
+ getRenderDocument: config.getRenderDocument,
1207
+ updateDragEl: config.updateDragEl,
1208
+ markContainerEnd: () => this.markContainerEnd(),
1209
+ delayedMarkContainer: (event, exclude) => {
1210
+ if (this.canAddToContainer()) {
1211
+ return this.delayedMarkContainer(event, exclude);
1212
+ }
1213
+ return void 0;
1214
+ },
1215
+ moveableOptions: this.changeCallback(config.moveableOptions)
1216
+ });
1217
+ this.multiDr = new StageMultiDragResize({
1218
+ container: config.container,
1219
+ multiMoveableOptions: config.multiMoveableOptions,
1220
+ getRootContainer: config.getRootContainer,
1221
+ getRenderDocument: config.getRenderDocument,
1222
+ updateDragEl: config.updateDragEl
1223
+ });
1224
+ this.highlightLayer = new StageHighlight({
1225
+ container: config.container,
1226
+ updateDragEl: config.updateDragEl,
1227
+ getRootContainer: config.getRootContainer
1228
+ });
1229
+ this.initMouseEvent();
1230
+ this.initKeyEvent();
1231
+ this.initActionEvent();
1232
+ }
1233
+ setGuidelines(type, guidelines) {
1234
+ this.dr.setGuidelines(type, guidelines);
1235
+ this.multiDr.setGuidelines(type, guidelines);
1236
+ }
1237
+ clearGuides() {
1238
+ this.dr.clearGuides();
1239
+ this.multiDr.clearGuides();
1240
+ }
1241
+ updateMoveable(el) {
1242
+ this.dr.updateMoveable(el);
1243
+ this.multiDr.updateMoveable();
1244
+ }
1245
+ isSelectedEl(el) {
1246
+ return el.id === this.selectedEl?.id;
1247
+ }
1248
+ setSelectedEl(el) {
1249
+ this.selectedEl = el;
1250
+ }
1251
+ getSelectedEl() {
1252
+ return this.selectedEl;
1253
+ }
1254
+ getSelectedElList() {
1255
+ return this.selectedElList;
1256
+ }
1257
+ async getElementFromPoint(event) {
1258
+ const els = this.getElementsFromPoint(event);
1259
+ let stopped = false;
1260
+ const stop = () => stopped = true;
1261
+ for (const el of els) {
1262
+ if (!el.id.startsWith(GHOST_EL_ID_PREFIX) && await this.isElCanSelect(el, event, stop)) {
1263
+ if (stopped)
1264
+ break;
1265
+ return el;
1266
+ }
1267
+ }
1268
+ }
1269
+ async isElCanSelect(el, event, stop) {
1270
+ const canSelectByProp = await this.canSelect(el, event, stop);
1271
+ if (!canSelectByProp)
1272
+ return false;
1273
+ if (this.isMultiSelectStatus) {
1274
+ return this.canMultiSelect(el, stop);
1275
+ }
1276
+ return true;
1277
+ }
1278
+ canMultiSelect(el, stop) {
1279
+ if (el.className.includes(PAGE_CLASS)) {
1280
+ stop();
1281
+ return false;
1282
+ }
1283
+ const selectedEl = this.getSelectedEl();
1284
+ if (selectedEl?.className.includes(PAGE_CLASS)) {
1285
+ return true;
1286
+ }
1287
+ return this.multiDr.canSelect(el, selectedEl);
1288
+ }
1289
+ select(el, event) {
1290
+ this.selectedEl = el;
1291
+ this.clearSelectStatus(SelectStatus.MULTI_SELECT);
1292
+ this.dr.select(el, event);
1293
+ }
1294
+ multiSelect(idOrElList) {
1295
+ this.selectedElList = idOrElList.map((idOrEl) => this.getTargetElement(idOrEl));
1296
+ this.clearSelectStatus(SelectStatus.SELECT);
1297
+ this.multiDr.multiSelect(this.selectedElList);
1298
+ }
1299
+ getHighlightEl() {
1300
+ return this.highlightedEl;
1301
+ }
1302
+ setHighlightEl(el) {
1303
+ this.highlightedEl = el;
1304
+ }
1305
+ highlight(idOrEl) {
1306
+ let el;
1307
+ try {
1308
+ el = this.getTargetElement(idOrEl);
1309
+ } catch (error) {
1310
+ this.clearHighlight();
1311
+ return;
1312
+ }
1313
+ if (el === this.getSelectedEl() || this.multiDr.dragStatus === StageDragStatus.ING) {
1314
+ this.clearHighlight();
1315
+ return;
1316
+ }
1317
+ if (el === this.highlightedEl || !el)
1318
+ return;
1319
+ this.highlightLayer.highlight(el);
1320
+ this.highlightedEl = el;
1321
+ this.emit("highlight", el);
1322
+ }
1323
+ clearHighlight() {
1324
+ this.setHighlightEl(void 0);
1325
+ this.highlightLayer.clearHighlight();
1326
+ }
1327
+ clearSelectStatus(selectType) {
1328
+ if (selectType === SelectStatus.MULTI_SELECT) {
1329
+ this.multiDr.clearSelectStatus();
1330
+ this.selectedElList = [];
1331
+ } else {
1332
+ this.dr.clearSelectStatus();
1333
+ }
1334
+ }
1335
+ async addContainerHighlightClassName(event, excludeElList) {
1336
+ const doc = this.getRenderDocument();
1337
+ if (!doc)
1338
+ return;
1339
+ const els = this.getElementsFromPoint(event);
1340
+ for (const el of els) {
1341
+ if (!el.id.startsWith(GHOST_EL_ID_PREFIX) && await this.isContainer(el) && !excludeElList.includes(el)) {
1342
+ addClassName(el, doc, this.containerHighlightClassName);
1343
+ break;
1344
+ }
1345
+ }
1346
+ }
1347
+ delayedMarkContainer(event, excludeElList = []) {
1348
+ return globalThis.setTimeout(() => {
1349
+ this.addContainerHighlightClassName(event, excludeElList);
1350
+ }, this.containerHighlightDuration);
1351
+ }
1352
+ destroy() {
1353
+ this.container.removeEventListener("mousedown", this.mouseDownHandler);
1354
+ this.container.removeEventListener("mousemove", this.mouseMoveHandler);
1355
+ this.container.removeEventListener("mouseleave", this.mouseLeaveHandler);
1356
+ this.container.removeEventListener("wheel", this.mouseWheelHandler);
1357
+ this.dr.destroy();
1358
+ this.multiDr.destroy();
1359
+ this.highlightLayer.destroy();
1360
+ }
1361
+ changeCallback(options) {
1362
+ if (typeof options === "function") {
1363
+ return () => {
1364
+ if (typeof options === "function") {
1365
+ const cfg = {
1366
+ targetElId: this.selectedEl?.id
1367
+ };
1368
+ return options(cfg);
1369
+ }
1370
+ return options;
1371
+ };
1372
+ }
1373
+ return options;
1374
+ }
1375
+ async beforeMultiSelect(event) {
1376
+ const el = await this.getElementFromPoint(event);
1377
+ if (!el)
1378
+ return;
1379
+ if (this.selectedEl && !this.selectedEl.className.includes(PAGE_CLASS)) {
1380
+ this.selectedElList.push(this.selectedEl);
1381
+ this.selectedEl = void 0;
1382
+ }
1383
+ const existIndex = this.selectedElList.findIndex((selectedDom) => selectedDom.id === el.id);
1384
+ if (existIndex !== -1) {
1385
+ this.selectedElList.splice(existIndex, 1);
1386
+ } else {
1387
+ this.selectedElList.push(el);
1388
+ }
1389
+ }
1390
+ canAddToContainer() {
1391
+ return this.containerHighlightType === ContainerHighlightType.DEFAULT || this.containerHighlightType === ContainerHighlightType.ALT && this.isAltKeydown;
1392
+ }
1393
+ markContainerEnd() {
1394
+ const doc = this.getRenderDocument();
1395
+ if (doc && this.canAddToContainer()) {
1396
+ return removeClassNameByClassName(doc, this.containerHighlightClassName);
1397
+ }
1398
+ return null;
1399
+ }
1400
+ initMouseEvent() {
1401
+ this.container.addEventListener("mousedown", this.mouseDownHandler);
1402
+ this.container.addEventListener("mousemove", this.mouseMoveHandler);
1403
+ this.container.addEventListener("mouseleave", this.mouseLeaveHandler);
1404
+ this.container.addEventListener("wheel", this.mouseWheelHandler);
1405
+ }
1406
+ initKeyEvent() {
1407
+ const { isMac } = new Env();
1408
+ const ctrl = isMac ? "meta" : "ctrl";
1409
+ KeyController.global.keydown(ctrl, (e) => {
1410
+ e.inputEvent.preventDefault();
1411
+ this.isMultiSelectStatus = true;
1412
+ });
1413
+ KeyController.global.on("blur", () => {
1414
+ this.isMultiSelectStatus = false;
1415
+ });
1416
+ KeyController.global.keyup(ctrl, (e) => {
1417
+ e.inputEvent.preventDefault();
1418
+ this.isMultiSelectStatus = false;
1419
+ });
1420
+ KeyController.global.keydown("alt", (e) => {
1421
+ e.inputEvent.preventDefault();
1422
+ this.isAltKeydown = true;
1423
+ });
1424
+ KeyController.global.keyup("alt", (e) => {
1425
+ e.inputEvent.preventDefault();
1426
+ this.markContainerEnd();
1427
+ this.isAltKeydown = false;
1428
+ });
1429
+ }
1430
+ initActionEvent() {
1431
+ this.dr.on("update", (data) => {
1432
+ setTimeout(() => this.emit("update", data));
1433
+ }).on("sort", (data) => {
1434
+ setTimeout(() => this.emit("sort", data));
1435
+ }).on("select-parent", () => {
1436
+ this.emit("select-parent");
1437
+ });
1438
+ this.multiDr.on("update", (data, parentEl) => {
1439
+ this.emit("multi-update", data, parentEl);
1440
+ }).on("change-to-select", async (id) => {
1441
+ if (this.isMultiSelectStatus)
1442
+ return false;
1443
+ const el = this.getTargetElement(id);
1444
+ this.emit("change-to-select", el);
1445
+ });
1446
+ }
1447
+ mouseDownHandler = async (event) => {
1448
+ this.clearHighlight();
1449
+ event.stopImmediatePropagation();
1450
+ event.stopPropagation();
1451
+ if (this.isStopTriggerSelect(event))
1452
+ return;
1453
+ this.container.removeEventListener("mousemove", this.mouseMoveHandler);
1454
+ if (this.isMultiSelectStatus) {
1455
+ await this.beforeMultiSelect(event);
1456
+ if (this.selectedElList.length > 0) {
1457
+ this.emit("before-multi-select", this.selectedElList);
1458
+ }
1459
+ } else {
1460
+ const el = await this.getElementFromPoint(event);
1461
+ if (!el)
1462
+ return;
1463
+ this.emit("before-select", el, event);
1464
+ }
1465
+ getDocument().addEventListener("mouseup", this.mouseUpHandler);
1466
+ };
1467
+ isStopTriggerSelect(event) {
1468
+ if (event.button !== MouseButton.LEFT && event.button !== MouseButton.RIGHT)
1469
+ return true;
1470
+ if (!event.target)
1471
+ return true;
1472
+ const targetClassList = event.target.classList;
1473
+ if (!this.isMultiSelectStatus && targetClassList.contains("moveable-area")) {
1474
+ return true;
1475
+ }
1476
+ if (targetClassList.contains("moveable-control") || isMoveableButton(event.target)) {
1477
+ return true;
1478
+ }
1479
+ return false;
1480
+ }
1481
+ mouseUpHandler = () => {
1482
+ getDocument().removeEventListener("mouseup", this.mouseUpHandler);
1483
+ this.container.addEventListener("mousemove", this.mouseMoveHandler);
1484
+ if (this.isMultiSelectStatus) {
1485
+ this.emit("multi-select", this.selectedElList);
1486
+ } else {
1487
+ this.emit("select", this.selectedEl);
1488
+ }
1489
+ };
1490
+ mouseLeaveHandler = () => {
1491
+ setTimeout(() => this.clearHighlight(), throttleTime);
1492
+ };
1493
+ mouseWheelHandler = () => {
1494
+ this.clearHighlight();
1495
+ };
1496
+ }
1497
+
1498
+ class Rule extends EventEmitter {
1499
+ hGuides;
1500
+ vGuides;
1501
+ horizontalGuidelines = [];
1502
+ verticalGuidelines = [];
1503
+ container;
1504
+ containerResizeObserver;
1505
+ isShowGuides = true;
1506
+ constructor(container) {
1507
+ super();
1508
+ this.container = container;
1509
+ this.hGuides = this.createGuides(GuidesType.HORIZONTAL, this.horizontalGuidelines);
1510
+ this.vGuides = this.createGuides(GuidesType.VERTICAL, this.verticalGuidelines);
1511
+ this.hGuides.on("changeGuides", this.hGuidesChangeGuidesHandler);
1512
+ this.vGuides.on("changeGuides", this.vGuidesChangeGuidesHandler);
1513
+ this.containerResizeObserver = new ResizeObserver(() => {
1514
+ this.vGuides.resize();
1515
+ this.hGuides.resize();
1516
+ });
1517
+ this.containerResizeObserver.observe(this.container);
1518
+ }
1519
+ showGuides(isShowGuides = true) {
1520
+ this.isShowGuides = isShowGuides;
1521
+ this.hGuides.setState({
1522
+ showGuides: isShowGuides
1523
+ });
1524
+ this.vGuides.setState({
1525
+ showGuides: isShowGuides
1526
+ });
1527
+ }
1528
+ setGuides([hLines, vLines]) {
1529
+ this.horizontalGuidelines = hLines;
1530
+ this.verticalGuidelines = vLines;
1531
+ this.hGuides.setState({
1532
+ defaultGuides: hLines
1533
+ });
1534
+ this.vGuides.setState({
1535
+ defaultGuides: vLines
1536
+ });
1537
+ this.emit("change-guides", {
1538
+ type: GuidesType.HORIZONTAL,
1539
+ guides: hLines
1540
+ });
1541
+ this.emit("change-guides", {
1542
+ type: GuidesType.VERTICAL,
1543
+ guides: vLines
1544
+ });
1545
+ }
1546
+ clearGuides() {
1547
+ this.setGuides([[], []]);
1548
+ }
1549
+ showRule(show = true) {
1550
+ if (show) {
1551
+ this.hGuides.destroy();
1552
+ this.hGuides = this.createGuides(GuidesType.HORIZONTAL, this.horizontalGuidelines);
1553
+ this.vGuides.destroy();
844
1554
  this.vGuides = this.createGuides(GuidesType.VERTICAL, this.verticalGuidelines);
845
1555
  } else {
846
1556
  this.hGuides.setState({
@@ -882,18 +1592,19 @@ class Rule extends EventEmitter$1 {
882
1592
  backgroundColor: "#fff",
883
1593
  lineColor: "#000",
884
1594
  textColor: "#000",
885
- style: this.getGuidesStyle(type)
1595
+ style: this.getGuidesStyle(type),
1596
+ showGuides: this.isShowGuides
886
1597
  });
887
1598
  hGuidesChangeGuidesHandler = (e) => {
888
1599
  this.horizontalGuidelines = e.guides;
889
- this.emit("changeGuides", {
1600
+ this.emit("change-guides", {
890
1601
  type: GuidesType.HORIZONTAL,
891
1602
  guides: this.horizontalGuidelines
892
1603
  });
893
1604
  };
894
1605
  vGuidesChangeGuidesHandler = (e) => {
895
1606
  this.verticalGuidelines = e.guides;
896
- this.emit("changeGuides", {
1607
+ this.emit("change-guides", {
897
1608
  type: GuidesType.VERTICAL,
898
1609
  guides: this.verticalGuidelines
899
1610
  });
@@ -901,9 +1612,8 @@ class Rule extends EventEmitter$1 {
901
1612
  }
902
1613
 
903
1614
  const wrapperClassName = "editor-mask-wrapper";
904
- const throttleTime = 100;
905
1615
  const hideScrollbar = () => {
906
- injectStyle(globalThis.document, `.${wrapperClassName}::-webkit-scrollbar { width: 0 !important; display: none }`);
1616
+ injectStyle(getDocument(), `.${wrapperClassName}::-webkit-scrollbar { width: 0 !important; display: none }`);
907
1617
  };
908
1618
  const createContent = () => createDiv({
909
1619
  className: "editor-mask",
@@ -933,9 +1643,7 @@ const createWrapper = () => {
933
1643
  class StageMask extends Rule {
934
1644
  content = createContent();
935
1645
  wrapper;
936
- core;
937
1646
  page = null;
938
- pageScrollParent = null;
939
1647
  scrollTop = 0;
940
1648
  scrollLeft = 0;
941
1649
  width = 0;
@@ -944,41 +1652,21 @@ class StageMask extends Rule {
944
1652
  wrapperWidth = 0;
945
1653
  maxScrollTop = 0;
946
1654
  maxScrollLeft = 0;
947
- intersectionObserver = null;
948
- isMultiSelectStatus = false;
949
1655
  mode = Mode.ABSOLUTE;
950
- pageResizeObserver = null;
1656
+ pageScrollParent = null;
1657
+ intersectionObserver = null;
951
1658
  wrapperResizeObserver = null;
952
- highlightHandler = throttle((event) => {
953
- this.emit("highlight", event);
954
- }, throttleTime);
955
- constructor(config) {
1659
+ constructor() {
956
1660
  const wrapper = createWrapper();
957
1661
  super(wrapper);
958
1662
  this.wrapper = wrapper;
959
- this.core = config.core;
960
- this.content.addEventListener("mousedown", this.mouseDownHandler);
961
- this.wrapper.appendChild(this.content);
962
1663
  this.content.addEventListener("wheel", this.mouseWheelHandler);
963
- this.content.addEventListener("mousemove", this.highlightHandler);
964
- this.content.addEventListener("mouseleave", this.mouseLeaveHandler);
965
- const isMac = /mac os x/.test(navigator.userAgent.toLowerCase());
966
- const ctrl = isMac ? "meta" : "ctrl";
967
- KeyController.global.keydown(ctrl, (e) => {
968
- e.inputEvent.preventDefault();
969
- this.isMultiSelectStatus = true;
970
- });
971
- KeyController.global.on("blur", () => {
972
- this.isMultiSelectStatus = false;
973
- });
974
- KeyController.global.keyup(ctrl, (e) => {
975
- e.inputEvent.preventDefault();
976
- this.isMultiSelectStatus = false;
977
- });
1664
+ this.wrapper.appendChild(this.content);
978
1665
  }
979
1666
  setMode(mode) {
980
1667
  this.mode = mode;
981
1668
  this.scroll();
1669
+ this.content.dataset.mode = mode;
982
1670
  if (mode === Mode.FIXED) {
983
1671
  this.content.style.width = `${this.wrapperWidth}px`;
984
1672
  this.content.style.height = `${this.wrapperHeight}px`;
@@ -991,9 +1679,44 @@ class StageMask extends Rule {
991
1679
  if (!page)
992
1680
  return;
993
1681
  this.page = page;
994
- this.pageScrollParent = getScrollParent(page) || this.core.renderer.contentWindow?.document.documentElement || null;
995
- this.pageResizeObserver?.disconnect();
1682
+ this.initObserverIntersection();
1683
+ this.initObserverWrapper();
1684
+ }
1685
+ pageResize(entries) {
1686
+ const [entry] = entries;
1687
+ const { clientHeight, clientWidth } = entry.target;
1688
+ this.setHeight(clientHeight);
1689
+ this.setWidth(clientWidth);
1690
+ this.scroll();
1691
+ }
1692
+ observerIntersection(el) {
1693
+ this.intersectionObserver?.observe(el);
1694
+ }
1695
+ mount(el) {
1696
+ if (!this.content)
1697
+ throw new Error("content \u4E0D\u5B58\u5728");
1698
+ el.appendChild(this.wrapper);
1699
+ }
1700
+ setLayout(el) {
1701
+ this.setMode(isFixedParent(el) ? Mode.FIXED : Mode.ABSOLUTE);
1702
+ }
1703
+ scrollIntoView(el) {
1704
+ el.scrollIntoView();
1705
+ if (!this.pageScrollParent)
1706
+ return;
1707
+ this.scrollLeft = this.pageScrollParent.scrollLeft;
1708
+ this.scrollTop = this.pageScrollParent.scrollTop;
1709
+ this.scroll();
1710
+ }
1711
+ destroy() {
1712
+ this.content?.remove();
1713
+ this.page = null;
1714
+ this.pageScrollParent = null;
996
1715
  this.wrapperResizeObserver?.disconnect();
1716
+ super.destroy();
1717
+ }
1718
+ initObserverIntersection() {
1719
+ this.pageScrollParent = getScrollParent(this.page) || null;
997
1720
  this.intersectionObserver?.disconnect();
998
1721
  if (typeof IntersectionObserver !== "undefined") {
999
1722
  this.intersectionObserver = new IntersectionObserver(
@@ -1013,18 +1736,10 @@ class StageMask extends Rule {
1013
1736
  }
1014
1737
  );
1015
1738
  }
1739
+ }
1740
+ initObserverWrapper() {
1741
+ this.wrapperResizeObserver?.disconnect();
1016
1742
  if (typeof ResizeObserver !== "undefined") {
1017
- this.pageResizeObserver = new ResizeObserver((entries) => {
1018
- const [entry] = entries;
1019
- const { clientHeight, clientWidth } = entry.target;
1020
- this.setHeight(clientHeight);
1021
- this.setWidth(clientWidth);
1022
- this.scroll();
1023
- if (this.core.dr.moveable) {
1024
- this.core.dr.updateMoveable();
1025
- }
1026
- });
1027
- this.pageResizeObserver.observe(page);
1028
1743
  this.wrapperResizeObserver = new ResizeObserver((entries) => {
1029
1744
  const [entry] = entries;
1030
1745
  const { clientHeight, clientWidth } = entry.target;
@@ -1036,354 +1751,91 @@ class StageMask extends Rule {
1036
1751
  this.wrapperResizeObserver.observe(this.wrapper);
1037
1752
  }
1038
1753
  }
1039
- mount(el) {
1040
- if (!this.content)
1041
- throw new Error("content \u4E0D\u5B58\u5728");
1042
- el.appendChild(this.wrapper);
1043
- }
1044
- setLayout(el) {
1045
- this.setMode(isFixedParent(el) ? Mode.FIXED : Mode.ABSOLUTE);
1046
- }
1047
- scrollIntoView(el) {
1048
- el.scrollIntoView();
1049
- if (!this.pageScrollParent)
1050
- return;
1051
- this.scrollLeft = this.pageScrollParent.scrollLeft;
1052
- this.scrollTop = this.pageScrollParent.scrollTop;
1053
- this.scroll();
1054
- }
1055
- destroy() {
1056
- this.content?.remove();
1057
- this.page = null;
1058
- this.pageScrollParent = null;
1059
- this.pageResizeObserver?.disconnect();
1060
- this.wrapperResizeObserver?.disconnect();
1061
- this.content.removeEventListener("mouseleave", this.mouseLeaveHandler);
1062
- super.destroy();
1063
- }
1064
1754
  scroll() {
1065
1755
  this.fixScrollValue();
1066
1756
  let { scrollLeft, scrollTop } = this;
1067
1757
  if (this.pageScrollParent) {
1068
1758
  this.pageScrollParent.scrollTo({
1069
1759
  top: scrollTop,
1070
- left: scrollLeft
1071
- });
1072
- }
1073
- if (this.mode === Mode.FIXED) {
1074
- scrollLeft = 0;
1075
- scrollTop = 0;
1076
- }
1077
- this.scrollRule(scrollTop);
1078
- this.scrollTo(scrollLeft, scrollTop);
1079
- }
1080
- scrollTo(scrollLeft, scrollTop) {
1081
- this.content.style.transform = `translate3d(${-scrollLeft}px, ${-scrollTop}px, 0)`;
1082
- }
1083
- setHeight(height) {
1084
- this.height = height;
1085
- this.setMaxScrollTop();
1086
- this.content.style.height = `${height}px`;
1087
- }
1088
- setWidth(width) {
1089
- this.width = width;
1090
- this.setMaxScrollLeft();
1091
- this.content.style.width = `${width}px`;
1092
- }
1093
- setMaxScrollLeft() {
1094
- this.maxScrollLeft = Math.max(this.width - this.wrapperWidth, 0);
1095
- }
1096
- setMaxScrollTop() {
1097
- this.maxScrollTop = Math.max(this.height - this.wrapperHeight, 0);
1098
- }
1099
- fixScrollValue() {
1100
- if (this.scrollTop < 0)
1101
- this.scrollTop = 0;
1102
- if (this.scrollLeft < 0)
1103
- this.scrollLeft = 0;
1104
- if (this.maxScrollTop < this.scrollTop)
1105
- this.scrollTop = this.maxScrollTop;
1106
- if (this.maxScrollLeft < this.scrollLeft)
1107
- this.scrollLeft = this.maxScrollLeft;
1108
- }
1109
- mouseDownHandler = (event) => {
1110
- this.emit("clearHighlight");
1111
- event.stopImmediatePropagation();
1112
- event.stopPropagation();
1113
- if (event.button !== MouseButton.LEFT && event.button !== MouseButton.RIGHT)
1114
- return;
1115
- if (!this.isMultiSelectStatus && event.target.className.indexOf("moveable-area") !== -1) {
1116
- return;
1117
- }
1118
- if (event.target.className.indexOf("moveable-control") !== -1) {
1119
- return;
1120
- }
1121
- this.content.removeEventListener("mousemove", this.highlightHandler);
1122
- if (this.isMultiSelectStatus) {
1123
- this.emit("beforeMultiSelect", event);
1124
- } else {
1125
- this.emit("beforeSelect", event);
1126
- }
1127
- globalThis.document.addEventListener("mouseup", this.mouseUpHandler);
1128
- };
1129
- mouseUpHandler = () => {
1130
- globalThis.document.removeEventListener("mouseup", this.mouseUpHandler);
1131
- this.content.addEventListener("mousemove", this.highlightHandler);
1132
- if (!this.isMultiSelectStatus) {
1133
- this.emit("select");
1134
- }
1135
- };
1136
- mouseWheelHandler = (event) => {
1137
- this.emit("clearHighlight");
1138
- if (!this.page)
1139
- throw new Error("page \u672A\u521D\u59CB\u5316");
1140
- const { deltaY, deltaX } = event;
1141
- if (this.page.clientHeight < this.wrapperHeight && deltaY)
1142
- return;
1143
- if (this.page.clientWidth < this.wrapperWidth && deltaX)
1144
- return;
1145
- if (this.maxScrollTop > 0) {
1146
- this.scrollTop = this.scrollTop + deltaY;
1147
- }
1148
- if (this.maxScrollLeft > 0) {
1149
- this.scrollLeft = this.scrollLeft + deltaX;
1150
- }
1151
- this.scroll();
1152
- this.emit("scroll", event);
1153
- };
1154
- mouseLeaveHandler = () => {
1155
- setTimeout(() => this.emit("clearHighlight"), throttleTime);
1156
- };
1157
- }
1158
-
1159
- class StageMultiDragResize extends EventEmitter {
1160
- core;
1161
- mask;
1162
- container;
1163
- targetList = [];
1164
- dragElList = [];
1165
- moveableForMulti;
1166
- dragStatus = StageDragStatus.END;
1167
- multiMoveableHelper;
1168
- constructor(config) {
1169
- super();
1170
- this.core = config.core;
1171
- this.container = config.container;
1172
- this.mask = config.mask;
1173
- }
1174
- multiSelect(els) {
1175
- this.targetList = els;
1176
- this.core.dr.destroyDragEl();
1177
- this.destroyDragElList();
1178
- this.dragElList = els.map((elItem) => {
1179
- const dragElDiv = globalThis.document.createElement("div");
1180
- this.container.append(dragElDiv);
1181
- dragElDiv.style.cssText = getTargetElStyle(elItem);
1182
- dragElDiv.id = `${DRAG_EL_ID_PREFIX}${elItem.id}`;
1183
- if (typeof this.core.config.updateDragEl === "function") {
1184
- this.core.config.updateDragEl(dragElDiv, elItem);
1185
- }
1186
- return dragElDiv;
1187
- });
1188
- this.moveableForMulti?.destroy();
1189
- this.multiMoveableHelper?.clear();
1190
- this.moveableForMulti = new Moveable(
1191
- this.container,
1192
- this.getOptions({
1193
- target: this.dragElList
1194
- })
1195
- );
1196
- this.multiMoveableHelper = MoveableHelper.create({
1197
- useBeforeRender: true,
1198
- useRender: false,
1199
- createAuto: true
1200
- });
1201
- const frames = [];
1202
- const setFrames = (events) => {
1203
- events.forEach((ev) => {
1204
- const matchEventTarget = this.targetList.find(
1205
- (targetItem) => targetItem.id === ev.target.id.replace(DRAG_EL_ID_PREFIX, "")
1206
- );
1207
- if (!matchEventTarget)
1208
- return;
1209
- frames.push({
1210
- left: matchEventTarget.offsetLeft,
1211
- top: matchEventTarget.offsetTop,
1212
- id: matchEventTarget.id
1213
- });
1214
- });
1215
- };
1216
- this.moveableForMulti.on("resizeGroupStart", (params) => {
1217
- const { events } = params;
1218
- this.multiMoveableHelper?.onResizeGroupStart(params);
1219
- setFrames(events);
1220
- this.dragStatus = StageDragStatus.START;
1221
- }).on("resizeGroup", (params) => {
1222
- const { events } = params;
1223
- events.forEach((ev) => {
1224
- const { width, height, beforeTranslate } = ev.drag;
1225
- const frameSnapShot = frames.find(
1226
- (frameItem) => frameItem.id === ev.target.id.replace(DRAG_EL_ID_PREFIX, "")
1227
- );
1228
- if (!frameSnapShot)
1229
- return;
1230
- const targeEl = this.targetList.find(
1231
- (targetItem) => targetItem.id === ev.target.id.replace(DRAG_EL_ID_PREFIX, "")
1232
- );
1233
- if (!targeEl)
1234
- return;
1235
- const isParentIncluded = this.targetList.find((targetItem) => targetItem.id === targeEl.parentElement?.id);
1236
- if (!isParentIncluded) {
1237
- targeEl.style.left = `${frameSnapShot.left + beforeTranslate[0]}px`;
1238
- targeEl.style.top = `${frameSnapShot.top + beforeTranslate[1]}px`;
1239
- }
1240
- targeEl.style.width = `${width}px`;
1241
- targeEl.style.height = `${height}px`;
1242
- });
1243
- this.multiMoveableHelper?.onResizeGroup(params);
1244
- this.dragStatus = StageDragStatus.ING;
1245
- }).on("resizeGroupEnd", () => {
1246
- this.update(true);
1247
- this.dragStatus = StageDragStatus.END;
1248
- }).on("dragGroupStart", (params) => {
1249
- const { events } = params;
1250
- this.multiMoveableHelper?.onDragGroupStart(params);
1251
- setFrames(events);
1252
- this.dragStatus = StageDragStatus.START;
1253
- }).on("dragGroup", (params) => {
1254
- const { events } = params;
1255
- events.forEach((ev) => {
1256
- const frameSnapShot = frames.find(
1257
- (frameItem) => frameItem.id === ev.target.id.replace(DRAG_EL_ID_PREFIX, "")
1258
- );
1259
- if (!frameSnapShot)
1260
- return;
1261
- const targeEl = this.targetList.find(
1262
- (targetItem) => targetItem.id === ev.target.id.replace(DRAG_EL_ID_PREFIX, "")
1263
- );
1264
- if (!targeEl)
1265
- return;
1266
- const isParentIncluded = this.targetList.find((targetItem) => targetItem.id === targeEl.parentElement?.id);
1267
- if (!isParentIncluded) {
1268
- targeEl.style.left = `${frameSnapShot.left + ev.beforeTranslate[0]}px`;
1269
- targeEl.style.top = `${frameSnapShot.top + ev.beforeTranslate[1]}px`;
1270
- }
1760
+ left: scrollLeft
1271
1761
  });
1272
- this.multiMoveableHelper?.onDragGroup(params);
1273
- this.dragStatus = StageDragStatus.ING;
1274
- }).on("dragGroupEnd", () => {
1275
- this.update();
1276
- this.dragStatus = StageDragStatus.END;
1277
- }).on("clickGroup", (params) => {
1278
- const { inputTarget, targets } = params;
1279
- if (!this.mask.isMultiSelectStatus && targets.length > 1 && targets.includes(inputTarget)) {
1280
- this.emit("select", inputTarget.id.replace(DRAG_EL_ID_PREFIX, ""));
1762
+ }
1763
+ if (this.mode === Mode.FIXED) {
1764
+ scrollLeft = 0;
1765
+ scrollTop = 0;
1766
+ }
1767
+ this.scrollRule(scrollTop);
1768
+ this.scrollTo(scrollLeft, scrollTop);
1769
+ }
1770
+ scrollTo(scrollLeft, scrollTop) {
1771
+ this.content.style.transform = `translate3d(${-scrollLeft}px, ${-scrollTop}px, 0)`;
1772
+ const event = new CustomEvent("customScroll", {
1773
+ detail: {
1774
+ scrollLeft: this.scrollLeft,
1775
+ scrollTop: this.scrollTop
1281
1776
  }
1282
1777
  });
1778
+ this.content.dispatchEvent(event);
1283
1779
  }
1284
- canSelect(el, stop) {
1285
- if (el.className.includes(PAGE_CLASS)) {
1286
- this.core.highlightedDom = void 0;
1287
- this.core.highlightLayer.clearHighlight();
1288
- stop();
1289
- return false;
1290
- }
1291
- const currentTargetMode = getMode(el);
1292
- let selectedDomMode = "";
1293
- if (this.core.selectedDom?.className.includes(PAGE_CLASS)) {
1294
- return true;
1295
- }
1296
- if (this.targetList.length === 0 && this.core.selectedDom) {
1297
- selectedDomMode = getMode(this.core.selectedDom);
1298
- } else if (this.targetList.length > 0) {
1299
- selectedDomMode = getMode(this.targetList[0]);
1300
- }
1301
- if (currentTargetMode !== selectedDomMode) {
1302
- return false;
1303
- }
1304
- return true;
1780
+ setHeight(height) {
1781
+ this.height = height;
1782
+ this.setMaxScrollTop();
1783
+ this.content.style.height = `${height}px`;
1305
1784
  }
1306
- clearSelectStatus() {
1307
- if (!this.moveableForMulti)
1308
- return;
1309
- this.destroyDragElList();
1310
- this.moveableForMulti.target = null;
1311
- this.moveableForMulti.updateTarget();
1312
- this.targetList = [];
1785
+ setWidth(width) {
1786
+ this.width = width;
1787
+ this.setMaxScrollLeft();
1788
+ this.content.style.width = `${width}px`;
1313
1789
  }
1314
- destroy() {
1315
- this.moveableForMulti?.destroy();
1316
- this.destroyDragElList();
1790
+ setMaxScrollLeft() {
1791
+ this.maxScrollLeft = Math.max(this.width - this.wrapperWidth, 0);
1317
1792
  }
1318
- destroyDragElList() {
1319
- this.dragElList.forEach((dragElItem) => dragElItem?.remove());
1793
+ setMaxScrollTop() {
1794
+ this.maxScrollTop = Math.max(this.height - this.wrapperHeight, 0);
1320
1795
  }
1321
- update(isResize = false) {
1322
- if (this.targetList.length === 0)
1796
+ fixScrollValue() {
1797
+ if (this.scrollTop < 0)
1798
+ this.scrollTop = 0;
1799
+ if (this.scrollLeft < 0)
1800
+ this.scrollLeft = 0;
1801
+ if (this.maxScrollTop < this.scrollTop)
1802
+ this.scrollTop = this.maxScrollTop;
1803
+ if (this.maxScrollLeft < this.scrollLeft)
1804
+ this.scrollLeft = this.maxScrollLeft;
1805
+ }
1806
+ mouseWheelHandler = (event) => {
1807
+ if (!this.page)
1808
+ throw new Error("page \u672A\u521D\u59CB\u5316");
1809
+ const { deltaY, deltaX } = event;
1810
+ if (this.page.clientHeight < this.wrapperHeight && deltaY)
1323
1811
  return;
1324
- const { contentWindow } = this.core.renderer;
1325
- const doc = contentWindow?.document;
1326
- if (!doc)
1812
+ if (this.page.clientWidth < this.wrapperWidth && deltaX)
1327
1813
  return;
1328
- this.emit("update", {
1329
- data: this.targetList.map((targetItem) => {
1330
- const offset = { left: targetItem.offsetLeft, top: targetItem.offsetTop };
1331
- const left = calcValueByFontsize(doc, offset.left);
1332
- const top = calcValueByFontsize(doc, offset.top);
1333
- const width = calcValueByFontsize(doc, targetItem.clientWidth);
1334
- const height = calcValueByFontsize(doc, targetItem.clientHeight);
1335
- return {
1336
- el: targetItem,
1337
- style: isResize ? { left, top, width, height } : { left, top }
1338
- };
1339
- }),
1340
- parentEl: null
1341
- });
1342
- }
1343
- getOptions(options = {}) {
1344
- let { multiMoveableOptions = {} } = this.core.config;
1345
- if (typeof multiMoveableOptions === "function") {
1346
- multiMoveableOptions = multiMoveableOptions(this.core);
1814
+ if (this.maxScrollTop > 0) {
1815
+ this.scrollTop = this.scrollTop + deltaY;
1347
1816
  }
1348
- return {
1349
- defaultGroupRotate: 0,
1350
- defaultGroupOrigin: "50% 50%",
1351
- draggable: true,
1352
- resizable: true,
1353
- throttleDrag: 0,
1354
- startDragRotate: 0,
1355
- throttleDragRotate: 0,
1356
- zoom: 1,
1357
- origin: true,
1358
- padding: { left: 0, top: 0, right: 0, bottom: 0 },
1359
- snappable: true,
1360
- bounds: {
1361
- top: 0,
1362
- left: -1,
1363
- right: this.container.clientWidth - 1,
1364
- bottom: this.container.clientHeight,
1365
- ...multiMoveableOptions.bounds || {}
1366
- },
1367
- ...options,
1368
- ...multiMoveableOptions
1369
- };
1370
- }
1817
+ if (this.maxScrollLeft > 0) {
1818
+ this.scrollLeft = this.scrollLeft + deltaX;
1819
+ }
1820
+ this.scroll();
1821
+ this.emit("scroll", event);
1822
+ };
1371
1823
  }
1372
1824
 
1373
1825
  const 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 pointer-events: none;\n}\n\n.magic-ui-container.magic-layout-relative {\n min-height: 50px;\n}\n";
1374
1826
 
1375
- class StageRender extends EventEmitter {
1827
+ class StageRender extends EventEmitter$1 {
1376
1828
  contentWindow = null;
1377
1829
  runtime = null;
1378
1830
  iframe;
1379
1831
  runtimeUrl;
1380
- core;
1381
- render;
1382
- constructor({ core }) {
1832
+ zoom = DEFAULT_ZOOM;
1833
+ customizedRender;
1834
+ constructor({ runtimeUrl, zoom, customizedRender }) {
1383
1835
  super();
1384
- this.core = core;
1385
- this.runtimeUrl = core.config.runtimeUrl || "";
1386
- this.render = core.config.render;
1836
+ this.runtimeUrl = runtimeUrl || "";
1837
+ this.customizedRender = customizedRender;
1838
+ this.setZoom(zoom);
1387
1839
  this.iframe = globalThis.document.createElement("iframe");
1388
1840
  this.iframe.src = isSameDomain(this.runtimeUrl) ? this.runtimeUrl : "";
1389
1841
  this.iframe.style.cssText = `
@@ -1401,6 +1853,31 @@ class StageRender extends EventEmitter {
1401
1853
  this.emit("runtime-ready", runtime);
1402
1854
  }
1403
1855
  });
1856
+ async add(data) {
1857
+ const runtime = await this.getRuntime();
1858
+ return runtime?.add?.(data);
1859
+ }
1860
+ async remove(data) {
1861
+ const runtime = await this.getRuntime();
1862
+ return runtime?.remove?.(data);
1863
+ }
1864
+ async update(data) {
1865
+ const runtime = await this.getRuntime();
1866
+ runtime?.update?.(data);
1867
+ }
1868
+ async select(els) {
1869
+ const runtime = await this.getRuntime();
1870
+ for (const el of els) {
1871
+ await runtime?.select?.(el.id);
1872
+ if (runtime?.beforeSelect) {
1873
+ await runtime.beforeSelect(el);
1874
+ }
1875
+ this.flagSelectedEl(el);
1876
+ }
1877
+ }
1878
+ setZoom(zoom = DEFAULT_ZOOM) {
1879
+ this.zoom = zoom;
1880
+ }
1404
1881
  async mount(el) {
1405
1882
  if (!this.iframe) {
1406
1883
  throw Error("mount \u5931\u8D25");
@@ -1426,6 +1903,30 @@ class StageRender extends EventEmitter {
1426
1903
  this.on("runtime-ready", listener);
1427
1904
  });
1428
1905
  };
1906
+ getDocument() {
1907
+ return this.contentWindow?.document;
1908
+ }
1909
+ getElementsFromPoint(point) {
1910
+ let x = point.clientX;
1911
+ let y = point.clientY;
1912
+ if (this.iframe) {
1913
+ const rect = this.iframe.getClientRects()[0];
1914
+ if (rect) {
1915
+ x = x - rect.left;
1916
+ y = y - rect.top;
1917
+ }
1918
+ }
1919
+ return this.getDocument()?.elementsFromPoint(x / this.zoom, y / this.zoom);
1920
+ }
1921
+ getTargetElement(idOrEl) {
1922
+ if (typeof idOrEl === "string" || typeof idOrEl === "number") {
1923
+ const el = this.getDocument()?.getElementById(`${idOrEl}`);
1924
+ if (!el)
1925
+ throw new Error(`\u4E0D\u5B58\u5728ID\u4E3A${idOrEl}\u7684\u5143\u7D20`);
1926
+ return el;
1927
+ }
1928
+ return idOrEl;
1929
+ }
1429
1930
  destroy() {
1430
1931
  this.iframe?.removeEventListener("load", this.loadHandler);
1431
1932
  this.contentWindow = null;
@@ -1433,14 +1934,21 @@ class StageRender extends EventEmitter {
1433
1934
  this.iframe = void 0;
1434
1935
  this.removeAllListeners();
1435
1936
  }
1937
+ flagSelectedEl(el) {
1938
+ const doc = this.getDocument();
1939
+ if (doc) {
1940
+ removeSelectedClassName(doc);
1941
+ addSelectedClassName(el, doc);
1942
+ }
1943
+ }
1436
1944
  loadHandler = async () => {
1437
1945
  if (!this.contentWindow?.magic) {
1438
1946
  this.postTmagicRuntimeReady();
1439
1947
  }
1440
1948
  if (!this.contentWindow)
1441
1949
  return;
1442
- if (this.render) {
1443
- const el = await this.render(this.core);
1950
+ if (this.customizedRender) {
1951
+ const el = await this.customizedRender();
1444
1952
  if (el) {
1445
1953
  this.contentWindow.document?.body?.appendChild(el);
1446
1954
  }
@@ -1460,207 +1968,81 @@ class StageRender extends EventEmitter {
1460
1968
  }
1461
1969
  }
1462
1970
 
1463
- class StageCore extends EventEmitter {
1971
+ class StageCore extends EventEmitter$1 {
1464
1972
  container;
1465
- selectedDom;
1466
- selectedDomList = [];
1467
- highlightedDom;
1468
1973
  renderer;
1469
1974
  mask;
1470
- dr;
1471
- multiDr;
1472
- highlightLayer;
1473
- config;
1474
- zoom = DEFAULT_ZOOM;
1475
- containerHighlightClassName;
1476
- containerHighlightDuration;
1477
- containerHighlightType;
1478
- isContainer;
1479
- canSelect;
1975
+ actionManager;
1976
+ pageResizeObserver = null;
1977
+ autoScrollIntoView;
1978
+ customizedRender;
1480
1979
  constructor(config) {
1481
1980
  super();
1482
- this.config = config;
1483
- this.setZoom(config.zoom);
1484
- this.canSelect = config.canSelect || ((el) => !!el.id);
1485
- this.isContainer = config.isContainer;
1486
- this.containerHighlightClassName = config.containerHighlightClassName || CONTAINER_HIGHLIGHT_CLASS;
1487
- this.containerHighlightDuration = config.containerHighlightDuration || 800;
1488
- this.containerHighlightType = config.containerHighlightType;
1489
- this.renderer = new StageRender({ core: this });
1490
- this.mask = new StageMask({ core: this });
1491
- this.dr = new StageDragResize({ core: this, container: this.mask.content, mask: this.mask });
1492
- this.multiDr = new StageMultiDragResize({ core: this, container: this.mask.content, mask: this.mask });
1493
- this.highlightLayer = new StageHighlight({ core: this, container: this.mask.wrapper });
1494
- this.renderer.on("runtime-ready", (runtime) => {
1495
- this.emit("runtime-ready", runtime);
1496
- });
1497
- this.renderer.on("page-el-update", (el) => {
1498
- this.mask?.observe(el);
1499
- });
1500
- this.mask.on("beforeSelect", async (event) => {
1501
- this.clearSelectStatus("multiSelect");
1502
- const el = await this.getElementFromPoint(event);
1503
- if (!el)
1504
- return;
1505
- this.select(el, event);
1506
- }).on("select", () => {
1507
- this.emit("select", this.selectedDom);
1508
- }).on("changeGuides", (data) => {
1509
- this.dr.setGuidelines(data.type, data.guides);
1510
- this.emit("changeGuides", data);
1511
- }).on("highlight", async (event) => {
1512
- const el = await this.getElementFromPoint(event);
1513
- if (!el)
1514
- return;
1515
- if (this.multiDr.dragStatus === StageDragStatus.ING)
1516
- return;
1517
- await this.highlight(el);
1518
- if (this.highlightedDom === this.selectedDom) {
1519
- this.highlightLayer.clearHighlight();
1520
- return;
1521
- }
1522
- this.emit("highlight", this.highlightedDom);
1523
- }).on("clearHighlight", async () => {
1524
- this.highlightLayer.clearHighlight();
1525
- }).on("beforeMultiSelect", async (event) => {
1526
- const el = await this.getElementFromPoint(event);
1527
- if (!el)
1528
- return;
1529
- if (this.selectedDom && !this.selectedDom.className.includes(PAGE_CLASS)) {
1530
- this.selectedDomList.push(this.selectedDom);
1531
- this.selectedDom = void 0;
1532
- }
1533
- const existIndex = this.selectedDomList.findIndex((selectedDom) => selectedDom.id === el.id);
1534
- if (existIndex !== -1) {
1535
- this.selectedDomList.splice(existIndex, 1);
1536
- } else {
1537
- this.selectedDomList.push(el);
1981
+ this.autoScrollIntoView = config.autoScrollIntoView;
1982
+ this.customizedRender = config.render;
1983
+ this.renderer = new StageRender({
1984
+ runtimeUrl: config.runtimeUrl,
1985
+ zoom: config.zoom,
1986
+ customizedRender: async () => {
1987
+ if (this?.customizedRender) {
1988
+ return await this.customizedRender(this);
1989
+ }
1990
+ return null;
1538
1991
  }
1539
- this.multiSelect(this.selectedDomList);
1540
- });
1541
- this.dr.on("update", (data) => {
1542
- setTimeout(() => this.emit("update", data));
1543
- }).on("sort", (data) => {
1544
- setTimeout(() => this.emit("sort", data));
1545
- });
1546
- this.multiDr.on("update", (data) => {
1547
- setTimeout(() => this.emit("update", data));
1548
- }).on("select", async (id) => {
1549
- const el = await this.getTargetElement(id);
1550
- this.select(el);
1551
- setTimeout(() => this.emit("select", el));
1552
1992
  });
1553
- }
1554
- getElementsFromPoint(event) {
1555
- const { renderer, zoom } = this;
1556
- const doc = renderer.contentWindow?.document;
1557
- let x = event.clientX;
1558
- let y = event.clientY;
1559
- if (renderer.iframe) {
1560
- const rect = renderer.iframe.getClientRects()[0];
1561
- if (rect) {
1562
- x = x - rect.left;
1563
- y = y - rect.top;
1564
- }
1565
- }
1566
- return doc?.elementsFromPoint(x / zoom, y / zoom);
1567
- }
1568
- async getElementFromPoint(event) {
1569
- const els = this.getElementsFromPoint(event);
1570
- let stopped = false;
1571
- const stop = () => stopped = true;
1572
- for (const el of els) {
1573
- if (!el.id.startsWith(GHOST_EL_ID_PREFIX) && await this.isElCanSelect(el, event, stop)) {
1574
- if (stopped)
1575
- break;
1576
- return el;
1577
- }
1578
- }
1579
- }
1580
- async isElCanSelect(el, event, stop) {
1581
- const canSelectByProp = await this.canSelect(el, event, stop);
1582
- if (!canSelectByProp)
1583
- return false;
1584
- if (this.mask.isMultiSelectStatus) {
1585
- return this.multiDr.canSelect(el, stop);
1586
- }
1587
- return true;
1993
+ this.mask = new StageMask();
1994
+ this.actionManager = new ActionManager(this.getActionManagerConfig(config));
1995
+ this.initRenderEvent();
1996
+ this.initActionEvent();
1997
+ this.initMaskEvent();
1588
1998
  }
1589
1999
  async select(idOrEl, event) {
1590
- this.clearSelectStatus("multiSelect");
1591
- const el = await this.getTargetElement(idOrEl);
1592
- if (el === this.selectedDom)
2000
+ const el = this.renderer.getTargetElement(idOrEl);
2001
+ if (el === this.actionManager.getSelectedEl())
1593
2002
  return;
1594
- const runtime = await this.renderer.getRuntime();
1595
- await runtime?.select?.(el.id);
1596
- if (runtime?.beforeSelect) {
1597
- await runtime.beforeSelect(el);
1598
- }
2003
+ await this.renderer.select([el]);
1599
2004
  this.mask.setLayout(el);
1600
- this.dr.select(el, event);
1601
- if (this.config.autoScrollIntoView || el.dataset.autoScrollIntoView) {
1602
- this.mask.intersectionObserver?.observe(el);
1603
- }
1604
- this.selectedDom = el;
1605
- if (this.renderer.contentWindow) {
1606
- removeSelectedClassName(this.renderer.contentWindow.document);
1607
- if (this.selectedDom) {
1608
- addSelectedClassName(this.selectedDom, this.renderer.contentWindow.document);
1609
- }
2005
+ this.actionManager.select(el, event);
2006
+ if (this.autoScrollIntoView || el.dataset.autoScrollIntoView) {
2007
+ this.mask.observerIntersection(el);
1610
2008
  }
1611
2009
  }
1612
2010
  async multiSelect(idOrElList) {
1613
- this.clearSelectStatus("select");
1614
- const elList = await Promise.all(idOrElList.map(async (idOrEl) => await this.getTargetElement(idOrEl)));
1615
- this.multiDr.multiSelect(elList);
1616
- this.emit("multiSelect", elList);
1617
- }
1618
- update(data) {
1619
- const { config } = data;
1620
- return this.renderer?.getRuntime().then((runtime) => {
1621
- runtime?.update?.(data);
1622
- setTimeout(() => {
1623
- const el = this.renderer.contentWindow?.document.getElementById(`${config.id}`);
1624
- if (el && el.id === this.selectedDom?.id) {
1625
- this.selectedDom = el;
1626
- this.mask.setLayout(el);
1627
- this.dr.updateMoveable(el);
1628
- }
1629
- }, 0);
1630
- });
1631
- }
1632
- async highlight(idOrEl) {
1633
- let el;
1634
- try {
1635
- el = await this.getTargetElement(idOrEl);
1636
- } catch (error) {
1637
- this.highlightLayer.clearHighlight();
2011
+ const els = idOrElList.map((idOrEl) => this.renderer.getTargetElement(idOrEl));
2012
+ if (els.length === 0)
1638
2013
  return;
2014
+ const lastEl = els[els.length - 1];
2015
+ const isReduceSelect = els.length < this.actionManager.getSelectedElList().length;
2016
+ await this.renderer.select(els);
2017
+ this.mask.setLayout(lastEl);
2018
+ this.actionManager.multiSelect(idOrElList);
2019
+ if ((this.autoScrollIntoView || lastEl.dataset.autoScrollIntoView) && !isReduceSelect) {
2020
+ this.mask.observerIntersection(lastEl);
1639
2021
  }
1640
- if (el === this.highlightedDom || !el)
1641
- return;
1642
- this.highlightLayer.highlight(el);
1643
- this.highlightedDom = el;
1644
2022
  }
1645
- sortNode(data) {
1646
- return this.renderer?.getRuntime().then((runtime) => runtime?.sortNode?.(data));
2023
+ highlight(idOrEl) {
2024
+ this.actionManager.highlight(idOrEl);
1647
2025
  }
1648
- add(data) {
1649
- return this.renderer?.getRuntime().then((runtime) => runtime?.add?.(data));
2026
+ async update(data) {
2027
+ const { config } = data;
2028
+ await this.renderer.update(data);
2029
+ setTimeout(() => {
2030
+ const el = this.renderer.getTargetElement(`${config.id}`);
2031
+ if (el && this.actionManager.isSelectedEl(el)) {
2032
+ this.mask.setLayout(el);
2033
+ this.actionManager.setSelectedEl(el);
2034
+ this.actionManager.updateMoveable(el);
2035
+ }
2036
+ });
1650
2037
  }
1651
- remove(data) {
1652
- return this.renderer?.getRuntime().then((runtime) => runtime?.remove?.(data));
2038
+ async add(data) {
2039
+ return await this.renderer.add(data);
1653
2040
  }
1654
- setZoom(zoom = DEFAULT_ZOOM) {
1655
- this.zoom = zoom;
2041
+ async remove(data) {
2042
+ return await this.renderer.remove(data);
1656
2043
  }
1657
- clearSelectStatus(selectType) {
1658
- if (selectType === "multiSelect") {
1659
- this.multiDr.clearSelectStatus();
1660
- this.selectedDomList = [];
1661
- } else {
1662
- this.dr.clearSelectStatus();
1663
- }
2044
+ setZoom(zoom = DEFAULT_ZOOM) {
2045
+ this.renderer.setZoom(zoom);
1664
2046
  }
1665
2047
  async mount(el) {
1666
2048
  this.container = el;
@@ -1671,45 +2053,105 @@ class StageCore extends EventEmitter {
1671
2053
  }
1672
2054
  clearGuides() {
1673
2055
  this.mask.clearGuides();
1674
- this.dr.clearGuides();
2056
+ this.actionManager.clearGuides();
1675
2057
  }
1676
- async addContainerHighlightClassName(event, exclude) {
1677
- const els = this.getElementsFromPoint(event);
1678
- const { renderer } = this;
1679
- const doc = renderer.contentWindow?.document;
1680
- if (!doc)
1681
- return;
1682
- for (const el of els) {
1683
- if (!el.id.startsWith(GHOST_EL_ID_PREFIX) && await this.isContainer(el) && !exclude.includes(el)) {
1684
- addClassName(el, doc, this.containerHighlightClassName);
1685
- break;
1686
- }
1687
- }
2058
+ getAddContainerHighlightClassNameTimeout(event, excludeElList = []) {
2059
+ return this.delayedMarkContainer(event, excludeElList);
1688
2060
  }
1689
- getAddContainerHighlightClassNameTimeout(event, exclude = []) {
1690
- return globalThis.setTimeout(() => {
1691
- this.addContainerHighlightClassName(event, exclude);
1692
- }, this.containerHighlightDuration);
2061
+ delayedMarkContainer(event, excludeElList = []) {
2062
+ return this.actionManager.delayedMarkContainer(event, excludeElList);
1693
2063
  }
1694
2064
  destroy() {
1695
- const { mask, renderer, dr, highlightLayer } = this;
2065
+ const { mask, renderer, actionManager, pageResizeObserver } = this;
1696
2066
  renderer.destroy();
1697
2067
  mask.destroy();
1698
- dr.destroy();
1699
- highlightLayer.destroy();
2068
+ actionManager.destroy();
2069
+ pageResizeObserver?.disconnect();
1700
2070
  this.removeAllListeners();
1701
2071
  this.container = void 0;
1702
2072
  }
1703
- async getTargetElement(idOrEl) {
1704
- if (typeof idOrEl === "string" || typeof idOrEl === "number") {
1705
- const el = this.renderer.contentWindow?.document.getElementById(`${idOrEl}`);
1706
- if (!el)
1707
- throw new Error(`\u4E0D\u5B58\u5728ID\u4E3A${idOrEl}\u7684\u5143\u7D20`);
1708
- return el;
2073
+ observePageResize(page) {
2074
+ if (typeof ResizeObserver !== "undefined") {
2075
+ this.pageResizeObserver = new ResizeObserver((entries) => {
2076
+ this.mask.pageResize(entries);
2077
+ this.actionManager.updateMoveable();
2078
+ });
2079
+ this.pageResizeObserver.observe(page);
1709
2080
  }
1710
- return idOrEl;
2081
+ }
2082
+ getActionManagerConfig(config) {
2083
+ const actionManagerConfig = {
2084
+ containerHighlightClassName: config.containerHighlightClassName,
2085
+ containerHighlightDuration: config.containerHighlightDuration,
2086
+ containerHighlightType: config.containerHighlightType,
2087
+ moveableOptions: config.moveableOptions,
2088
+ multiMoveableOptions: config.multiMoveableOptions,
2089
+ container: this.mask.content,
2090
+ canSelect: config.canSelect,
2091
+ isContainer: config.isContainer,
2092
+ updateDragEl: config.updateDragEl,
2093
+ getRootContainer: () => this.container,
2094
+ getRenderDocument: () => this.renderer.getDocument(),
2095
+ getTargetElement: (idOrEl) => this.renderer.getTargetElement(idOrEl),
2096
+ getElementsFromPoint: (point) => this.renderer.getElementsFromPoint(point)
2097
+ };
2098
+ return actionManagerConfig;
2099
+ }
2100
+ initRenderEvent() {
2101
+ this.renderer.on("runtime-ready", (runtime) => {
2102
+ this.emit("runtime-ready", runtime);
2103
+ });
2104
+ this.renderer.on("page-el-update", (el) => {
2105
+ this.mask?.observe(el);
2106
+ this.observePageResize(el);
2107
+ });
2108
+ }
2109
+ initMaskEvent() {
2110
+ this.mask.on("change-guides", (data) => {
2111
+ this.actionManager.setGuidelines(data.type, data.guides);
2112
+ this.emit("change-guides", data);
2113
+ });
2114
+ }
2115
+ initActionEvent() {
2116
+ this.initActionManagerEvent();
2117
+ this.initDrEvent();
2118
+ this.initMulDrEvent();
2119
+ this.initHighlightEvent();
2120
+ }
2121
+ initActionManagerEvent() {
2122
+ this.actionManager.on("before-select", (idOrEl, event) => {
2123
+ this.select(idOrEl, event);
2124
+ }).on("select", (selectedEl) => {
2125
+ this.emit("select", selectedEl);
2126
+ }).on("before-multi-select", (idOrElList) => {
2127
+ this.multiSelect(idOrElList);
2128
+ }).on("multi-select", (selectedElList) => {
2129
+ this.emit("multi-select", selectedElList);
2130
+ });
2131
+ }
2132
+ initDrEvent() {
2133
+ this.actionManager.on("update", (data) => {
2134
+ this.emit("update", data);
2135
+ }).on("sort", (data) => {
2136
+ this.emit("sort", data);
2137
+ }).on("select-parent", () => {
2138
+ this.emit("select-parent");
2139
+ });
2140
+ }
2141
+ initMulDrEvent() {
2142
+ this.actionManager.on("change-to-select", (el) => {
2143
+ this.select(el);
2144
+ setTimeout(() => this.emit("select", el));
2145
+ }).on("multi-update", (data, parentEl) => {
2146
+ this.emit("update", { data, parentEl });
2147
+ });
2148
+ }
2149
+ initHighlightEvent() {
2150
+ this.actionManager.on("highlight", async (highlightEl) => {
2151
+ this.emit("highlight", highlightEl);
2152
+ });
1711
2153
  }
1712
2154
  }
1713
2155
 
1714
- export { CONTAINER_HIGHLIGHT_CLASS, ContainerHighlightType, DEFAULT_ZOOM, DRAG_EL_ID_PREFIX, GHOST_EL_ID_PREFIX, GuidesType, HIGHLIGHT_EL_ID_PREFIX, Mode, MouseButton, PAGE_CLASS, SELECTED_CLASS, StageDragResize, StageDragStatus, StageMask, StageRender, ZIndex, addSelectedClassName, calcValueByFontsize, StageCore as default, down, getAbsolutePosition, getMode, getOffset, getScrollParent, getTargetElStyle, isAbsolute, isFixed, isFixedParent, isRelative, isStatic, removeSelectedClassName, up };
2156
+ export { CONTAINER_HIGHLIGHT_CLASS_NAME, ContainerHighlightType, DEFAULT_ZOOM, DRAG_EL_ID_PREFIX, GHOST_EL_ID_PREFIX, GuidesType, HIGHLIGHT_EL_ID_PREFIX, Mode, MouseButton, PAGE_CLASS, SELECTED_CLASS, SelectStatus, StageDragResize, StageDragStatus, StageMask, StageRender, ZIndex, addSelectedClassName, calcValueByFontsize, StageCore as default, down, getAbsolutePosition, getMode, getOffset, getScrollParent, getTargetElStyle, isAbsolute, isFixed, isFixedParent, isMoveableButton, isRelative, isStatic, removeSelectedClassName, up };
1715
2157
  //# sourceMappingURL=tmagic-stage.mjs.map