@tmagic/stage 1.0.0-beta.8 → 1.0.0-rc.2
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/README.md +1 -0
- package/dist/tmagic-stage.es.js +482 -220
- package/dist/tmagic-stage.es.js.map +1 -1
- package/dist/tmagic-stage.umd.js +486 -226
- package/dist/tmagic-stage.umd.js.map +1 -1
- package/dist/types/src/StageCore.d.ts +14 -4
- package/dist/types/src/StageDragResize.d.ts +9 -6
- package/dist/types/src/StageHighlight.d.ts +27 -0
- package/dist/types/src/StageMask.d.ts +22 -0
- package/dist/types/src/TargetCalibrate.d.ts +18 -0
- package/dist/types/src/const.d.ts +5 -1
- package/dist/types/src/types.d.ts +13 -2
- package/dist/types/src/util.d.ts +2 -0
- package/package.json +12 -7
- package/src/StageCore.ts +87 -24
- package/src/StageDragResize.ts +110 -59
- package/src/StageHighlight.ts +81 -0
- package/src/StageMask.ts +84 -25
- package/src/StageRender.ts +13 -0
- package/src/TargetCalibrate.ts +135 -0
- package/src/const.ts +7 -0
- package/src/types.ts +15 -3
- package/src/util.ts +31 -1
- package/tsconfig.json +0 -9
- package/vite.config.ts +0 -27
package/dist/tmagic-stage.es.js
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import EventEmitter$1, { EventEmitter } from 'events';
|
|
2
2
|
import Moveable from 'moveable';
|
|
3
|
+
import MoveableHelper from 'moveable-helper';
|
|
4
|
+
import { throttle } from 'lodash-es';
|
|
3
5
|
import Guides from '@scena/guides';
|
|
4
6
|
|
|
5
7
|
const GHOST_EL_ID_PREFIX = "ghost_el_";
|
|
8
|
+
const DRAG_EL_ID_PREFIX = "drag_el_";
|
|
9
|
+
const HIGHLIGHT_EL_ID_PREFIX = "highlight_el_";
|
|
6
10
|
const DEFAULT_ZOOM = 1;
|
|
7
11
|
var GuidesType = /* @__PURE__ */ ((GuidesType2) => {
|
|
8
12
|
GuidesType2["HORIZONTAL"] = "horizontal";
|
|
@@ -11,6 +15,7 @@ var GuidesType = /* @__PURE__ */ ((GuidesType2) => {
|
|
|
11
15
|
})(GuidesType || {});
|
|
12
16
|
var ZIndex = /* @__PURE__ */ ((ZIndex2) => {
|
|
13
17
|
ZIndex2["MASK"] = "99999";
|
|
18
|
+
ZIndex2["SELECTED_EL"] = "666";
|
|
14
19
|
return ZIndex2;
|
|
15
20
|
})(ZIndex || {});
|
|
16
21
|
var MouseButton = /* @__PURE__ */ ((MouseButton2) => {
|
|
@@ -25,7 +30,17 @@ var Mode = /* @__PURE__ */ ((Mode2) => {
|
|
|
25
30
|
Mode2["SORTABLE"] = "sortable";
|
|
26
31
|
return Mode2;
|
|
27
32
|
})(Mode || {});
|
|
33
|
+
const SELECTED_CLASS = "tmagic-stage-selected-area";
|
|
28
34
|
|
|
35
|
+
const getParents = (el, relative) => {
|
|
36
|
+
let cur = el.parentElement;
|
|
37
|
+
const parents = [];
|
|
38
|
+
while (cur && cur !== relative) {
|
|
39
|
+
parents.push(cur);
|
|
40
|
+
cur = cur.parentElement;
|
|
41
|
+
}
|
|
42
|
+
return parents;
|
|
43
|
+
};
|
|
29
44
|
const getOffset = (el) => {
|
|
30
45
|
const { transform } = getComputedStyle(el);
|
|
31
46
|
const { offsetParent } = el;
|
|
@@ -145,46 +160,64 @@ const createDiv = ({ className, cssText }) => {
|
|
|
145
160
|
el.style.cssText = cssText;
|
|
146
161
|
return el;
|
|
147
162
|
};
|
|
163
|
+
const removeSelectedClassName = (doc) => {
|
|
164
|
+
const oldEl = doc.querySelector(`.${SELECTED_CLASS}`);
|
|
165
|
+
if (oldEl) {
|
|
166
|
+
oldEl.classList.remove(SELECTED_CLASS);
|
|
167
|
+
oldEl.parentNode?.classList.remove(`${SELECTED_CLASS}-parent`);
|
|
168
|
+
doc.querySelectorAll(`.${SELECTED_CLASS}-parents`).forEach((item) => {
|
|
169
|
+
item.classList.remove(`${SELECTED_CLASS}-parents`);
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
const addSelectedClassName = (el, doc) => {
|
|
174
|
+
el.classList.add(SELECTED_CLASS);
|
|
175
|
+
el.parentNode?.classList.add(`${SELECTED_CLASS}-parent`);
|
|
176
|
+
getParents(el, doc.body).forEach((item) => {
|
|
177
|
+
item.classList.add(`${SELECTED_CLASS}-parents`);
|
|
178
|
+
});
|
|
179
|
+
};
|
|
148
180
|
|
|
149
181
|
class StageDragResize extends EventEmitter {
|
|
150
|
-
core;
|
|
151
|
-
container;
|
|
152
|
-
target;
|
|
153
|
-
dragEl;
|
|
154
|
-
moveable;
|
|
155
|
-
horizontalGuidelines = [];
|
|
156
|
-
verticalGuidelines = [];
|
|
157
|
-
moveableOptions = {};
|
|
158
|
-
dragStatus = "end" /* END */;
|
|
159
|
-
ghostEl;
|
|
160
|
-
mode = Mode.ABSOLUTE;
|
|
161
182
|
constructor(config) {
|
|
162
183
|
super();
|
|
184
|
+
this.horizontalGuidelines = [];
|
|
185
|
+
this.verticalGuidelines = [];
|
|
186
|
+
this.elementGuidelines = [];
|
|
187
|
+
this.mode = Mode.ABSOLUTE;
|
|
188
|
+
this.moveableOptions = {};
|
|
189
|
+
this.dragStatus = "end" /* END */;
|
|
163
190
|
this.core = config.core;
|
|
164
191
|
this.container = config.container;
|
|
192
|
+
this.dragEl = globalThis.document.createElement("div");
|
|
193
|
+
this.container.append(this.dragEl);
|
|
165
194
|
}
|
|
166
|
-
|
|
195
|
+
select(el, event) {
|
|
196
|
+
const oldTarget = this.target;
|
|
167
197
|
this.target = el;
|
|
168
|
-
|
|
169
|
-
|
|
198
|
+
this.init(el);
|
|
199
|
+
if (!this.moveable || this.target !== oldTarget) {
|
|
200
|
+
this.moveableHelper = MoveableHelper.create({
|
|
201
|
+
useBeforeRender: true,
|
|
202
|
+
useRender: false,
|
|
203
|
+
createAuto: true
|
|
204
|
+
});
|
|
205
|
+
this.initMoveable();
|
|
206
|
+
} else {
|
|
207
|
+
this.updateMoveable();
|
|
170
208
|
}
|
|
171
|
-
this.mode = getMode(el);
|
|
172
|
-
this.destroyDragEl();
|
|
173
|
-
this.destroyGhostEl();
|
|
174
|
-
this.dragEl = this.generateDragEl(el);
|
|
175
|
-
this.moveableOptions = await this.getOptions({
|
|
176
|
-
target: this.dragEl || this.target
|
|
177
|
-
});
|
|
178
|
-
this.initMoveable();
|
|
179
209
|
if (event) {
|
|
180
210
|
this.moveable?.dragStart(event);
|
|
181
211
|
}
|
|
182
212
|
}
|
|
183
|
-
|
|
213
|
+
updateMoveable(el = this.target) {
|
|
184
214
|
if (!this.moveable)
|
|
185
215
|
throw new Error("\u672A\u521D\u59CB\u5316moveable");
|
|
186
|
-
|
|
187
|
-
|
|
216
|
+
if (!el)
|
|
217
|
+
throw new Error("\u4E3A\u9009\u4E2D\u4EFB\u4F55\u8282\u70B9");
|
|
218
|
+
this.target = el;
|
|
219
|
+
this.init(el);
|
|
220
|
+
Object.entries(this.moveableOptions).forEach(([key, value]) => {
|
|
188
221
|
this.moveable[key] = value;
|
|
189
222
|
});
|
|
190
223
|
this.moveable.updateTarget();
|
|
@@ -192,15 +225,19 @@ class StageDragResize extends EventEmitter {
|
|
|
192
225
|
setGuidelines(type, guidelines) {
|
|
193
226
|
if (type === GuidesType.HORIZONTAL) {
|
|
194
227
|
this.horizontalGuidelines = guidelines;
|
|
228
|
+
this.moveableOptions.horizontalGuidelines = guidelines;
|
|
195
229
|
} else if (type === GuidesType.VERTICAL) {
|
|
196
230
|
this.verticalGuidelines = guidelines;
|
|
231
|
+
this.moveableOptions.verticalGuidelines = guidelines;
|
|
197
232
|
}
|
|
198
|
-
this.
|
|
233
|
+
this.updateMoveable();
|
|
199
234
|
}
|
|
200
235
|
clearGuides() {
|
|
201
|
-
this.verticalGuidelines = [];
|
|
202
236
|
this.horizontalGuidelines = [];
|
|
203
|
-
this.
|
|
237
|
+
this.verticalGuidelines = [];
|
|
238
|
+
this.moveableOptions.horizontalGuidelines = [];
|
|
239
|
+
this.moveableOptions.verticalGuidelines = [];
|
|
240
|
+
this.updateMoveable();
|
|
204
241
|
}
|
|
205
242
|
destroy() {
|
|
206
243
|
this.moveable?.destroy();
|
|
@@ -209,6 +246,17 @@ class StageDragResize extends EventEmitter {
|
|
|
209
246
|
this.dragStatus = "end" /* END */;
|
|
210
247
|
this.removeAllListeners();
|
|
211
248
|
}
|
|
249
|
+
init(el) {
|
|
250
|
+
if (/(auto|scroll)/.test(el.style.overflow)) {
|
|
251
|
+
el.style.overflow = "hidden";
|
|
252
|
+
}
|
|
253
|
+
this.mode = getMode(el);
|
|
254
|
+
this.destroyGhostEl();
|
|
255
|
+
this.updateDragEl(el);
|
|
256
|
+
this.moveableOptions = this.getOptions({
|
|
257
|
+
target: this.dragEl
|
|
258
|
+
});
|
|
259
|
+
}
|
|
212
260
|
initMoveable() {
|
|
213
261
|
this.moveable?.destroy();
|
|
214
262
|
this.moveable = new Moveable(this.container, {
|
|
@@ -253,27 +301,31 @@ class StageDragResize extends EventEmitter {
|
|
|
253
301
|
bindDragEvent() {
|
|
254
302
|
if (!this.moveable)
|
|
255
303
|
throw new Error("moveable \u4E3A\u521D\u59CB\u5316");
|
|
256
|
-
|
|
304
|
+
let offset = null;
|
|
305
|
+
this.moveable.on("dragStart", (e) => {
|
|
257
306
|
if (!this.target)
|
|
258
307
|
throw new Error("\u672A\u9009\u4E2D\u7EC4\u4EF6");
|
|
259
308
|
this.dragStatus = "start" /* START */;
|
|
309
|
+
this.moveableHelper?.onDragStart(e);
|
|
260
310
|
if (this.mode === Mode.SORTABLE) {
|
|
261
311
|
this.ghostEl = this.generateGhostEl(this.target);
|
|
262
312
|
}
|
|
263
|
-
}).on("drag", (
|
|
313
|
+
}).on("drag", (e) => {
|
|
264
314
|
if (!this.target || !this.dragEl)
|
|
265
315
|
return;
|
|
316
|
+
if (!offset) {
|
|
317
|
+
offset = getAbsolutePosition(this.target, { left: 0, top: 0 });
|
|
318
|
+
}
|
|
266
319
|
this.dragStatus = "ing" /* ING */;
|
|
267
|
-
const
|
|
320
|
+
const { left, top } = e;
|
|
268
321
|
if (this.ghostEl) {
|
|
269
322
|
this.dragEl.style.top = `${top}px`;
|
|
270
|
-
this.ghostEl.style.top = `${offset.top}px`;
|
|
323
|
+
this.ghostEl.style.top = `${top + offset.top}px`;
|
|
271
324
|
return;
|
|
272
325
|
}
|
|
273
|
-
this.
|
|
274
|
-
this.
|
|
275
|
-
this.target.style.
|
|
276
|
-
this.target.style.top = `${offset.top}px`;
|
|
326
|
+
this.moveableHelper?.onDrag(e);
|
|
327
|
+
this.target.style.left = `${left + offset.left}px`;
|
|
328
|
+
this.target.style.top = `${top + offset.top}px`;
|
|
277
329
|
}).on("dragEnd", () => {
|
|
278
330
|
if (this.dragStatus === "ing" /* ING */) {
|
|
279
331
|
switch (this.mode) {
|
|
@@ -284,17 +336,18 @@ class StageDragResize extends EventEmitter {
|
|
|
284
336
|
this.update();
|
|
285
337
|
}
|
|
286
338
|
}
|
|
339
|
+
offset = null;
|
|
287
340
|
this.dragStatus = "end" /* END */;
|
|
288
341
|
this.destroyGhostEl();
|
|
289
342
|
});
|
|
290
343
|
}
|
|
291
|
-
|
|
292
|
-
const { renderer } = this.core;
|
|
293
|
-
const getSnapElements =
|
|
344
|
+
getSnapElements(runtime, el) {
|
|
345
|
+
const { renderer, mask } = this.core;
|
|
346
|
+
const getSnapElements = runtime?.getSnapElements || (() => {
|
|
294
347
|
const doc = renderer.contentWindow?.document;
|
|
295
348
|
return doc ? Array.from(doc.querySelectorAll("[id]")) : [];
|
|
296
349
|
});
|
|
297
|
-
return getSnapElements(el).filter((element) => element !== this.target && !this.target?.contains(element));
|
|
350
|
+
return getSnapElements(el).filter((element) => element !== this.target && !this.target?.contains(element) && element !== mask.page);
|
|
298
351
|
}
|
|
299
352
|
sort() {
|
|
300
353
|
if (!this.target || !this.ghostEl)
|
|
@@ -333,7 +386,7 @@ class StageDragResize extends EventEmitter {
|
|
|
333
386
|
}
|
|
334
387
|
const ghostEl = el.cloneNode(true);
|
|
335
388
|
const { top, left } = getAbsolutePosition(el, getOffset(el));
|
|
336
|
-
ghostEl.id = `${GHOST_EL_ID_PREFIX}${
|
|
389
|
+
ghostEl.id = `${GHOST_EL_ID_PREFIX}${el.id}`;
|
|
337
390
|
ghostEl.style.zIndex = "5";
|
|
338
391
|
ghostEl.style.opacity = ".5";
|
|
339
392
|
ghostEl.style.position = "absolute";
|
|
@@ -346,49 +399,62 @@ class StageDragResize extends EventEmitter {
|
|
|
346
399
|
this.ghostEl?.remove();
|
|
347
400
|
this.ghostEl = void 0;
|
|
348
401
|
}
|
|
349
|
-
|
|
350
|
-
if (this.dragEl) {
|
|
351
|
-
this.destroyDragEl();
|
|
352
|
-
}
|
|
402
|
+
updateDragEl(el) {
|
|
353
403
|
const { width, height } = el.getBoundingClientRect();
|
|
354
404
|
const offset = getOffset(el);
|
|
355
|
-
|
|
356
|
-
dragEl.style.cssText = `
|
|
405
|
+
this.dragEl.style.cssText = `
|
|
357
406
|
position: absolute;
|
|
358
407
|
left: ${offset.left}px;
|
|
359
408
|
top: ${offset.top}px;
|
|
360
409
|
width: ${width}px;
|
|
361
410
|
height: ${height}px;
|
|
411
|
+
z-index: 9;
|
|
362
412
|
`;
|
|
363
|
-
this.
|
|
364
|
-
return dragEl;
|
|
413
|
+
this.dragEl.id = `${DRAG_EL_ID_PREFIX}${el.id}`;
|
|
365
414
|
}
|
|
366
415
|
destroyDragEl() {
|
|
367
416
|
this.dragEl?.remove();
|
|
368
|
-
this.dragEl = void 0;
|
|
369
417
|
}
|
|
370
|
-
|
|
418
|
+
getOptions(options = {}) {
|
|
371
419
|
if (!this.target)
|
|
372
420
|
return {};
|
|
373
421
|
const isAbsolute = this.mode === Mode.ABSOLUTE;
|
|
422
|
+
const isFixed = this.mode === Mode.FIXED;
|
|
374
423
|
let { moveableOptions = {} } = this.core.config;
|
|
375
424
|
if (typeof moveableOptions === "function") {
|
|
376
425
|
moveableOptions = moveableOptions(this.core);
|
|
377
426
|
}
|
|
378
427
|
return {
|
|
379
|
-
|
|
380
|
-
|
|
428
|
+
origin: false,
|
|
429
|
+
rootContainer: this.core.container,
|
|
381
430
|
zoom: 1,
|
|
382
|
-
dragArea:
|
|
431
|
+
dragArea: false,
|
|
383
432
|
draggable: true,
|
|
384
433
|
resizable: true,
|
|
385
|
-
snappable: isAbsolute,
|
|
386
|
-
snapGap: isAbsolute,
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
434
|
+
snappable: isAbsolute || isFixed,
|
|
435
|
+
snapGap: isAbsolute || isFixed,
|
|
436
|
+
snapThreshold: 5,
|
|
437
|
+
snapDigit: 0,
|
|
438
|
+
throttleDrag: 0,
|
|
439
|
+
isDisplaySnapDigit: isAbsolute,
|
|
440
|
+
snapDirections: {
|
|
441
|
+
top: isAbsolute,
|
|
442
|
+
right: isAbsolute,
|
|
443
|
+
bottom: isAbsolute,
|
|
444
|
+
left: isAbsolute,
|
|
445
|
+
center: isAbsolute,
|
|
446
|
+
middle: isAbsolute
|
|
447
|
+
},
|
|
448
|
+
elementSnapDirections: {
|
|
449
|
+
top: isAbsolute,
|
|
450
|
+
right: isAbsolute,
|
|
451
|
+
bottom: isAbsolute,
|
|
452
|
+
left: isAbsolute
|
|
453
|
+
},
|
|
454
|
+
isDisplayInnerSnapDigit: true,
|
|
390
455
|
horizontalGuidelines: this.horizontalGuidelines,
|
|
391
456
|
verticalGuidelines: this.verticalGuidelines,
|
|
457
|
+
elementGuidelines: this.elementGuidelines,
|
|
392
458
|
bounds: {
|
|
393
459
|
top: 0,
|
|
394
460
|
left: 0,
|
|
@@ -457,15 +523,159 @@ const up = (deltaTop, target) => {
|
|
|
457
523
|
};
|
|
458
524
|
};
|
|
459
525
|
|
|
526
|
+
class TargetCalibrate extends EventEmitter {
|
|
527
|
+
constructor(config) {
|
|
528
|
+
super();
|
|
529
|
+
this.parent = config.parent;
|
|
530
|
+
this.mask = config.mask;
|
|
531
|
+
this.dr = config.dr;
|
|
532
|
+
this.operationEl = globalThis.document.createElement("div");
|
|
533
|
+
this.parent.append(this.operationEl);
|
|
534
|
+
}
|
|
535
|
+
update(el, prefix) {
|
|
536
|
+
const { width, height } = el.getBoundingClientRect();
|
|
537
|
+
const { left, top } = this.getOffset(el);
|
|
538
|
+
this.operationEl.style.cssText = `
|
|
539
|
+
position: absolute;
|
|
540
|
+
left: ${left}px;
|
|
541
|
+
top: ${top}px;
|
|
542
|
+
width: ${width}px;
|
|
543
|
+
height: ${height}px;
|
|
544
|
+
`;
|
|
545
|
+
this.operationEl.id = `${prefix}${el.id}`;
|
|
546
|
+
return this.operationEl;
|
|
547
|
+
}
|
|
548
|
+
destroy() {
|
|
549
|
+
this.operationEl?.remove();
|
|
550
|
+
}
|
|
551
|
+
getOffset(el) {
|
|
552
|
+
const { transform } = getComputedStyle(el);
|
|
553
|
+
const { offsetParent } = el;
|
|
554
|
+
let left = el.offsetLeft;
|
|
555
|
+
let top = el.offsetTop;
|
|
556
|
+
if (transform.indexOf("matrix") > -1) {
|
|
557
|
+
let a = 1;
|
|
558
|
+
let b = 1;
|
|
559
|
+
let c = 1;
|
|
560
|
+
let d = 1;
|
|
561
|
+
let e = 0;
|
|
562
|
+
let f = 0;
|
|
563
|
+
transform.replace(/matrix\((.+), (.+), (.+), (.+), (.+), (.+)\)/, ($0, $1, $2, $3, $4, $5, $6) => {
|
|
564
|
+
a = +$1;
|
|
565
|
+
b = +$2;
|
|
566
|
+
c = +$3;
|
|
567
|
+
d = +$4;
|
|
568
|
+
e = +$5;
|
|
569
|
+
f = +$6;
|
|
570
|
+
return transform;
|
|
571
|
+
});
|
|
572
|
+
left = a * left + c * top + e;
|
|
573
|
+
top = b * left + d * top + f;
|
|
574
|
+
}
|
|
575
|
+
if (offsetParent) {
|
|
576
|
+
const parentOffset = this.getOffset(offsetParent);
|
|
577
|
+
return {
|
|
578
|
+
left: left + parentOffset.left,
|
|
579
|
+
top: top + parentOffset.top
|
|
580
|
+
};
|
|
581
|
+
}
|
|
582
|
+
if (this.dr.mode === Mode.FIXED) {
|
|
583
|
+
if (getMode(el) === Mode.FIXED) {
|
|
584
|
+
return {
|
|
585
|
+
left,
|
|
586
|
+
top
|
|
587
|
+
};
|
|
588
|
+
}
|
|
589
|
+
return {
|
|
590
|
+
left: left - this.mask.scrollLeft,
|
|
591
|
+
top: top - this.mask.scrollTop
|
|
592
|
+
};
|
|
593
|
+
}
|
|
594
|
+
if (getMode(el) === Mode.FIXED) {
|
|
595
|
+
return {
|
|
596
|
+
left: left + this.mask.scrollLeft,
|
|
597
|
+
top: top + this.mask.scrollTop
|
|
598
|
+
};
|
|
599
|
+
}
|
|
600
|
+
return {
|
|
601
|
+
left,
|
|
602
|
+
top
|
|
603
|
+
};
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
class StageHighlight extends EventEmitter {
|
|
608
|
+
constructor(config) {
|
|
609
|
+
super();
|
|
610
|
+
this.core = config.core;
|
|
611
|
+
this.container = config.container;
|
|
612
|
+
this.calibrationTarget = new TargetCalibrate({
|
|
613
|
+
parent: this.core.mask.content,
|
|
614
|
+
mask: this.core.mask,
|
|
615
|
+
dr: this.core.dr
|
|
616
|
+
});
|
|
617
|
+
}
|
|
618
|
+
highlight(el) {
|
|
619
|
+
if (!el || el === this.target)
|
|
620
|
+
return;
|
|
621
|
+
this.target = el;
|
|
622
|
+
this.moveable?.destroy();
|
|
623
|
+
this.moveable = new Moveable(this.container, {
|
|
624
|
+
target: this.calibrationTarget.update(el, HIGHLIGHT_EL_ID_PREFIX),
|
|
625
|
+
origin: false,
|
|
626
|
+
rootContainer: this.core.container,
|
|
627
|
+
zoom: 1
|
|
628
|
+
});
|
|
629
|
+
}
|
|
630
|
+
clearHighlight() {
|
|
631
|
+
if (!this.moveable)
|
|
632
|
+
return;
|
|
633
|
+
this.target = void 0;
|
|
634
|
+
this.moveable.target = null;
|
|
635
|
+
this.moveable.updateTarget();
|
|
636
|
+
}
|
|
637
|
+
destroy() {
|
|
638
|
+
this.moveable?.destroy();
|
|
639
|
+
this.calibrationTarget.destroy();
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
|
|
460
643
|
class Rule extends EventEmitter$1 {
|
|
461
|
-
hGuides;
|
|
462
|
-
vGuides;
|
|
463
|
-
horizontalGuidelines = [];
|
|
464
|
-
verticalGuidelines = [];
|
|
465
|
-
container;
|
|
466
|
-
containerResizeObserver;
|
|
467
644
|
constructor(container) {
|
|
468
645
|
super();
|
|
646
|
+
this.horizontalGuidelines = [];
|
|
647
|
+
this.verticalGuidelines = [];
|
|
648
|
+
this.getGuidesStyle = (type) => ({
|
|
649
|
+
position: "fixed",
|
|
650
|
+
zIndex: 1,
|
|
651
|
+
left: type === GuidesType.HORIZONTAL ? 0 : "-30px",
|
|
652
|
+
top: type === GuidesType.HORIZONTAL ? "-30px" : 0,
|
|
653
|
+
width: type === GuidesType.HORIZONTAL ? "100%" : "30px",
|
|
654
|
+
height: type === GuidesType.HORIZONTAL ? "30px" : "100%"
|
|
655
|
+
});
|
|
656
|
+
this.createGuides = (type, defaultGuides = []) => new Guides(this.container, {
|
|
657
|
+
type,
|
|
658
|
+
defaultGuides,
|
|
659
|
+
displayDragPos: true,
|
|
660
|
+
backgroundColor: "#fff",
|
|
661
|
+
lineColor: "#000",
|
|
662
|
+
textColor: "#000",
|
|
663
|
+
style: this.getGuidesStyle(type)
|
|
664
|
+
});
|
|
665
|
+
this.hGuidesChangeGuidesHandler = (e) => {
|
|
666
|
+
this.horizontalGuidelines = e.guides;
|
|
667
|
+
this.emit("changeGuides", {
|
|
668
|
+
type: GuidesType.HORIZONTAL,
|
|
669
|
+
guides: this.horizontalGuidelines
|
|
670
|
+
});
|
|
671
|
+
};
|
|
672
|
+
this.vGuidesChangeGuidesHandler = (e) => {
|
|
673
|
+
this.verticalGuidelines = e.guides;
|
|
674
|
+
this.emit("changeGuides", {
|
|
675
|
+
type: GuidesType.VERTICAL,
|
|
676
|
+
guides: this.verticalGuidelines
|
|
677
|
+
});
|
|
678
|
+
};
|
|
469
679
|
this.container = container;
|
|
470
680
|
this.hGuides = this.createGuides(GuidesType.HORIZONTAL);
|
|
471
681
|
this.vGuides = this.createGuides(GuidesType.VERTICAL);
|
|
@@ -534,40 +744,10 @@ class Rule extends EventEmitter$1 {
|
|
|
534
744
|
this.containerResizeObserver.disconnect();
|
|
535
745
|
this.removeAllListeners();
|
|
536
746
|
}
|
|
537
|
-
getGuidesStyle = (type) => ({
|
|
538
|
-
position: "fixed",
|
|
539
|
-
zIndex: 1,
|
|
540
|
-
left: type === GuidesType.HORIZONTAL ? 0 : "-30px",
|
|
541
|
-
top: type === GuidesType.HORIZONTAL ? "-30px" : 0,
|
|
542
|
-
width: type === GuidesType.HORIZONTAL ? "100%" : "30px",
|
|
543
|
-
height: type === GuidesType.HORIZONTAL ? "30px" : "100%"
|
|
544
|
-
});
|
|
545
|
-
createGuides = (type, defaultGuides = []) => new Guides(this.container, {
|
|
546
|
-
type,
|
|
547
|
-
defaultGuides,
|
|
548
|
-
displayDragPos: true,
|
|
549
|
-
backgroundColor: "#fff",
|
|
550
|
-
lineColor: "#000",
|
|
551
|
-
textColor: "#000",
|
|
552
|
-
style: this.getGuidesStyle(type)
|
|
553
|
-
});
|
|
554
|
-
hGuidesChangeGuidesHandler = (e) => {
|
|
555
|
-
this.horizontalGuidelines = e.guides;
|
|
556
|
-
this.emit("changeGuides", {
|
|
557
|
-
type: GuidesType.HORIZONTAL,
|
|
558
|
-
guides: this.horizontalGuidelines
|
|
559
|
-
});
|
|
560
|
-
};
|
|
561
|
-
vGuidesChangeGuidesHandler = (e) => {
|
|
562
|
-
this.verticalGuidelines = e.guides;
|
|
563
|
-
this.emit("changeGuides", {
|
|
564
|
-
type: GuidesType.VERTICAL,
|
|
565
|
-
guides: this.verticalGuidelines
|
|
566
|
-
});
|
|
567
|
-
};
|
|
568
747
|
}
|
|
569
748
|
|
|
570
749
|
const wrapperClassName = "editor-mask-wrapper";
|
|
750
|
+
const throttleTime = 100;
|
|
571
751
|
const hideScrollbar = () => {
|
|
572
752
|
const style = globalThis.document.createElement("style");
|
|
573
753
|
style.innerHTML = `
|
|
@@ -601,28 +781,73 @@ const createWrapper = () => {
|
|
|
601
781
|
return el;
|
|
602
782
|
};
|
|
603
783
|
class StageMask extends Rule {
|
|
604
|
-
content = createContent();
|
|
605
|
-
wrapper;
|
|
606
|
-
core;
|
|
607
|
-
page = null;
|
|
608
|
-
pageScrollParent = null;
|
|
609
|
-
scrollTop = 0;
|
|
610
|
-
scrollLeft = 0;
|
|
611
|
-
width = 0;
|
|
612
|
-
height = 0;
|
|
613
|
-
wrapperHeight = 0;
|
|
614
|
-
wrapperWidth = 0;
|
|
615
|
-
mode = Mode.ABSOLUTE;
|
|
616
|
-
pageResizeObserver = null;
|
|
617
|
-
wrapperResizeObserver = null;
|
|
618
784
|
constructor(config) {
|
|
619
785
|
const wrapper = createWrapper();
|
|
620
786
|
super(wrapper);
|
|
787
|
+
this.content = createContent();
|
|
788
|
+
this.page = null;
|
|
789
|
+
this.pageScrollParent = null;
|
|
790
|
+
this.scrollTop = 0;
|
|
791
|
+
this.scrollLeft = 0;
|
|
792
|
+
this.width = 0;
|
|
793
|
+
this.height = 0;
|
|
794
|
+
this.wrapperHeight = 0;
|
|
795
|
+
this.wrapperWidth = 0;
|
|
796
|
+
this.maxScrollTop = 0;
|
|
797
|
+
this.maxScrollLeft = 0;
|
|
798
|
+
this.mode = Mode.ABSOLUTE;
|
|
799
|
+
this.pageResizeObserver = null;
|
|
800
|
+
this.wrapperResizeObserver = null;
|
|
801
|
+
this.highlightHandler = throttle((event) => {
|
|
802
|
+
this.emit("highlight", event);
|
|
803
|
+
}, throttleTime);
|
|
804
|
+
this.mouseDownHandler = (event) => {
|
|
805
|
+
this.emit("clearHighlight");
|
|
806
|
+
event.stopImmediatePropagation();
|
|
807
|
+
event.stopPropagation();
|
|
808
|
+
if (event.button !== MouseButton.LEFT && event.button !== MouseButton.RIGHT)
|
|
809
|
+
return;
|
|
810
|
+
if (event.target.className.indexOf("moveable-control") !== -1) {
|
|
811
|
+
return;
|
|
812
|
+
}
|
|
813
|
+
this.content.removeEventListener("mousemove", this.highlightHandler);
|
|
814
|
+
this.emit("beforeSelect", event);
|
|
815
|
+
globalThis.document.addEventListener("mouseup", this.mouseUpHandler);
|
|
816
|
+
};
|
|
817
|
+
this.mouseUpHandler = () => {
|
|
818
|
+
globalThis.document.removeEventListener("mouseup", this.mouseUpHandler);
|
|
819
|
+
this.content.addEventListener("mousemove", this.highlightHandler);
|
|
820
|
+
this.emit("select");
|
|
821
|
+
};
|
|
822
|
+
this.mouseWheelHandler = (event) => {
|
|
823
|
+
this.emit("clearHighlight");
|
|
824
|
+
if (!this.page)
|
|
825
|
+
throw new Error("page \u672A\u521D\u59CB\u5316");
|
|
826
|
+
const { deltaY, deltaX } = event;
|
|
827
|
+
if (this.page.clientHeight < this.wrapperHeight && deltaY)
|
|
828
|
+
return;
|
|
829
|
+
if (this.page.clientWidth < this.wrapperWidth && deltaX)
|
|
830
|
+
return;
|
|
831
|
+
if (this.maxScrollTop > 0) {
|
|
832
|
+
this.scrollTop = this.scrollTop + deltaY;
|
|
833
|
+
}
|
|
834
|
+
if (this.maxScrollLeft > 0) {
|
|
835
|
+
this.scrollLeft = this.scrollLeft + deltaX;
|
|
836
|
+
}
|
|
837
|
+
this.fixScrollValue();
|
|
838
|
+
this.scroll();
|
|
839
|
+
this.emit("scroll", event);
|
|
840
|
+
};
|
|
841
|
+
this.mouseLeaveHandler = () => {
|
|
842
|
+
setTimeout(() => this.emit("clearHighlight"), throttleTime);
|
|
843
|
+
};
|
|
621
844
|
this.wrapper = wrapper;
|
|
622
845
|
this.core = config.core;
|
|
623
846
|
this.content.addEventListener("mousedown", this.mouseDownHandler);
|
|
624
847
|
this.wrapper.appendChild(this.content);
|
|
625
848
|
this.content.addEventListener("wheel", this.mouseWheelHandler);
|
|
849
|
+
this.content.addEventListener("mousemove", this.highlightHandler);
|
|
850
|
+
this.content.addEventListener("mouseleave", this.mouseLeaveHandler);
|
|
626
851
|
}
|
|
627
852
|
setMode(mode) {
|
|
628
853
|
this.mode = mode;
|
|
@@ -647,6 +872,9 @@ class StageMask extends Rule {
|
|
|
647
872
|
const { clientHeight, clientWidth } = entry.target;
|
|
648
873
|
this.setHeight(clientHeight);
|
|
649
874
|
this.setWidth(clientWidth);
|
|
875
|
+
this.fixScrollValue();
|
|
876
|
+
this.scroll();
|
|
877
|
+
this.core.dr.updateMoveable();
|
|
650
878
|
});
|
|
651
879
|
this.pageResizeObserver.observe(page);
|
|
652
880
|
this.wrapperResizeObserver = new ResizeObserver((entries) => {
|
|
@@ -654,6 +882,8 @@ class StageMask extends Rule {
|
|
|
654
882
|
const { clientHeight, clientWidth } = entry.target;
|
|
655
883
|
this.wrapperHeight = clientHeight;
|
|
656
884
|
this.wrapperWidth = clientWidth;
|
|
885
|
+
this.setMaxScrollLeft();
|
|
886
|
+
this.setMaxScrollTop();
|
|
657
887
|
});
|
|
658
888
|
this.wrapperResizeObserver.observe(this.wrapper);
|
|
659
889
|
}
|
|
@@ -666,16 +896,33 @@ class StageMask extends Rule {
|
|
|
666
896
|
setLayout(el) {
|
|
667
897
|
this.setMode(isFixedParent(el) ? Mode.FIXED : Mode.ABSOLUTE);
|
|
668
898
|
}
|
|
899
|
+
scrollIntoView(el) {
|
|
900
|
+
if (this.mode === Mode.FIXED)
|
|
901
|
+
return;
|
|
902
|
+
el.scrollIntoView();
|
|
903
|
+
if (!this.pageScrollParent)
|
|
904
|
+
return;
|
|
905
|
+
this.scrollLeft = this.pageScrollParent.scrollLeft;
|
|
906
|
+
this.scrollTop = this.pageScrollParent.scrollTop;
|
|
907
|
+
this.scroll();
|
|
908
|
+
}
|
|
669
909
|
destroy() {
|
|
670
910
|
this.content?.remove();
|
|
671
911
|
this.page = null;
|
|
672
912
|
this.pageScrollParent = null;
|
|
673
913
|
this.pageResizeObserver?.disconnect();
|
|
674
914
|
this.wrapperResizeObserver?.disconnect();
|
|
915
|
+
this.content.removeEventListener("mouseleave", this.mouseLeaveHandler);
|
|
675
916
|
super.destroy();
|
|
676
917
|
}
|
|
677
918
|
scroll() {
|
|
678
919
|
let { scrollLeft, scrollTop } = this;
|
|
920
|
+
if (this.pageScrollParent) {
|
|
921
|
+
this.pageScrollParent.scrollTo({
|
|
922
|
+
top: scrollTop,
|
|
923
|
+
left: scrollLeft
|
|
924
|
+
});
|
|
925
|
+
}
|
|
679
926
|
if (this.mode === Mode.FIXED) {
|
|
680
927
|
scrollLeft = 0;
|
|
681
928
|
scrollTop = 0;
|
|
@@ -688,71 +935,75 @@ class StageMask extends Rule {
|
|
|
688
935
|
}
|
|
689
936
|
setHeight(height) {
|
|
690
937
|
this.height = height;
|
|
938
|
+
this.setMaxScrollTop();
|
|
691
939
|
this.content.style.height = `${height}px`;
|
|
692
940
|
}
|
|
693
941
|
setWidth(width) {
|
|
694
942
|
this.width = width;
|
|
943
|
+
this.setMaxScrollLeft();
|
|
695
944
|
this.content.style.width = `${width}px`;
|
|
696
945
|
}
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
this.
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
if (!this.page)
|
|
714
|
-
throw new Error("page \u672A\u521D\u59CB\u5316");
|
|
715
|
-
const { deltaY, deltaX } = event;
|
|
716
|
-
const { height, wrapperHeight, width, wrapperWidth } = this;
|
|
717
|
-
const maxScrollTop = height - wrapperHeight;
|
|
718
|
-
const maxScrollLeft = width - wrapperWidth;
|
|
719
|
-
if (maxScrollTop > 0) {
|
|
720
|
-
if (deltaY > 0) {
|
|
721
|
-
this.scrollTop = this.scrollTop + Math.min(maxScrollTop - this.scrollTop, deltaY);
|
|
722
|
-
} else {
|
|
723
|
-
this.scrollTop = Math.max(this.scrollTop + deltaY, 0);
|
|
724
|
-
}
|
|
725
|
-
}
|
|
726
|
-
if (width > wrapperWidth) {
|
|
727
|
-
if (deltaX > 0) {
|
|
728
|
-
this.scrollLeft = this.scrollLeft + Math.min(maxScrollLeft - this.scrollLeft, deltaX);
|
|
729
|
-
} else {
|
|
730
|
-
this.scrollLeft = Math.max(this.scrollLeft + deltaX, 0);
|
|
731
|
-
}
|
|
732
|
-
}
|
|
733
|
-
if (this.mode !== Mode.FIXED) {
|
|
734
|
-
this.scrollTo(this.scrollLeft, this.scrollTop);
|
|
735
|
-
}
|
|
736
|
-
if (this.pageScrollParent) {
|
|
737
|
-
this.pageScrollParent.scrollTo({
|
|
738
|
-
top: this.scrollTop,
|
|
739
|
-
left: this.scrollLeft
|
|
740
|
-
});
|
|
741
|
-
}
|
|
742
|
-
this.scroll();
|
|
743
|
-
this.emit("scroll", event);
|
|
744
|
-
};
|
|
946
|
+
setMaxScrollLeft() {
|
|
947
|
+
this.maxScrollLeft = this.width - this.wrapperWidth;
|
|
948
|
+
}
|
|
949
|
+
setMaxScrollTop() {
|
|
950
|
+
this.maxScrollTop = this.height - this.wrapperHeight;
|
|
951
|
+
}
|
|
952
|
+
fixScrollValue() {
|
|
953
|
+
if (this.scrollTop < 0)
|
|
954
|
+
this.scrollTop = 0;
|
|
955
|
+
if (this.scrollLeft < 0)
|
|
956
|
+
this.scrollLeft = 0;
|
|
957
|
+
if (this.maxScrollTop < this.scrollTop)
|
|
958
|
+
this.scrollTop = this.maxScrollTop;
|
|
959
|
+
if (this.maxScrollLeft < this.scrollLeft)
|
|
960
|
+
this.scrollLeft = this.maxScrollLeft;
|
|
961
|
+
}
|
|
745
962
|
}
|
|
746
963
|
|
|
747
964
|
class StageRender extends EventEmitter {
|
|
748
|
-
contentWindow = null;
|
|
749
|
-
runtime = null;
|
|
750
|
-
iframe;
|
|
751
|
-
runtimeUrl;
|
|
752
|
-
core;
|
|
753
|
-
render;
|
|
754
965
|
constructor({ core }) {
|
|
755
966
|
super();
|
|
967
|
+
this.contentWindow = null;
|
|
968
|
+
this.runtime = null;
|
|
969
|
+
this.getMagicApi = () => ({
|
|
970
|
+
onPageElUpdate: (el) => this.emit("page-el-update", el),
|
|
971
|
+
onRuntimeReady: (runtime) => {
|
|
972
|
+
this.runtime = runtime;
|
|
973
|
+
globalThis.runtime = runtime;
|
|
974
|
+
this.emit("runtime-ready", runtime);
|
|
975
|
+
}
|
|
976
|
+
});
|
|
977
|
+
this.getRuntime = () => {
|
|
978
|
+
if (this.runtime)
|
|
979
|
+
return Promise.resolve(this.runtime);
|
|
980
|
+
return new Promise((resolve) => {
|
|
981
|
+
const listener = (runtime) => {
|
|
982
|
+
this.off("runtime-ready", listener);
|
|
983
|
+
resolve(runtime);
|
|
984
|
+
};
|
|
985
|
+
this.on("runtime-ready", listener);
|
|
986
|
+
});
|
|
987
|
+
};
|
|
988
|
+
this.loadHandler = async () => {
|
|
989
|
+
this.emit("onload");
|
|
990
|
+
if (this.render) {
|
|
991
|
+
const el = await this.render(this.core);
|
|
992
|
+
if (el) {
|
|
993
|
+
this.iframe?.contentDocument?.body?.appendChild(el);
|
|
994
|
+
}
|
|
995
|
+
}
|
|
996
|
+
if (this.contentWindow) {
|
|
997
|
+
const style = this.contentWindow.document.createElement("style");
|
|
998
|
+
style.id = "tmagic-stage-render";
|
|
999
|
+
style.innerHTML = `
|
|
1000
|
+
.${SELECTED_CLASS}, .${SELECTED_CLASS}-parent {
|
|
1001
|
+
z-index: ${ZIndex.SELECTED_EL};
|
|
1002
|
+
}
|
|
1003
|
+
`;
|
|
1004
|
+
this.contentWindow.document.head.appendChild(style);
|
|
1005
|
+
}
|
|
1006
|
+
};
|
|
756
1007
|
this.core = core;
|
|
757
1008
|
this.runtimeUrl = core.config.runtimeUrl || "";
|
|
758
1009
|
this.render = core.config.render;
|
|
@@ -765,14 +1016,6 @@ class StageRender extends EventEmitter {
|
|
|
765
1016
|
`;
|
|
766
1017
|
this.iframe.addEventListener("load", this.loadHandler);
|
|
767
1018
|
}
|
|
768
|
-
getMagicApi = () => ({
|
|
769
|
-
onPageElUpdate: (el) => this.emit("page-el-update", el),
|
|
770
|
-
onRuntimeReady: (runtime) => {
|
|
771
|
-
this.runtime = runtime;
|
|
772
|
-
globalThis.runtime = runtime;
|
|
773
|
-
this.emit("runtime-ready", runtime);
|
|
774
|
-
}
|
|
775
|
-
});
|
|
776
1019
|
async mount(el) {
|
|
777
1020
|
if (this.iframe) {
|
|
778
1021
|
if (!isSameDomain(this.runtimeUrl) && this.runtimeUrl) {
|
|
@@ -789,17 +1032,6 @@ class StageRender extends EventEmitter {
|
|
|
789
1032
|
throw Error("mount \u5931\u8D25");
|
|
790
1033
|
}
|
|
791
1034
|
}
|
|
792
|
-
getRuntime = () => {
|
|
793
|
-
if (this.runtime)
|
|
794
|
-
return Promise.resolve(this.runtime);
|
|
795
|
-
return new Promise((resolve) => {
|
|
796
|
-
const listener = (runtime) => {
|
|
797
|
-
this.off("runtime-ready", listener);
|
|
798
|
-
resolve(runtime);
|
|
799
|
-
};
|
|
800
|
-
this.on("runtime-ready", listener);
|
|
801
|
-
});
|
|
802
|
-
};
|
|
803
1035
|
destroy() {
|
|
804
1036
|
this.iframe?.removeEventListener("load", this.loadHandler);
|
|
805
1037
|
this.contentWindow = null;
|
|
@@ -807,35 +1039,25 @@ class StageRender extends EventEmitter {
|
|
|
807
1039
|
this.iframe = void 0;
|
|
808
1040
|
this.removeAllListeners();
|
|
809
1041
|
}
|
|
810
|
-
loadHandler = async () => {
|
|
811
|
-
this.emit("onload");
|
|
812
|
-
if (this.render) {
|
|
813
|
-
const el = await this.render(this.core);
|
|
814
|
-
if (el) {
|
|
815
|
-
this.iframe?.contentDocument?.body?.appendChild(el);
|
|
816
|
-
}
|
|
817
|
-
}
|
|
818
|
-
};
|
|
819
1042
|
}
|
|
820
1043
|
|
|
821
1044
|
class StageCore extends EventEmitter {
|
|
822
|
-
selectedDom;
|
|
823
|
-
renderer;
|
|
824
|
-
mask;
|
|
825
|
-
dr;
|
|
826
|
-
config;
|
|
827
|
-
zoom = DEFAULT_ZOOM;
|
|
828
|
-
canSelect;
|
|
829
1045
|
constructor(config) {
|
|
830
1046
|
super();
|
|
1047
|
+
this.zoom = DEFAULT_ZOOM;
|
|
831
1048
|
this.config = config;
|
|
832
1049
|
this.setZoom(config.zoom);
|
|
833
1050
|
this.canSelect = config.canSelect || ((el) => !!el.id);
|
|
834
1051
|
this.renderer = new StageRender({ core: this });
|
|
835
1052
|
this.mask = new StageMask({ core: this });
|
|
836
1053
|
this.dr = new StageDragResize({ core: this, container: this.mask.content });
|
|
837
|
-
this.
|
|
838
|
-
this.renderer.on("
|
|
1054
|
+
this.highlightLayer = new StageHighlight({ core: this, container: this.mask.wrapper });
|
|
1055
|
+
this.renderer.on("runtime-ready", (runtime) => {
|
|
1056
|
+
this.emit("runtime-ready", runtime);
|
|
1057
|
+
});
|
|
1058
|
+
this.renderer.on("page-el-update", (el) => {
|
|
1059
|
+
this.mask?.observe(el);
|
|
1060
|
+
});
|
|
839
1061
|
this.mask.on("beforeSelect", (event) => {
|
|
840
1062
|
this.setElementFromPoint(event);
|
|
841
1063
|
}).on("select", () => {
|
|
@@ -843,6 +1065,16 @@ class StageCore extends EventEmitter {
|
|
|
843
1065
|
}).on("changeGuides", (data) => {
|
|
844
1066
|
this.dr.setGuidelines(data.type, data.guides);
|
|
845
1067
|
this.emit("changeGuides", data);
|
|
1068
|
+
}).on("highlight", async (event) => {
|
|
1069
|
+
await this.setElementFromPoint(event);
|
|
1070
|
+
if (this.highlightedDom === this.selectedDom) {
|
|
1071
|
+
this.highlightLayer.clearHighlight();
|
|
1072
|
+
return;
|
|
1073
|
+
}
|
|
1074
|
+
this.highlightLayer.highlight(this.highlightedDom);
|
|
1075
|
+
this.emit("highlight", this.highlightedDom);
|
|
1076
|
+
}).on("clearHighlight", async () => {
|
|
1077
|
+
this.highlightLayer.clearHighlight();
|
|
846
1078
|
});
|
|
847
1079
|
this.dr.on("update", (data) => {
|
|
848
1080
|
setTimeout(() => this.emit("update", data));
|
|
@@ -866,60 +1098,79 @@ class StageCore extends EventEmitter {
|
|
|
866
1098
|
let stopped = false;
|
|
867
1099
|
const stop = () => stopped = true;
|
|
868
1100
|
for (const el of els) {
|
|
869
|
-
if (!el.id.startsWith(GHOST_EL_ID_PREFIX) && await this.canSelect(el, stop)) {
|
|
1101
|
+
if (!el.id.startsWith(GHOST_EL_ID_PREFIX) && await this.canSelect(el, event, stop)) {
|
|
870
1102
|
if (stopped)
|
|
871
1103
|
break;
|
|
1104
|
+
if (event.type === "mousemove") {
|
|
1105
|
+
this.highlight(el);
|
|
1106
|
+
break;
|
|
1107
|
+
}
|
|
872
1108
|
this.select(el, event);
|
|
873
1109
|
break;
|
|
874
1110
|
}
|
|
875
1111
|
}
|
|
876
1112
|
}
|
|
877
1113
|
async select(idOrEl, event) {
|
|
878
|
-
|
|
879
|
-
if (typeof idOrEl === "string" || typeof idOrEl === "number") {
|
|
880
|
-
const runtime2 = await this.renderer?.getRuntime();
|
|
881
|
-
el = await runtime2?.select?.(`${idOrEl}`);
|
|
882
|
-
if (!el)
|
|
883
|
-
throw new Error(`\u4E0D\u5B58\u5728ID\u4E3A${idOrEl}\u7684\u5143\u7D20`);
|
|
884
|
-
} else {
|
|
885
|
-
el = idOrEl;
|
|
886
|
-
}
|
|
1114
|
+
const el = await this.getTargetElement(idOrEl);
|
|
887
1115
|
if (el === this.selectedDom)
|
|
888
1116
|
return;
|
|
889
|
-
const runtime = await this.renderer
|
|
1117
|
+
const runtime = await this.renderer.getRuntime();
|
|
1118
|
+
await runtime?.select?.(el.id);
|
|
890
1119
|
if (runtime?.beforeSelect) {
|
|
891
1120
|
await runtime.beforeSelect(el);
|
|
892
1121
|
}
|
|
893
1122
|
this.mask.setLayout(el);
|
|
894
|
-
this.dr
|
|
1123
|
+
this.dr.select(el, event);
|
|
1124
|
+
this.mask.scrollIntoView(el);
|
|
895
1125
|
this.selectedDom = el;
|
|
1126
|
+
if (this.renderer.contentWindow) {
|
|
1127
|
+
removeSelectedClassName(this.renderer.contentWindow.document);
|
|
1128
|
+
if (this.selectedDom) {
|
|
1129
|
+
addSelectedClassName(this.selectedDom, this.renderer.contentWindow.document);
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
896
1132
|
}
|
|
897
1133
|
update(data) {
|
|
898
1134
|
const { config } = data;
|
|
899
|
-
this.renderer?.getRuntime().then((runtime) => {
|
|
1135
|
+
return this.renderer?.getRuntime().then((runtime) => {
|
|
900
1136
|
runtime?.update?.(data);
|
|
901
1137
|
setTimeout(() => {
|
|
902
1138
|
const el = this.renderer.contentWindow?.document.getElementById(`${config.id}`);
|
|
903
|
-
if (el) {
|
|
1139
|
+
if (el && el.id === this.selectedDom?.id) {
|
|
1140
|
+
this.selectedDom = el;
|
|
904
1141
|
this.mask.setLayout(el);
|
|
905
|
-
this.dr
|
|
1142
|
+
this.dr.updateMoveable(el);
|
|
906
1143
|
}
|
|
907
1144
|
}, 0);
|
|
908
1145
|
});
|
|
909
1146
|
}
|
|
1147
|
+
async highlight(idOrEl) {
|
|
1148
|
+
let el;
|
|
1149
|
+
try {
|
|
1150
|
+
el = await this.getTargetElement(idOrEl);
|
|
1151
|
+
} catch (error) {
|
|
1152
|
+
this.highlightLayer.clearHighlight();
|
|
1153
|
+
return;
|
|
1154
|
+
}
|
|
1155
|
+
if (el === this.highlightedDom)
|
|
1156
|
+
return;
|
|
1157
|
+
this.highlightLayer.highlight(el);
|
|
1158
|
+
this.highlightedDom = el;
|
|
1159
|
+
}
|
|
910
1160
|
sortNode(data) {
|
|
911
|
-
this.renderer?.getRuntime().then((runtime) => runtime?.sortNode?.(data));
|
|
1161
|
+
return this.renderer?.getRuntime().then((runtime) => runtime?.sortNode?.(data));
|
|
912
1162
|
}
|
|
913
1163
|
add(data) {
|
|
914
|
-
this.renderer?.getRuntime().then((runtime) => runtime?.add?.(data));
|
|
1164
|
+
return this.renderer?.getRuntime().then((runtime) => runtime?.add?.(data));
|
|
915
1165
|
}
|
|
916
1166
|
remove(data) {
|
|
917
|
-
this.renderer?.getRuntime().then((runtime) => runtime?.remove?.(data));
|
|
1167
|
+
return this.renderer?.getRuntime().then((runtime) => runtime?.remove?.(data));
|
|
918
1168
|
}
|
|
919
1169
|
setZoom(zoom = DEFAULT_ZOOM) {
|
|
920
1170
|
this.zoom = zoom;
|
|
921
1171
|
}
|
|
922
1172
|
mount(el) {
|
|
1173
|
+
this.container = el;
|
|
923
1174
|
const { mask, renderer } = this;
|
|
924
1175
|
renderer.mount(el);
|
|
925
1176
|
mask.mount(el);
|
|
@@ -930,11 +1181,22 @@ class StageCore extends EventEmitter {
|
|
|
930
1181
|
this.dr.clearGuides();
|
|
931
1182
|
}
|
|
932
1183
|
destroy() {
|
|
933
|
-
const { mask, renderer, dr } = this;
|
|
1184
|
+
const { mask, renderer, dr, highlightLayer } = this;
|
|
934
1185
|
renderer.destroy();
|
|
935
1186
|
mask.destroy();
|
|
936
1187
|
dr.destroy();
|
|
1188
|
+
highlightLayer.destroy();
|
|
937
1189
|
this.removeAllListeners();
|
|
1190
|
+
this.container = void 0;
|
|
1191
|
+
}
|
|
1192
|
+
async getTargetElement(idOrEl) {
|
|
1193
|
+
if (typeof idOrEl === "string" || typeof idOrEl === "number") {
|
|
1194
|
+
const el = this.renderer.contentWindow?.document.getElementById(`${idOrEl}`);
|
|
1195
|
+
if (!el)
|
|
1196
|
+
throw new Error(`\u4E0D\u5B58\u5728ID\u4E3A${idOrEl}\u7684\u5143\u7D20`);
|
|
1197
|
+
return el;
|
|
1198
|
+
}
|
|
1199
|
+
return idOrEl;
|
|
938
1200
|
}
|
|
939
1201
|
}
|
|
940
1202
|
|