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