@tmagic/stage 1.0.6 → 1.1.0-beta.10
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.
- package/dist/{tmagic-stage.es.js → tmagic-stage.mjs} +689 -295
- package/dist/tmagic-stage.mjs.map +1 -0
- package/dist/tmagic-stage.umd.js +722 -310
- package/dist/tmagic-stage.umd.js.map +1 -1
- package/package.json +14 -11
- package/src/StageCore.ts +126 -19
- package/src/StageDragResize.ts +155 -162
- package/src/StageHighlight.ts +1 -2
- package/src/StageMask.ts +33 -11
- package/src/StageMultiDragResize.ts +260 -0
- package/src/StageRender.ts +31 -17
- package/src/TargetCalibrate.ts +2 -2
- package/src/const.ts +4 -0
- package/src/index.ts +1 -0
- package/src/style.css +11 -0
- package/src/types.ts +40 -13
- package/src/util.ts +102 -22
- package/tsconfig.build.json +13 -0
- package/{dist/types/src → types}/Rule.d.ts +0 -0
- package/{dist/types/src → types}/StageCore.d.ts +26 -4
- package/{dist/types/src → types}/StageDragResize.d.ts +10 -19
- package/{dist/types/src → types}/StageHighlight.d.ts +0 -0
- package/{dist/types/src → types}/StageMask.d.ts +1 -0
- package/types/StageMultiDragResize.d.ts +51 -0
- package/{dist/types/src → types}/StageRender.d.ts +1 -0
- package/{dist/types/src → types}/TargetCalibrate.d.ts +0 -0
- package/{dist/types/src → types}/const.d.ts +2 -0
- package/{dist/types/src → types}/index.d.ts +1 -0
- package/types/logger.d.ts +5 -0
- package/{dist/types/src → types}/types.d.ts +38 -13
- package/{dist/types/src → types}/util.d.ts +17 -7
- package/dist/tmagic-stage.es.js.map +0 -1
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import EventEmitter$1, { EventEmitter } from 'events';
|
|
2
|
+
import { removeClassName, removeClassNameByClassName, createDiv, injectStyle, isSameDomain, getHost, addClassName } from '@tmagic/utils';
|
|
3
|
+
import KeyController from 'keycon';
|
|
2
4
|
import Moveable from 'moveable';
|
|
3
5
|
import MoveableHelper from 'moveable-helper';
|
|
4
6
|
import { throttle } from 'lodash-es';
|
|
@@ -7,6 +9,8 @@ import Guides from '@scena/guides';
|
|
|
7
9
|
const GHOST_EL_ID_PREFIX = "ghost_el_";
|
|
8
10
|
const DRAG_EL_ID_PREFIX = "drag_el_";
|
|
9
11
|
const HIGHLIGHT_EL_ID_PREFIX = "highlight_el_";
|
|
12
|
+
const CONTAINER_HIGHLIGHT_CLASS = "tmagic-stage-container-highlight";
|
|
13
|
+
const PAGE_CLASS = "magic-ui-page";
|
|
10
14
|
const DEFAULT_ZOOM = 1;
|
|
11
15
|
var GuidesType = /* @__PURE__ */ ((GuidesType2) => {
|
|
12
16
|
GuidesType2["HORIZONTAL"] = "horizontal";
|
|
@@ -34,6 +38,18 @@ var Mode = /* @__PURE__ */ ((Mode2) => {
|
|
|
34
38
|
})(Mode || {});
|
|
35
39
|
const SELECTED_CLASS = "tmagic-stage-selected-area";
|
|
36
40
|
|
|
41
|
+
var ContainerHighlightType = /* @__PURE__ */ ((ContainerHighlightType2) => {
|
|
42
|
+
ContainerHighlightType2["DEFAULT"] = "default";
|
|
43
|
+
ContainerHighlightType2["ALT"] = "alt";
|
|
44
|
+
return ContainerHighlightType2;
|
|
45
|
+
})(ContainerHighlightType || {});
|
|
46
|
+
var StageDragStatus = /* @__PURE__ */ ((StageDragStatus2) => {
|
|
47
|
+
StageDragStatus2["START"] = "start";
|
|
48
|
+
StageDragStatus2["ING"] = "ing";
|
|
49
|
+
StageDragStatus2["END"] = "end";
|
|
50
|
+
return StageDragStatus2;
|
|
51
|
+
})(StageDragStatus || {});
|
|
52
|
+
|
|
37
53
|
const getParents = (el, relative) => {
|
|
38
54
|
let cur = el.parentElement;
|
|
39
55
|
const parents = [];
|
|
@@ -59,6 +75,19 @@ const getOffset = (el) => {
|
|
|
59
75
|
top
|
|
60
76
|
};
|
|
61
77
|
};
|
|
78
|
+
const getTargetElStyle = (el) => {
|
|
79
|
+
const offset = getOffset(el);
|
|
80
|
+
const { transform } = getComputedStyle(el);
|
|
81
|
+
return `
|
|
82
|
+
position: absolute;
|
|
83
|
+
transform: ${transform};
|
|
84
|
+
left: ${offset.left}px;
|
|
85
|
+
top: ${offset.top}px;
|
|
86
|
+
width: ${el.clientWidth}px;
|
|
87
|
+
height: ${el.clientHeight}px;
|
|
88
|
+
z-index: ${ZIndex.DRAG_EL};
|
|
89
|
+
`;
|
|
90
|
+
};
|
|
62
91
|
const getAbsolutePosition = (el, { top, left }) => {
|
|
63
92
|
const { offsetParent } = el;
|
|
64
93
|
if (offsetParent) {
|
|
@@ -70,13 +99,6 @@ const getAbsolutePosition = (el, { top, left }) => {
|
|
|
70
99
|
}
|
|
71
100
|
return { left, top };
|
|
72
101
|
};
|
|
73
|
-
const getHost = (targetUrl) => targetUrl.match(/\/\/([^/]+)/)?.[1];
|
|
74
|
-
const isSameDomain = (targetUrl = "", source = globalThis.location.host) => {
|
|
75
|
-
const isHttpUrl = /^(http[s]?:)?\/\//.test(targetUrl);
|
|
76
|
-
if (!isHttpUrl)
|
|
77
|
-
return true;
|
|
78
|
-
return getHost(targetUrl) === source;
|
|
79
|
-
};
|
|
80
102
|
const isAbsolute = (style) => style.position === "absolute";
|
|
81
103
|
const isRelative = (style) => style.position === "relative";
|
|
82
104
|
const isStatic = (style) => style.position === "static";
|
|
@@ -120,19 +142,14 @@ const getScrollParent = (element, includeHidden = false) => {
|
|
|
120
142
|
}
|
|
121
143
|
return null;
|
|
122
144
|
};
|
|
123
|
-
const createDiv = ({ className, cssText }) => {
|
|
124
|
-
const el = globalThis.document.createElement("div");
|
|
125
|
-
el.className = className;
|
|
126
|
-
el.style.cssText = cssText;
|
|
127
|
-
return el;
|
|
128
|
-
};
|
|
129
145
|
const removeSelectedClassName = (doc) => {
|
|
130
146
|
const oldEl = doc.querySelector(`.${SELECTED_CLASS}`);
|
|
131
147
|
if (oldEl) {
|
|
132
|
-
oldEl
|
|
133
|
-
oldEl.parentNode
|
|
148
|
+
removeClassName(oldEl, SELECTED_CLASS);
|
|
149
|
+
if (oldEl.parentNode)
|
|
150
|
+
removeClassName(oldEl.parentNode, `${SELECTED_CLASS}-parent`);
|
|
134
151
|
doc.querySelectorAll(`.${SELECTED_CLASS}-parents`).forEach((item) => {
|
|
135
|
-
item
|
|
152
|
+
removeClassName(item, `${SELECTED_CLASS}-parents`);
|
|
136
153
|
});
|
|
137
154
|
}
|
|
138
155
|
};
|
|
@@ -143,20 +160,94 @@ const addSelectedClassName = (el, doc) => {
|
|
|
143
160
|
item.classList.add(`${SELECTED_CLASS}-parents`);
|
|
144
161
|
});
|
|
145
162
|
};
|
|
163
|
+
const calcValueByFontsize = (doc, value) => {
|
|
164
|
+
const { fontSize } = doc.documentElement.style;
|
|
165
|
+
if (fontSize) {
|
|
166
|
+
const times = globalThis.parseFloat(fontSize) / 100;
|
|
167
|
+
return Number((value / times).toFixed(2));
|
|
168
|
+
}
|
|
169
|
+
return value;
|
|
170
|
+
};
|
|
171
|
+
const down = (deltaTop, target) => {
|
|
172
|
+
let swapIndex = 0;
|
|
173
|
+
let addUpH = target.clientHeight;
|
|
174
|
+
const brothers = Array.from(target.parentNode?.children || []).filter((node) => !node.id.startsWith(GHOST_EL_ID_PREFIX));
|
|
175
|
+
const index = brothers.indexOf(target);
|
|
176
|
+
const downEls = brothers.slice(index + 1);
|
|
177
|
+
for (let i = 0; i < downEls.length; i++) {
|
|
178
|
+
const ele = downEls[i];
|
|
179
|
+
if (ele.style?.position === "fixed") {
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
addUpH += ele.clientHeight / 2;
|
|
183
|
+
if (deltaTop <= addUpH) {
|
|
184
|
+
break;
|
|
185
|
+
}
|
|
186
|
+
addUpH += ele.clientHeight / 2;
|
|
187
|
+
swapIndex = i;
|
|
188
|
+
}
|
|
189
|
+
return {
|
|
190
|
+
src: target.id,
|
|
191
|
+
dist: downEls.length && swapIndex > -1 ? downEls[swapIndex].id : target.id
|
|
192
|
+
};
|
|
193
|
+
};
|
|
194
|
+
const up = (deltaTop, target) => {
|
|
195
|
+
const brothers = Array.from(target.parentNode?.children || []).filter((node) => !node.id.startsWith(GHOST_EL_ID_PREFIX));
|
|
196
|
+
const index = brothers.indexOf(target);
|
|
197
|
+
const upEls = brothers.slice(0, index);
|
|
198
|
+
let addUpH = target.clientHeight;
|
|
199
|
+
let swapIndex = upEls.length - 1;
|
|
200
|
+
for (let i = upEls.length - 1; i >= 0; i--) {
|
|
201
|
+
const ele = upEls[i];
|
|
202
|
+
if (!ele)
|
|
203
|
+
continue;
|
|
204
|
+
if (ele.style.position === "fixed")
|
|
205
|
+
continue;
|
|
206
|
+
addUpH += ele.clientHeight / 2;
|
|
207
|
+
if (-deltaTop <= addUpH)
|
|
208
|
+
break;
|
|
209
|
+
addUpH += ele.clientHeight / 2;
|
|
210
|
+
swapIndex = i;
|
|
211
|
+
}
|
|
212
|
+
return {
|
|
213
|
+
src: target.id,
|
|
214
|
+
dist: upEls.length && swapIndex > -1 ? upEls[swapIndex].id : target.id
|
|
215
|
+
};
|
|
216
|
+
};
|
|
146
217
|
|
|
147
218
|
class StageDragResize extends EventEmitter {
|
|
219
|
+
core;
|
|
220
|
+
mask;
|
|
221
|
+
container;
|
|
222
|
+
target;
|
|
223
|
+
dragEl;
|
|
224
|
+
moveable;
|
|
225
|
+
horizontalGuidelines = [];
|
|
226
|
+
verticalGuidelines = [];
|
|
227
|
+
elementGuidelines = [];
|
|
228
|
+
mode = Mode.ABSOLUTE;
|
|
229
|
+
moveableOptions = {};
|
|
230
|
+
dragStatus = StageDragStatus.END;
|
|
231
|
+
ghostEl;
|
|
232
|
+
moveableHelper;
|
|
233
|
+
isContainerHighlight = false;
|
|
148
234
|
constructor(config) {
|
|
149
235
|
super();
|
|
150
|
-
this.horizontalGuidelines = [];
|
|
151
|
-
this.verticalGuidelines = [];
|
|
152
|
-
this.elementGuidelines = [];
|
|
153
|
-
this.mode = Mode.ABSOLUTE;
|
|
154
|
-
this.moveableOptions = {};
|
|
155
|
-
this.dragStatus = "end" /* END */;
|
|
156
236
|
this.core = config.core;
|
|
157
237
|
this.container = config.container;
|
|
158
|
-
this.
|
|
159
|
-
|
|
238
|
+
this.mask = config.mask;
|
|
239
|
+
KeyController.global.keydown("alt", (e) => {
|
|
240
|
+
e.inputEvent.preventDefault();
|
|
241
|
+
this.isContainerHighlight = true;
|
|
242
|
+
});
|
|
243
|
+
KeyController.global.keyup("alt", (e) => {
|
|
244
|
+
e.inputEvent.preventDefault();
|
|
245
|
+
const doc = this.core.renderer.contentWindow?.document;
|
|
246
|
+
if (doc && this.canContainerHighlight()) {
|
|
247
|
+
removeClassNameByClassName(doc, this.core.containerHighlightClassName);
|
|
248
|
+
}
|
|
249
|
+
this.isContainerHighlight = false;
|
|
250
|
+
});
|
|
160
251
|
}
|
|
161
252
|
select(el, event) {
|
|
162
253
|
const oldTarget = this.target;
|
|
@@ -207,11 +298,21 @@ class StageDragResize extends EventEmitter {
|
|
|
207
298
|
this.moveableOptions.verticalGuidelines = [];
|
|
208
299
|
this.updateMoveable();
|
|
209
300
|
}
|
|
301
|
+
clearSelectStatus() {
|
|
302
|
+
if (!this.moveable)
|
|
303
|
+
return;
|
|
304
|
+
this.destroyDragEl();
|
|
305
|
+
this.moveable.target = null;
|
|
306
|
+
this.moveable.updateTarget();
|
|
307
|
+
}
|
|
308
|
+
destroyDragEl() {
|
|
309
|
+
this.dragEl?.remove();
|
|
310
|
+
}
|
|
210
311
|
destroy() {
|
|
211
312
|
this.moveable?.destroy();
|
|
212
313
|
this.destroyGhostEl();
|
|
213
314
|
this.destroyDragEl();
|
|
214
|
-
this.dragStatus =
|
|
315
|
+
this.dragStatus = StageDragStatus.END;
|
|
215
316
|
this.removeAllListeners();
|
|
216
317
|
}
|
|
217
318
|
init(el) {
|
|
@@ -220,7 +321,14 @@ class StageDragResize extends EventEmitter {
|
|
|
220
321
|
}
|
|
221
322
|
this.mode = getMode(el);
|
|
222
323
|
this.destroyGhostEl();
|
|
223
|
-
this.
|
|
324
|
+
this.destroyDragEl();
|
|
325
|
+
this.dragEl = globalThis.document.createElement("div");
|
|
326
|
+
this.container.append(this.dragEl);
|
|
327
|
+
this.dragEl.style.cssText = getTargetElStyle(el);
|
|
328
|
+
this.dragEl.id = `${DRAG_EL_ID_PREFIX}${el.id}`;
|
|
329
|
+
if (typeof this.core.config.updateDragEl === "function") {
|
|
330
|
+
this.core.config.updateDragEl(this.dragEl, el);
|
|
331
|
+
}
|
|
224
332
|
this.moveableOptions = this.getOptions({
|
|
225
333
|
target: this.dragEl
|
|
226
334
|
});
|
|
@@ -231,19 +339,22 @@ class StageDragResize extends EventEmitter {
|
|
|
231
339
|
});
|
|
232
340
|
this.elementGuidelines = [];
|
|
233
341
|
if (this.mode === Mode.ABSOLUTE) {
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
342
|
+
this.container.append(this.createGuidelineElements(nodes));
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
createGuidelineElements(nodes) {
|
|
346
|
+
const frame = globalThis.document.createDocumentFragment();
|
|
347
|
+
for (const node of nodes) {
|
|
348
|
+
const { width, height } = node.getBoundingClientRect();
|
|
349
|
+
if (node === this.target)
|
|
350
|
+
continue;
|
|
351
|
+
const { left, top } = getOffset(node);
|
|
352
|
+
const elementGuideline = globalThis.document.createElement("div");
|
|
353
|
+
elementGuideline.style.cssText = `position: absolute;width: ${width}px;height: ${height}px;top: ${top}px;left: ${left}px`;
|
|
354
|
+
this.elementGuidelines.push(elementGuideline);
|
|
355
|
+
frame.append(elementGuideline);
|
|
246
356
|
}
|
|
357
|
+
return frame;
|
|
247
358
|
}
|
|
248
359
|
initMoveable() {
|
|
249
360
|
this.moveable?.destroy();
|
|
@@ -265,7 +376,7 @@ class StageDragResize extends EventEmitter {
|
|
|
265
376
|
this.moveable.on("resizeStart", (e) => {
|
|
266
377
|
if (!this.target)
|
|
267
378
|
return;
|
|
268
|
-
this.dragStatus =
|
|
379
|
+
this.dragStatus = StageDragStatus.START;
|
|
269
380
|
this.moveableHelper?.onResizeStart(e);
|
|
270
381
|
frame.top = this.target.offsetTop;
|
|
271
382
|
frame.left = this.target.offsetLeft;
|
|
@@ -274,7 +385,7 @@ class StageDragResize extends EventEmitter {
|
|
|
274
385
|
if (!this.moveable || !this.target || !this.dragEl)
|
|
275
386
|
return;
|
|
276
387
|
const { beforeTranslate } = drag;
|
|
277
|
-
this.dragStatus =
|
|
388
|
+
this.dragStatus = StageDragStatus.ING;
|
|
278
389
|
this.moveableHelper?.onResize(e);
|
|
279
390
|
if (this.mode === Mode.SORTABLE) {
|
|
280
391
|
this.target.style.top = "0px";
|
|
@@ -285,7 +396,7 @@ class StageDragResize extends EventEmitter {
|
|
|
285
396
|
this.target.style.width = `${width}px`;
|
|
286
397
|
this.target.style.height = `${height}px`;
|
|
287
398
|
}).on("resizeEnd", () => {
|
|
288
|
-
this.dragStatus =
|
|
399
|
+
this.dragStatus = StageDragStatus.END;
|
|
289
400
|
this.update(true);
|
|
290
401
|
});
|
|
291
402
|
}
|
|
@@ -296,10 +407,13 @@ class StageDragResize extends EventEmitter {
|
|
|
296
407
|
left: 0,
|
|
297
408
|
top: 0
|
|
298
409
|
};
|
|
410
|
+
let timeout;
|
|
411
|
+
const { contentWindow } = this.core.renderer;
|
|
412
|
+
const doc = contentWindow?.document;
|
|
299
413
|
this.moveable.on("dragStart", (e) => {
|
|
300
414
|
if (!this.target)
|
|
301
415
|
throw new Error("\u672A\u9009\u4E2D\u7EC4\u4EF6");
|
|
302
|
-
this.dragStatus =
|
|
416
|
+
this.dragStatus = StageDragStatus.START;
|
|
303
417
|
this.moveableHelper?.onDragStart(e);
|
|
304
418
|
if (this.mode === Mode.SORTABLE) {
|
|
305
419
|
this.ghostEl = this.generateGhostEl(this.target);
|
|
@@ -309,7 +423,14 @@ class StageDragResize extends EventEmitter {
|
|
|
309
423
|
}).on("drag", (e) => {
|
|
310
424
|
if (!this.target || !this.dragEl)
|
|
311
425
|
return;
|
|
312
|
-
|
|
426
|
+
if (timeout) {
|
|
427
|
+
globalThis.clearTimeout(timeout);
|
|
428
|
+
timeout = void 0;
|
|
429
|
+
}
|
|
430
|
+
if (this.canContainerHighlight()) {
|
|
431
|
+
timeout = this.core.getAddContainerHighlightClassNameTimeout(e.inputEvent, [this.target]);
|
|
432
|
+
}
|
|
433
|
+
this.dragStatus = StageDragStatus.ING;
|
|
313
434
|
if (this.ghostEl) {
|
|
314
435
|
this.ghostEl.style.top = `${frame.top + e.beforeTranslate[1]}px`;
|
|
315
436
|
return;
|
|
@@ -318,16 +439,28 @@ class StageDragResize extends EventEmitter {
|
|
|
318
439
|
this.target.style.left = `${frame.left + e.beforeTranslate[0]}px`;
|
|
319
440
|
this.target.style.top = `${frame.top + e.beforeTranslate[1]}px`;
|
|
320
441
|
}).on("dragEnd", () => {
|
|
321
|
-
if (
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
442
|
+
if (timeout) {
|
|
443
|
+
globalThis.clearTimeout(timeout);
|
|
444
|
+
timeout = void 0;
|
|
445
|
+
}
|
|
446
|
+
let parentEl = null;
|
|
447
|
+
if (doc && this.canContainerHighlight()) {
|
|
448
|
+
parentEl = removeClassNameByClassName(doc, this.core.containerHighlightClassName);
|
|
449
|
+
}
|
|
450
|
+
if (this.dragStatus === StageDragStatus.ING) {
|
|
451
|
+
if (parentEl) {
|
|
452
|
+
this.update(false, parentEl);
|
|
453
|
+
} else {
|
|
454
|
+
switch (this.mode) {
|
|
455
|
+
case Mode.SORTABLE:
|
|
456
|
+
this.sort();
|
|
457
|
+
break;
|
|
458
|
+
default:
|
|
459
|
+
this.update();
|
|
460
|
+
}
|
|
328
461
|
}
|
|
329
462
|
}
|
|
330
|
-
this.dragStatus =
|
|
463
|
+
this.dragStatus = StageDragStatus.END;
|
|
331
464
|
this.destroyGhostEl();
|
|
332
465
|
});
|
|
333
466
|
}
|
|
@@ -335,17 +468,17 @@ class StageDragResize extends EventEmitter {
|
|
|
335
468
|
if (!this.moveable)
|
|
336
469
|
throw new Error("moveable \u672A\u521D\u59CB\u5316");
|
|
337
470
|
this.moveable.on("rotateStart", (e) => {
|
|
338
|
-
this.dragStatus =
|
|
471
|
+
this.dragStatus = StageDragStatus.START;
|
|
339
472
|
this.moveableHelper?.onRotateStart(e);
|
|
340
473
|
}).on("rotate", (e) => {
|
|
341
474
|
if (!this.target || !this.dragEl)
|
|
342
475
|
return;
|
|
343
|
-
this.dragStatus =
|
|
476
|
+
this.dragStatus = StageDragStatus.ING;
|
|
344
477
|
this.moveableHelper?.onRotate(e);
|
|
345
478
|
const frame = this.moveableHelper?.getFrame(e.target);
|
|
346
479
|
this.target.style.transform = frame?.toCSSObject().transform || "";
|
|
347
480
|
}).on("rotateEnd", (e) => {
|
|
348
|
-
this.dragStatus =
|
|
481
|
+
this.dragStatus = StageDragStatus.END;
|
|
349
482
|
const frame = this.moveableHelper?.getFrame(e.target);
|
|
350
483
|
this.emit("update", {
|
|
351
484
|
el: this.target,
|
|
@@ -359,17 +492,17 @@ class StageDragResize extends EventEmitter {
|
|
|
359
492
|
if (!this.moveable)
|
|
360
493
|
throw new Error("moveable \u672A\u521D\u59CB\u5316");
|
|
361
494
|
this.moveable.on("scaleStart", (e) => {
|
|
362
|
-
this.dragStatus =
|
|
495
|
+
this.dragStatus = StageDragStatus.START;
|
|
363
496
|
this.moveableHelper?.onScaleStart(e);
|
|
364
497
|
}).on("scale", (e) => {
|
|
365
498
|
if (!this.target || !this.dragEl)
|
|
366
499
|
return;
|
|
367
|
-
this.dragStatus =
|
|
500
|
+
this.dragStatus = StageDragStatus.ING;
|
|
368
501
|
this.moveableHelper?.onScale(e);
|
|
369
502
|
const frame = this.moveableHelper?.getFrame(e.target);
|
|
370
503
|
this.target.style.transform = frame?.toCSSObject().transform || "";
|
|
371
504
|
}).on("scaleEnd", (e) => {
|
|
372
|
-
this.dragStatus =
|
|
505
|
+
this.dragStatus = StageDragStatus.END;
|
|
373
506
|
const frame = this.moveableHelper?.getFrame(e.target);
|
|
374
507
|
this.emit("update", {
|
|
375
508
|
el: this.target,
|
|
@@ -398,17 +531,32 @@ class StageDragResize extends EventEmitter {
|
|
|
398
531
|
});
|
|
399
532
|
}
|
|
400
533
|
}
|
|
401
|
-
update(isResize = false) {
|
|
534
|
+
update(isResize = false, parentEl = null) {
|
|
402
535
|
if (!this.target)
|
|
403
536
|
return;
|
|
537
|
+
const { contentWindow } = this.core.renderer;
|
|
538
|
+
const doc = contentWindow?.document;
|
|
539
|
+
if (!doc)
|
|
540
|
+
return;
|
|
404
541
|
const offset = this.mode === Mode.SORTABLE ? { left: 0, top: 0 } : { left: this.target.offsetLeft, top: this.target.offsetTop };
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
const width =
|
|
408
|
-
const height =
|
|
542
|
+
let left = calcValueByFontsize(doc, offset.left);
|
|
543
|
+
let top = calcValueByFontsize(doc, offset.top);
|
|
544
|
+
const width = calcValueByFontsize(doc, this.target.clientWidth);
|
|
545
|
+
const height = calcValueByFontsize(doc, this.target.clientHeight);
|
|
546
|
+
if (parentEl && this.mode === Mode.ABSOLUTE && this.dragEl) {
|
|
547
|
+
const [translateX, translateY] = this.moveableHelper?.getFrame(this.dragEl).properties.transform.translate.value;
|
|
548
|
+
const { left: parentLeft, top: parentTop } = getOffset(parentEl);
|
|
549
|
+
left = calcValueByFontsize(doc, this.dragEl.offsetLeft) + parseFloat(translateX) - calcValueByFontsize(doc, parentLeft);
|
|
550
|
+
top = calcValueByFontsize(doc, this.dragEl.offsetTop) + parseFloat(translateY) - calcValueByFontsize(doc, parentTop);
|
|
551
|
+
}
|
|
409
552
|
this.emit("update", {
|
|
410
|
-
|
|
411
|
-
|
|
553
|
+
data: [
|
|
554
|
+
{
|
|
555
|
+
el: this.target,
|
|
556
|
+
style: isResize ? { left, top, width, height } : { left, top }
|
|
557
|
+
}
|
|
558
|
+
],
|
|
559
|
+
parentEl
|
|
412
560
|
});
|
|
413
561
|
}
|
|
414
562
|
generateGhostEl(el) {
|
|
@@ -416,6 +564,7 @@ class StageDragResize extends EventEmitter {
|
|
|
416
564
|
this.destroyGhostEl();
|
|
417
565
|
}
|
|
418
566
|
const ghostEl = el.cloneNode(true);
|
|
567
|
+
this.setGhostElChildrenId(ghostEl);
|
|
419
568
|
const { top, left } = getAbsolutePosition(el, getOffset(el));
|
|
420
569
|
ghostEl.id = `${GHOST_EL_ID_PREFIX}${el.id}`;
|
|
421
570
|
ghostEl.style.zIndex = ZIndex.GHOST_EL;
|
|
@@ -426,30 +575,20 @@ class StageDragResize extends EventEmitter {
|
|
|
426
575
|
el.after(ghostEl);
|
|
427
576
|
return ghostEl;
|
|
428
577
|
}
|
|
578
|
+
setGhostElChildrenId(el) {
|
|
579
|
+
for (const child of Array.from(el.children)) {
|
|
580
|
+
if (child.id) {
|
|
581
|
+
child.id = `${GHOST_EL_ID_PREFIX}${child.id}`;
|
|
582
|
+
}
|
|
583
|
+
if (child.children.length) {
|
|
584
|
+
this.setGhostElChildrenId(child);
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
}
|
|
429
588
|
destroyGhostEl() {
|
|
430
589
|
this.ghostEl?.remove();
|
|
431
590
|
this.ghostEl = void 0;
|
|
432
591
|
}
|
|
433
|
-
updateDragEl(el) {
|
|
434
|
-
const offset = getOffset(el);
|
|
435
|
-
const { transform } = getComputedStyle(el);
|
|
436
|
-
this.dragEl.style.cssText = `
|
|
437
|
-
position: absolute;
|
|
438
|
-
transform: ${transform};
|
|
439
|
-
left: ${offset.left}px;
|
|
440
|
-
top: ${offset.top}px;
|
|
441
|
-
width: ${el.clientWidth}px;
|
|
442
|
-
height: ${el.clientHeight}px;
|
|
443
|
-
z-index: ${ZIndex.DRAG_EL};
|
|
444
|
-
`;
|
|
445
|
-
this.dragEl.id = `${DRAG_EL_ID_PREFIX}${el.id}`;
|
|
446
|
-
if (typeof this.core.config.updateDragEl === "function") {
|
|
447
|
-
this.core.config.updateDragEl(this.dragEl, el);
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
destroyDragEl() {
|
|
451
|
-
this.dragEl?.remove();
|
|
452
|
-
}
|
|
453
592
|
getOptions(options = {}) {
|
|
454
593
|
if (!this.target)
|
|
455
594
|
return {};
|
|
@@ -500,7 +639,7 @@ class StageDragResize extends EventEmitter {
|
|
|
500
639
|
bounds: {
|
|
501
640
|
top: 0,
|
|
502
641
|
left: -1,
|
|
503
|
-
right: this.container.clientWidth,
|
|
642
|
+
right: this.container.clientWidth - 1,
|
|
504
643
|
bottom: this.container.clientHeight,
|
|
505
644
|
...moveableOptions.bounds || {}
|
|
506
645
|
},
|
|
@@ -508,64 +647,17 @@ class StageDragResize extends EventEmitter {
|
|
|
508
647
|
...moveableOptions
|
|
509
648
|
};
|
|
510
649
|
}
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
const fontSize = contentWindow?.document.documentElement.style.fontSize;
|
|
514
|
-
if (fontSize) {
|
|
515
|
-
const times = globalThis.parseFloat(fontSize) / 100;
|
|
516
|
-
return (value / times).toFixed(2);
|
|
517
|
-
}
|
|
518
|
-
return value;
|
|
650
|
+
canContainerHighlight() {
|
|
651
|
+
return this.core.containerHighlightType === ContainerHighlightType.DEFAULT || this.core.containerHighlightType === ContainerHighlightType.ALT && this.isContainerHighlight;
|
|
519
652
|
}
|
|
520
653
|
}
|
|
521
|
-
const down = (deltaTop, target) => {
|
|
522
|
-
let swapIndex = 0;
|
|
523
|
-
let addUpH = target.clientHeight;
|
|
524
|
-
const brothers = Array.from(target.parentNode?.children || []).filter((node) => !node.id.startsWith(GHOST_EL_ID_PREFIX));
|
|
525
|
-
const index = brothers.indexOf(target);
|
|
526
|
-
const downEls = brothers.slice(index + 1);
|
|
527
|
-
for (let i = 0; i < downEls.length; i++) {
|
|
528
|
-
const ele = downEls[i];
|
|
529
|
-
if (ele.style?.position === "fixed") {
|
|
530
|
-
continue;
|
|
531
|
-
}
|
|
532
|
-
addUpH += ele.clientHeight / 2;
|
|
533
|
-
if (deltaTop <= addUpH) {
|
|
534
|
-
break;
|
|
535
|
-
}
|
|
536
|
-
addUpH += ele.clientHeight / 2;
|
|
537
|
-
swapIndex = i;
|
|
538
|
-
}
|
|
539
|
-
return {
|
|
540
|
-
src: target.id,
|
|
541
|
-
dist: downEls.length && swapIndex > -1 ? downEls[swapIndex].id : target.id
|
|
542
|
-
};
|
|
543
|
-
};
|
|
544
|
-
const up = (deltaTop, target) => {
|
|
545
|
-
const brothers = Array.from(target.parentNode?.children || []).filter((node) => !node.id.startsWith(GHOST_EL_ID_PREFIX));
|
|
546
|
-
const index = brothers.indexOf(target);
|
|
547
|
-
const upEls = brothers.slice(0, index);
|
|
548
|
-
let addUpH = target.clientHeight;
|
|
549
|
-
let swapIndex = upEls.length - 1;
|
|
550
|
-
for (let i = upEls.length - 1; i >= 0; i--) {
|
|
551
|
-
const ele = upEls[i];
|
|
552
|
-
if (!ele)
|
|
553
|
-
continue;
|
|
554
|
-
if (ele.style.position === "fixed")
|
|
555
|
-
continue;
|
|
556
|
-
addUpH += ele.clientHeight / 2;
|
|
557
|
-
if (-deltaTop <= addUpH)
|
|
558
|
-
break;
|
|
559
|
-
addUpH += ele.clientHeight / 2;
|
|
560
|
-
swapIndex = i;
|
|
561
|
-
}
|
|
562
|
-
return {
|
|
563
|
-
src: target.id,
|
|
564
|
-
dist: upEls.length && swapIndex > -1 ? upEls[swapIndex].id : target.id
|
|
565
|
-
};
|
|
566
|
-
};
|
|
567
654
|
|
|
568
655
|
class TargetCalibrate extends EventEmitter {
|
|
656
|
+
parent;
|
|
657
|
+
mask;
|
|
658
|
+
dr;
|
|
659
|
+
core;
|
|
660
|
+
operationEl;
|
|
569
661
|
constructor(config) {
|
|
570
662
|
super();
|
|
571
663
|
this.parent = config.parent;
|
|
@@ -585,6 +677,7 @@ class TargetCalibrate extends EventEmitter {
|
|
|
585
677
|
top: ${top}px;
|
|
586
678
|
width: ${el.clientWidth}px;
|
|
587
679
|
height: ${el.clientHeight}px;
|
|
680
|
+
z-index: ${ZIndex.DRAG_EL};
|
|
588
681
|
`;
|
|
589
682
|
this.operationEl.id = `${prefix}${el.id}`;
|
|
590
683
|
if (typeof this.core.config.updateDragEl === "function") {
|
|
@@ -632,6 +725,11 @@ class TargetCalibrate extends EventEmitter {
|
|
|
632
725
|
}
|
|
633
726
|
|
|
634
727
|
class StageHighlight extends EventEmitter {
|
|
728
|
+
core;
|
|
729
|
+
container;
|
|
730
|
+
target;
|
|
731
|
+
moveable;
|
|
732
|
+
calibrationTarget;
|
|
635
733
|
constructor(config) {
|
|
636
734
|
super();
|
|
637
735
|
this.core = config.core;
|
|
@@ -652,7 +750,7 @@ class StageHighlight extends EventEmitter {
|
|
|
652
750
|
target: this.calibrationTarget.update(el, HIGHLIGHT_EL_ID_PREFIX),
|
|
653
751
|
origin: false,
|
|
654
752
|
rootContainer: this.core.container,
|
|
655
|
-
zoom:
|
|
753
|
+
zoom: 2
|
|
656
754
|
});
|
|
657
755
|
}
|
|
658
756
|
clearHighlight() {
|
|
@@ -669,41 +767,14 @@ class StageHighlight extends EventEmitter {
|
|
|
669
767
|
}
|
|
670
768
|
|
|
671
769
|
class Rule extends EventEmitter$1 {
|
|
770
|
+
hGuides;
|
|
771
|
+
vGuides;
|
|
772
|
+
horizontalGuidelines = [];
|
|
773
|
+
verticalGuidelines = [];
|
|
774
|
+
container;
|
|
775
|
+
containerResizeObserver;
|
|
672
776
|
constructor(container) {
|
|
673
777
|
super();
|
|
674
|
-
this.horizontalGuidelines = [];
|
|
675
|
-
this.verticalGuidelines = [];
|
|
676
|
-
this.getGuidesStyle = (type) => ({
|
|
677
|
-
position: "fixed",
|
|
678
|
-
zIndex: 1,
|
|
679
|
-
left: type === GuidesType.HORIZONTAL ? 0 : "-30px",
|
|
680
|
-
top: type === GuidesType.HORIZONTAL ? "-30px" : 0,
|
|
681
|
-
width: type === GuidesType.HORIZONTAL ? "100%" : "30px",
|
|
682
|
-
height: type === GuidesType.HORIZONTAL ? "30px" : "100%"
|
|
683
|
-
});
|
|
684
|
-
this.createGuides = (type, defaultGuides = []) => new Guides(this.container, {
|
|
685
|
-
type,
|
|
686
|
-
defaultGuides,
|
|
687
|
-
displayDragPos: true,
|
|
688
|
-
backgroundColor: "#fff",
|
|
689
|
-
lineColor: "#000",
|
|
690
|
-
textColor: "#000",
|
|
691
|
-
style: this.getGuidesStyle(type)
|
|
692
|
-
});
|
|
693
|
-
this.hGuidesChangeGuidesHandler = (e) => {
|
|
694
|
-
this.horizontalGuidelines = e.guides;
|
|
695
|
-
this.emit("changeGuides", {
|
|
696
|
-
type: GuidesType.HORIZONTAL,
|
|
697
|
-
guides: this.horizontalGuidelines
|
|
698
|
-
});
|
|
699
|
-
};
|
|
700
|
-
this.vGuidesChangeGuidesHandler = (e) => {
|
|
701
|
-
this.verticalGuidelines = e.guides;
|
|
702
|
-
this.emit("changeGuides", {
|
|
703
|
-
type: GuidesType.VERTICAL,
|
|
704
|
-
guides: this.verticalGuidelines
|
|
705
|
-
});
|
|
706
|
-
};
|
|
707
778
|
this.container = container;
|
|
708
779
|
this.hGuides = this.createGuides(GuidesType.HORIZONTAL, this.horizontalGuidelines);
|
|
709
780
|
this.vGuides = this.createGuides(GuidesType.VERTICAL, this.verticalGuidelines);
|
|
@@ -775,16 +846,43 @@ class Rule extends EventEmitter$1 {
|
|
|
775
846
|
this.containerResizeObserver.disconnect();
|
|
776
847
|
this.removeAllListeners();
|
|
777
848
|
}
|
|
849
|
+
getGuidesStyle = (type) => ({
|
|
850
|
+
position: "fixed",
|
|
851
|
+
zIndex: 1,
|
|
852
|
+
left: type === GuidesType.HORIZONTAL ? 0 : "-30px",
|
|
853
|
+
top: type === GuidesType.HORIZONTAL ? "-30px" : 0,
|
|
854
|
+
width: type === GuidesType.HORIZONTAL ? "100%" : "30px",
|
|
855
|
+
height: type === GuidesType.HORIZONTAL ? "30px" : "100%"
|
|
856
|
+
});
|
|
857
|
+
createGuides = (type, defaultGuides = []) => new Guides(this.container, {
|
|
858
|
+
type,
|
|
859
|
+
defaultGuides,
|
|
860
|
+
displayDragPos: true,
|
|
861
|
+
backgroundColor: "#fff",
|
|
862
|
+
lineColor: "#000",
|
|
863
|
+
textColor: "#000",
|
|
864
|
+
style: this.getGuidesStyle(type)
|
|
865
|
+
});
|
|
866
|
+
hGuidesChangeGuidesHandler = (e) => {
|
|
867
|
+
this.horizontalGuidelines = e.guides;
|
|
868
|
+
this.emit("changeGuides", {
|
|
869
|
+
type: GuidesType.HORIZONTAL,
|
|
870
|
+
guides: this.horizontalGuidelines
|
|
871
|
+
});
|
|
872
|
+
};
|
|
873
|
+
vGuidesChangeGuidesHandler = (e) => {
|
|
874
|
+
this.verticalGuidelines = e.guides;
|
|
875
|
+
this.emit("changeGuides", {
|
|
876
|
+
type: GuidesType.VERTICAL,
|
|
877
|
+
guides: this.verticalGuidelines
|
|
878
|
+
});
|
|
879
|
+
};
|
|
778
880
|
}
|
|
779
881
|
|
|
780
882
|
const wrapperClassName = "editor-mask-wrapper";
|
|
781
883
|
const throttleTime = 100;
|
|
782
884
|
const hideScrollbar = () => {
|
|
783
|
-
|
|
784
|
-
style.innerHTML = `
|
|
785
|
-
.${wrapperClassName}::-webkit-scrollbar { width: 0 !important; display: none }
|
|
786
|
-
`;
|
|
787
|
-
globalThis.document.head.appendChild(style);
|
|
885
|
+
injectStyle(globalThis.document, `.${wrapperClassName}::-webkit-scrollbar { width: 0 !important; display: none }`);
|
|
788
886
|
};
|
|
789
887
|
const createContent = () => createDiv({
|
|
790
888
|
className: "editor-mask",
|
|
@@ -812,66 +910,30 @@ const createWrapper = () => {
|
|
|
812
910
|
return el;
|
|
813
911
|
};
|
|
814
912
|
class StageMask extends Rule {
|
|
913
|
+
content = createContent();
|
|
914
|
+
wrapper;
|
|
915
|
+
core;
|
|
916
|
+
page = null;
|
|
917
|
+
pageScrollParent = null;
|
|
918
|
+
scrollTop = 0;
|
|
919
|
+
scrollLeft = 0;
|
|
920
|
+
width = 0;
|
|
921
|
+
height = 0;
|
|
922
|
+
wrapperHeight = 0;
|
|
923
|
+
wrapperWidth = 0;
|
|
924
|
+
maxScrollTop = 0;
|
|
925
|
+
maxScrollLeft = 0;
|
|
926
|
+
intersectionObserver = null;
|
|
927
|
+
isMultiSelectStatus = false;
|
|
928
|
+
mode = Mode.ABSOLUTE;
|
|
929
|
+
pageResizeObserver = null;
|
|
930
|
+
wrapperResizeObserver = null;
|
|
931
|
+
highlightHandler = throttle((event) => {
|
|
932
|
+
this.emit("highlight", event);
|
|
933
|
+
}, throttleTime);
|
|
815
934
|
constructor(config) {
|
|
816
935
|
const wrapper = createWrapper();
|
|
817
936
|
super(wrapper);
|
|
818
|
-
this.content = createContent();
|
|
819
|
-
this.page = null;
|
|
820
|
-
this.pageScrollParent = null;
|
|
821
|
-
this.scrollTop = 0;
|
|
822
|
-
this.scrollLeft = 0;
|
|
823
|
-
this.width = 0;
|
|
824
|
-
this.height = 0;
|
|
825
|
-
this.wrapperHeight = 0;
|
|
826
|
-
this.wrapperWidth = 0;
|
|
827
|
-
this.maxScrollTop = 0;
|
|
828
|
-
this.maxScrollLeft = 0;
|
|
829
|
-
this.intersectionObserver = null;
|
|
830
|
-
this.mode = Mode.ABSOLUTE;
|
|
831
|
-
this.pageResizeObserver = null;
|
|
832
|
-
this.wrapperResizeObserver = null;
|
|
833
|
-
this.highlightHandler = throttle((event) => {
|
|
834
|
-
this.emit("highlight", event);
|
|
835
|
-
}, throttleTime);
|
|
836
|
-
this.mouseDownHandler = (event) => {
|
|
837
|
-
this.emit("clearHighlight");
|
|
838
|
-
event.stopImmediatePropagation();
|
|
839
|
-
event.stopPropagation();
|
|
840
|
-
if (event.button !== MouseButton.LEFT && event.button !== MouseButton.RIGHT)
|
|
841
|
-
return;
|
|
842
|
-
if (event.target.className.indexOf("moveable-control") !== -1) {
|
|
843
|
-
return;
|
|
844
|
-
}
|
|
845
|
-
this.content.removeEventListener("mousemove", this.highlightHandler);
|
|
846
|
-
this.emit("beforeSelect", event);
|
|
847
|
-
globalThis.document.addEventListener("mouseup", this.mouseUpHandler);
|
|
848
|
-
};
|
|
849
|
-
this.mouseUpHandler = () => {
|
|
850
|
-
globalThis.document.removeEventListener("mouseup", this.mouseUpHandler);
|
|
851
|
-
this.content.addEventListener("mousemove", this.highlightHandler);
|
|
852
|
-
this.emit("select");
|
|
853
|
-
};
|
|
854
|
-
this.mouseWheelHandler = (event) => {
|
|
855
|
-
this.emit("clearHighlight");
|
|
856
|
-
if (!this.page)
|
|
857
|
-
throw new Error("page \u672A\u521D\u59CB\u5316");
|
|
858
|
-
const { deltaY, deltaX } = event;
|
|
859
|
-
if (this.page.clientHeight < this.wrapperHeight && deltaY)
|
|
860
|
-
return;
|
|
861
|
-
if (this.page.clientWidth < this.wrapperWidth && deltaX)
|
|
862
|
-
return;
|
|
863
|
-
if (this.maxScrollTop > 0) {
|
|
864
|
-
this.scrollTop = this.scrollTop + deltaY;
|
|
865
|
-
}
|
|
866
|
-
if (this.maxScrollLeft > 0) {
|
|
867
|
-
this.scrollLeft = this.scrollLeft + deltaX;
|
|
868
|
-
}
|
|
869
|
-
this.scroll();
|
|
870
|
-
this.emit("scroll", event);
|
|
871
|
-
};
|
|
872
|
-
this.mouseLeaveHandler = () => {
|
|
873
|
-
setTimeout(() => this.emit("clearHighlight"), throttleTime);
|
|
874
|
-
};
|
|
875
937
|
this.wrapper = wrapper;
|
|
876
938
|
this.core = config.core;
|
|
877
939
|
this.content.addEventListener("mousedown", this.mouseDownHandler);
|
|
@@ -879,6 +941,16 @@ class StageMask extends Rule {
|
|
|
879
941
|
this.content.addEventListener("wheel", this.mouseWheelHandler);
|
|
880
942
|
this.content.addEventListener("mousemove", this.highlightHandler);
|
|
881
943
|
this.content.addEventListener("mouseleave", this.mouseLeaveHandler);
|
|
944
|
+
const isMac = /mac os x/.test(navigator.userAgent.toLowerCase());
|
|
945
|
+
const ctrl = isMac ? "meta" : "ctrl";
|
|
946
|
+
KeyController.global.keydown(ctrl, (e) => {
|
|
947
|
+
e.inputEvent.preventDefault();
|
|
948
|
+
this.isMultiSelectStatus = true;
|
|
949
|
+
});
|
|
950
|
+
KeyController.global.keyup(ctrl, (e) => {
|
|
951
|
+
e.inputEvent.preventDefault();
|
|
952
|
+
this.isMultiSelectStatus = false;
|
|
953
|
+
});
|
|
882
954
|
}
|
|
883
955
|
setMode(mode) {
|
|
884
956
|
this.mode = mode;
|
|
@@ -1007,46 +1079,237 @@ class StageMask extends Rule {
|
|
|
1007
1079
|
if (this.maxScrollLeft < this.scrollLeft)
|
|
1008
1080
|
this.scrollLeft = this.maxScrollLeft;
|
|
1009
1081
|
}
|
|
1082
|
+
mouseDownHandler = (event) => {
|
|
1083
|
+
this.emit("clearHighlight");
|
|
1084
|
+
event.stopImmediatePropagation();
|
|
1085
|
+
event.stopPropagation();
|
|
1086
|
+
if (event.button !== MouseButton.LEFT && event.button !== MouseButton.RIGHT)
|
|
1087
|
+
return;
|
|
1088
|
+
if (!this.isMultiSelectStatus && event.target.className.indexOf("moveable-area") !== -1) {
|
|
1089
|
+
return;
|
|
1090
|
+
}
|
|
1091
|
+
if (event.target.className.indexOf("moveable-control") !== -1) {
|
|
1092
|
+
return;
|
|
1093
|
+
}
|
|
1094
|
+
this.content.removeEventListener("mousemove", this.highlightHandler);
|
|
1095
|
+
if (this.isMultiSelectStatus) {
|
|
1096
|
+
this.emit("beforeMultiSelect", event);
|
|
1097
|
+
} else {
|
|
1098
|
+
this.emit("beforeSelect", event);
|
|
1099
|
+
}
|
|
1100
|
+
globalThis.document.addEventListener("mouseup", this.mouseUpHandler);
|
|
1101
|
+
};
|
|
1102
|
+
mouseUpHandler = () => {
|
|
1103
|
+
globalThis.document.removeEventListener("mouseup", this.mouseUpHandler);
|
|
1104
|
+
this.content.addEventListener("mousemove", this.highlightHandler);
|
|
1105
|
+
if (!this.isMultiSelectStatus) {
|
|
1106
|
+
this.emit("select");
|
|
1107
|
+
}
|
|
1108
|
+
};
|
|
1109
|
+
mouseWheelHandler = (event) => {
|
|
1110
|
+
this.emit("clearHighlight");
|
|
1111
|
+
if (!this.page)
|
|
1112
|
+
throw new Error("page \u672A\u521D\u59CB\u5316");
|
|
1113
|
+
const { deltaY, deltaX } = event;
|
|
1114
|
+
if (this.page.clientHeight < this.wrapperHeight && deltaY)
|
|
1115
|
+
return;
|
|
1116
|
+
if (this.page.clientWidth < this.wrapperWidth && deltaX)
|
|
1117
|
+
return;
|
|
1118
|
+
if (this.maxScrollTop > 0) {
|
|
1119
|
+
this.scrollTop = this.scrollTop + deltaY;
|
|
1120
|
+
}
|
|
1121
|
+
if (this.maxScrollLeft > 0) {
|
|
1122
|
+
this.scrollLeft = this.scrollLeft + deltaX;
|
|
1123
|
+
}
|
|
1124
|
+
this.scroll();
|
|
1125
|
+
this.emit("scroll", event);
|
|
1126
|
+
};
|
|
1127
|
+
mouseLeaveHandler = () => {
|
|
1128
|
+
setTimeout(() => this.emit("clearHighlight"), throttleTime);
|
|
1129
|
+
};
|
|
1010
1130
|
}
|
|
1011
1131
|
|
|
1012
|
-
class
|
|
1013
|
-
|
|
1132
|
+
class StageMultiDragResize extends EventEmitter {
|
|
1133
|
+
core;
|
|
1134
|
+
mask;
|
|
1135
|
+
container;
|
|
1136
|
+
targetList = [];
|
|
1137
|
+
dragElList = [];
|
|
1138
|
+
moveableForMulti;
|
|
1139
|
+
dragStatus = StageDragStatus.END;
|
|
1140
|
+
multiMoveableHelper;
|
|
1141
|
+
constructor(config) {
|
|
1014
1142
|
super();
|
|
1015
|
-
this.
|
|
1016
|
-
this.
|
|
1017
|
-
this.
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1143
|
+
this.core = config.core;
|
|
1144
|
+
this.container = config.container;
|
|
1145
|
+
this.mask = config.mask;
|
|
1146
|
+
}
|
|
1147
|
+
multiSelect(els) {
|
|
1148
|
+
this.targetList = els;
|
|
1149
|
+
this.core.dr.destroyDragEl();
|
|
1150
|
+
this.destroyDragElList();
|
|
1151
|
+
this.dragElList = els.map((elItem) => {
|
|
1152
|
+
const dragElDiv = globalThis.document.createElement("div");
|
|
1153
|
+
this.container.append(dragElDiv);
|
|
1154
|
+
dragElDiv.style.cssText = getTargetElStyle(elItem);
|
|
1155
|
+
dragElDiv.id = `${DRAG_EL_ID_PREFIX}${elItem.id}`;
|
|
1156
|
+
if (typeof this.core.config.updateDragEl === "function") {
|
|
1157
|
+
this.core.config.updateDragEl(dragElDiv, elItem);
|
|
1023
1158
|
}
|
|
1159
|
+
return dragElDiv;
|
|
1024
1160
|
});
|
|
1025
|
-
this.
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1161
|
+
this.moveableForMulti?.destroy();
|
|
1162
|
+
this.multiMoveableHelper?.clear();
|
|
1163
|
+
this.moveableForMulti = new Moveable(this.container, this.getOptions({
|
|
1164
|
+
target: this.dragElList
|
|
1165
|
+
}));
|
|
1166
|
+
this.multiMoveableHelper = MoveableHelper.create({
|
|
1167
|
+
useBeforeRender: true,
|
|
1168
|
+
useRender: false,
|
|
1169
|
+
createAuto: true
|
|
1170
|
+
});
|
|
1171
|
+
const frames = [];
|
|
1172
|
+
this.moveableForMulti.on("dragGroupStart", (params) => {
|
|
1173
|
+
const { events } = params;
|
|
1174
|
+
this.multiMoveableHelper?.onDragGroupStart(params);
|
|
1175
|
+
events.forEach((ev) => {
|
|
1176
|
+
const matchEventTarget = this.targetList.find((targetItem) => targetItem.id === ev.target.id.replace(DRAG_EL_ID_PREFIX, ""));
|
|
1177
|
+
if (!matchEventTarget)
|
|
1178
|
+
return;
|
|
1179
|
+
frames.push({
|
|
1180
|
+
left: matchEventTarget.offsetLeft,
|
|
1181
|
+
top: matchEventTarget.offsetTop,
|
|
1182
|
+
id: matchEventTarget.id
|
|
1183
|
+
});
|
|
1034
1184
|
});
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1185
|
+
this.dragStatus = StageDragStatus.START;
|
|
1186
|
+
}).on("dragGroup", (params) => {
|
|
1187
|
+
const { events } = params;
|
|
1188
|
+
events.forEach((ev) => {
|
|
1189
|
+
const frameSnapShot = frames.find((frameItem) => frameItem.id === ev.target.id.replace(DRAG_EL_ID_PREFIX, ""));
|
|
1190
|
+
if (!frameSnapShot)
|
|
1191
|
+
return;
|
|
1192
|
+
const targeEl = this.targetList.find((targetItem) => targetItem.id === ev.target.id.replace(DRAG_EL_ID_PREFIX, ""));
|
|
1193
|
+
if (!targeEl)
|
|
1194
|
+
return;
|
|
1195
|
+
const isParentIncluded = this.targetList.find((targetItem) => targetItem.id === targeEl.parentElement?.id);
|
|
1196
|
+
if (!isParentIncluded) {
|
|
1197
|
+
targeEl.style.left = `${frameSnapShot.left + ev.beforeTranslate[0]}px`;
|
|
1198
|
+
targeEl.style.top = `${frameSnapShot.top + ev.beforeTranslate[1]}px`;
|
|
1043
1199
|
}
|
|
1200
|
+
});
|
|
1201
|
+
this.multiMoveableHelper?.onDragGroup(params);
|
|
1202
|
+
this.dragStatus = StageDragStatus.ING;
|
|
1203
|
+
}).on("dragGroupEnd", () => {
|
|
1204
|
+
this.update();
|
|
1205
|
+
this.dragStatus = StageDragStatus.END;
|
|
1206
|
+
}).on("clickGroup", (params) => {
|
|
1207
|
+
const { inputTarget, targets } = params;
|
|
1208
|
+
if (!this.mask.isMultiSelectStatus && targets.length > 1 && targets.includes(inputTarget)) {
|
|
1209
|
+
this.emit("select", inputTarget.id.replace(DRAG_EL_ID_PREFIX, ""));
|
|
1044
1210
|
}
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1211
|
+
});
|
|
1212
|
+
}
|
|
1213
|
+
canSelect(el, stop) {
|
|
1214
|
+
if (el.className.includes(PAGE_CLASS)) {
|
|
1215
|
+
this.core.highlightedDom = void 0;
|
|
1216
|
+
this.core.highlightLayer.clearHighlight();
|
|
1217
|
+
stop();
|
|
1218
|
+
return false;
|
|
1219
|
+
}
|
|
1220
|
+
const currentTargetMode = getMode(el);
|
|
1221
|
+
let selectedDomMode = "";
|
|
1222
|
+
if (this.core.selectedDom?.className.includes(PAGE_CLASS)) {
|
|
1223
|
+
return true;
|
|
1224
|
+
}
|
|
1225
|
+
if (this.targetList.length === 0 && this.core.selectedDom) {
|
|
1226
|
+
selectedDomMode = getMode(this.core.selectedDom);
|
|
1227
|
+
} else if (this.targetList.length > 0) {
|
|
1228
|
+
selectedDomMode = getMode(this.targetList[0]);
|
|
1229
|
+
}
|
|
1230
|
+
if (currentTargetMode !== selectedDomMode) {
|
|
1231
|
+
return false;
|
|
1232
|
+
}
|
|
1233
|
+
return true;
|
|
1234
|
+
}
|
|
1235
|
+
clearSelectStatus() {
|
|
1236
|
+
if (!this.moveableForMulti)
|
|
1237
|
+
return;
|
|
1238
|
+
this.destroyDragElList();
|
|
1239
|
+
this.moveableForMulti.target = null;
|
|
1240
|
+
this.moveableForMulti.updateTarget();
|
|
1241
|
+
this.targetList = [];
|
|
1242
|
+
}
|
|
1243
|
+
destroy() {
|
|
1244
|
+
this.moveableForMulti?.destroy();
|
|
1245
|
+
this.destroyDragElList();
|
|
1246
|
+
}
|
|
1247
|
+
destroyDragElList() {
|
|
1248
|
+
this.dragElList.forEach((dragElItem) => dragElItem?.remove());
|
|
1249
|
+
}
|
|
1250
|
+
update(isResize = false) {
|
|
1251
|
+
if (this.targetList.length === 0)
|
|
1252
|
+
return;
|
|
1253
|
+
const { contentWindow } = this.core.renderer;
|
|
1254
|
+
const doc = contentWindow?.document;
|
|
1255
|
+
if (!doc)
|
|
1256
|
+
return;
|
|
1257
|
+
this.emit("update", {
|
|
1258
|
+
data: this.targetList.map((targetItem) => {
|
|
1259
|
+
const offset = { left: targetItem.offsetLeft, top: targetItem.offsetTop };
|
|
1260
|
+
const left = calcValueByFontsize(doc, offset.left);
|
|
1261
|
+
const top = calcValueByFontsize(doc, offset.top);
|
|
1262
|
+
const width = calcValueByFontsize(doc, targetItem.clientWidth);
|
|
1263
|
+
const height = calcValueByFontsize(doc, targetItem.clientHeight);
|
|
1264
|
+
return {
|
|
1265
|
+
el: targetItem,
|
|
1266
|
+
style: isResize ? { left, top, width, height } : { left, top }
|
|
1267
|
+
};
|
|
1268
|
+
}),
|
|
1269
|
+
parentEl: null
|
|
1270
|
+
});
|
|
1271
|
+
}
|
|
1272
|
+
getOptions(options = {}) {
|
|
1273
|
+
let { multiMoveableOptions = {} } = this.core.config;
|
|
1274
|
+
if (typeof multiMoveableOptions === "function") {
|
|
1275
|
+
multiMoveableOptions = multiMoveableOptions(this.core);
|
|
1276
|
+
}
|
|
1277
|
+
return {
|
|
1278
|
+
defaultGroupRotate: 0,
|
|
1279
|
+
defaultGroupOrigin: "50% 50%",
|
|
1280
|
+
draggable: true,
|
|
1281
|
+
resizable: false,
|
|
1282
|
+
throttleDrag: 0,
|
|
1283
|
+
startDragRotate: 0,
|
|
1284
|
+
throttleDragRotate: 0,
|
|
1285
|
+
zoom: 1,
|
|
1286
|
+
origin: true,
|
|
1287
|
+
padding: { left: 0, top: 0, right: 0, bottom: 0 },
|
|
1288
|
+
snappable: true,
|
|
1289
|
+
bounds: {
|
|
1290
|
+
top: 0,
|
|
1291
|
+
left: -1,
|
|
1292
|
+
right: this.container.clientWidth - 1,
|
|
1293
|
+
bottom: this.container.clientHeight,
|
|
1294
|
+
...multiMoveableOptions.bounds || {}
|
|
1295
|
+
},
|
|
1296
|
+
...options,
|
|
1297
|
+
...multiMoveableOptions
|
|
1049
1298
|
};
|
|
1299
|
+
}
|
|
1300
|
+
}
|
|
1301
|
+
|
|
1302
|
+
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";
|
|
1303
|
+
|
|
1304
|
+
class StageRender extends EventEmitter {
|
|
1305
|
+
contentWindow = null;
|
|
1306
|
+
runtime = null;
|
|
1307
|
+
iframe;
|
|
1308
|
+
runtimeUrl;
|
|
1309
|
+
core;
|
|
1310
|
+
render;
|
|
1311
|
+
constructor({ core }) {
|
|
1312
|
+
super();
|
|
1050
1313
|
this.core = core;
|
|
1051
1314
|
this.runtimeUrl = core.config.runtimeUrl || "";
|
|
1052
1315
|
this.render = core.config.render;
|
|
@@ -1059,20 +1322,39 @@ class StageRender extends EventEmitter {
|
|
|
1059
1322
|
`;
|
|
1060
1323
|
this.iframe.addEventListener("load", this.loadHandler);
|
|
1061
1324
|
}
|
|
1325
|
+
getMagicApi = () => ({
|
|
1326
|
+
onPageElUpdate: (el) => this.emit("page-el-update", el),
|
|
1327
|
+
onRuntimeReady: (runtime) => {
|
|
1328
|
+
this.runtime = runtime;
|
|
1329
|
+
globalThis.runtime = runtime;
|
|
1330
|
+
this.emit("runtime-ready", runtime);
|
|
1331
|
+
}
|
|
1332
|
+
});
|
|
1062
1333
|
async mount(el) {
|
|
1063
|
-
if (this.iframe) {
|
|
1064
|
-
if (!isSameDomain(this.runtimeUrl) && this.runtimeUrl) {
|
|
1065
|
-
let html = await fetch(this.runtimeUrl).then((res) => res.text());
|
|
1066
|
-
const base = `${location.protocol}//${getHost(this.runtimeUrl)}`;
|
|
1067
|
-
html = html.replace("<head>", `<head>
|
|
1068
|
-
<base href="${base}">`);
|
|
1069
|
-
this.iframe.srcdoc = html;
|
|
1070
|
-
}
|
|
1071
|
-
el.appendChild(this.iframe);
|
|
1072
|
-
} else {
|
|
1334
|
+
if (!this.iframe) {
|
|
1073
1335
|
throw Error("mount \u5931\u8D25");
|
|
1074
1336
|
}
|
|
1075
|
-
|
|
1337
|
+
if (!isSameDomain(this.runtimeUrl) && this.runtimeUrl) {
|
|
1338
|
+
let html = await fetch(this.runtimeUrl).then((res) => res.text());
|
|
1339
|
+
const base = `${location.protocol}//${getHost(this.runtimeUrl)}`;
|
|
1340
|
+
html = html.replace("<head>", `<head>
|
|
1341
|
+
<base href="${base}">`);
|
|
1342
|
+
this.iframe.srcdoc = html;
|
|
1343
|
+
}
|
|
1344
|
+
el.appendChild(this.iframe);
|
|
1345
|
+
this.postTmagicRuntimeReady();
|
|
1346
|
+
}
|
|
1347
|
+
getRuntime = () => {
|
|
1348
|
+
if (this.runtime)
|
|
1349
|
+
return Promise.resolve(this.runtime);
|
|
1350
|
+
return new Promise((resolve) => {
|
|
1351
|
+
const listener = (runtime) => {
|
|
1352
|
+
this.off("runtime-ready", listener);
|
|
1353
|
+
resolve(runtime);
|
|
1354
|
+
};
|
|
1355
|
+
this.on("runtime-ready", listener);
|
|
1356
|
+
});
|
|
1357
|
+
};
|
|
1076
1358
|
destroy() {
|
|
1077
1359
|
this.iframe?.removeEventListener("load", this.loadHandler);
|
|
1078
1360
|
this.contentWindow = null;
|
|
@@ -1080,18 +1362,60 @@ class StageRender extends EventEmitter {
|
|
|
1080
1362
|
this.iframe = void 0;
|
|
1081
1363
|
this.removeAllListeners();
|
|
1082
1364
|
}
|
|
1365
|
+
loadHandler = async () => {
|
|
1366
|
+
if (!this.contentWindow?.magic) {
|
|
1367
|
+
this.postTmagicRuntimeReady();
|
|
1368
|
+
}
|
|
1369
|
+
if (!this.contentWindow)
|
|
1370
|
+
return;
|
|
1371
|
+
if (this.render) {
|
|
1372
|
+
const el = await this.render(this.core);
|
|
1373
|
+
if (el) {
|
|
1374
|
+
this.contentWindow.document?.body?.appendChild(el);
|
|
1375
|
+
}
|
|
1376
|
+
}
|
|
1377
|
+
this.emit("onload");
|
|
1378
|
+
injectStyle(this.contentWindow.document, style);
|
|
1379
|
+
};
|
|
1380
|
+
postTmagicRuntimeReady() {
|
|
1381
|
+
this.contentWindow = this.iframe?.contentWindow;
|
|
1382
|
+
this.contentWindow.magic = this.getMagicApi();
|
|
1383
|
+
this.contentWindow.postMessage({
|
|
1384
|
+
tmagicRuntimeReady: true
|
|
1385
|
+
}, "*");
|
|
1386
|
+
}
|
|
1083
1387
|
}
|
|
1084
1388
|
|
|
1085
1389
|
class StageCore extends EventEmitter {
|
|
1390
|
+
container;
|
|
1391
|
+
selectedDom;
|
|
1392
|
+
selectedDomList = [];
|
|
1393
|
+
highlightedDom;
|
|
1394
|
+
renderer;
|
|
1395
|
+
mask;
|
|
1396
|
+
dr;
|
|
1397
|
+
multiDr;
|
|
1398
|
+
highlightLayer;
|
|
1399
|
+
config;
|
|
1400
|
+
zoom = DEFAULT_ZOOM;
|
|
1401
|
+
containerHighlightClassName;
|
|
1402
|
+
containerHighlightDuration;
|
|
1403
|
+
containerHighlightType;
|
|
1404
|
+
isContainer;
|
|
1405
|
+
canSelect;
|
|
1086
1406
|
constructor(config) {
|
|
1087
1407
|
super();
|
|
1088
|
-
this.zoom = DEFAULT_ZOOM;
|
|
1089
1408
|
this.config = config;
|
|
1090
1409
|
this.setZoom(config.zoom);
|
|
1091
1410
|
this.canSelect = config.canSelect || ((el) => !!el.id);
|
|
1411
|
+
this.isContainer = config.isContainer;
|
|
1412
|
+
this.containerHighlightClassName = config.containerHighlightClassName || CONTAINER_HIGHLIGHT_CLASS;
|
|
1413
|
+
this.containerHighlightDuration = config.containerHighlightDuration || 800;
|
|
1414
|
+
this.containerHighlightType = config.containerHighlightType;
|
|
1092
1415
|
this.renderer = new StageRender({ core: this });
|
|
1093
1416
|
this.mask = new StageMask({ core: this });
|
|
1094
|
-
this.dr = new StageDragResize({ core: this, container: this.mask.content });
|
|
1417
|
+
this.dr = new StageDragResize({ core: this, container: this.mask.content, mask: this.mask });
|
|
1418
|
+
this.multiDr = new StageMultiDragResize({ core: this, container: this.mask.content, mask: this.mask });
|
|
1095
1419
|
this.highlightLayer = new StageHighlight({ core: this, container: this.mask.wrapper });
|
|
1096
1420
|
this.renderer.on("runtime-ready", (runtime) => {
|
|
1097
1421
|
this.emit("runtime-ready", runtime);
|
|
@@ -1099,31 +1423,61 @@ class StageCore extends EventEmitter {
|
|
|
1099
1423
|
this.renderer.on("page-el-update", (el) => {
|
|
1100
1424
|
this.mask?.observe(el);
|
|
1101
1425
|
});
|
|
1102
|
-
this.mask.on("beforeSelect", (event) => {
|
|
1103
|
-
this.
|
|
1426
|
+
this.mask.on("beforeSelect", async (event) => {
|
|
1427
|
+
this.clearSelectStatus("multiSelect");
|
|
1428
|
+
const el = await this.getElementFromPoint(event);
|
|
1429
|
+
if (!el)
|
|
1430
|
+
return;
|
|
1431
|
+
this.select(el, event);
|
|
1104
1432
|
}).on("select", () => {
|
|
1105
1433
|
this.emit("select", this.selectedDom);
|
|
1106
1434
|
}).on("changeGuides", (data) => {
|
|
1107
1435
|
this.dr.setGuidelines(data.type, data.guides);
|
|
1108
1436
|
this.emit("changeGuides", data);
|
|
1109
1437
|
}).on("highlight", async (event) => {
|
|
1110
|
-
await this.
|
|
1438
|
+
const el = await this.getElementFromPoint(event);
|
|
1439
|
+
if (!el)
|
|
1440
|
+
return;
|
|
1441
|
+
if (this.multiDr.dragStatus === StageDragStatus.ING)
|
|
1442
|
+
return;
|
|
1443
|
+
await this.highlight(el);
|
|
1111
1444
|
if (this.highlightedDom === this.selectedDom) {
|
|
1112
1445
|
this.highlightLayer.clearHighlight();
|
|
1113
1446
|
return;
|
|
1114
1447
|
}
|
|
1115
|
-
this.highlightLayer.highlight(this.highlightedDom);
|
|
1116
1448
|
this.emit("highlight", this.highlightedDom);
|
|
1117
1449
|
}).on("clearHighlight", async () => {
|
|
1118
1450
|
this.highlightLayer.clearHighlight();
|
|
1451
|
+
}).on("beforeMultiSelect", async (event) => {
|
|
1452
|
+
const el = await this.getElementFromPoint(event);
|
|
1453
|
+
if (!el)
|
|
1454
|
+
return;
|
|
1455
|
+
if (this.selectedDom && !this.selectedDom.className.includes(PAGE_CLASS)) {
|
|
1456
|
+
this.selectedDomList.push(this.selectedDom);
|
|
1457
|
+
this.selectedDom = void 0;
|
|
1458
|
+
}
|
|
1459
|
+
const existIndex = this.selectedDomList.findIndex((selectedDom) => selectedDom.id === el.id);
|
|
1460
|
+
if (existIndex !== -1) {
|
|
1461
|
+
this.selectedDomList.splice(existIndex, 1);
|
|
1462
|
+
} else {
|
|
1463
|
+
this.selectedDomList.push(el);
|
|
1464
|
+
}
|
|
1465
|
+
this.multiSelect(this.selectedDomList);
|
|
1119
1466
|
});
|
|
1120
1467
|
this.dr.on("update", (data) => {
|
|
1121
1468
|
setTimeout(() => this.emit("update", data));
|
|
1122
1469
|
}).on("sort", (data) => {
|
|
1123
1470
|
setTimeout(() => this.emit("sort", data));
|
|
1124
1471
|
});
|
|
1472
|
+
this.multiDr.on("update", (data) => {
|
|
1473
|
+
setTimeout(() => this.emit("update", data));
|
|
1474
|
+
}).on("select", async (id) => {
|
|
1475
|
+
const el = await this.getTargetElement(id);
|
|
1476
|
+
this.select(el);
|
|
1477
|
+
setTimeout(() => this.emit("select", el));
|
|
1478
|
+
});
|
|
1125
1479
|
}
|
|
1126
|
-
|
|
1480
|
+
getElementsFromPoint(event) {
|
|
1127
1481
|
const { renderer, zoom } = this;
|
|
1128
1482
|
const doc = renderer.contentWindow?.document;
|
|
1129
1483
|
let x = event.clientX;
|
|
@@ -1135,23 +1489,31 @@ class StageCore extends EventEmitter {
|
|
|
1135
1489
|
y = y - rect.top;
|
|
1136
1490
|
}
|
|
1137
1491
|
}
|
|
1138
|
-
|
|
1492
|
+
return doc?.elementsFromPoint(x / zoom, y / zoom);
|
|
1493
|
+
}
|
|
1494
|
+
async getElementFromPoint(event) {
|
|
1495
|
+
const els = this.getElementsFromPoint(event);
|
|
1139
1496
|
let stopped = false;
|
|
1140
1497
|
const stop = () => stopped = true;
|
|
1141
1498
|
for (const el of els) {
|
|
1142
|
-
if (!el.id.startsWith(GHOST_EL_ID_PREFIX) && await this.
|
|
1499
|
+
if (!el.id.startsWith(GHOST_EL_ID_PREFIX) && await this.isElCanSelect(el, event, stop)) {
|
|
1143
1500
|
if (stopped)
|
|
1144
1501
|
break;
|
|
1145
|
-
|
|
1146
|
-
this.highlight(el);
|
|
1147
|
-
break;
|
|
1148
|
-
}
|
|
1149
|
-
this.select(el, event);
|
|
1150
|
-
break;
|
|
1502
|
+
return el;
|
|
1151
1503
|
}
|
|
1152
1504
|
}
|
|
1153
1505
|
}
|
|
1506
|
+
async isElCanSelect(el, event, stop) {
|
|
1507
|
+
const canSelectByProp = await this.canSelect(el, event, stop);
|
|
1508
|
+
if (!canSelectByProp)
|
|
1509
|
+
return false;
|
|
1510
|
+
if (this.mask.isMultiSelectStatus) {
|
|
1511
|
+
return this.multiDr.canSelect(el, stop);
|
|
1512
|
+
}
|
|
1513
|
+
return true;
|
|
1514
|
+
}
|
|
1154
1515
|
async select(idOrEl, event) {
|
|
1516
|
+
this.clearSelectStatus("multiSelect");
|
|
1155
1517
|
const el = await this.getTargetElement(idOrEl);
|
|
1156
1518
|
if (el === this.selectedDom)
|
|
1157
1519
|
return;
|
|
@@ -1173,6 +1535,12 @@ class StageCore extends EventEmitter {
|
|
|
1173
1535
|
}
|
|
1174
1536
|
}
|
|
1175
1537
|
}
|
|
1538
|
+
async multiSelect(idOrElList) {
|
|
1539
|
+
this.clearSelectStatus("select");
|
|
1540
|
+
const elList = await Promise.all(idOrElList.map(async (idOrEl) => await this.getTargetElement(idOrEl)));
|
|
1541
|
+
this.multiDr.multiSelect(elList);
|
|
1542
|
+
this.emit("multiSelect", elList);
|
|
1543
|
+
}
|
|
1176
1544
|
update(data) {
|
|
1177
1545
|
const { config } = data;
|
|
1178
1546
|
return this.renderer?.getRuntime().then((runtime) => {
|
|
@@ -1195,7 +1563,7 @@ class StageCore extends EventEmitter {
|
|
|
1195
1563
|
this.highlightLayer.clearHighlight();
|
|
1196
1564
|
return;
|
|
1197
1565
|
}
|
|
1198
|
-
if (el === this.highlightedDom)
|
|
1566
|
+
if (el === this.highlightedDom || !el)
|
|
1199
1567
|
return;
|
|
1200
1568
|
this.highlightLayer.highlight(el);
|
|
1201
1569
|
this.highlightedDom = el;
|
|
@@ -1212,6 +1580,14 @@ class StageCore extends EventEmitter {
|
|
|
1212
1580
|
setZoom(zoom = DEFAULT_ZOOM) {
|
|
1213
1581
|
this.zoom = zoom;
|
|
1214
1582
|
}
|
|
1583
|
+
clearSelectStatus(selectType) {
|
|
1584
|
+
if (selectType === "multiSelect") {
|
|
1585
|
+
this.multiDr.clearSelectStatus();
|
|
1586
|
+
this.selectedDomList = [];
|
|
1587
|
+
} else {
|
|
1588
|
+
this.dr.clearSelectStatus();
|
|
1589
|
+
}
|
|
1590
|
+
}
|
|
1215
1591
|
async mount(el) {
|
|
1216
1592
|
this.container = el;
|
|
1217
1593
|
const { mask, renderer } = this;
|
|
@@ -1223,6 +1599,24 @@ class StageCore extends EventEmitter {
|
|
|
1223
1599
|
this.mask.clearGuides();
|
|
1224
1600
|
this.dr.clearGuides();
|
|
1225
1601
|
}
|
|
1602
|
+
async addContainerHighlightClassName(event, exclude) {
|
|
1603
|
+
const els = this.getElementsFromPoint(event);
|
|
1604
|
+
const { renderer } = this;
|
|
1605
|
+
const doc = renderer.contentWindow?.document;
|
|
1606
|
+
if (!doc)
|
|
1607
|
+
return;
|
|
1608
|
+
for (const el of els) {
|
|
1609
|
+
if (!el.id.startsWith(GHOST_EL_ID_PREFIX) && await this.isContainer(el) && !exclude.includes(el)) {
|
|
1610
|
+
addClassName(el, doc, this.containerHighlightClassName);
|
|
1611
|
+
break;
|
|
1612
|
+
}
|
|
1613
|
+
}
|
|
1614
|
+
}
|
|
1615
|
+
getAddContainerHighlightClassNameTimeout(event, exclude = []) {
|
|
1616
|
+
return globalThis.setTimeout(() => {
|
|
1617
|
+
this.addContainerHighlightClassName(event, exclude);
|
|
1618
|
+
}, this.containerHighlightDuration);
|
|
1619
|
+
}
|
|
1226
1620
|
destroy() {
|
|
1227
1621
|
const { mask, renderer, dr, highlightLayer } = this;
|
|
1228
1622
|
renderer.destroy();
|
|
@@ -1243,5 +1637,5 @@ class StageCore extends EventEmitter {
|
|
|
1243
1637
|
}
|
|
1244
1638
|
}
|
|
1245
1639
|
|
|
1246
|
-
export { DEFAULT_ZOOM, DRAG_EL_ID_PREFIX, GHOST_EL_ID_PREFIX, GuidesType, HIGHLIGHT_EL_ID_PREFIX, Mode, MouseButton, SELECTED_CLASS, StageDragResize, StageMask, StageRender, ZIndex, StageCore as default };
|
|
1247
|
-
//# sourceMappingURL=tmagic-stage.
|
|
1640
|
+
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 };
|
|
1641
|
+
//# sourceMappingURL=tmagic-stage.mjs.map
|