@plait/core 0.24.0-next.2 → 0.24.0-next.4
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/board/board.component.d.ts +1 -1
- package/core/children/children.component.d.ts +1 -1
- package/core/element/element.component.d.ts +1 -1
- package/core/element/plugin-element.d.ts +1 -1
- package/core/island/island-base.component.d.ts +1 -1
- package/{esm2020 → esm2022}/board/board.component.mjs +6 -6
- package/{esm2020 → esm2022}/core/children/children.component.mjs +6 -6
- package/{esm2020 → esm2022}/core/element/element.component.mjs +4 -4
- package/{esm2020 → esm2022}/core/element/plugin-element.mjs +4 -4
- package/{esm2020 → esm2022}/core/island/island-base.component.mjs +7 -7
- package/{esm2020 → esm2022}/interfaces/rectangle-client.mjs +11 -3
- package/{esm2020 → esm2022}/plait.module.mjs +5 -5
- package/esm2022/plugins/with-moving.mjs +98 -0
- package/esm2022/plugins/with-selection.mjs +181 -0
- package/{esm2020 → esm2022}/services/image-context.service.mjs +4 -4
- package/esm2022/utils/dom/common.mjs +68 -0
- package/esm2022/utils/dom/foreign.mjs +25 -0
- package/esm2022/utils/draw/rectangle.mjs +36 -0
- package/esm2022/utils/element.mjs +53 -0
- package/esm2022/utils/math.mjs +176 -0
- package/{fesm2020 → fesm2022}/plait-core.mjs +178 -42
- package/fesm2022/plait-core.mjs.map +1 -0
- package/interfaces/rectangle-client.d.ts +1 -0
- package/package.json +14 -14
- package/utils/dom/common.d.ts +4 -0
- package/utils/dom/foreign.d.ts +2 -1
- package/utils/draw/rectangle.d.ts +3 -0
- package/utils/element.d.ts +1 -0
- package/utils/math.d.ts +5 -0
- package/esm2020/plugins/with-moving.mjs +0 -97
- package/esm2020/plugins/with-selection.mjs +0 -183
- package/esm2020/utils/dom/common.mjs +0 -53
- package/esm2020/utils/dom/foreign.mjs +0 -19
- package/esm2020/utils/draw/rectangle.mjs +0 -26
- package/esm2020/utils/element.mjs +0 -44
- package/esm2020/utils/math.mjs +0 -85
- package/fesm2015/plait-core.mjs +0 -3498
- package/fesm2015/plait-core.mjs.map +0 -1
- package/fesm2020/plait-core.mjs.map +0 -1
- /package/{esm2020 → esm2022}/board/board.component.interface.mjs +0 -0
- /package/{esm2020 → esm2022}/constants/index.mjs +0 -0
- /package/{esm2020 → esm2022}/constants/keycodes.mjs +0 -0
- /package/{esm2020 → esm2022}/constants/resize.mjs +0 -0
- /package/{esm2020 → esm2022}/constants/selection.mjs +0 -0
- /package/{esm2020 → esm2022}/core/children/effect.mjs +0 -0
- /package/{esm2020 → esm2022}/core/element/context-change.mjs +0 -0
- /package/{esm2020 → esm2022}/core/element/context.mjs +0 -0
- /package/{esm2020 → esm2022}/interfaces/board.mjs +0 -0
- /package/{esm2020 → esm2022}/interfaces/custom-types.mjs +0 -0
- /package/{esm2020 → esm2022}/interfaces/element.mjs +0 -0
- /package/{esm2020 → esm2022}/interfaces/history.mjs +0 -0
- /package/{esm2020 → esm2022}/interfaces/index.mjs +0 -0
- /package/{esm2020 → esm2022}/interfaces/node.mjs +0 -0
- /package/{esm2020 → esm2022}/interfaces/operation.mjs +0 -0
- /package/{esm2020 → esm2022}/interfaces/path-ref.mjs +0 -0
- /package/{esm2020 → esm2022}/interfaces/path.mjs +0 -0
- /package/{esm2020 → esm2022}/interfaces/plugin-key.mjs +0 -0
- /package/{esm2020 → esm2022}/interfaces/plugin.mjs +0 -0
- /package/{esm2020 → esm2022}/interfaces/point.mjs +0 -0
- /package/{esm2020 → esm2022}/interfaces/pointer.mjs +0 -0
- /package/{esm2020 → esm2022}/interfaces/selection.mjs +0 -0
- /package/{esm2020 → esm2022}/interfaces/theme.mjs +0 -0
- /package/{esm2020 → esm2022}/interfaces/viewport.mjs +0 -0
- /package/{esm2020 → esm2022}/plait-core.mjs +0 -0
- /package/{esm2020 → esm2022}/plugins/create-board.mjs +0 -0
- /package/{esm2020 → esm2022}/plugins/with-board.mjs +0 -0
- /package/{esm2020 → esm2022}/plugins/with-hand.mjs +0 -0
- /package/{esm2020 → esm2022}/plugins/with-history.mjs +0 -0
- /package/{esm2020 → esm2022}/plugins/with-hotkey.mjs +0 -0
- /package/{esm2020 → esm2022}/plugins/with-options.mjs +0 -0
- /package/{esm2020 → esm2022}/plugins/with-viewport.mjs +0 -0
- /package/{esm2020 → esm2022}/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/testing/core/create-board.mjs +0 -0
- /package/{esm2020 → esm2022}/testing/core/fake-weak-map.mjs +0 -0
- /package/{esm2020 → esm2022}/testing/core/index.mjs +0 -0
- /package/{esm2020 → esm2022}/testing/fake-events/event-objects.mjs +0 -0
- /package/{esm2020 → esm2022}/testing/fake-events/index.mjs +0 -0
- /package/{esm2020 → esm2022}/testing/index.mjs +0 -0
- /package/{esm2020 → esm2022}/testing/test-element.mjs +0 -0
- /package/{esm2020 → esm2022}/transforms/board.mjs +0 -0
- /package/{esm2020 → esm2022}/transforms/general.mjs +0 -0
- /package/{esm2020 → esm2022}/transforms/index.mjs +0 -0
- /package/{esm2020 → esm2022}/transforms/node.mjs +0 -0
- /package/{esm2020 → esm2022}/transforms/selection.mjs +0 -0
- /package/{esm2020 → esm2022}/transforms/theme.mjs +0 -0
- /package/{esm2020 → esm2022}/transforms/viewport.mjs +0 -0
- /package/{esm2020 → esm2022}/utils/board.mjs +0 -0
- /package/{esm2020 → esm2022}/utils/clipboard.mjs +0 -0
- /package/{esm2020 → esm2022}/utils/common.mjs +0 -0
- /package/{esm2020 → esm2022}/utils/dom/environment.mjs +0 -0
- /package/{esm2020 → esm2022}/utils/dom/index.mjs +0 -0
- /package/{esm2020 → esm2022}/utils/draw/arrow.mjs +0 -0
- /package/{esm2020 → esm2022}/utils/draw/circle.mjs +0 -0
- /package/{esm2020 → esm2022}/utils/draw/line.mjs +0 -0
- /package/{esm2020 → esm2022}/utils/environment.mjs +0 -0
- /package/{esm2020 → esm2022}/utils/helper.mjs +0 -0
- /package/{esm2020 → esm2022}/utils/history.mjs +0 -0
- /package/{esm2020 → esm2022}/utils/hotkeys.mjs +0 -0
- /package/{esm2020 → esm2022}/utils/id-creator.mjs +0 -0
- /package/{esm2020 → esm2022}/utils/index.mjs +0 -0
- /package/{esm2020 → esm2022}/utils/moving-element.mjs +0 -0
- /package/{esm2020 → esm2022}/utils/selected-element.mjs +0 -0
- /package/{esm2020 → esm2022}/utils/to-image.mjs +0 -0
- /package/{esm2020 → esm2022}/utils/touch.mjs +0 -0
- /package/{esm2020 → esm2022}/utils/tree.mjs +0 -0
- /package/{esm2020 → esm2022}/utils/viewport.mjs +0 -0
- /package/{esm2020 → esm2022}/utils/weak-maps.mjs +0 -0
package/fesm2015/plait-core.mjs
DELETED
|
@@ -1,3498 +0,0 @@
|
|
|
1
|
-
import * as i0 from '@angular/core';
|
|
2
|
-
import { Directive, Input, Injectable, Component, ChangeDetectionStrategy, EventEmitter, ElementRef, Output, HostBinding, ViewChild, ContentChildren, NgModule } from '@angular/core';
|
|
3
|
-
import rough from 'roughjs/bin/rough';
|
|
4
|
-
import { timer, Subject, fromEvent } from 'rxjs';
|
|
5
|
-
import { takeUntil, filter, tap } from 'rxjs/operators';
|
|
6
|
-
import produce, { createDraft, finishDraft, isDraft } from 'immer';
|
|
7
|
-
import { isKeyHotkey, isHotkey } from 'is-hotkey';
|
|
8
|
-
import { __awaiter } from 'tslib';
|
|
9
|
-
import * as i1 from '@angular/common';
|
|
10
|
-
import { CommonModule } from '@angular/common';
|
|
11
|
-
|
|
12
|
-
// record richtext type status
|
|
13
|
-
const IS_BOARD_CACHE = new WeakMap();
|
|
14
|
-
const FLUSHING = new WeakMap();
|
|
15
|
-
const NODE_TO_INDEX = new WeakMap();
|
|
16
|
-
const NODE_TO_PARENT = new WeakMap();
|
|
17
|
-
const IS_TEXT_EDITABLE = new WeakMap();
|
|
18
|
-
const BOARD_TO_ON_CHANGE = new WeakMap();
|
|
19
|
-
const BOARD_TO_COMPONENT = new WeakMap();
|
|
20
|
-
const BOARD_TO_ROUGH_SVG = new WeakMap();
|
|
21
|
-
const BOARD_TO_HOST = new WeakMap();
|
|
22
|
-
const BOARD_TO_ELEMENT_HOST = new WeakMap();
|
|
23
|
-
const BOARD_TO_SELECTED_ELEMENT = new WeakMap();
|
|
24
|
-
const BOARD_TO_MOVING_POINT_IN_BOARD = new WeakMap();
|
|
25
|
-
const BOARD_TO_MOVING_POINT = new WeakMap();
|
|
26
|
-
const BOARD_TO_VIEWPORT_ORIGINATION = new WeakMap();
|
|
27
|
-
const BOARD_TO_IS_SELECTION_MOVING = new WeakMap();
|
|
28
|
-
// save no standard selected elements
|
|
29
|
-
const BOARD_TO_TEMPORARY_ELEMENTS = new WeakMap();
|
|
30
|
-
const BOARD_TO_MOVING_ELEMENT = new WeakMap();
|
|
31
|
-
const IS_PREVENT_TOUCH_MOVE = new WeakMap();
|
|
32
|
-
const PATH_REFS = new WeakMap();
|
|
33
|
-
|
|
34
|
-
function depthFirstRecursion(node, callback, recursion, isReverse) {
|
|
35
|
-
if (!recursion || recursion(node)) {
|
|
36
|
-
let children = [];
|
|
37
|
-
if (node.children) {
|
|
38
|
-
children = [...node.children];
|
|
39
|
-
}
|
|
40
|
-
children = isReverse ? children.reverse() : children;
|
|
41
|
-
children.forEach(child => {
|
|
42
|
-
depthFirstRecursion(child, callback, recursion);
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
callback(node);
|
|
46
|
-
}
|
|
47
|
-
const getIsRecursionFunc = (board) => {
|
|
48
|
-
return (element) => {
|
|
49
|
-
if (PlaitBoard.isBoard(element) || board.isRecursion(element)) {
|
|
50
|
-
return true;
|
|
51
|
-
}
|
|
52
|
-
else {
|
|
53
|
-
return false;
|
|
54
|
-
}
|
|
55
|
-
};
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
function getRectangleByElements(board, elements, recursion) {
|
|
59
|
-
const boundaryBox = {
|
|
60
|
-
left: Number.MAX_VALUE,
|
|
61
|
-
top: Number.MAX_VALUE,
|
|
62
|
-
right: Number.NEGATIVE_INFINITY,
|
|
63
|
-
bottom: Number.NEGATIVE_INFINITY
|
|
64
|
-
};
|
|
65
|
-
const calcRectangleClient = (node) => {
|
|
66
|
-
const nodeRectangle = board.getRectangle(node);
|
|
67
|
-
if (nodeRectangle) {
|
|
68
|
-
boundaryBox.left = Math.min(boundaryBox.left, nodeRectangle.x);
|
|
69
|
-
boundaryBox.top = Math.min(boundaryBox.top, nodeRectangle.y);
|
|
70
|
-
boundaryBox.right = Math.max(boundaryBox.right, nodeRectangle.x + nodeRectangle.width);
|
|
71
|
-
boundaryBox.bottom = Math.max(boundaryBox.bottom, nodeRectangle.y + nodeRectangle.height);
|
|
72
|
-
}
|
|
73
|
-
};
|
|
74
|
-
elements.forEach(element => {
|
|
75
|
-
if (recursion) {
|
|
76
|
-
depthFirstRecursion(element, node => calcRectangleClient(node), node => board.isRecursion(node));
|
|
77
|
-
}
|
|
78
|
-
else {
|
|
79
|
-
calcRectangleClient(element);
|
|
80
|
-
}
|
|
81
|
-
});
|
|
82
|
-
if (boundaryBox.left === Number.MAX_VALUE) {
|
|
83
|
-
return {
|
|
84
|
-
x: 0,
|
|
85
|
-
y: 0,
|
|
86
|
-
width: 0,
|
|
87
|
-
height: 0
|
|
88
|
-
};
|
|
89
|
-
}
|
|
90
|
-
return {
|
|
91
|
-
x: boundaryBox.left,
|
|
92
|
-
y: boundaryBox.top,
|
|
93
|
-
width: boundaryBox.right - boundaryBox.left,
|
|
94
|
-
height: boundaryBox.bottom - boundaryBox.top
|
|
95
|
-
};
|
|
96
|
-
}
|
|
97
|
-
function getBoardRectangle(board) {
|
|
98
|
-
return getRectangleByElements(board, board.children, true);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
var ThemeColorMode;
|
|
102
|
-
(function (ThemeColorMode) {
|
|
103
|
-
ThemeColorMode["default"] = "default";
|
|
104
|
-
ThemeColorMode["colorful"] = "colorful";
|
|
105
|
-
ThemeColorMode["soft"] = "soft";
|
|
106
|
-
ThemeColorMode["retro"] = "retro";
|
|
107
|
-
ThemeColorMode["dark"] = "dark";
|
|
108
|
-
ThemeColorMode["starry"] = "starry";
|
|
109
|
-
})(ThemeColorMode || (ThemeColorMode = {}));
|
|
110
|
-
const DefaultThemeColor = {
|
|
111
|
-
mode: ThemeColorMode.default,
|
|
112
|
-
boardBackground: '#ffffff',
|
|
113
|
-
textColor: '#333333'
|
|
114
|
-
};
|
|
115
|
-
const ColorfulThemeColor = {
|
|
116
|
-
mode: ThemeColorMode.colorful,
|
|
117
|
-
boardBackground: '#ffffff',
|
|
118
|
-
textColor: '#333333'
|
|
119
|
-
};
|
|
120
|
-
const SoftThemeColor = {
|
|
121
|
-
mode: ThemeColorMode.soft,
|
|
122
|
-
boardBackground: '#f5f5f5',
|
|
123
|
-
textColor: '#333333'
|
|
124
|
-
};
|
|
125
|
-
const RetroThemeColor = {
|
|
126
|
-
mode: ThemeColorMode.retro,
|
|
127
|
-
boardBackground: '#f9f8ed',
|
|
128
|
-
textColor: '#333333'
|
|
129
|
-
};
|
|
130
|
-
const DarkThemeColor = {
|
|
131
|
-
mode: ThemeColorMode.dark,
|
|
132
|
-
boardBackground: '#141414',
|
|
133
|
-
textColor: '#FFFFFF'
|
|
134
|
-
};
|
|
135
|
-
const StarryThemeColor = {
|
|
136
|
-
mode: ThemeColorMode.starry,
|
|
137
|
-
boardBackground: '#0d2537',
|
|
138
|
-
textColor: '#FFFFFF'
|
|
139
|
-
};
|
|
140
|
-
const ThemeColors = [
|
|
141
|
-
DefaultThemeColor,
|
|
142
|
-
ColorfulThemeColor,
|
|
143
|
-
SoftThemeColor,
|
|
144
|
-
RetroThemeColor,
|
|
145
|
-
DarkThemeColor,
|
|
146
|
-
StarryThemeColor
|
|
147
|
-
];
|
|
148
|
-
|
|
149
|
-
const RectangleClient = {
|
|
150
|
-
isHit: (origin, target) => {
|
|
151
|
-
const minX = origin.x < target.x ? origin.x : target.x;
|
|
152
|
-
const maxX = origin.x + origin.width > target.x + target.width ? origin.x + origin.width : target.x + target.width;
|
|
153
|
-
const minY = origin.y < target.y ? origin.y : target.y;
|
|
154
|
-
const maxY = origin.y + origin.height > target.y + target.height ? origin.y + origin.height : target.y + target.height;
|
|
155
|
-
// float calculate error( eg: 1.4210854715202004e-14 > 0)
|
|
156
|
-
if (Math.floor(maxX - minX - origin.width - target.width) <= 0 && Math.floor(maxY - minY - origin.height - target.height) <= 0) {
|
|
157
|
-
return true;
|
|
158
|
-
}
|
|
159
|
-
else {
|
|
160
|
-
return false;
|
|
161
|
-
}
|
|
162
|
-
},
|
|
163
|
-
toRectangleClient: (points) => {
|
|
164
|
-
const xArray = points.map(ele => ele[0]);
|
|
165
|
-
const yArray = points.map(ele => ele[1]);
|
|
166
|
-
const xMin = Math.min(...xArray);
|
|
167
|
-
const xMax = Math.max(...xArray);
|
|
168
|
-
const yMin = Math.min(...yArray);
|
|
169
|
-
const yMax = Math.max(...yArray);
|
|
170
|
-
const rect = { x: xMin, y: yMin, width: xMax - xMin, height: yMax - yMin };
|
|
171
|
-
return rect;
|
|
172
|
-
},
|
|
173
|
-
getOutlineRectangle: (rectangle, offset) => {
|
|
174
|
-
return {
|
|
175
|
-
x: rectangle.x + offset,
|
|
176
|
-
y: rectangle.y + offset,
|
|
177
|
-
width: rectangle.width + Math.abs(offset) * 2,
|
|
178
|
-
height: rectangle.height + Math.abs(offset) * 2
|
|
179
|
-
};
|
|
180
|
-
},
|
|
181
|
-
isEqual: (rectangle, otherRectangle) => {
|
|
182
|
-
return (rectangle.x === otherRectangle.x &&
|
|
183
|
-
rectangle.y === otherRectangle.y &&
|
|
184
|
-
rectangle.width === otherRectangle.width &&
|
|
185
|
-
rectangle.height === otherRectangle.height);
|
|
186
|
-
},
|
|
187
|
-
getCornerPoints: (rectangle) => {
|
|
188
|
-
return [
|
|
189
|
-
[rectangle.x, rectangle.y],
|
|
190
|
-
[rectangle.x + rectangle.width, rectangle.y],
|
|
191
|
-
[rectangle.x + rectangle.width, rectangle.y + rectangle.height],
|
|
192
|
-
[rectangle.x, rectangle.y + rectangle.height]
|
|
193
|
-
];
|
|
194
|
-
}
|
|
195
|
-
};
|
|
196
|
-
|
|
197
|
-
// https://stackoverflow.com/a/6853926/232122
|
|
198
|
-
function distanceBetweenPointAndSegment(x, y, x1, y1, x2, y2) {
|
|
199
|
-
const A = x - x1;
|
|
200
|
-
const B = y - y1;
|
|
201
|
-
const C = x2 - x1;
|
|
202
|
-
const D = y2 - y1;
|
|
203
|
-
const dot = A * C + B * D;
|
|
204
|
-
const lenSquare = C * C + D * D;
|
|
205
|
-
let param = -1;
|
|
206
|
-
if (lenSquare !== 0) {
|
|
207
|
-
// in case of 0 length line
|
|
208
|
-
param = dot / lenSquare;
|
|
209
|
-
}
|
|
210
|
-
let xx, yy;
|
|
211
|
-
if (param < 0) {
|
|
212
|
-
xx = x1;
|
|
213
|
-
yy = y1;
|
|
214
|
-
}
|
|
215
|
-
else if (param > 1) {
|
|
216
|
-
xx = x2;
|
|
217
|
-
yy = y2;
|
|
218
|
-
}
|
|
219
|
-
else {
|
|
220
|
-
xx = x1 + param * C;
|
|
221
|
-
yy = y1 + param * D;
|
|
222
|
-
}
|
|
223
|
-
const dx = x - xx;
|
|
224
|
-
const dy = y - yy;
|
|
225
|
-
return Math.hypot(dx, dy);
|
|
226
|
-
}
|
|
227
|
-
function distanceBetweenPointAndSegments(points, point) {
|
|
228
|
-
const len = points.length;
|
|
229
|
-
let distance = Infinity;
|
|
230
|
-
for (let i = 0; i < len - 1; i++) {
|
|
231
|
-
const p = points[i];
|
|
232
|
-
const p2 = points[i + 1];
|
|
233
|
-
const currentDistance = distanceBetweenPointAndSegment(point[0], point[1], p[0], p[1], p2[0], p2[1]);
|
|
234
|
-
if (currentDistance < distance) {
|
|
235
|
-
distance = currentDistance;
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
return distance;
|
|
239
|
-
}
|
|
240
|
-
function rotate(x1, y1, x2, y2, angle) {
|
|
241
|
-
// 𝑎′𝑥=(𝑎𝑥−𝑐𝑥)cos𝜃−(𝑎𝑦−𝑐𝑦)sin𝜃+𝑐𝑥
|
|
242
|
-
// 𝑎′𝑦=(𝑎𝑥−𝑐𝑥)sin𝜃+(𝑎𝑦−𝑐𝑦)cos𝜃+𝑐𝑦.
|
|
243
|
-
// https://math.stackexchange.com/questions/2204520/how-do-i-rotate-a-line-segment-in-a-specific-point-on-the-line
|
|
244
|
-
return [(x1 - x2) * Math.cos(angle) - (y1 - y2) * Math.sin(angle) + x2, (x1 - x2) * Math.sin(angle) + (y1 - y2) * Math.cos(angle) + y2];
|
|
245
|
-
}
|
|
246
|
-
function distanceBetweenPointAndPoint(x1, y1, x2, y2) {
|
|
247
|
-
const dx = x1 - x2;
|
|
248
|
-
const dy = y1 - y2;
|
|
249
|
-
return Math.hypot(dx, dy);
|
|
250
|
-
}
|
|
251
|
-
// https://stackoverflow.com/questions/5254838/calculating-distance-between-a-point-and-a-rectangular-box-nearest-point
|
|
252
|
-
function distanceBetweenPointAndRectangle(x, y, rect) {
|
|
253
|
-
var dx = Math.max(rect.x - x, 0, x - (rect.x + rect.width));
|
|
254
|
-
var dy = Math.max(rect.y - y, 0, y - (rect.y + rect.height));
|
|
255
|
-
return Math.sqrt(dx * dx + dy * dy);
|
|
256
|
-
}
|
|
257
|
-
const isLineHitLine = (a, b, c, d) => {
|
|
258
|
-
const crossProduct = (v1, v2) => v1[0] * v2[1] - v1[1] * v2[0];
|
|
259
|
-
const ab = [b[0] - a[0], b[1] - a[1]];
|
|
260
|
-
const ac = [c[0] - a[0], c[1] - a[1]];
|
|
261
|
-
const ad = [d[0] - a[0], d[1] - a[1]];
|
|
262
|
-
const ca = [a[0] - c[0], a[1] - c[1]];
|
|
263
|
-
const cb = [b[0] - c[0], b[1] - c[1]];
|
|
264
|
-
const cd = [d[0] - c[0], d[1] - c[1]];
|
|
265
|
-
return crossProduct(ab, ac) * crossProduct(ab, ad) <= 0 && crossProduct(cd, ca) * crossProduct(cd, cb) <= 0;
|
|
266
|
-
};
|
|
267
|
-
const isPolylineHitRectangle = (points, rectangle) => {
|
|
268
|
-
const rectanglePoints = RectangleClient.getCornerPoints(rectangle);
|
|
269
|
-
for (let i = 1; i < points.length; i++) {
|
|
270
|
-
const isIntersect = isLineHitLine(points[i], points[i - 1], rectanglePoints[0], rectanglePoints[1]) ||
|
|
271
|
-
isLineHitLine(points[i], points[i - 1], rectanglePoints[1], rectanglePoints[2]) ||
|
|
272
|
-
isLineHitLine(points[i], points[i - 1], rectanglePoints[2], rectanglePoints[3]) ||
|
|
273
|
-
isLineHitLine(points[i], points[i - 1], rectanglePoints[3], rectanglePoints[0]);
|
|
274
|
-
if (isIntersect) {
|
|
275
|
-
return true;
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
return false;
|
|
279
|
-
};
|
|
280
|
-
|
|
281
|
-
const PlaitBoard = {
|
|
282
|
-
isBoard(value) {
|
|
283
|
-
const cachedIsBoard = IS_BOARD_CACHE.get(value);
|
|
284
|
-
if (cachedIsBoard !== undefined) {
|
|
285
|
-
return cachedIsBoard;
|
|
286
|
-
}
|
|
287
|
-
const isBoard = typeof value.onChange === 'function' && typeof value.apply === 'function';
|
|
288
|
-
IS_BOARD_CACHE.set(value, isBoard);
|
|
289
|
-
return isBoard;
|
|
290
|
-
},
|
|
291
|
-
findPath(board, node) {
|
|
292
|
-
const path = [];
|
|
293
|
-
let child = node;
|
|
294
|
-
while (true) {
|
|
295
|
-
const parent = NODE_TO_PARENT.get(child);
|
|
296
|
-
if (parent == null) {
|
|
297
|
-
if (PlaitBoard.isBoard(child)) {
|
|
298
|
-
return path;
|
|
299
|
-
}
|
|
300
|
-
else {
|
|
301
|
-
break;
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
const i = NODE_TO_INDEX.get(child);
|
|
305
|
-
if (i == null) {
|
|
306
|
-
break;
|
|
307
|
-
}
|
|
308
|
-
path.unshift(i);
|
|
309
|
-
child = parent;
|
|
310
|
-
}
|
|
311
|
-
throw new Error(`Unable to find the path for Plait node: ${JSON.stringify(node)}`);
|
|
312
|
-
},
|
|
313
|
-
getHost(board) {
|
|
314
|
-
return BOARD_TO_HOST.get(board);
|
|
315
|
-
},
|
|
316
|
-
getElementHost(board) {
|
|
317
|
-
var _a;
|
|
318
|
-
return (_a = BOARD_TO_ELEMENT_HOST.get(board)) === null || _a === void 0 ? void 0 : _a.host;
|
|
319
|
-
},
|
|
320
|
-
getElementUpperHost(board) {
|
|
321
|
-
var _a;
|
|
322
|
-
return (_a = BOARD_TO_ELEMENT_HOST.get(board)) === null || _a === void 0 ? void 0 : _a.upperHost;
|
|
323
|
-
},
|
|
324
|
-
getElementActiveHost(board) {
|
|
325
|
-
var _a;
|
|
326
|
-
return (_a = BOARD_TO_ELEMENT_HOST.get(board)) === null || _a === void 0 ? void 0 : _a.activeHost;
|
|
327
|
-
},
|
|
328
|
-
getRoughSVG(board) {
|
|
329
|
-
return BOARD_TO_ROUGH_SVG.get(board);
|
|
330
|
-
},
|
|
331
|
-
getComponent(board) {
|
|
332
|
-
return BOARD_TO_COMPONENT.get(board);
|
|
333
|
-
},
|
|
334
|
-
getBoardContainer(board) {
|
|
335
|
-
return PlaitBoard.getComponent(board).nativeElement;
|
|
336
|
-
},
|
|
337
|
-
getRectangle(board) {
|
|
338
|
-
return getRectangleByElements(board, board.children, true);
|
|
339
|
-
},
|
|
340
|
-
getViewportContainer(board) {
|
|
341
|
-
return PlaitBoard.getHost(board).parentElement;
|
|
342
|
-
},
|
|
343
|
-
isFocus(board) {
|
|
344
|
-
return !!board.selection;
|
|
345
|
-
},
|
|
346
|
-
isReadonly(board) {
|
|
347
|
-
return board.options.readonly;
|
|
348
|
-
},
|
|
349
|
-
hasBeenTextEditing(board) {
|
|
350
|
-
return !!IS_TEXT_EDITABLE.get(board);
|
|
351
|
-
},
|
|
352
|
-
getPointer(board) {
|
|
353
|
-
return board.pointer;
|
|
354
|
-
},
|
|
355
|
-
isPointer(board, pointer) {
|
|
356
|
-
return board.pointer === pointer;
|
|
357
|
-
},
|
|
358
|
-
isInPointer(board, pointers) {
|
|
359
|
-
const point = board.pointer;
|
|
360
|
-
return pointers.includes(point);
|
|
361
|
-
},
|
|
362
|
-
getMovingPointInBoard(board) {
|
|
363
|
-
return BOARD_TO_MOVING_POINT_IN_BOARD.get(board);
|
|
364
|
-
},
|
|
365
|
-
isMovingPointInBoard(board) {
|
|
366
|
-
const point = BOARD_TO_MOVING_POINT.get(board);
|
|
367
|
-
const rect = PlaitBoard.getBoardContainer(board).getBoundingClientRect();
|
|
368
|
-
if (point && distanceBetweenPointAndRectangle(point[0], point[1], rect) === 0) {
|
|
369
|
-
return true;
|
|
370
|
-
}
|
|
371
|
-
return false;
|
|
372
|
-
},
|
|
373
|
-
getThemeColors(board) {
|
|
374
|
-
return (board.options.themeColors || ThemeColors);
|
|
375
|
-
}
|
|
376
|
-
};
|
|
377
|
-
|
|
378
|
-
var PlaitPointerType;
|
|
379
|
-
(function (PlaitPointerType) {
|
|
380
|
-
PlaitPointerType["hand"] = "hand";
|
|
381
|
-
PlaitPointerType["selection"] = "selection";
|
|
382
|
-
})(PlaitPointerType || (PlaitPointerType = {}));
|
|
383
|
-
|
|
384
|
-
function isNullOrUndefined(value) {
|
|
385
|
-
return value === null || value === undefined;
|
|
386
|
-
}
|
|
387
|
-
/**
|
|
388
|
-
* 规范 point
|
|
389
|
-
* @param point
|
|
390
|
-
* @returns point
|
|
391
|
-
*/
|
|
392
|
-
function normalizePoint(point) {
|
|
393
|
-
return Array.isArray(point)
|
|
394
|
-
? {
|
|
395
|
-
x: point[0],
|
|
396
|
-
y: point[1]
|
|
397
|
-
}
|
|
398
|
-
: point;
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
const Viewport = {
|
|
402
|
-
isViewport: (value) => {
|
|
403
|
-
return !isNullOrUndefined(value.zoom) && !isNullOrUndefined(value.viewBackgroundColor);
|
|
404
|
-
},
|
|
405
|
-
};
|
|
406
|
-
|
|
407
|
-
const Path = {
|
|
408
|
-
/**
|
|
409
|
-
* Get a list of ancestor paths for a given path.
|
|
410
|
-
*
|
|
411
|
-
* The paths are sorted from shallowest to deepest ancestor. However, if the
|
|
412
|
-
* `reverse: true` option is passed, they are reversed.
|
|
413
|
-
*/
|
|
414
|
-
ancestors(path, options = {}) {
|
|
415
|
-
const { reverse = false } = options;
|
|
416
|
-
let paths = Path.levels(path, options);
|
|
417
|
-
if (reverse) {
|
|
418
|
-
paths = paths.slice(1);
|
|
419
|
-
}
|
|
420
|
-
else {
|
|
421
|
-
paths = paths.slice(0, -1);
|
|
422
|
-
}
|
|
423
|
-
return paths;
|
|
424
|
-
},
|
|
425
|
-
/**
|
|
426
|
-
* Get a list of paths at every level down to a path. Note: this is the same
|
|
427
|
-
* as `Path.ancestors`, but including the path itself.
|
|
428
|
-
*
|
|
429
|
-
* The paths are sorted from shallowest to deepest. However, if the `reverse:
|
|
430
|
-
* true` option is passed, they are reversed.
|
|
431
|
-
*/
|
|
432
|
-
levels(path, options = {}) {
|
|
433
|
-
const { reverse = false } = options;
|
|
434
|
-
const list = [];
|
|
435
|
-
for (let i = 0; i <= path.length; i++) {
|
|
436
|
-
list.push(path.slice(0, i));
|
|
437
|
-
}
|
|
438
|
-
if (reverse) {
|
|
439
|
-
list.reverse();
|
|
440
|
-
}
|
|
441
|
-
return list;
|
|
442
|
-
},
|
|
443
|
-
parent(path) {
|
|
444
|
-
if (path.length === 0) {
|
|
445
|
-
throw new Error(`Cannot get the parent path of the root path [${path}].`);
|
|
446
|
-
}
|
|
447
|
-
return path.slice(0, -1);
|
|
448
|
-
},
|
|
449
|
-
next(path) {
|
|
450
|
-
if (path.length === 0) {
|
|
451
|
-
throw new Error(`Cannot get the next path of a root path [${path}], because it has no next index.`);
|
|
452
|
-
}
|
|
453
|
-
const last = path[path.length - 1];
|
|
454
|
-
return path.slice(0, -1).concat(last + 1);
|
|
455
|
-
},
|
|
456
|
-
hasPrevious(path) {
|
|
457
|
-
return path[path.length - 1] > 0;
|
|
458
|
-
},
|
|
459
|
-
previous(path) {
|
|
460
|
-
if (path.length === 0) {
|
|
461
|
-
throw new Error(`Cannot get the next path of a root path [${path}], because it has no previous index.`);
|
|
462
|
-
}
|
|
463
|
-
const last = path[path.length - 1];
|
|
464
|
-
return path.slice(0, -1).concat(last - 1);
|
|
465
|
-
},
|
|
466
|
-
/**
|
|
467
|
-
* Check if a path is an ancestor of another.
|
|
468
|
-
*/
|
|
469
|
-
isAncestor(path, another) {
|
|
470
|
-
return path.length < another.length && Path.compare(path, another) === 0;
|
|
471
|
-
},
|
|
472
|
-
/**
|
|
473
|
-
* Compare a path to another, returning an integer indicating whether the path
|
|
474
|
-
* was before, at, or after the other.
|
|
475
|
-
*
|
|
476
|
-
* Note: Two paths of unequal length can still receive a `0` result if one is
|
|
477
|
-
* directly above or below the other. If you want exact matching, use
|
|
478
|
-
* [[Path.equals]] instead.
|
|
479
|
-
*/
|
|
480
|
-
compare(path, another) {
|
|
481
|
-
const min = Math.min(path.length, another.length);
|
|
482
|
-
for (let i = 0; i < min; i++) {
|
|
483
|
-
if (path[i] < another[i])
|
|
484
|
-
return -1;
|
|
485
|
-
if (path[i] > another[i])
|
|
486
|
-
return 1;
|
|
487
|
-
}
|
|
488
|
-
return 0;
|
|
489
|
-
},
|
|
490
|
-
/**
|
|
491
|
-
* Check if a path is exactly equal to another.
|
|
492
|
-
*/
|
|
493
|
-
equals(path, another) {
|
|
494
|
-
return path.length === another.length && path.every((n, i) => n === another[i]);
|
|
495
|
-
},
|
|
496
|
-
/**
|
|
497
|
-
* Check if a path ends before one of the indexes in another.
|
|
498
|
-
*/
|
|
499
|
-
endsBefore(path, another) {
|
|
500
|
-
const i = path.length - 1;
|
|
501
|
-
const as = path.slice(0, i);
|
|
502
|
-
const bs = another.slice(0, i);
|
|
503
|
-
const av = path[i];
|
|
504
|
-
const bv = another[i];
|
|
505
|
-
return Path.equals(as, bs) && av < bv;
|
|
506
|
-
},
|
|
507
|
-
/**
|
|
508
|
-
* Check if a path is a sibling of another.
|
|
509
|
-
*/
|
|
510
|
-
isSibling(path, another) {
|
|
511
|
-
if (path.length !== another.length) {
|
|
512
|
-
return false;
|
|
513
|
-
}
|
|
514
|
-
const as = path.slice(0, -1);
|
|
515
|
-
const bs = another.slice(0, -1);
|
|
516
|
-
const al = path[path.length - 1];
|
|
517
|
-
const bl = another[another.length - 1];
|
|
518
|
-
return al !== bl && Path.equals(as, bs);
|
|
519
|
-
},
|
|
520
|
-
transform(path, operation) {
|
|
521
|
-
return produce(path, p => {
|
|
522
|
-
// PERF: Exit early if the operation is guaranteed not to have an effect.
|
|
523
|
-
if (!path || (path === null || path === void 0 ? void 0 : path.length) === 0) {
|
|
524
|
-
return;
|
|
525
|
-
}
|
|
526
|
-
if (p === null) {
|
|
527
|
-
return null;
|
|
528
|
-
}
|
|
529
|
-
switch (operation.type) {
|
|
530
|
-
case 'insert_node': {
|
|
531
|
-
const { path: op } = operation;
|
|
532
|
-
if (Path.equals(op, p) || Path.endsBefore(op, p) || Path.isAncestor(op, p)) {
|
|
533
|
-
p[op.length - 1] += 1;
|
|
534
|
-
}
|
|
535
|
-
break;
|
|
536
|
-
}
|
|
537
|
-
case 'remove_node': {
|
|
538
|
-
const { path: op } = operation;
|
|
539
|
-
if (Path.equals(op, p) || Path.isAncestor(op, p)) {
|
|
540
|
-
return null;
|
|
541
|
-
}
|
|
542
|
-
else if (Path.endsBefore(op, p)) {
|
|
543
|
-
p[op.length - 1] -= 1;
|
|
544
|
-
}
|
|
545
|
-
break;
|
|
546
|
-
}
|
|
547
|
-
case 'move_node': {
|
|
548
|
-
const { path: op, newPath: onp } = operation;
|
|
549
|
-
// If the old and new path are the same, it's a no-op.
|
|
550
|
-
if (Path.equals(op, onp)) {
|
|
551
|
-
return;
|
|
552
|
-
}
|
|
553
|
-
if (Path.isAncestor(op, p) || Path.equals(op, p)) {
|
|
554
|
-
const copy = onp.slice();
|
|
555
|
-
// op.length <= onp.length is different for slate
|
|
556
|
-
// resolve drag from [0, 0] to [0, 3] issue
|
|
557
|
-
if (Path.endsBefore(op, onp) && op.length <= onp.length) {
|
|
558
|
-
copy[op.length - 1] -= 1;
|
|
559
|
-
}
|
|
560
|
-
return copy.concat(p.slice(op.length));
|
|
561
|
-
}
|
|
562
|
-
else if (Path.isSibling(op, onp) && (Path.isAncestor(onp, p) || Path.equals(onp, p))) {
|
|
563
|
-
if (Path.endsBefore(op, p)) {
|
|
564
|
-
p[op.length - 1] -= 1;
|
|
565
|
-
}
|
|
566
|
-
else {
|
|
567
|
-
p[op.length - 1] += 1;
|
|
568
|
-
}
|
|
569
|
-
}
|
|
570
|
-
else if (Path.endsBefore(onp, p) || Path.equals(onp, p) || Path.isAncestor(onp, p)) {
|
|
571
|
-
if (Path.endsBefore(op, p)) {
|
|
572
|
-
p[op.length - 1] -= 1;
|
|
573
|
-
}
|
|
574
|
-
p[onp.length - 1] += 1;
|
|
575
|
-
}
|
|
576
|
-
else if (Path.endsBefore(op, p)) {
|
|
577
|
-
if (Path.equals(onp, p)) {
|
|
578
|
-
p[onp.length - 1] += 1;
|
|
579
|
-
}
|
|
580
|
-
p[op.length - 1] -= 1;
|
|
581
|
-
}
|
|
582
|
-
break;
|
|
583
|
-
}
|
|
584
|
-
}
|
|
585
|
-
return p;
|
|
586
|
-
});
|
|
587
|
-
}
|
|
588
|
-
};
|
|
589
|
-
|
|
590
|
-
const PlaitNode = {
|
|
591
|
-
parent: (board, path) => {
|
|
592
|
-
const parentPath = Path.parent(path);
|
|
593
|
-
const p = PlaitNode.get(board, parentPath);
|
|
594
|
-
return p;
|
|
595
|
-
},
|
|
596
|
-
/**
|
|
597
|
-
* Return a generator of all the ancestor nodes above a specific path.
|
|
598
|
-
*
|
|
599
|
-
* By default the order is top-down, from highest to lowest ancestor in
|
|
600
|
-
* the tree, but you can pass the `reverse: true` option to go bottom-up.
|
|
601
|
-
*/
|
|
602
|
-
*parents(root, path, options = {}) {
|
|
603
|
-
for (const p of Path.ancestors(path, options)) {
|
|
604
|
-
const n = PlaitNode.get(root, p);
|
|
605
|
-
yield n;
|
|
606
|
-
}
|
|
607
|
-
},
|
|
608
|
-
get(root, path) {
|
|
609
|
-
let node = root;
|
|
610
|
-
for (let i = 0; i < path.length; i++) {
|
|
611
|
-
const p = path[i];
|
|
612
|
-
if (!node || !node.children || !node.children[p]) {
|
|
613
|
-
throw new Error(`Cannot find a descendant at path [${path}]`);
|
|
614
|
-
}
|
|
615
|
-
node = node.children[p];
|
|
616
|
-
}
|
|
617
|
-
return node;
|
|
618
|
-
},
|
|
619
|
-
last(board, path) {
|
|
620
|
-
let n = PlaitNode.get(board, path);
|
|
621
|
-
while (n && n.children && n.children.length > 0) {
|
|
622
|
-
const i = n.children.length - 1;
|
|
623
|
-
n = n.children[i];
|
|
624
|
-
}
|
|
625
|
-
return n;
|
|
626
|
-
}
|
|
627
|
-
};
|
|
628
|
-
|
|
629
|
-
const applyToDraft = (board, selection, viewport, theme, op) => {
|
|
630
|
-
var _a, _b;
|
|
631
|
-
switch (op.type) {
|
|
632
|
-
case 'insert_node': {
|
|
633
|
-
const { path, node } = op;
|
|
634
|
-
const parent = PlaitNode.parent(board, path);
|
|
635
|
-
const index = path[path.length - 1];
|
|
636
|
-
if (!parent.children || index > parent.children.length) {
|
|
637
|
-
throw new Error(`Cannot apply an "insert_node" operation at path [${path}] because the destination is past the end of the node.`);
|
|
638
|
-
}
|
|
639
|
-
parent.children.splice(index, 0, node);
|
|
640
|
-
break;
|
|
641
|
-
}
|
|
642
|
-
case 'remove_node': {
|
|
643
|
-
const { path } = op;
|
|
644
|
-
const parent = PlaitNode.parent(board, path);
|
|
645
|
-
const index = path[path.length - 1];
|
|
646
|
-
if (!parent.children || index > parent.children.length) {
|
|
647
|
-
throw new Error(`Cannot apply an "insert_node" operation at path [${path}] because the destination is past the end of the node.`);
|
|
648
|
-
}
|
|
649
|
-
parent.children.splice(index, 1);
|
|
650
|
-
break;
|
|
651
|
-
}
|
|
652
|
-
case 'move_node': {
|
|
653
|
-
const { path, newPath } = op;
|
|
654
|
-
if (Path.isAncestor(path, newPath)) {
|
|
655
|
-
throw new Error(`Cannot move a path [${path}] to new path [${newPath}] because the destination is inside itself.`);
|
|
656
|
-
}
|
|
657
|
-
const node = PlaitNode.get(board, path);
|
|
658
|
-
const parent = PlaitNode.parent(board, path);
|
|
659
|
-
const index = path[path.length - 1];
|
|
660
|
-
// This is tricky, but since the `path` and `newPath` both refer to
|
|
661
|
-
// the same snapshot in time, there's a mismatch. After either
|
|
662
|
-
// removing the original position, the second step's path can be out
|
|
663
|
-
// of date. So instead of using the `op.newPath` directly, we
|
|
664
|
-
// transform `op.path` to ascertain what the `newPath` would be after
|
|
665
|
-
// the operation was applied.
|
|
666
|
-
(_a = parent.children) === null || _a === void 0 ? void 0 : _a.splice(index, 1);
|
|
667
|
-
const truePath = Path.transform(path, op);
|
|
668
|
-
const newParent = PlaitNode.get(board, Path.parent(truePath));
|
|
669
|
-
const newIndex = truePath[truePath.length - 1];
|
|
670
|
-
(_b = newParent.children) === null || _b === void 0 ? void 0 : _b.splice(newIndex, 0, node);
|
|
671
|
-
break;
|
|
672
|
-
}
|
|
673
|
-
case 'set_node': {
|
|
674
|
-
const { path, properties, newProperties } = op;
|
|
675
|
-
if (path.length === 0) {
|
|
676
|
-
throw new Error(`Cannot set properties on the root node!`);
|
|
677
|
-
}
|
|
678
|
-
const node = PlaitNode.get(board, path);
|
|
679
|
-
for (const key in newProperties) {
|
|
680
|
-
const value = newProperties[key];
|
|
681
|
-
if (value == null) {
|
|
682
|
-
delete node[key];
|
|
683
|
-
}
|
|
684
|
-
else {
|
|
685
|
-
node[key] = value;
|
|
686
|
-
}
|
|
687
|
-
}
|
|
688
|
-
// properties that were previously defined, but are now missing, must be deleted
|
|
689
|
-
for (const key in properties) {
|
|
690
|
-
if (!newProperties.hasOwnProperty(key)) {
|
|
691
|
-
delete node[key];
|
|
692
|
-
}
|
|
693
|
-
}
|
|
694
|
-
break;
|
|
695
|
-
}
|
|
696
|
-
case 'set_viewport': {
|
|
697
|
-
const { newProperties } = op;
|
|
698
|
-
if (newProperties == null) {
|
|
699
|
-
viewport = newProperties;
|
|
700
|
-
}
|
|
701
|
-
else {
|
|
702
|
-
if (viewport == null) {
|
|
703
|
-
if (!Viewport.isViewport(newProperties)) {
|
|
704
|
-
throw new Error(`Cannot apply an incomplete "set_viewport" operation properties ${JSON.stringify(newProperties)} when there is no current viewport.`);
|
|
705
|
-
}
|
|
706
|
-
viewport = Object.assign({}, newProperties);
|
|
707
|
-
}
|
|
708
|
-
for (const key in newProperties) {
|
|
709
|
-
const value = newProperties[key];
|
|
710
|
-
if (value == null) {
|
|
711
|
-
delete viewport[key];
|
|
712
|
-
}
|
|
713
|
-
else {
|
|
714
|
-
viewport[key] = value;
|
|
715
|
-
}
|
|
716
|
-
}
|
|
717
|
-
}
|
|
718
|
-
break;
|
|
719
|
-
}
|
|
720
|
-
case 'set_selection': {
|
|
721
|
-
const { newProperties } = op;
|
|
722
|
-
if (newProperties == null) {
|
|
723
|
-
selection = newProperties;
|
|
724
|
-
}
|
|
725
|
-
else {
|
|
726
|
-
if (selection === null) {
|
|
727
|
-
selection = op.newProperties;
|
|
728
|
-
}
|
|
729
|
-
else {
|
|
730
|
-
selection.ranges = newProperties.ranges;
|
|
731
|
-
}
|
|
732
|
-
}
|
|
733
|
-
break;
|
|
734
|
-
}
|
|
735
|
-
case 'set_theme': {
|
|
736
|
-
const { newProperties } = op;
|
|
737
|
-
theme = newProperties;
|
|
738
|
-
break;
|
|
739
|
-
}
|
|
740
|
-
}
|
|
741
|
-
return { selection, viewport, theme };
|
|
742
|
-
};
|
|
743
|
-
const GeneralTransforms = {
|
|
744
|
-
/**
|
|
745
|
-
* Transform the board by an operation.
|
|
746
|
-
*/
|
|
747
|
-
transform(board, op) {
|
|
748
|
-
board.children = createDraft(board.children);
|
|
749
|
-
let viewport = board.viewport && createDraft(board.viewport);
|
|
750
|
-
let selection = board.selection && createDraft(board.selection);
|
|
751
|
-
let theme = board.theme && createDraft(board.theme);
|
|
752
|
-
try {
|
|
753
|
-
const state = applyToDraft(board, selection, viewport, theme, op);
|
|
754
|
-
viewport = state.viewport;
|
|
755
|
-
selection = state.selection;
|
|
756
|
-
theme = state.theme;
|
|
757
|
-
}
|
|
758
|
-
finally {
|
|
759
|
-
board.children = finishDraft(board.children);
|
|
760
|
-
if (selection) {
|
|
761
|
-
board.selection = isDraft(selection) ? finishDraft(selection) : selection;
|
|
762
|
-
}
|
|
763
|
-
else {
|
|
764
|
-
board.selection = null;
|
|
765
|
-
}
|
|
766
|
-
board.viewport = isDraft(viewport) ? finishDraft(viewport) : viewport;
|
|
767
|
-
board.theme = isDraft(theme) ? finishDraft(theme) : theme;
|
|
768
|
-
}
|
|
769
|
-
}
|
|
770
|
-
};
|
|
771
|
-
|
|
772
|
-
function insertNode(board, node, path) {
|
|
773
|
-
const operation = { type: 'insert_node', node, path };
|
|
774
|
-
board.apply(operation);
|
|
775
|
-
}
|
|
776
|
-
function setNode(board, props, path) {
|
|
777
|
-
const properties = {};
|
|
778
|
-
const newProperties = {};
|
|
779
|
-
const node = PlaitNode.get(board, path);
|
|
780
|
-
for (const k in props) {
|
|
781
|
-
if (node[k] !== props[k]) {
|
|
782
|
-
if (node.hasOwnProperty(k)) {
|
|
783
|
-
properties[k] = node[k];
|
|
784
|
-
}
|
|
785
|
-
if (props[k] != null)
|
|
786
|
-
newProperties[k] = props[k];
|
|
787
|
-
}
|
|
788
|
-
}
|
|
789
|
-
const operation = { type: 'set_node', properties, newProperties, path };
|
|
790
|
-
board.apply(operation);
|
|
791
|
-
}
|
|
792
|
-
function removeNode(board, path) {
|
|
793
|
-
const node = PlaitNode.get(board, path);
|
|
794
|
-
const operation = { type: 'remove_node', path, node };
|
|
795
|
-
board.apply(operation);
|
|
796
|
-
}
|
|
797
|
-
function moveNode(board, path, newPath) {
|
|
798
|
-
const operation = { type: 'move_node', path, newPath };
|
|
799
|
-
board.apply(operation);
|
|
800
|
-
}
|
|
801
|
-
const NodeTransforms = {
|
|
802
|
-
insertNode,
|
|
803
|
-
setNode,
|
|
804
|
-
removeNode,
|
|
805
|
-
moveNode
|
|
806
|
-
};
|
|
807
|
-
|
|
808
|
-
function setSelection(board, selection) {
|
|
809
|
-
const operation = { type: 'set_selection', properties: board.selection, newProperties: selection };
|
|
810
|
-
board.apply(operation);
|
|
811
|
-
}
|
|
812
|
-
const SelectionTransforms = {
|
|
813
|
-
setSelection,
|
|
814
|
-
setSelectionWithTemporaryElements
|
|
815
|
-
};
|
|
816
|
-
function setSelectionWithTemporaryElements(board, elements) {
|
|
817
|
-
setTimeout(() => {
|
|
818
|
-
BOARD_TO_TEMPORARY_ELEMENTS.set(board, elements);
|
|
819
|
-
setSelection(board, { ranges: [] });
|
|
820
|
-
});
|
|
821
|
-
}
|
|
822
|
-
|
|
823
|
-
function setViewport(board, viewport) {
|
|
824
|
-
const operation = { type: 'set_viewport', properties: board.viewport, newProperties: viewport };
|
|
825
|
-
board.apply(operation);
|
|
826
|
-
}
|
|
827
|
-
const ViewportTransforms$1 = {
|
|
828
|
-
setViewport
|
|
829
|
-
};
|
|
830
|
-
|
|
831
|
-
/**
|
|
832
|
-
* @license
|
|
833
|
-
* Copyright Google LLC All Rights Reserved.
|
|
834
|
-
*
|
|
835
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
836
|
-
* found in the LICENSE file at https://angular.io/license
|
|
837
|
-
*/
|
|
838
|
-
const MAC_ENTER = 3;
|
|
839
|
-
const BACKSPACE = 8;
|
|
840
|
-
const TAB = 9;
|
|
841
|
-
const NUM_CENTER = 12;
|
|
842
|
-
const ENTER = 13;
|
|
843
|
-
const SHIFT = 16;
|
|
844
|
-
const CONTROL = 17;
|
|
845
|
-
const ALT = 18;
|
|
846
|
-
const PAUSE = 19;
|
|
847
|
-
const CAPS_LOCK = 20;
|
|
848
|
-
const ESCAPE = 27;
|
|
849
|
-
const SPACE = 32;
|
|
850
|
-
const PAGE_UP = 33;
|
|
851
|
-
const PAGE_DOWN = 34;
|
|
852
|
-
const END = 35;
|
|
853
|
-
const HOME = 36;
|
|
854
|
-
const LEFT_ARROW = 37;
|
|
855
|
-
const UP_ARROW = 38;
|
|
856
|
-
const RIGHT_ARROW = 39;
|
|
857
|
-
const DOWN_ARROW = 40;
|
|
858
|
-
const PLUS_SIGN = 43;
|
|
859
|
-
const PRINT_SCREEN = 44;
|
|
860
|
-
const INSERT = 45;
|
|
861
|
-
const DELETE = 46;
|
|
862
|
-
const ZERO = 48;
|
|
863
|
-
const ONE = 49;
|
|
864
|
-
const TWO = 50;
|
|
865
|
-
const THREE = 51;
|
|
866
|
-
const FOUR = 52;
|
|
867
|
-
const FIVE = 53;
|
|
868
|
-
const SIX = 54;
|
|
869
|
-
const SEVEN = 55;
|
|
870
|
-
const EIGHT = 56;
|
|
871
|
-
const NINE = 57;
|
|
872
|
-
const FF_SEMICOLON = 59; // Firefox (Gecko) fires this for semicolon instead of 186
|
|
873
|
-
const FF_EQUALS = 61; // Firefox (Gecko) fires this for equals instead of 187
|
|
874
|
-
const QUESTION_MARK = 63;
|
|
875
|
-
const AT_SIGN = 64;
|
|
876
|
-
const A = 65;
|
|
877
|
-
const B = 66;
|
|
878
|
-
const C = 67;
|
|
879
|
-
const D = 68;
|
|
880
|
-
const E = 69;
|
|
881
|
-
const F = 70;
|
|
882
|
-
const G = 71;
|
|
883
|
-
const H = 72;
|
|
884
|
-
const I = 73;
|
|
885
|
-
const J = 74;
|
|
886
|
-
const K = 75;
|
|
887
|
-
const L = 76;
|
|
888
|
-
const M = 77;
|
|
889
|
-
const N = 78;
|
|
890
|
-
const O = 79;
|
|
891
|
-
const P = 80;
|
|
892
|
-
const Q = 81;
|
|
893
|
-
const R = 82;
|
|
894
|
-
const S = 83;
|
|
895
|
-
const T = 84;
|
|
896
|
-
const U = 85;
|
|
897
|
-
const V = 86;
|
|
898
|
-
const W = 87;
|
|
899
|
-
const X = 88;
|
|
900
|
-
const Y = 89;
|
|
901
|
-
const Z = 90;
|
|
902
|
-
const META = 91; // WIN_KEY_LEFT
|
|
903
|
-
const MAC_WK_CMD_LEFT = 91;
|
|
904
|
-
const MAC_WK_CMD_RIGHT = 93;
|
|
905
|
-
const CONTEXT_MENU = 93;
|
|
906
|
-
const NUMPAD_ZERO = 96;
|
|
907
|
-
const NUMPAD_ONE = 97;
|
|
908
|
-
const NUMPAD_TWO = 98;
|
|
909
|
-
const NUMPAD_THREE = 99;
|
|
910
|
-
const NUMPAD_FOUR = 100;
|
|
911
|
-
const NUMPAD_FIVE = 101;
|
|
912
|
-
const NUMPAD_SIX = 102;
|
|
913
|
-
const NUMPAD_SEVEN = 103;
|
|
914
|
-
const NUMPAD_EIGHT = 104;
|
|
915
|
-
const NUMPAD_NINE = 105;
|
|
916
|
-
const NUMPAD_MULTIPLY = 106;
|
|
917
|
-
const NUMPAD_PLUS = 107;
|
|
918
|
-
const NUMPAD_MINUS = 109;
|
|
919
|
-
const NUMPAD_PERIOD = 110;
|
|
920
|
-
const NUMPAD_DIVIDE = 111;
|
|
921
|
-
const F1 = 112;
|
|
922
|
-
const F2 = 113;
|
|
923
|
-
const F3 = 114;
|
|
924
|
-
const F4 = 115;
|
|
925
|
-
const F5 = 116;
|
|
926
|
-
const F6 = 117;
|
|
927
|
-
const F7 = 118;
|
|
928
|
-
const F8 = 119;
|
|
929
|
-
const F9 = 120;
|
|
930
|
-
const F10 = 121;
|
|
931
|
-
const F11 = 122;
|
|
932
|
-
const F12 = 123;
|
|
933
|
-
const NUM_LOCK = 144;
|
|
934
|
-
const SCROLL_LOCK = 145;
|
|
935
|
-
const FIRST_MEDIA = 166;
|
|
936
|
-
const FF_MINUS = 173;
|
|
937
|
-
const MUTE = 173; // Firefox (Gecko) fires 181 for MUTE
|
|
938
|
-
const VOLUME_DOWN = 174; // Firefox (Gecko) fires 182 for VOLUME_DOWN
|
|
939
|
-
const VOLUME_UP = 175; // Firefox (Gecko) fires 183 for VOLUME_UP
|
|
940
|
-
const FF_MUTE = 181;
|
|
941
|
-
const FF_VOLUME_DOWN = 182;
|
|
942
|
-
const LAST_MEDIA = 183;
|
|
943
|
-
const FF_VOLUME_UP = 183;
|
|
944
|
-
const SEMICOLON = 186; // Firefox (Gecko) fires 59 for SEMICOLON
|
|
945
|
-
const EQUALS = 187; // Firefox (Gecko) fires 61 for EQUALS
|
|
946
|
-
const COMMA = 188;
|
|
947
|
-
const DASH = 189; // Firefox (Gecko) fires 173 for DASH/MINUS
|
|
948
|
-
const PERIOD = 190;
|
|
949
|
-
const SLASH = 191;
|
|
950
|
-
const APOSTROPHE = 192;
|
|
951
|
-
const TILDE = 192;
|
|
952
|
-
const OPEN_SQUARE_BRACKET = 219;
|
|
953
|
-
const BACKSLASH = 220;
|
|
954
|
-
const CLOSE_SQUARE_BRACKET = 221;
|
|
955
|
-
const SINGLE_QUOTE = 222;
|
|
956
|
-
const MAC_META = 224;
|
|
957
|
-
|
|
958
|
-
var ResizeCursorClass;
|
|
959
|
-
(function (ResizeCursorClass) {
|
|
960
|
-
ResizeCursorClass["ew-resize"] = "ew-resize";
|
|
961
|
-
})(ResizeCursorClass || (ResizeCursorClass = {}));
|
|
962
|
-
|
|
963
|
-
const ATTACHED_ELEMENT_CLASS_NAME = 'plait-board-attached';
|
|
964
|
-
|
|
965
|
-
const CLIP_BOARD_FORMAT_KEY = 'x-plait-fragment';
|
|
966
|
-
const HOST_CLASS_NAME = 'plait-board-container';
|
|
967
|
-
const SCROLL_BAR_WIDTH = 20;
|
|
968
|
-
const MAX_RADIUS = 16;
|
|
969
|
-
const POINTER_BUTTON = {
|
|
970
|
-
MAIN: 0,
|
|
971
|
-
WHEEL: 1,
|
|
972
|
-
SECONDARY: 2,
|
|
973
|
-
TOUCH: -1
|
|
974
|
-
};
|
|
975
|
-
const PRESS_AND_MOVE_BUFFER = 5;
|
|
976
|
-
|
|
977
|
-
const NS = 'http://www.w3.org/2000/svg';
|
|
978
|
-
function toPoint(x, y, container) {
|
|
979
|
-
const rect = container.getBoundingClientRect();
|
|
980
|
-
return [x - rect.x, y - rect.y];
|
|
981
|
-
}
|
|
982
|
-
function createG() {
|
|
983
|
-
const newG = document.createElementNS(NS, 'g');
|
|
984
|
-
return newG;
|
|
985
|
-
}
|
|
986
|
-
function createPath() {
|
|
987
|
-
const newG = document.createElementNS(NS, 'path');
|
|
988
|
-
return newG;
|
|
989
|
-
}
|
|
990
|
-
function createSVG() {
|
|
991
|
-
const svg = document.createElementNS(NS, 'svg');
|
|
992
|
-
return svg;
|
|
993
|
-
}
|
|
994
|
-
function createText(x, y, fill, textContent) {
|
|
995
|
-
var text = document.createElementNS(NS, 'text');
|
|
996
|
-
text.setAttribute('x', `${x}`);
|
|
997
|
-
text.setAttribute('y', `${y}`);
|
|
998
|
-
text.setAttribute('fill', fill);
|
|
999
|
-
text.textContent = textContent;
|
|
1000
|
-
return text;
|
|
1001
|
-
}
|
|
1002
|
-
/**
|
|
1003
|
-
* Check if a DOM node is an element node.
|
|
1004
|
-
*/
|
|
1005
|
-
const isDOMElement = (value) => {
|
|
1006
|
-
return isDOMNode(value) && value.nodeType === 1;
|
|
1007
|
-
};
|
|
1008
|
-
/**
|
|
1009
|
-
* Check if a value is a DOM node.
|
|
1010
|
-
*/
|
|
1011
|
-
const isDOMNode = (value) => {
|
|
1012
|
-
return value instanceof window.Node;
|
|
1013
|
-
};
|
|
1014
|
-
const hasInputOrTextareaTarget = (target) => {
|
|
1015
|
-
if (isDOMElement(target)) {
|
|
1016
|
-
if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA') {
|
|
1017
|
-
return true;
|
|
1018
|
-
}
|
|
1019
|
-
}
|
|
1020
|
-
return false;
|
|
1021
|
-
};
|
|
1022
|
-
const isSecondaryPointer = (event) => {
|
|
1023
|
-
return event.button === POINTER_BUTTON.SECONDARY;
|
|
1024
|
-
};
|
|
1025
|
-
const isMainPointer = (event) => {
|
|
1026
|
-
return event.button === POINTER_BUTTON.MAIN;
|
|
1027
|
-
};
|
|
1028
|
-
|
|
1029
|
-
const SELECTION_BORDER_COLOR = '#6698FF';
|
|
1030
|
-
const SELECTION_FILL_COLOR = '#6698FF19'; // 主色 0.1 透明度
|
|
1031
|
-
const Selection = {
|
|
1032
|
-
isCollapsed(selection) {
|
|
1033
|
-
if (selection.anchor[0] == selection.focus[0] && selection.anchor[1] === selection.focus[1]) {
|
|
1034
|
-
return true;
|
|
1035
|
-
}
|
|
1036
|
-
else {
|
|
1037
|
-
return false;
|
|
1038
|
-
}
|
|
1039
|
-
}
|
|
1040
|
-
};
|
|
1041
|
-
|
|
1042
|
-
const getHitElements = (board, selection, match = () => true) => {
|
|
1043
|
-
const realSelection = selection || board.selection;
|
|
1044
|
-
const selectedElements = [];
|
|
1045
|
-
const isCollapsed = realSelection && realSelection.ranges.length === 1 && Selection.isCollapsed(realSelection.ranges[0]);
|
|
1046
|
-
depthFirstRecursion(board, node => {
|
|
1047
|
-
if (selectedElements.length > 0 && isCollapsed) {
|
|
1048
|
-
return;
|
|
1049
|
-
}
|
|
1050
|
-
if (!PlaitBoard.isBoard(node) &&
|
|
1051
|
-
match(node) &&
|
|
1052
|
-
realSelection &&
|
|
1053
|
-
realSelection.ranges.some(range => {
|
|
1054
|
-
return board.isHitSelection(node, range);
|
|
1055
|
-
})) {
|
|
1056
|
-
selectedElements.push(node);
|
|
1057
|
-
}
|
|
1058
|
-
}, getIsRecursionFunc(board), true);
|
|
1059
|
-
return selectedElements;
|
|
1060
|
-
};
|
|
1061
|
-
const getHitElementOfRoot = (board, rootElements, range) => {
|
|
1062
|
-
const newRootElements = [...rootElements].reverse();
|
|
1063
|
-
return newRootElements.find(item => {
|
|
1064
|
-
return board.isHitSelection(item, range);
|
|
1065
|
-
});
|
|
1066
|
-
};
|
|
1067
|
-
const isHitElements = (board, elements, ranges) => {
|
|
1068
|
-
let isIntersectionElements = false;
|
|
1069
|
-
if (elements.length) {
|
|
1070
|
-
elements.map(item => {
|
|
1071
|
-
if (!isIntersectionElements) {
|
|
1072
|
-
isIntersectionElements = ranges.some(range => {
|
|
1073
|
-
return board.isHitSelection(item, range);
|
|
1074
|
-
});
|
|
1075
|
-
}
|
|
1076
|
-
});
|
|
1077
|
-
}
|
|
1078
|
-
return isIntersectionElements;
|
|
1079
|
-
};
|
|
1080
|
-
const cacheSelectedElements = (board, selectedElements) => {
|
|
1081
|
-
BOARD_TO_SELECTED_ELEMENT.set(board, selectedElements);
|
|
1082
|
-
};
|
|
1083
|
-
const getSelectedElements = (board) => {
|
|
1084
|
-
return BOARD_TO_SELECTED_ELEMENT.get(board) || [];
|
|
1085
|
-
};
|
|
1086
|
-
const addSelectedElement = (board, element) => {
|
|
1087
|
-
const selectedElements = getSelectedElements(board);
|
|
1088
|
-
cacheSelectedElements(board, [...selectedElements, element]);
|
|
1089
|
-
};
|
|
1090
|
-
const removeSelectedElement = (board, element) => {
|
|
1091
|
-
const selectedElements = getSelectedElements(board);
|
|
1092
|
-
const newSelectedElements = selectedElements.filter(value => value !== element);
|
|
1093
|
-
cacheSelectedElements(board, newSelectedElements);
|
|
1094
|
-
};
|
|
1095
|
-
const clearSelectedElement = (board) => {
|
|
1096
|
-
cacheSelectedElements(board, []);
|
|
1097
|
-
};
|
|
1098
|
-
const isSelectedElement = (board, element) => {
|
|
1099
|
-
const selectedElements = getSelectedElements(board);
|
|
1100
|
-
return !!selectedElements.find(value => value === element);
|
|
1101
|
-
};
|
|
1102
|
-
|
|
1103
|
-
function hasBeforeContextChange(value) {
|
|
1104
|
-
if (value.beforeContextChange) {
|
|
1105
|
-
return true;
|
|
1106
|
-
}
|
|
1107
|
-
return false;
|
|
1108
|
-
}
|
|
1109
|
-
function hasOnContextChanged(value) {
|
|
1110
|
-
if (value.onContextChanged) {
|
|
1111
|
-
return true;
|
|
1112
|
-
}
|
|
1113
|
-
return false;
|
|
1114
|
-
}
|
|
1115
|
-
|
|
1116
|
-
class PlaitPluginElementComponent {
|
|
1117
|
-
set context(value) {
|
|
1118
|
-
if (hasBeforeContextChange(this)) {
|
|
1119
|
-
this.beforeContextChange(value);
|
|
1120
|
-
}
|
|
1121
|
-
const previousContext = this._context;
|
|
1122
|
-
this._context = value;
|
|
1123
|
-
if (this.element) {
|
|
1124
|
-
ELEMENT_TO_COMPONENT.set(this.element, this);
|
|
1125
|
-
}
|
|
1126
|
-
if (this.initialized) {
|
|
1127
|
-
this.cdr.markForCheck();
|
|
1128
|
-
if (hasOnContextChanged(this)) {
|
|
1129
|
-
this.onContextChanged(value, previousContext);
|
|
1130
|
-
}
|
|
1131
|
-
}
|
|
1132
|
-
else {
|
|
1133
|
-
if (PlaitElement.isRootElement(this.element) && this.element.children) {
|
|
1134
|
-
this.g = createG();
|
|
1135
|
-
this.rootG = createG();
|
|
1136
|
-
this.rootG.append(this.g);
|
|
1137
|
-
}
|
|
1138
|
-
else {
|
|
1139
|
-
this.g = createG();
|
|
1140
|
-
}
|
|
1141
|
-
}
|
|
1142
|
-
}
|
|
1143
|
-
get context() {
|
|
1144
|
-
return this._context;
|
|
1145
|
-
}
|
|
1146
|
-
get element() {
|
|
1147
|
-
return this.context && this.context.element;
|
|
1148
|
-
}
|
|
1149
|
-
get board() {
|
|
1150
|
-
return this.context && this.context.board;
|
|
1151
|
-
}
|
|
1152
|
-
get selected() {
|
|
1153
|
-
return this.context && this.context.selected;
|
|
1154
|
-
}
|
|
1155
|
-
get effect() {
|
|
1156
|
-
return this.context && this.context.effect;
|
|
1157
|
-
}
|
|
1158
|
-
constructor(cdr) {
|
|
1159
|
-
this.cdr = cdr;
|
|
1160
|
-
this.initialized = false;
|
|
1161
|
-
}
|
|
1162
|
-
ngOnInit() {
|
|
1163
|
-
if (this.element.type) {
|
|
1164
|
-
(this.rootG || this.g).setAttribute(`plait-${this.element.type}`, 'true');
|
|
1165
|
-
}
|
|
1166
|
-
this.initialized = true;
|
|
1167
|
-
}
|
|
1168
|
-
ngOnDestroy() {
|
|
1169
|
-
if (ELEMENT_TO_COMPONENT.get(this.element) === this) {
|
|
1170
|
-
ELEMENT_TO_COMPONENT.delete(this.element);
|
|
1171
|
-
}
|
|
1172
|
-
removeSelectedElement(this.board, this.element);
|
|
1173
|
-
(this.rootG || this.g).remove();
|
|
1174
|
-
}
|
|
1175
|
-
}
|
|
1176
|
-
PlaitPluginElementComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: PlaitPluginElementComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive });
|
|
1177
|
-
PlaitPluginElementComponent.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.5", type: PlaitPluginElementComponent, inputs: { context: "context" }, ngImport: i0 });
|
|
1178
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: PlaitPluginElementComponent, decorators: [{
|
|
1179
|
-
type: Directive
|
|
1180
|
-
}], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { context: [{
|
|
1181
|
-
type: Input
|
|
1182
|
-
}] } });
|
|
1183
|
-
const ELEMENT_TO_COMPONENT = new WeakMap();
|
|
1184
|
-
|
|
1185
|
-
function transformPoints(board, points) {
|
|
1186
|
-
const newPoints = points.map(point => {
|
|
1187
|
-
return transformPoint(board, point);
|
|
1188
|
-
});
|
|
1189
|
-
return newPoints;
|
|
1190
|
-
}
|
|
1191
|
-
function transformPoint(board, point) {
|
|
1192
|
-
const { width, height } = PlaitBoard.getHost(board).getBoundingClientRect();
|
|
1193
|
-
const viewBox = PlaitBoard.getHost(board).viewBox.baseVal;
|
|
1194
|
-
const x = (point[0] / width) * viewBox.width + viewBox.x;
|
|
1195
|
-
const y = (point[1] / height) * viewBox.height + viewBox.y;
|
|
1196
|
-
const newPoint = [x, y];
|
|
1197
|
-
return newPoint;
|
|
1198
|
-
}
|
|
1199
|
-
function isInPlaitBoard(board, x, y) {
|
|
1200
|
-
const plaitBoardElement = PlaitBoard.getBoardContainer(board);
|
|
1201
|
-
const plaitBoardRect = plaitBoardElement.getBoundingClientRect();
|
|
1202
|
-
const distances = distanceBetweenPointAndRectangle(x, y, plaitBoardRect);
|
|
1203
|
-
return distances === 0;
|
|
1204
|
-
}
|
|
1205
|
-
function getRealScrollBarWidth(board) {
|
|
1206
|
-
const { hideScrollbar } = board.options;
|
|
1207
|
-
let scrollBarWidth = 0;
|
|
1208
|
-
if (!hideScrollbar) {
|
|
1209
|
-
const viewportContainer = PlaitBoard.getViewportContainer(board);
|
|
1210
|
-
scrollBarWidth = viewportContainer.offsetWidth - viewportContainer.clientWidth;
|
|
1211
|
-
}
|
|
1212
|
-
return scrollBarWidth;
|
|
1213
|
-
}
|
|
1214
|
-
|
|
1215
|
-
function createForeignObject(x, y, width, height) {
|
|
1216
|
-
var newForeignObject = document.createElementNS(NS, 'foreignObject');
|
|
1217
|
-
newForeignObject.setAttribute('x', `${x}`);
|
|
1218
|
-
newForeignObject.setAttribute('y', `${y}`);
|
|
1219
|
-
newForeignObject.setAttribute('width', `${width}`);
|
|
1220
|
-
newForeignObject.setAttribute('height', `${height}`);
|
|
1221
|
-
return newForeignObject;
|
|
1222
|
-
}
|
|
1223
|
-
function updateForeignObject(g, width, height, x, y) {
|
|
1224
|
-
const foreignObject = g.querySelector('foreignObject');
|
|
1225
|
-
if (foreignObject) {
|
|
1226
|
-
foreignObject.setAttribute('width', `${width}`);
|
|
1227
|
-
foreignObject.setAttribute('height', `${height}`);
|
|
1228
|
-
foreignObject.setAttribute('x', `${x}`);
|
|
1229
|
-
foreignObject.setAttribute('y', `${y}`);
|
|
1230
|
-
}
|
|
1231
|
-
}
|
|
1232
|
-
|
|
1233
|
-
const IS_MAC = typeof window != 'undefined' && /Mac|iPod|iPhone|iPad/.test(window.navigator.platform);
|
|
1234
|
-
|
|
1235
|
-
const IS_IOS = typeof navigator !== 'undefined' &&
|
|
1236
|
-
typeof window !== 'undefined' &&
|
|
1237
|
-
/iPad|iPhone|iPod/.test(navigator.userAgent) &&
|
|
1238
|
-
!window.MSStream;
|
|
1239
|
-
const IS_APPLE = typeof navigator !== 'undefined' && /Mac OS X/.test(navigator.userAgent);
|
|
1240
|
-
const IS_FIREFOX = typeof navigator !== 'undefined' && /^(?!.*Seamonkey)(?=.*Firefox).*/i.test(navigator.userAgent);
|
|
1241
|
-
const IS_SAFARI = typeof navigator !== 'undefined' && /Version\/[\d\.]+.*Safari/.test(navigator.userAgent);
|
|
1242
|
-
// "modern" Edge was released at 79.x
|
|
1243
|
-
const IS_EDGE_LEGACY = typeof navigator !== 'undefined' && /Edge?\/(?:[0-6][0-9]|[0-7][0-8])/i.test(navigator.userAgent);
|
|
1244
|
-
const IS_CHROME = typeof navigator !== 'undefined' && /Chrome/i.test(navigator.userAgent);
|
|
1245
|
-
// Native beforeInput events don't work well with react on Chrome 75 and older, Chrome 76+ can use beforeInput
|
|
1246
|
-
const IS_CHROME_LEGACY = typeof navigator !== 'undefined' && /Chrome?\/(?:[0-7][0-5]|[0-6][0-9])/i.test(navigator.userAgent);
|
|
1247
|
-
|
|
1248
|
-
/**
|
|
1249
|
-
* Check whether to merge an operation into the previous operation.
|
|
1250
|
-
*/
|
|
1251
|
-
const shouldMerge = (op, prev) => {
|
|
1252
|
-
if (op.type === 'set_viewport' && op.type === (prev === null || prev === void 0 ? void 0 : prev.type)) {
|
|
1253
|
-
return true;
|
|
1254
|
-
}
|
|
1255
|
-
return false;
|
|
1256
|
-
};
|
|
1257
|
-
/**
|
|
1258
|
-
* Check whether an operation needs to be saved to the history.
|
|
1259
|
-
*/
|
|
1260
|
-
const shouldSave = (op, prev) => {
|
|
1261
|
-
if (op.type === 'set_selection' || op.type === 'set_viewport') {
|
|
1262
|
-
return false;
|
|
1263
|
-
}
|
|
1264
|
-
return true;
|
|
1265
|
-
};
|
|
1266
|
-
/**
|
|
1267
|
-
* Check whether an operation should clear the redos stack.
|
|
1268
|
-
*/
|
|
1269
|
-
const shouldClear = (op) => {
|
|
1270
|
-
if (op.type === 'set_selection') {
|
|
1271
|
-
return false;
|
|
1272
|
-
}
|
|
1273
|
-
return true;
|
|
1274
|
-
};
|
|
1275
|
-
const PlaitHistoryBoard = {
|
|
1276
|
-
/**
|
|
1277
|
-
* Get the saving flag's current value.
|
|
1278
|
-
*/
|
|
1279
|
-
isSaving(board) {
|
|
1280
|
-
return SAVING.get(board);
|
|
1281
|
-
},
|
|
1282
|
-
/**
|
|
1283
|
-
* Get the merge flag's current value.
|
|
1284
|
-
*/
|
|
1285
|
-
isMerging(board) {
|
|
1286
|
-
return MERGING.get(board);
|
|
1287
|
-
},
|
|
1288
|
-
/**
|
|
1289
|
-
* Apply a series of changes inside a synchronous `fn`, without merging any of
|
|
1290
|
-
* the new operations into previous save point in the history.
|
|
1291
|
-
*/
|
|
1292
|
-
withoutMerging(board, fn) {
|
|
1293
|
-
const prev = PlaitHistoryBoard.isMerging(board);
|
|
1294
|
-
MERGING.set(board, false);
|
|
1295
|
-
fn();
|
|
1296
|
-
MERGING.set(board, prev);
|
|
1297
|
-
},
|
|
1298
|
-
/**
|
|
1299
|
-
* Apply a series of changes inside a synchronous `fn`, without saving any of
|
|
1300
|
-
* their operations into the history.
|
|
1301
|
-
*/
|
|
1302
|
-
withoutSaving(board, fn) {
|
|
1303
|
-
const prev = PlaitHistoryBoard.isSaving(board);
|
|
1304
|
-
SAVING.set(board, false);
|
|
1305
|
-
fn();
|
|
1306
|
-
SAVING.set(board, prev);
|
|
1307
|
-
}
|
|
1308
|
-
};
|
|
1309
|
-
|
|
1310
|
-
/**
|
|
1311
|
-
* Hotkey mappings for each platform.
|
|
1312
|
-
*/
|
|
1313
|
-
const HOTKEYS = {
|
|
1314
|
-
bold: 'mod+b',
|
|
1315
|
-
compose: ['down', 'left', 'right', 'up', 'backspace', 'enter'],
|
|
1316
|
-
moveBackward: 'left',
|
|
1317
|
-
moveForward: 'right',
|
|
1318
|
-
moveUp: 'up',
|
|
1319
|
-
moveDown: 'down',
|
|
1320
|
-
moveWordBackward: 'ctrl+left',
|
|
1321
|
-
moveWordForward: 'ctrl+right',
|
|
1322
|
-
deleteBackward: 'shift?+backspace',
|
|
1323
|
-
deleteForward: 'shift?+delete',
|
|
1324
|
-
extendBackward: 'shift+left',
|
|
1325
|
-
extendForward: 'shift+right',
|
|
1326
|
-
italic: 'mod+i',
|
|
1327
|
-
splitBlock: 'shift?+enter',
|
|
1328
|
-
undo: 'mod+z'
|
|
1329
|
-
};
|
|
1330
|
-
const APPLE_HOTKEYS = {
|
|
1331
|
-
moveLineBackward: 'opt+up',
|
|
1332
|
-
moveLineForward: 'opt+down',
|
|
1333
|
-
moveWordBackward: 'opt+left',
|
|
1334
|
-
moveWordForward: 'opt+right',
|
|
1335
|
-
deleteBackward: ['ctrl+backspace', 'ctrl+h'],
|
|
1336
|
-
deleteForward: ['ctrl+delete', 'ctrl+d'],
|
|
1337
|
-
deleteLineBackward: 'cmd+shift?+backspace',
|
|
1338
|
-
deleteLineForward: ['cmd+shift?+delete', 'ctrl+k'],
|
|
1339
|
-
deleteWordBackward: 'opt+shift?+backspace',
|
|
1340
|
-
deleteWordForward: 'opt+shift?+delete',
|
|
1341
|
-
extendLineBackward: 'opt+shift+up',
|
|
1342
|
-
extendLineForward: 'opt+shift+down',
|
|
1343
|
-
redo: 'cmd+shift+z',
|
|
1344
|
-
transposeCharacter: 'ctrl+t'
|
|
1345
|
-
};
|
|
1346
|
-
const WINDOWS_HOTKEYS = {
|
|
1347
|
-
deleteWordBackward: 'ctrl+shift?+backspace',
|
|
1348
|
-
deleteWordForward: 'ctrl+shift?+delete',
|
|
1349
|
-
redo: ['ctrl+y', 'ctrl+shift+z']
|
|
1350
|
-
};
|
|
1351
|
-
/**
|
|
1352
|
-
* Create a platform-aware hotkey checker.
|
|
1353
|
-
*/
|
|
1354
|
-
const create = (key) => {
|
|
1355
|
-
const generic = HOTKEYS[key];
|
|
1356
|
-
const apple = APPLE_HOTKEYS[key];
|
|
1357
|
-
const windows = WINDOWS_HOTKEYS[key];
|
|
1358
|
-
const isGeneric = generic && isKeyHotkey(generic);
|
|
1359
|
-
const isApple = apple && isKeyHotkey(apple);
|
|
1360
|
-
const isWindows = windows && isKeyHotkey(windows);
|
|
1361
|
-
return (event) => {
|
|
1362
|
-
if (isGeneric && isGeneric(event)) {
|
|
1363
|
-
return true;
|
|
1364
|
-
}
|
|
1365
|
-
if (IS_APPLE && isApple && isApple(event)) {
|
|
1366
|
-
return true;
|
|
1367
|
-
}
|
|
1368
|
-
if (!IS_APPLE && isWindows && isWindows(event)) {
|
|
1369
|
-
return true;
|
|
1370
|
-
}
|
|
1371
|
-
return false;
|
|
1372
|
-
};
|
|
1373
|
-
};
|
|
1374
|
-
/**
|
|
1375
|
-
* Hotkeys.
|
|
1376
|
-
*/
|
|
1377
|
-
const hotkeys = {
|
|
1378
|
-
isBold: create('bold'),
|
|
1379
|
-
isCompose: create('compose'),
|
|
1380
|
-
isMoveBackward: create('moveBackward'),
|
|
1381
|
-
isMoveForward: create('moveForward'),
|
|
1382
|
-
isMoveUp: create('moveUp'),
|
|
1383
|
-
isMoveDown: create('moveDown'),
|
|
1384
|
-
isDeleteBackward: create('deleteBackward'),
|
|
1385
|
-
isDeleteForward: create('deleteForward'),
|
|
1386
|
-
isDeleteLineBackward: create('deleteLineBackward'),
|
|
1387
|
-
isDeleteLineForward: create('deleteLineForward'),
|
|
1388
|
-
isDeleteWordBackward: create('deleteWordBackward'),
|
|
1389
|
-
isDeleteWordForward: create('deleteWordForward'),
|
|
1390
|
-
isExtendBackward: create('extendBackward'),
|
|
1391
|
-
isExtendForward: create('extendForward'),
|
|
1392
|
-
isExtendLineBackward: create('extendLineBackward'),
|
|
1393
|
-
isExtendLineForward: create('extendLineForward'),
|
|
1394
|
-
isItalic: create('italic'),
|
|
1395
|
-
isMoveLineBackward: create('moveLineBackward'),
|
|
1396
|
-
isMoveLineForward: create('moveLineForward'),
|
|
1397
|
-
isMoveWordBackward: create('moveWordBackward'),
|
|
1398
|
-
isMoveWordForward: create('moveWordForward'),
|
|
1399
|
-
isRedo: create('redo'),
|
|
1400
|
-
isSplitBlock: create('splitBlock'),
|
|
1401
|
-
isTransposeCharacter: create('transposeCharacter'),
|
|
1402
|
-
isUndo: create('undo')
|
|
1403
|
-
};
|
|
1404
|
-
|
|
1405
|
-
function idCreator(length = 5) {
|
|
1406
|
-
// remove numeral
|
|
1407
|
-
const $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz'; /****默认去掉了容易混淆的字符oOLl,9gq,Vv,Uu,I1****/
|
|
1408
|
-
const maxPosition = $chars.length;
|
|
1409
|
-
let key = '';
|
|
1410
|
-
for (let i = 0; i < length; i++) {
|
|
1411
|
-
key += $chars.charAt(Math.floor(Math.random() * maxPosition));
|
|
1412
|
-
}
|
|
1413
|
-
return key;
|
|
1414
|
-
}
|
|
1415
|
-
|
|
1416
|
-
/**
|
|
1417
|
-
* drawRoundRectangle
|
|
1418
|
-
*/
|
|
1419
|
-
function drawRoundRectangle(rs, x1, y1, x2, y2, options, outline = false, borderRadius) {
|
|
1420
|
-
const width = Math.abs(x1 - x2);
|
|
1421
|
-
const height = Math.abs(y1 - y2);
|
|
1422
|
-
let radius = borderRadius || 0;
|
|
1423
|
-
if (radius === 0) {
|
|
1424
|
-
const defaultRadius = Math.min(width, height) / 8;
|
|
1425
|
-
let radius = defaultRadius;
|
|
1426
|
-
if (defaultRadius > MAX_RADIUS) {
|
|
1427
|
-
radius = outline ? MAX_RADIUS + 2 : MAX_RADIUS;
|
|
1428
|
-
}
|
|
1429
|
-
}
|
|
1430
|
-
const point1 = [x1 + radius, y1];
|
|
1431
|
-
const point2 = [x2 - radius, y1];
|
|
1432
|
-
const point3 = [x2, y1 + radius];
|
|
1433
|
-
const point4 = [x2, y2 - radius];
|
|
1434
|
-
const point5 = [x2 - radius, y2];
|
|
1435
|
-
const point6 = [x1 + radius, y2];
|
|
1436
|
-
const point7 = [x1, y2 - radius];
|
|
1437
|
-
const point8 = [x1, y1 + radius];
|
|
1438
|
-
return rs.path(`M${point2[0]} ${point2[1]} A ${radius} ${radius}, 0, 0, 1, ${point3[0]} ${point3[1]} L ${point4[0]} ${point4[1]} A ${radius} ${radius}, 0, 0, 1, ${point5[0]} ${point5[1]} L ${point6[0]} ${point6[1]} A ${radius} ${radius}, 0, 0, 1, ${point7[0]} ${point7[1]} L ${point8[0]} ${point8[1]} A ${radius} ${radius}, 0, 0, 1, ${point1[0]} ${point1[1]} Z`, options);
|
|
1439
|
-
}
|
|
1440
|
-
|
|
1441
|
-
function arrowPoints(start, end, maxHypotenuseLength = 10, degree = 40) {
|
|
1442
|
-
const width = Math.abs(start[0] - end[0]);
|
|
1443
|
-
const height = Math.abs(start[1] - end[1]);
|
|
1444
|
-
let hypotenuse = Math.hypot(width, height); // 斜边
|
|
1445
|
-
const realRotateLine = hypotenuse > maxHypotenuseLength * 2 ? maxHypotenuseLength : hypotenuse / 2;
|
|
1446
|
-
const rotateWidth = (realRotateLine / hypotenuse) * width;
|
|
1447
|
-
const rotateHeight = (realRotateLine / hypotenuse) * height;
|
|
1448
|
-
const rotatePoint = [
|
|
1449
|
-
end[0] > start[0] ? end[0] - rotateWidth : end[0] + rotateWidth,
|
|
1450
|
-
end[1] > start[1] ? end[1] - rotateHeight : end[1] + rotateHeight
|
|
1451
|
-
];
|
|
1452
|
-
const pointRight = rotate(rotatePoint[0], rotatePoint[1], end[0], end[1], (degree * Math.PI) / 180);
|
|
1453
|
-
const pointLeft = rotate(rotatePoint[0], rotatePoint[1], end[0], end[1], (-degree * Math.PI) / 180);
|
|
1454
|
-
return { pointLeft, pointRight };
|
|
1455
|
-
}
|
|
1456
|
-
function drawArrow(rs, start, end, options, maxHypotenuseLength = 10, degree = 40) {
|
|
1457
|
-
const { pointLeft, pointRight } = arrowPoints(start, end, maxHypotenuseLength, degree);
|
|
1458
|
-
const arrowLineLeft = rs.linearPath([pointLeft, end], options);
|
|
1459
|
-
const arrowLineRight = rs.linearPath([pointRight, end], options);
|
|
1460
|
-
return [arrowLineLeft, arrowLineRight];
|
|
1461
|
-
}
|
|
1462
|
-
|
|
1463
|
-
function drawCircle(roughSVG, point, diameter, options) {
|
|
1464
|
-
return roughSVG.circle(point[0], point[1], diameter, options);
|
|
1465
|
-
}
|
|
1466
|
-
|
|
1467
|
-
function drawLine(rs, start, end, options) {
|
|
1468
|
-
return rs.linearPath([start, end], options);
|
|
1469
|
-
}
|
|
1470
|
-
function drawLinearPath(points, options) {
|
|
1471
|
-
const g = createG();
|
|
1472
|
-
const path = createPath();
|
|
1473
|
-
let polylinePath = '';
|
|
1474
|
-
points.forEach((point, index) => {
|
|
1475
|
-
if (index === 0) {
|
|
1476
|
-
polylinePath += `M ${point[0]} ${point[1]} `;
|
|
1477
|
-
}
|
|
1478
|
-
else {
|
|
1479
|
-
polylinePath += `L ${point[0]} ${point[1]} `;
|
|
1480
|
-
}
|
|
1481
|
-
});
|
|
1482
|
-
path.setAttribute('d', polylinePath);
|
|
1483
|
-
path.setAttribute('stroke', `${options === null || options === void 0 ? void 0 : options.stroke}`);
|
|
1484
|
-
path.setAttribute('stroke-width', `${options === null || options === void 0 ? void 0 : options.strokeWidth}`);
|
|
1485
|
-
path.setAttribute('fill', `none`);
|
|
1486
|
-
g.appendChild(path);
|
|
1487
|
-
return g;
|
|
1488
|
-
}
|
|
1489
|
-
function drawBezierPath(points, options) {
|
|
1490
|
-
const g = createG();
|
|
1491
|
-
const path = createPath();
|
|
1492
|
-
let polylinePath = '';
|
|
1493
|
-
for (let i = 0; i < points.length - 3; i += 3) {
|
|
1494
|
-
if (i === 0) {
|
|
1495
|
-
polylinePath += `M ${points[0][0]} ${points[0][1]} `;
|
|
1496
|
-
}
|
|
1497
|
-
else {
|
|
1498
|
-
polylinePath += `C ${points[i + 1][0]} ${points[i + 1][1]}, ${points[i + 2][0]} ${points[i + 2][1]}, ${points[i + 3][0]} ${points[i + 3][1]}`;
|
|
1499
|
-
}
|
|
1500
|
-
}
|
|
1501
|
-
path.setAttribute('d', polylinePath);
|
|
1502
|
-
path.setAttribute('stroke', `${options === null || options === void 0 ? void 0 : options.stroke}`);
|
|
1503
|
-
path.setAttribute('stroke-width', `${options === null || options === void 0 ? void 0 : options.strokeWidth}`);
|
|
1504
|
-
path.setAttribute('fill', `none`);
|
|
1505
|
-
g.appendChild(path);
|
|
1506
|
-
return g;
|
|
1507
|
-
}
|
|
1508
|
-
|
|
1509
|
-
let timerId = null;
|
|
1510
|
-
const throttleRAF = (fn) => {
|
|
1511
|
-
const scheduleFunc = () => {
|
|
1512
|
-
timerId = requestAnimationFrame(() => {
|
|
1513
|
-
timerId = null;
|
|
1514
|
-
fn();
|
|
1515
|
-
});
|
|
1516
|
-
};
|
|
1517
|
-
if (timerId !== null) {
|
|
1518
|
-
cancelAnimationFrame(timerId);
|
|
1519
|
-
timerId = null;
|
|
1520
|
-
}
|
|
1521
|
-
scheduleFunc();
|
|
1522
|
-
};
|
|
1523
|
-
const debounce = (func, wait, options) => {
|
|
1524
|
-
let timerSubscription = null;
|
|
1525
|
-
return () => {
|
|
1526
|
-
if (timerSubscription && !timerSubscription.closed) {
|
|
1527
|
-
timerSubscription.unsubscribe();
|
|
1528
|
-
timerSubscription = timer(wait).subscribe(() => {
|
|
1529
|
-
func();
|
|
1530
|
-
});
|
|
1531
|
-
}
|
|
1532
|
-
else {
|
|
1533
|
-
if (options === null || options === void 0 ? void 0 : options.leading) {
|
|
1534
|
-
func();
|
|
1535
|
-
}
|
|
1536
|
-
timerSubscription = timer(wait).subscribe();
|
|
1537
|
-
}
|
|
1538
|
-
};
|
|
1539
|
-
};
|
|
1540
|
-
|
|
1541
|
-
const getMovingElements = (board) => {
|
|
1542
|
-
return BOARD_TO_MOVING_ELEMENT.get(board) || [];
|
|
1543
|
-
};
|
|
1544
|
-
const addMovingElements = (board, elements) => {
|
|
1545
|
-
const movingElements = getMovingElements(board);
|
|
1546
|
-
const newElements = elements.filter(item => !movingElements.find(movingElement => movingElement.key === item.key));
|
|
1547
|
-
cacheMovingElements(board, [...movingElements, ...newElements]);
|
|
1548
|
-
};
|
|
1549
|
-
const removeMovingElements = (board) => {
|
|
1550
|
-
BOARD_TO_MOVING_ELEMENT.delete(board);
|
|
1551
|
-
};
|
|
1552
|
-
const cacheMovingElements = (board, elements) => {
|
|
1553
|
-
BOARD_TO_MOVING_ELEMENT.set(board, elements);
|
|
1554
|
-
};
|
|
1555
|
-
|
|
1556
|
-
function cloneCSSStyle(nativeNode, clonedNode) {
|
|
1557
|
-
const targetStyle = clonedNode.style;
|
|
1558
|
-
if (!targetStyle) {
|
|
1559
|
-
return;
|
|
1560
|
-
}
|
|
1561
|
-
const sourceStyle = window.getComputedStyle(nativeNode);
|
|
1562
|
-
if (sourceStyle.cssText) {
|
|
1563
|
-
targetStyle.cssText = sourceStyle.cssText;
|
|
1564
|
-
targetStyle.transformOrigin = sourceStyle.transformOrigin;
|
|
1565
|
-
}
|
|
1566
|
-
else {
|
|
1567
|
-
Array.from(sourceStyle).forEach(name => {
|
|
1568
|
-
let value = sourceStyle.getPropertyValue(name);
|
|
1569
|
-
targetStyle.setProperty(name, value, sourceStyle.getPropertyPriority(name));
|
|
1570
|
-
});
|
|
1571
|
-
}
|
|
1572
|
-
}
|
|
1573
|
-
function createCanvas(width, height, fillStyle) {
|
|
1574
|
-
const canvas = document.createElement('canvas');
|
|
1575
|
-
const ctx = canvas.getContext('2d');
|
|
1576
|
-
canvas.width = width;
|
|
1577
|
-
canvas.height = height;
|
|
1578
|
-
canvas.style.width = `${width}px`;
|
|
1579
|
-
canvas.style.height = `${height}px`;
|
|
1580
|
-
ctx.strokeStyle = '#ffffff';
|
|
1581
|
-
ctx.fillStyle = fillStyle;
|
|
1582
|
-
ctx.fillRect(0, 0, width, height);
|
|
1583
|
-
return {
|
|
1584
|
-
canvas,
|
|
1585
|
-
ctx
|
|
1586
|
-
};
|
|
1587
|
-
}
|
|
1588
|
-
function isElementNode(node) {
|
|
1589
|
-
return node.nodeType === Node.ELEMENT_NODE;
|
|
1590
|
-
}
|
|
1591
|
-
function cloneSvg(board, options) {
|
|
1592
|
-
const elementHostBox = getRectangleByElements(board, board.children, true);
|
|
1593
|
-
const { width, height, x, y } = elementHostBox;
|
|
1594
|
-
const { padding = 4, inlineStyleClassNames } = options;
|
|
1595
|
-
const sourceSvg = PlaitBoard.getHost(board);
|
|
1596
|
-
const cloneSvgElement = sourceSvg.cloneNode(true);
|
|
1597
|
-
cloneSvgElement.style.width = `${width}px`;
|
|
1598
|
-
cloneSvgElement.style.height = `${height}px`;
|
|
1599
|
-
cloneSvgElement.style.backgroundColor = '';
|
|
1600
|
-
cloneSvgElement.setAttribute('width', `${width}`);
|
|
1601
|
-
cloneSvgElement.setAttribute('height', `${height}`);
|
|
1602
|
-
cloneSvgElement.setAttribute('viewBox', [x - padding, y - padding, width + 2 * padding, height + 2 * padding].join(','));
|
|
1603
|
-
if (inlineStyleClassNames) {
|
|
1604
|
-
const sourceNodes = Array.from(sourceSvg.querySelectorAll(inlineStyleClassNames));
|
|
1605
|
-
const cloneNodes = Array.from(cloneSvgElement.querySelectorAll(inlineStyleClassNames));
|
|
1606
|
-
sourceNodes.forEach((node, index) => {
|
|
1607
|
-
const cloneNode = cloneNodes[index];
|
|
1608
|
-
const childElements = Array.from(node.querySelectorAll('*')).filter(isElementNode);
|
|
1609
|
-
const cloneChildElements = Array.from(cloneNode.querySelectorAll('*')).filter(isElementNode);
|
|
1610
|
-
sourceNodes.push(...childElements);
|
|
1611
|
-
cloneNodes.push(...cloneChildElements);
|
|
1612
|
-
});
|
|
1613
|
-
sourceNodes.forEach((node, index) => {
|
|
1614
|
-
const cloneNode = cloneNodes[index];
|
|
1615
|
-
cloneCSSStyle(node, cloneNode);
|
|
1616
|
-
});
|
|
1617
|
-
}
|
|
1618
|
-
return cloneSvgElement;
|
|
1619
|
-
}
|
|
1620
|
-
function loadImage(src) {
|
|
1621
|
-
return new Promise((resolve, reject) => {
|
|
1622
|
-
const img = new Image();
|
|
1623
|
-
img.onload = () => resolve(img);
|
|
1624
|
-
img.onerror = () => reject(new Error('Failed to load image'));
|
|
1625
|
-
img.src = src;
|
|
1626
|
-
});
|
|
1627
|
-
}
|
|
1628
|
-
function toImage(board, options) {
|
|
1629
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
1630
|
-
if (!board) {
|
|
1631
|
-
return undefined;
|
|
1632
|
-
}
|
|
1633
|
-
const elementHostBox = getRectangleByElements(board, board.children, true);
|
|
1634
|
-
const { ratio = 2, fillStyle = 'transparent' } = options;
|
|
1635
|
-
const { width, height } = elementHostBox;
|
|
1636
|
-
const ratioWidth = width * ratio;
|
|
1637
|
-
const ratioHeight = height * ratio;
|
|
1638
|
-
const cloneSvgElement = cloneSvg(board, options);
|
|
1639
|
-
const { canvas, ctx } = createCanvas(ratioWidth, ratioHeight, fillStyle);
|
|
1640
|
-
const svgStr = new XMLSerializer().serializeToString(cloneSvgElement);
|
|
1641
|
-
const imgSrc = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svgStr)}`;
|
|
1642
|
-
try {
|
|
1643
|
-
const img = yield loadImage(imgSrc);
|
|
1644
|
-
ctx.drawImage(img, 0, 0, ratioWidth, ratioHeight);
|
|
1645
|
-
const url = canvas.toDataURL('image/png');
|
|
1646
|
-
return url;
|
|
1647
|
-
}
|
|
1648
|
-
catch (error) {
|
|
1649
|
-
console.error('Error converting SVG to image:', error);
|
|
1650
|
-
return undefined;
|
|
1651
|
-
}
|
|
1652
|
-
});
|
|
1653
|
-
}
|
|
1654
|
-
function downloadImage(url, name) {
|
|
1655
|
-
const a = document.createElement('a');
|
|
1656
|
-
a.href = url;
|
|
1657
|
-
a.download = name;
|
|
1658
|
-
a.click();
|
|
1659
|
-
a.remove();
|
|
1660
|
-
}
|
|
1661
|
-
|
|
1662
|
-
const getClipboardByKey = (key) => {
|
|
1663
|
-
return `application/x-plait-${key}-fragment`;
|
|
1664
|
-
};
|
|
1665
|
-
const setClipboardData = (data, elements) => {
|
|
1666
|
-
const result = [...elements];
|
|
1667
|
-
const pluginContextResult = getDataFromClipboard(data);
|
|
1668
|
-
if (pluginContextResult) {
|
|
1669
|
-
result.push(...pluginContextResult);
|
|
1670
|
-
}
|
|
1671
|
-
const stringObj = JSON.stringify(result);
|
|
1672
|
-
const encoded = window.btoa(encodeURIComponent(stringObj));
|
|
1673
|
-
data === null || data === void 0 ? void 0 : data.setData(`application/${CLIP_BOARD_FORMAT_KEY}`, encoded);
|
|
1674
|
-
};
|
|
1675
|
-
const setClipboardDataByText = (data, text) => {
|
|
1676
|
-
const pluginContextResult = getTextFromClipboard(data);
|
|
1677
|
-
data === null || data === void 0 ? void 0 : data.setData(`text/plain`, text + '\n' + pluginContextResult);
|
|
1678
|
-
};
|
|
1679
|
-
const setClipboardDataByMedia = (data, media, key) => {
|
|
1680
|
-
const stringObj = JSON.stringify(media);
|
|
1681
|
-
const encoded = window.btoa(encodeURIComponent(stringObj));
|
|
1682
|
-
data === null || data === void 0 ? void 0 : data.setData(getClipboardByKey(key), encoded);
|
|
1683
|
-
};
|
|
1684
|
-
const getDataFromClipboard = (data) => {
|
|
1685
|
-
const encoded = data === null || data === void 0 ? void 0 : data.getData(`application/${CLIP_BOARD_FORMAT_KEY}`);
|
|
1686
|
-
let nodesData = [];
|
|
1687
|
-
if (encoded) {
|
|
1688
|
-
const decoded = decodeURIComponent(window.atob(encoded));
|
|
1689
|
-
nodesData = JSON.parse(decoded);
|
|
1690
|
-
}
|
|
1691
|
-
return nodesData;
|
|
1692
|
-
};
|
|
1693
|
-
const getTextFromClipboard = (data) => {
|
|
1694
|
-
return (data ? data.getData(`text/plain`) : '');
|
|
1695
|
-
};
|
|
1696
|
-
const getClipboardDataByMedia = (data, key) => {
|
|
1697
|
-
const encoded = data === null || data === void 0 ? void 0 : data.getData(getClipboardByKey(key));
|
|
1698
|
-
let imageItem = null;
|
|
1699
|
-
if (encoded) {
|
|
1700
|
-
const decoded = decodeURIComponent(window.atob(encoded));
|
|
1701
|
-
imageItem = JSON.parse(decoded);
|
|
1702
|
-
}
|
|
1703
|
-
return imageItem;
|
|
1704
|
-
};
|
|
1705
|
-
|
|
1706
|
-
const isPreventTouchMove = (board) => {
|
|
1707
|
-
return !!IS_PREVENT_TOUCH_MOVE.get(board);
|
|
1708
|
-
};
|
|
1709
|
-
const preventTouchMove = (board, state) => {
|
|
1710
|
-
IS_PREVENT_TOUCH_MOVE.set(board, state);
|
|
1711
|
-
};
|
|
1712
|
-
|
|
1713
|
-
const PlaitElement = {
|
|
1714
|
-
isRootElement(value) {
|
|
1715
|
-
const parent = NODE_TO_PARENT.get(value);
|
|
1716
|
-
if (parent && PlaitBoard.isBoard(parent)) {
|
|
1717
|
-
return true;
|
|
1718
|
-
}
|
|
1719
|
-
else {
|
|
1720
|
-
return false;
|
|
1721
|
-
}
|
|
1722
|
-
},
|
|
1723
|
-
getComponent(value) {
|
|
1724
|
-
return ELEMENT_TO_COMPONENT.get(value);
|
|
1725
|
-
}
|
|
1726
|
-
};
|
|
1727
|
-
|
|
1728
|
-
const isSetViewportOperation = (value) => {
|
|
1729
|
-
return value.type === 'set_viewport';
|
|
1730
|
-
};
|
|
1731
|
-
const inverse = (op) => {
|
|
1732
|
-
switch (op.type) {
|
|
1733
|
-
case 'insert_node': {
|
|
1734
|
-
return Object.assign(Object.assign({}, op), { type: 'remove_node' });
|
|
1735
|
-
}
|
|
1736
|
-
case 'remove_node': {
|
|
1737
|
-
return Object.assign(Object.assign({}, op), { type: 'insert_node' });
|
|
1738
|
-
}
|
|
1739
|
-
case 'move_node': {
|
|
1740
|
-
const { newPath, path } = op;
|
|
1741
|
-
// PERF: in this case the move operation is a no-op anyways.
|
|
1742
|
-
if (Path.equals(newPath, path)) {
|
|
1743
|
-
return op;
|
|
1744
|
-
}
|
|
1745
|
-
// when operation path is [0,0] -> [0,2], should exec Path.transform to get [0,1] -> [0,0]
|
|
1746
|
-
// shoud not return [0,2] -> [0,0] #WIK-8981
|
|
1747
|
-
// if (Path.isSibling(path, newPath)) {
|
|
1748
|
-
// return { ...op, path: newPath, newPath: path };
|
|
1749
|
-
// }
|
|
1750
|
-
// If the move does not happen within a single parent it is possible
|
|
1751
|
-
// for the move to impact the true path to the location where the node
|
|
1752
|
-
// was removed from and where it was inserted. We have to adjust for this
|
|
1753
|
-
// and find the original path. We can accomplish this (only in non-sibling)
|
|
1754
|
-
// moves by looking at the impact of the move operation on the node
|
|
1755
|
-
// after the original move path.
|
|
1756
|
-
const inversePath = Path.transform(path, op);
|
|
1757
|
-
const inverseNewPath = Path.transform(Path.next(path), op);
|
|
1758
|
-
return Object.assign(Object.assign({}, op), { path: inversePath, newPath: inverseNewPath });
|
|
1759
|
-
}
|
|
1760
|
-
case 'set_node': {
|
|
1761
|
-
const { properties, newProperties } = op;
|
|
1762
|
-
return Object.assign(Object.assign({}, op), { properties: newProperties, newProperties: properties });
|
|
1763
|
-
}
|
|
1764
|
-
case 'set_selection': {
|
|
1765
|
-
const { properties, newProperties } = op;
|
|
1766
|
-
if (properties == null) {
|
|
1767
|
-
return Object.assign(Object.assign({}, op), { properties: newProperties, newProperties: null });
|
|
1768
|
-
}
|
|
1769
|
-
else if (newProperties == null) {
|
|
1770
|
-
return Object.assign(Object.assign({}, op), { properties: null, newProperties: properties });
|
|
1771
|
-
}
|
|
1772
|
-
else {
|
|
1773
|
-
return Object.assign(Object.assign({}, op), { properties: newProperties, newProperties: properties });
|
|
1774
|
-
}
|
|
1775
|
-
}
|
|
1776
|
-
case 'set_viewport': {
|
|
1777
|
-
const { properties, newProperties } = op;
|
|
1778
|
-
if (properties == null) {
|
|
1779
|
-
return Object.assign(Object.assign({}, op), { properties: newProperties, newProperties: newProperties });
|
|
1780
|
-
}
|
|
1781
|
-
else if (newProperties == null) {
|
|
1782
|
-
return Object.assign(Object.assign({}, op), { properties: properties, newProperties: properties });
|
|
1783
|
-
}
|
|
1784
|
-
else {
|
|
1785
|
-
return Object.assign(Object.assign({}, op), { properties: newProperties, newProperties: properties });
|
|
1786
|
-
}
|
|
1787
|
-
}
|
|
1788
|
-
case 'set_theme': {
|
|
1789
|
-
const { properties, newProperties } = op;
|
|
1790
|
-
return Object.assign(Object.assign({}, op), { properties: newProperties, newProperties: properties });
|
|
1791
|
-
}
|
|
1792
|
-
}
|
|
1793
|
-
};
|
|
1794
|
-
const PlaitOperation = {
|
|
1795
|
-
isSetViewportOperation,
|
|
1796
|
-
inverse
|
|
1797
|
-
};
|
|
1798
|
-
|
|
1799
|
-
const Point = {
|
|
1800
|
-
isEquals(point, otherPoint) {
|
|
1801
|
-
return point && otherPoint && point[0] === otherPoint[0] && point[1] === otherPoint[1];
|
|
1802
|
-
}
|
|
1803
|
-
};
|
|
1804
|
-
|
|
1805
|
-
const SAVING = new WeakMap();
|
|
1806
|
-
const MERGING = new WeakMap();
|
|
1807
|
-
|
|
1808
|
-
var PlaitPluginKey;
|
|
1809
|
-
(function (PlaitPluginKey) {
|
|
1810
|
-
PlaitPluginKey["withSelection"] = "withSelection";
|
|
1811
|
-
})(PlaitPluginKey || (PlaitPluginKey = {}));
|
|
1812
|
-
|
|
1813
|
-
const IS_FROM_SCROLLING = new WeakMap();
|
|
1814
|
-
const IS_FROM_VIEWPORT_CHANGE = new WeakMap();
|
|
1815
|
-
function getViewportContainerRect(board) {
|
|
1816
|
-
const { hideScrollbar } = board.options;
|
|
1817
|
-
const scrollBarWidth = hideScrollbar ? SCROLL_BAR_WIDTH : 0;
|
|
1818
|
-
const viewportRect = PlaitBoard.getBoardContainer(board).getBoundingClientRect();
|
|
1819
|
-
return {
|
|
1820
|
-
width: viewportRect.width + scrollBarWidth,
|
|
1821
|
-
height: viewportRect.height + scrollBarWidth
|
|
1822
|
-
};
|
|
1823
|
-
}
|
|
1824
|
-
function getElementHostBBox(board, zoom) {
|
|
1825
|
-
const childrenRect = getRectangleByElements(board, board.children, true);
|
|
1826
|
-
const viewportContainerRect = PlaitBoard.getBoardContainer(board).getBoundingClientRect();
|
|
1827
|
-
const containerWidth = viewportContainerRect.width / zoom;
|
|
1828
|
-
const containerHeight = viewportContainerRect.height / zoom;
|
|
1829
|
-
let left;
|
|
1830
|
-
let right;
|
|
1831
|
-
let top;
|
|
1832
|
-
let bottom;
|
|
1833
|
-
if (childrenRect.width < containerWidth) {
|
|
1834
|
-
const centerX = childrenRect.x + childrenRect.width / 2;
|
|
1835
|
-
const halfContainerWidth = containerWidth / 2;
|
|
1836
|
-
left = centerX - halfContainerWidth;
|
|
1837
|
-
right = centerX + halfContainerWidth;
|
|
1838
|
-
}
|
|
1839
|
-
else {
|
|
1840
|
-
left = childrenRect.x;
|
|
1841
|
-
right = childrenRect.x + childrenRect.width;
|
|
1842
|
-
}
|
|
1843
|
-
if (childrenRect.height < containerHeight) {
|
|
1844
|
-
const centerY = childrenRect.y + childrenRect.height / 2;
|
|
1845
|
-
const halfContainerHeight = containerHeight / 2;
|
|
1846
|
-
top = centerY - halfContainerHeight;
|
|
1847
|
-
bottom = centerY + halfContainerHeight;
|
|
1848
|
-
}
|
|
1849
|
-
else {
|
|
1850
|
-
top = childrenRect.y;
|
|
1851
|
-
bottom = childrenRect.y + childrenRect.height;
|
|
1852
|
-
}
|
|
1853
|
-
return {
|
|
1854
|
-
left,
|
|
1855
|
-
right,
|
|
1856
|
-
top,
|
|
1857
|
-
bottom
|
|
1858
|
-
};
|
|
1859
|
-
}
|
|
1860
|
-
/**
|
|
1861
|
-
* 验证缩放比是否符合限制,如果超出限制,则返回合适的缩放比
|
|
1862
|
-
* @param zoom 缩放比
|
|
1863
|
-
* @param minZoom 最小缩放比
|
|
1864
|
-
* @param maxZoom 最大缩放比
|
|
1865
|
-
* @returns 正确的缩放比
|
|
1866
|
-
*/
|
|
1867
|
-
function clampZoomLevel(zoom, minZoom = 0.2, maxZoom = 4) {
|
|
1868
|
-
return zoom < minZoom ? minZoom : zoom > maxZoom ? maxZoom : zoom;
|
|
1869
|
-
}
|
|
1870
|
-
function getViewBox(board, zoom) {
|
|
1871
|
-
const boardContainerRectangle = PlaitBoard.getBoardContainer(board).getBoundingClientRect();
|
|
1872
|
-
const elementHostBBox = getElementHostBBox(board, zoom);
|
|
1873
|
-
const horizontalPadding = boardContainerRectangle.width / 2;
|
|
1874
|
-
const verticalPadding = boardContainerRectangle.height / 2;
|
|
1875
|
-
const viewBox = [
|
|
1876
|
-
elementHostBBox.left - horizontalPadding / zoom,
|
|
1877
|
-
elementHostBBox.top - verticalPadding / zoom,
|
|
1878
|
-
elementHostBBox.right - elementHostBBox.left + (horizontalPadding * 2) / zoom,
|
|
1879
|
-
elementHostBBox.bottom - elementHostBBox.top + (verticalPadding * 2) / zoom
|
|
1880
|
-
];
|
|
1881
|
-
return viewBox;
|
|
1882
|
-
}
|
|
1883
|
-
function getViewBoxCenterPoint(board) {
|
|
1884
|
-
const childrenRectangle = getRectangleByElements(board, board.children, true);
|
|
1885
|
-
return [childrenRectangle.x + childrenRectangle.width / 2, childrenRectangle.y + childrenRectangle.height / 2];
|
|
1886
|
-
}
|
|
1887
|
-
function setSVGViewBox(board, viewBox) {
|
|
1888
|
-
const zoom = board.viewport.zoom;
|
|
1889
|
-
const hostElement = PlaitBoard.getHost(board);
|
|
1890
|
-
hostElement.style.display = 'block';
|
|
1891
|
-
hostElement.style.width = `${viewBox[2] * zoom}px`;
|
|
1892
|
-
hostElement.style.height = `${viewBox[3] * zoom}px`;
|
|
1893
|
-
if (viewBox && viewBox[2] > 0 && viewBox[3] > 0) {
|
|
1894
|
-
hostElement.setAttribute('viewBox', viewBox.join(' '));
|
|
1895
|
-
}
|
|
1896
|
-
}
|
|
1897
|
-
function updateViewportOffset(board) {
|
|
1898
|
-
const origination = getViewportOrigination(board);
|
|
1899
|
-
if (!origination)
|
|
1900
|
-
return;
|
|
1901
|
-
const { zoom } = board.viewport;
|
|
1902
|
-
const viewBox = getViewBox(board, zoom);
|
|
1903
|
-
const scrollLeft = (origination[0] - viewBox[0]) * zoom;
|
|
1904
|
-
const scrollTop = (origination[1] - viewBox[1]) * zoom;
|
|
1905
|
-
updateViewportContainerScroll(board, scrollLeft, scrollTop);
|
|
1906
|
-
}
|
|
1907
|
-
function updateViewportContainerScroll(board, left, top, isFromViewportChange = true) {
|
|
1908
|
-
const viewportContainer = PlaitBoard.getViewportContainer(board);
|
|
1909
|
-
if (viewportContainer.scrollLeft !== left || viewportContainer.scrollTop !== top) {
|
|
1910
|
-
viewportContainer.scrollLeft = left;
|
|
1911
|
-
viewportContainer.scrollTop = top;
|
|
1912
|
-
isFromViewportChange && setIsFromViewportChange(board, true);
|
|
1913
|
-
}
|
|
1914
|
-
}
|
|
1915
|
-
function initializeViewportContainer(board) {
|
|
1916
|
-
const { width, height } = getViewportContainerRect(board);
|
|
1917
|
-
const viewportContainer = PlaitBoard.getViewportContainer(board);
|
|
1918
|
-
viewportContainer.style.width = `${width}px`;
|
|
1919
|
-
viewportContainer.style.height = `${height}px`;
|
|
1920
|
-
}
|
|
1921
|
-
function initializeViewBox(board) {
|
|
1922
|
-
const zoom = board.viewport.zoom;
|
|
1923
|
-
const viewBox = getViewBox(board, zoom);
|
|
1924
|
-
setSVGViewBox(board, viewBox);
|
|
1925
|
-
}
|
|
1926
|
-
function initializeViewportOffset(board) {
|
|
1927
|
-
var _a;
|
|
1928
|
-
if (!((_a = board.viewport) === null || _a === void 0 ? void 0 : _a.origination)) {
|
|
1929
|
-
const zoom = board.viewport.zoom;
|
|
1930
|
-
const viewportContainerRect = PlaitBoard.getBoardContainer(board).getBoundingClientRect();
|
|
1931
|
-
const viewBox = getViewBox(board, zoom);
|
|
1932
|
-
const centerX = viewBox[0] + viewBox[2] / 2;
|
|
1933
|
-
const centerY = viewBox[1] + viewBox[3] / 2;
|
|
1934
|
-
const origination = [centerX - viewportContainerRect.width / 2 / zoom, centerY - viewportContainerRect.height / 2 / zoom];
|
|
1935
|
-
updateViewportOrigination(board, origination);
|
|
1936
|
-
updateViewportOffset(board);
|
|
1937
|
-
return;
|
|
1938
|
-
}
|
|
1939
|
-
updateViewportOffset(board);
|
|
1940
|
-
}
|
|
1941
|
-
const updateViewportOrigination = (board, origination) => {
|
|
1942
|
-
BOARD_TO_VIEWPORT_ORIGINATION.set(board, origination);
|
|
1943
|
-
};
|
|
1944
|
-
const clearViewportOrigination = (board) => {
|
|
1945
|
-
BOARD_TO_VIEWPORT_ORIGINATION.delete(board);
|
|
1946
|
-
};
|
|
1947
|
-
const getViewportOrigination = (board) => {
|
|
1948
|
-
const origination = BOARD_TO_VIEWPORT_ORIGINATION.get(board);
|
|
1949
|
-
if (origination) {
|
|
1950
|
-
return origination;
|
|
1951
|
-
}
|
|
1952
|
-
else {
|
|
1953
|
-
return board.viewport.origination;
|
|
1954
|
-
}
|
|
1955
|
-
};
|
|
1956
|
-
const isFromScrolling = (board) => {
|
|
1957
|
-
return !!IS_FROM_SCROLLING.get(board);
|
|
1958
|
-
};
|
|
1959
|
-
const setIsFromScrolling = (board, state) => {
|
|
1960
|
-
IS_FROM_SCROLLING.set(board, state);
|
|
1961
|
-
};
|
|
1962
|
-
const isFromViewportChange = (board) => {
|
|
1963
|
-
return !!IS_FROM_VIEWPORT_CHANGE.get(board);
|
|
1964
|
-
};
|
|
1965
|
-
const setIsFromViewportChange = (board, state) => {
|
|
1966
|
-
IS_FROM_VIEWPORT_CHANGE.set(board, state);
|
|
1967
|
-
};
|
|
1968
|
-
function scrollToRectangle(board, client) { }
|
|
1969
|
-
|
|
1970
|
-
function setTheme(board, themeColorMode) {
|
|
1971
|
-
const operation = { type: 'set_theme', properties: board.theme, newProperties: themeColorMode };
|
|
1972
|
-
board.apply(operation);
|
|
1973
|
-
}
|
|
1974
|
-
const ViewportTransforms = {
|
|
1975
|
-
setTheme
|
|
1976
|
-
};
|
|
1977
|
-
|
|
1978
|
-
function updateViewport(board, origination, zoom) {
|
|
1979
|
-
zoom = zoom !== null && zoom !== void 0 ? zoom : board.viewport.zoom;
|
|
1980
|
-
setViewport(board, Object.assign(Object.assign({}, board.viewport), { zoom,
|
|
1981
|
-
origination }));
|
|
1982
|
-
clearViewportOrigination(board);
|
|
1983
|
-
}
|
|
1984
|
-
const updatePointerType = (board, pointer) => {
|
|
1985
|
-
board.pointer = pointer;
|
|
1986
|
-
const boardComponent = BOARD_TO_COMPONENT.get(board);
|
|
1987
|
-
boardComponent === null || boardComponent === void 0 ? void 0 : boardComponent.markForCheck();
|
|
1988
|
-
};
|
|
1989
|
-
function updateZoom(board, newZoom, isCenter = true) {
|
|
1990
|
-
newZoom = clampZoomLevel(newZoom);
|
|
1991
|
-
const mousePoint = PlaitBoard.getMovingPointInBoard(board);
|
|
1992
|
-
const nativeElement = PlaitBoard.getBoardContainer(board);
|
|
1993
|
-
const nativeElementRect = nativeElement.getBoundingClientRect();
|
|
1994
|
-
const boardContainerRect = PlaitBoard.getBoardContainer(board).getBoundingClientRect();
|
|
1995
|
-
let focusPoint = [boardContainerRect.width / 2, boardContainerRect.height / 2];
|
|
1996
|
-
if (!isCenter && mousePoint && distanceBetweenPointAndRectangle(mousePoint[0], mousePoint[1], nativeElementRect) === 0) {
|
|
1997
|
-
focusPoint = toPoint(mousePoint[0], mousePoint[1], nativeElement);
|
|
1998
|
-
}
|
|
1999
|
-
const zoom = board.viewport.zoom;
|
|
2000
|
-
const origination = getViewportOrigination(board);
|
|
2001
|
-
const centerX = origination[0] + focusPoint[0] / zoom;
|
|
2002
|
-
const centerY = origination[1] + focusPoint[1] / zoom;
|
|
2003
|
-
const newOrigination = [centerX - focusPoint[0] / newZoom, centerY - focusPoint[1] / newZoom];
|
|
2004
|
-
updateViewport(board, newOrigination, newZoom);
|
|
2005
|
-
}
|
|
2006
|
-
function fitViewport(board) {
|
|
2007
|
-
let scrollBarWidth = getRealScrollBarWidth(board);
|
|
2008
|
-
const boardContainerRect = PlaitBoard.getBoardContainer(board).getBoundingClientRect();
|
|
2009
|
-
const elementHostBox = getRectangleByElements(board, board.children, true);
|
|
2010
|
-
const zoom = board.viewport.zoom;
|
|
2011
|
-
const autoFitPadding = 16;
|
|
2012
|
-
const viewportWidth = boardContainerRect.width - 2 * autoFitPadding;
|
|
2013
|
-
const viewportHeight = boardContainerRect.height - 2 * autoFitPadding;
|
|
2014
|
-
let newZoom = zoom;
|
|
2015
|
-
if (viewportWidth < elementHostBox.width || viewportHeight < elementHostBox.height) {
|
|
2016
|
-
newZoom = Math.min(viewportWidth / elementHostBox.width, viewportHeight / elementHostBox.height);
|
|
2017
|
-
}
|
|
2018
|
-
else {
|
|
2019
|
-
newZoom = 1;
|
|
2020
|
-
}
|
|
2021
|
-
const centerPoint = getViewBoxCenterPoint(board);
|
|
2022
|
-
const newOrigination = [
|
|
2023
|
-
centerPoint[0] - boardContainerRect.width / 2 / newZoom + scrollBarWidth / 2 / zoom,
|
|
2024
|
-
centerPoint[1] - boardContainerRect.height / 2 / newZoom + scrollBarWidth / 2 / zoom
|
|
2025
|
-
];
|
|
2026
|
-
updateViewport(board, newOrigination, newZoom);
|
|
2027
|
-
}
|
|
2028
|
-
function fitViewportWidth(board, options) {
|
|
2029
|
-
let scrollBarWidth = getRealScrollBarWidth(board);
|
|
2030
|
-
const boardContainer = PlaitBoard.getBoardContainer(board);
|
|
2031
|
-
const boardContainerRectangle = boardContainer.getBoundingClientRect();
|
|
2032
|
-
let finalWidth = 0;
|
|
2033
|
-
if (options.maxWidth) {
|
|
2034
|
-
finalWidth = options.maxWidth;
|
|
2035
|
-
}
|
|
2036
|
-
else {
|
|
2037
|
-
finalWidth = boardContainerRectangle.width;
|
|
2038
|
-
}
|
|
2039
|
-
const elementHostBox = getRectangleByElements(board, board.children, true);
|
|
2040
|
-
const contentWidth = finalWidth - 2 * options.autoFitPadding;
|
|
2041
|
-
let newZoom = 0;
|
|
2042
|
-
if (contentWidth < elementHostBox.width) {
|
|
2043
|
-
newZoom = Math.min(contentWidth / elementHostBox.width);
|
|
2044
|
-
}
|
|
2045
|
-
else {
|
|
2046
|
-
newZoom = 1;
|
|
2047
|
-
}
|
|
2048
|
-
let finalHeight = elementHostBox.height * newZoom + 2 * options.autoFitPadding;
|
|
2049
|
-
if (finalHeight > options.limitHeight) {
|
|
2050
|
-
const containerEl = boardContainer.closest(`.${options.containerClass}`);
|
|
2051
|
-
containerEl.style.height = `${finalHeight}px`;
|
|
2052
|
-
initializeViewportContainer(board);
|
|
2053
|
-
}
|
|
2054
|
-
else {
|
|
2055
|
-
finalHeight = options.limitHeight;
|
|
2056
|
-
}
|
|
2057
|
-
const centerX = elementHostBox.x + elementHostBox.width / 2;
|
|
2058
|
-
const centerY = elementHostBox.y + elementHostBox.height / 2;
|
|
2059
|
-
const newOrigination = [
|
|
2060
|
-
centerX - finalWidth / 2 / newZoom + scrollBarWidth / 2 / newZoom,
|
|
2061
|
-
centerY - finalHeight / 2 / newZoom + scrollBarWidth / 2 / newZoom
|
|
2062
|
-
];
|
|
2063
|
-
updateViewport(board, newOrigination, newZoom);
|
|
2064
|
-
}
|
|
2065
|
-
/**
|
|
2066
|
-
* apply theme to every element (remove element custom properties)
|
|
2067
|
-
* invoke applyThemeColor
|
|
2068
|
-
*/
|
|
2069
|
-
function updateThemeColor(board, mode) {
|
|
2070
|
-
mode = mode !== null && mode !== void 0 ? mode : board.theme.themeColorMode;
|
|
2071
|
-
setTheme(board, { themeColorMode: mode });
|
|
2072
|
-
depthFirstRecursion(board, element => {
|
|
2073
|
-
board.applyTheme(element);
|
|
2074
|
-
});
|
|
2075
|
-
}
|
|
2076
|
-
const BoardTransforms = {
|
|
2077
|
-
updatePointerType,
|
|
2078
|
-
updateViewport,
|
|
2079
|
-
fitViewport,
|
|
2080
|
-
updateZoom,
|
|
2081
|
-
updateThemeColor,
|
|
2082
|
-
fitViewportWidth
|
|
2083
|
-
};
|
|
2084
|
-
|
|
2085
|
-
const Transforms = Object.assign(Object.assign(Object.assign(Object.assign({}, GeneralTransforms), ViewportTransforms$1), SelectionTransforms), NodeTransforms);
|
|
2086
|
-
|
|
2087
|
-
const PathRef = {
|
|
2088
|
-
transform(ref, op) {
|
|
2089
|
-
const { current } = ref;
|
|
2090
|
-
if (current == null) {
|
|
2091
|
-
return;
|
|
2092
|
-
}
|
|
2093
|
-
const path = Path.transform(current, op);
|
|
2094
|
-
ref.current = path;
|
|
2095
|
-
if (path == null) {
|
|
2096
|
-
ref.unref();
|
|
2097
|
-
}
|
|
2098
|
-
}
|
|
2099
|
-
};
|
|
2100
|
-
|
|
2101
|
-
function createBoard(children, options) {
|
|
2102
|
-
const board = {
|
|
2103
|
-
viewport: {
|
|
2104
|
-
zoom: 1
|
|
2105
|
-
},
|
|
2106
|
-
children,
|
|
2107
|
-
theme: { themeColorMode: ThemeColorMode.default },
|
|
2108
|
-
operations: [],
|
|
2109
|
-
history: {
|
|
2110
|
-
redos: [],
|
|
2111
|
-
undos: []
|
|
2112
|
-
},
|
|
2113
|
-
selection: null,
|
|
2114
|
-
options: options || {
|
|
2115
|
-
readonly: false,
|
|
2116
|
-
hideScrollbar: false,
|
|
2117
|
-
disabledScrollOnNonFocus: false
|
|
2118
|
-
},
|
|
2119
|
-
pointer: (options === null || options === void 0 ? void 0 : options.readonly) ? PlaitPointerType.hand : PlaitPointerType.selection,
|
|
2120
|
-
undo: () => { },
|
|
2121
|
-
redo: () => { },
|
|
2122
|
-
apply: (operation) => {
|
|
2123
|
-
for (const ref of board.pathRefs()) {
|
|
2124
|
-
PathRef.transform(ref, operation);
|
|
2125
|
-
}
|
|
2126
|
-
board.operations.push(operation);
|
|
2127
|
-
Transforms.transform(board, operation);
|
|
2128
|
-
if (!FLUSHING.get(board)) {
|
|
2129
|
-
FLUSHING.set(board, true);
|
|
2130
|
-
Promise.resolve().then(() => {
|
|
2131
|
-
FLUSHING.set(board, false);
|
|
2132
|
-
board.onChange();
|
|
2133
|
-
board.operations = [];
|
|
2134
|
-
});
|
|
2135
|
-
}
|
|
2136
|
-
},
|
|
2137
|
-
pathRef: (path, options) => {
|
|
2138
|
-
const affinity = (options === null || options === void 0 ? void 0 : options.affinity) || 'forward';
|
|
2139
|
-
const ref = {
|
|
2140
|
-
current: path,
|
|
2141
|
-
affinity,
|
|
2142
|
-
unref() {
|
|
2143
|
-
const { current } = ref;
|
|
2144
|
-
const pathRefs = board.pathRefs();
|
|
2145
|
-
pathRefs.delete(ref);
|
|
2146
|
-
ref.current = null;
|
|
2147
|
-
return current;
|
|
2148
|
-
}
|
|
2149
|
-
};
|
|
2150
|
-
const refs = board.pathRefs();
|
|
2151
|
-
refs.add(ref);
|
|
2152
|
-
return ref;
|
|
2153
|
-
},
|
|
2154
|
-
pathRefs: () => {
|
|
2155
|
-
let refs = PATH_REFS.get(board);
|
|
2156
|
-
if (!refs) {
|
|
2157
|
-
refs = new Set();
|
|
2158
|
-
PATH_REFS.set(board, refs);
|
|
2159
|
-
}
|
|
2160
|
-
return refs;
|
|
2161
|
-
},
|
|
2162
|
-
onChange: () => { },
|
|
2163
|
-
mousedown: (event) => { },
|
|
2164
|
-
mousemove: (event) => { },
|
|
2165
|
-
mouseleave: (event) => { },
|
|
2166
|
-
globalMousemove: (event) => { },
|
|
2167
|
-
mouseup: (event) => { },
|
|
2168
|
-
globalMouseup: (event) => { },
|
|
2169
|
-
keydown: (event) => { },
|
|
2170
|
-
globalKeydown: (event) => { },
|
|
2171
|
-
keyup: (event) => { },
|
|
2172
|
-
dblclick: (event) => { },
|
|
2173
|
-
setFragment: (data) => { },
|
|
2174
|
-
insertFragment: (data) => { },
|
|
2175
|
-
deleteFragment: (data) => { },
|
|
2176
|
-
drawElement: (context) => [],
|
|
2177
|
-
redrawElement: (context, previousContext) => { },
|
|
2178
|
-
destroyElement: (context) => { },
|
|
2179
|
-
isWithinSelection: element => false,
|
|
2180
|
-
isHitSelection: element => false,
|
|
2181
|
-
isRecursion: element => true,
|
|
2182
|
-
isMovable: element => false,
|
|
2183
|
-
getRectangle: element => null,
|
|
2184
|
-
applyTheme: (element) => { },
|
|
2185
|
-
pointerDown: (pointer) => { },
|
|
2186
|
-
pointerMove: (pointer) => { },
|
|
2187
|
-
pointerUp: (pointer) => { },
|
|
2188
|
-
pointerCancel: (pointer) => { },
|
|
2189
|
-
pointerOut: (pointer) => { },
|
|
2190
|
-
pointerLeave: (pointer) => { },
|
|
2191
|
-
globalPointerMove: (pointer) => { },
|
|
2192
|
-
globalPointerUp: (pointer) => { },
|
|
2193
|
-
};
|
|
2194
|
-
return board;
|
|
2195
|
-
}
|
|
2196
|
-
|
|
2197
|
-
function withBoard(board) {
|
|
2198
|
-
const { onChange } = board;
|
|
2199
|
-
board.onChange = () => {
|
|
2200
|
-
const onContextChange = BOARD_TO_ON_CHANGE.get(board);
|
|
2201
|
-
if (onContextChange) {
|
|
2202
|
-
onContextChange();
|
|
2203
|
-
}
|
|
2204
|
-
onChange();
|
|
2205
|
-
};
|
|
2206
|
-
return board;
|
|
2207
|
-
}
|
|
2208
|
-
|
|
2209
|
-
function withHistory(board) {
|
|
2210
|
-
const { apply, keydown } = board;
|
|
2211
|
-
board.history = { undos: [], redos: [] };
|
|
2212
|
-
board.redo = () => {
|
|
2213
|
-
const { history } = board;
|
|
2214
|
-
const { redos } = history;
|
|
2215
|
-
if (redos.length > 0) {
|
|
2216
|
-
const batch = redos[redos.length - 1];
|
|
2217
|
-
PlaitHistoryBoard.withoutSaving(board, () => {
|
|
2218
|
-
for (const op of batch) {
|
|
2219
|
-
board.apply(op);
|
|
2220
|
-
}
|
|
2221
|
-
});
|
|
2222
|
-
history.redos.pop();
|
|
2223
|
-
history.undos.push(batch);
|
|
2224
|
-
}
|
|
2225
|
-
};
|
|
2226
|
-
board.undo = () => {
|
|
2227
|
-
const { history } = board;
|
|
2228
|
-
const { undos } = history;
|
|
2229
|
-
if (undos.length > 0) {
|
|
2230
|
-
const batch = undos[undos.length - 1];
|
|
2231
|
-
PlaitHistoryBoard.withoutSaving(board, () => {
|
|
2232
|
-
const inverseOps = batch.map(PlaitOperation.inverse).reverse();
|
|
2233
|
-
for (const op of inverseOps) {
|
|
2234
|
-
board.apply(op);
|
|
2235
|
-
}
|
|
2236
|
-
});
|
|
2237
|
-
history.redos.push(batch);
|
|
2238
|
-
history.undos.pop();
|
|
2239
|
-
}
|
|
2240
|
-
};
|
|
2241
|
-
board.apply = (op) => {
|
|
2242
|
-
const { operations, history } = board;
|
|
2243
|
-
const { undos } = history;
|
|
2244
|
-
const lastBatch = undos[undos.length - 1];
|
|
2245
|
-
const lastOp = lastBatch && lastBatch[lastBatch.length - 1];
|
|
2246
|
-
let save = PlaitHistoryBoard.isSaving(board);
|
|
2247
|
-
let merge = PlaitHistoryBoard.isMerging(board);
|
|
2248
|
-
if (save == null) {
|
|
2249
|
-
save = shouldSave(op, lastOp);
|
|
2250
|
-
}
|
|
2251
|
-
if (save) {
|
|
2252
|
-
if (!merge) {
|
|
2253
|
-
if (lastBatch == null) {
|
|
2254
|
-
merge = false;
|
|
2255
|
-
}
|
|
2256
|
-
else if (operations.length !== 0) {
|
|
2257
|
-
merge = true;
|
|
2258
|
-
}
|
|
2259
|
-
else {
|
|
2260
|
-
merge = shouldMerge(op, lastOp);
|
|
2261
|
-
}
|
|
2262
|
-
}
|
|
2263
|
-
if (lastBatch && merge) {
|
|
2264
|
-
lastBatch.push(op);
|
|
2265
|
-
}
|
|
2266
|
-
else {
|
|
2267
|
-
const batch = [op];
|
|
2268
|
-
undos.push(batch);
|
|
2269
|
-
}
|
|
2270
|
-
while (undos.length > 100) {
|
|
2271
|
-
undos.shift();
|
|
2272
|
-
}
|
|
2273
|
-
if (shouldClear(op)) {
|
|
2274
|
-
history.redos = [];
|
|
2275
|
-
}
|
|
2276
|
-
}
|
|
2277
|
-
apply(op);
|
|
2278
|
-
};
|
|
2279
|
-
board.keydown = (event) => {
|
|
2280
|
-
if (isHotkey('mod+z', event)) {
|
|
2281
|
-
board.undo();
|
|
2282
|
-
return;
|
|
2283
|
-
}
|
|
2284
|
-
if (isHotkey('mod+shift+z', event)) {
|
|
2285
|
-
board.redo();
|
|
2286
|
-
return;
|
|
2287
|
-
}
|
|
2288
|
-
keydown(event);
|
|
2289
|
-
};
|
|
2290
|
-
return board;
|
|
2291
|
-
}
|
|
2292
|
-
|
|
2293
|
-
function withHandPointer(board) {
|
|
2294
|
-
const { mousedown, mousemove, globalMouseup, keydown, keyup } = board;
|
|
2295
|
-
let isMoving = false;
|
|
2296
|
-
const plaitBoardMove = {
|
|
2297
|
-
x: 0,
|
|
2298
|
-
y: 0
|
|
2299
|
-
};
|
|
2300
|
-
board.mousedown = (event) => {
|
|
2301
|
-
if (PlaitBoard.isPointer(board, PlaitPointerType.hand) && isMainPointer(event)) {
|
|
2302
|
-
isMoving = true;
|
|
2303
|
-
PlaitBoard.getBoardContainer(board).classList.add('viewport-moving');
|
|
2304
|
-
plaitBoardMove.x = event.x;
|
|
2305
|
-
plaitBoardMove.y = event.y;
|
|
2306
|
-
}
|
|
2307
|
-
mousedown(event);
|
|
2308
|
-
};
|
|
2309
|
-
board.mousemove = (event) => {
|
|
2310
|
-
if (PlaitBoard.isPointer(board, PlaitPointerType.hand) && board.selection && isMoving) {
|
|
2311
|
-
const viewportContainer = PlaitBoard.getViewportContainer(board);
|
|
2312
|
-
const left = viewportContainer.scrollLeft - (event.x - plaitBoardMove.x);
|
|
2313
|
-
const top = viewportContainer.scrollTop - (event.y - plaitBoardMove.y);
|
|
2314
|
-
updateViewportContainerScroll(board, left, top, false);
|
|
2315
|
-
plaitBoardMove.x = event.x;
|
|
2316
|
-
plaitBoardMove.y = event.y;
|
|
2317
|
-
}
|
|
2318
|
-
mousemove(event);
|
|
2319
|
-
};
|
|
2320
|
-
board.globalMouseup = (event) => {
|
|
2321
|
-
if (board.selection) {
|
|
2322
|
-
isMoving = false;
|
|
2323
|
-
PlaitBoard.getBoardContainer(board).classList.remove('viewport-moving');
|
|
2324
|
-
plaitBoardMove.x = 0;
|
|
2325
|
-
plaitBoardMove.y = 0;
|
|
2326
|
-
}
|
|
2327
|
-
globalMouseup(event);
|
|
2328
|
-
};
|
|
2329
|
-
board.keydown = (event) => {
|
|
2330
|
-
if (event.code === 'Space') {
|
|
2331
|
-
if (!PlaitBoard.isPointer(board, PlaitPointerType.hand)) {
|
|
2332
|
-
BoardTransforms.updatePointerType(board, PlaitPointerType.hand);
|
|
2333
|
-
}
|
|
2334
|
-
event.preventDefault();
|
|
2335
|
-
}
|
|
2336
|
-
keydown(event);
|
|
2337
|
-
};
|
|
2338
|
-
board.keyup = (event) => {
|
|
2339
|
-
if (!board.options.readonly && event.code === 'Space') {
|
|
2340
|
-
BoardTransforms.updatePointerType(board, PlaitPointerType.selection);
|
|
2341
|
-
}
|
|
2342
|
-
keyup(event);
|
|
2343
|
-
};
|
|
2344
|
-
return board;
|
|
2345
|
-
}
|
|
2346
|
-
|
|
2347
|
-
function withSelection(board) {
|
|
2348
|
-
const { pointerDown, globalPointerMove, globalPointerUp, onChange } = board;
|
|
2349
|
-
let start = null;
|
|
2350
|
-
let end = null;
|
|
2351
|
-
let selectionMovingG;
|
|
2352
|
-
let selectionOuterG;
|
|
2353
|
-
let previousSelectedElements;
|
|
2354
|
-
// prevent text from being selected when user pressed main pointer and is moving
|
|
2355
|
-
let needPreventNativeSelectionWhenMoving = false;
|
|
2356
|
-
board.pointerDown = (event) => {
|
|
2357
|
-
if (event.target instanceof Element && !event.target.closest('.plait-richtext-container')) {
|
|
2358
|
-
needPreventNativeSelectionWhenMoving = true;
|
|
2359
|
-
}
|
|
2360
|
-
if (!isMainPointer(event)) {
|
|
2361
|
-
pointerDown(event);
|
|
2362
|
-
return;
|
|
2363
|
-
}
|
|
2364
|
-
const options = board.getPluginOptions(PlaitPluginKey.withSelection);
|
|
2365
|
-
const point = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
|
|
2366
|
-
const range = { anchor: point, focus: point };
|
|
2367
|
-
const hitElements = getHitElements(board, { ranges: [range] });
|
|
2368
|
-
const selectedElements = getSelectedElements(board);
|
|
2369
|
-
if (hitElements.length === 1 && selectedElements.includes(hitElements[0]) && !options.isDisabledSelect) {
|
|
2370
|
-
pointerDown(event);
|
|
2371
|
-
return;
|
|
2372
|
-
}
|
|
2373
|
-
if (PlaitBoard.isPointer(board, PlaitPointerType.selection) &&
|
|
2374
|
-
hitElements.length === 0 &&
|
|
2375
|
-
options.isMultiple &&
|
|
2376
|
-
!options.isDisabledSelect) {
|
|
2377
|
-
start = point;
|
|
2378
|
-
preventTouchMove(board, true);
|
|
2379
|
-
}
|
|
2380
|
-
Transforms.setSelection(board, { ranges: [range] });
|
|
2381
|
-
pointerDown(event);
|
|
2382
|
-
};
|
|
2383
|
-
board.globalPointerMove = (event) => {
|
|
2384
|
-
if (needPreventNativeSelectionWhenMoving) {
|
|
2385
|
-
// prevent text from being selected
|
|
2386
|
-
event.preventDefault();
|
|
2387
|
-
}
|
|
2388
|
-
if (start) {
|
|
2389
|
-
const movedTarget = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
|
|
2390
|
-
const { x, y, width, height } = RectangleClient.toRectangleClient([start, movedTarget]);
|
|
2391
|
-
selectionMovingG === null || selectionMovingG === void 0 ? void 0 : selectionMovingG.remove();
|
|
2392
|
-
if (Math.hypot(width, height) > 5) {
|
|
2393
|
-
end = movedTarget;
|
|
2394
|
-
throttleRAF(() => {
|
|
2395
|
-
if (start && end) {
|
|
2396
|
-
Transforms.setSelection(board, { ranges: [{ anchor: start, focus: end }] });
|
|
2397
|
-
}
|
|
2398
|
-
});
|
|
2399
|
-
setSelectionMoving(board);
|
|
2400
|
-
const rough = PlaitBoard.getRoughSVG(board);
|
|
2401
|
-
selectionMovingG = rough.rectangle(x, y, width, height, {
|
|
2402
|
-
stroke: SELECTION_BORDER_COLOR,
|
|
2403
|
-
strokeWidth: 1,
|
|
2404
|
-
fill: SELECTION_FILL_COLOR,
|
|
2405
|
-
fillStyle: 'solid'
|
|
2406
|
-
});
|
|
2407
|
-
PlaitBoard.getHost(board).append(selectionMovingG);
|
|
2408
|
-
}
|
|
2409
|
-
}
|
|
2410
|
-
globalPointerMove(event);
|
|
2411
|
-
};
|
|
2412
|
-
board.globalPointerUp = (event) => {
|
|
2413
|
-
if (start && end) {
|
|
2414
|
-
selectionMovingG === null || selectionMovingG === void 0 ? void 0 : selectionMovingG.remove();
|
|
2415
|
-
clearSelectionMoving(board);
|
|
2416
|
-
Transforms.setSelection(board, { ranges: [{ anchor: start, focus: end }] });
|
|
2417
|
-
}
|
|
2418
|
-
if (PlaitBoard.isFocus(board)) {
|
|
2419
|
-
const isInBoard = event.target instanceof Node && PlaitBoard.getBoardContainer(board).contains(event.target);
|
|
2420
|
-
const isInDocument = event.target instanceof Node && document.contains(event.target);
|
|
2421
|
-
const isAttachedElement = event.target instanceof Element && event.target.closest(`.${ATTACHED_ELEMENT_CLASS_NAME}`);
|
|
2422
|
-
// Clear selection when mouse board outside area
|
|
2423
|
-
// The framework needs to determine whether the board is focused through selection
|
|
2424
|
-
if (!isInBoard && !start && !isAttachedElement && isInDocument) {
|
|
2425
|
-
Transforms.setSelection(board, null);
|
|
2426
|
-
}
|
|
2427
|
-
}
|
|
2428
|
-
start = null;
|
|
2429
|
-
end = null;
|
|
2430
|
-
needPreventNativeSelectionWhenMoving = false;
|
|
2431
|
-
preventTouchMove(board, false);
|
|
2432
|
-
globalPointerUp(event);
|
|
2433
|
-
};
|
|
2434
|
-
board.onChange = () => {
|
|
2435
|
-
const options = board.getPluginOptions(PlaitPluginKey.withSelection);
|
|
2436
|
-
if (options.isDisabledSelect) {
|
|
2437
|
-
selectionOuterG === null || selectionOuterG === void 0 ? void 0 : selectionOuterG.remove();
|
|
2438
|
-
clearSelectedElement(board);
|
|
2439
|
-
}
|
|
2440
|
-
// calc selected elements entry
|
|
2441
|
-
if (board.pointer !== PlaitPointerType.hand && !options.isDisabledSelect) {
|
|
2442
|
-
try {
|
|
2443
|
-
if (board.operations.find(value => value.type === 'set_selection')) {
|
|
2444
|
-
selectionOuterG === null || selectionOuterG === void 0 ? void 0 : selectionOuterG.remove();
|
|
2445
|
-
const temporaryElements = getTemporaryElements(board);
|
|
2446
|
-
let elements = temporaryElements ? temporaryElements : getHitElements(board);
|
|
2447
|
-
if (!options.isMultiple && elements.length > 1) {
|
|
2448
|
-
elements = [elements[0]];
|
|
2449
|
-
}
|
|
2450
|
-
cacheSelectedElements(board, elements);
|
|
2451
|
-
previousSelectedElements = elements;
|
|
2452
|
-
const { width, height } = getRectangleByElements(board, elements, false);
|
|
2453
|
-
if (width > 0 && height > 0 && elements.length > 1) {
|
|
2454
|
-
selectionOuterG = createSelectionOuterG(board, elements);
|
|
2455
|
-
selectionOuterG.classList.add('selection-outer');
|
|
2456
|
-
PlaitBoard.getHost(board).append(selectionOuterG);
|
|
2457
|
-
}
|
|
2458
|
-
deleteTemporaryElements(board);
|
|
2459
|
-
}
|
|
2460
|
-
else {
|
|
2461
|
-
// wait node destroy and remove selected element state
|
|
2462
|
-
setTimeout(() => {
|
|
2463
|
-
const currentSelectedElements = getSelectedElements(board);
|
|
2464
|
-
if (currentSelectedElements.length && currentSelectedElements.length > 1) {
|
|
2465
|
-
const selectedElementChange = currentSelectedElements.some(item => !previousSelectedElements.includes(item));
|
|
2466
|
-
if (selectedElementChange) {
|
|
2467
|
-
selectionOuterG === null || selectionOuterG === void 0 ? void 0 : selectionOuterG.remove();
|
|
2468
|
-
selectionOuterG = createSelectionOuterG(board, currentSelectedElements);
|
|
2469
|
-
selectionOuterG.classList.add('selection-outer');
|
|
2470
|
-
PlaitBoard.getHost(board).append(selectionOuterG);
|
|
2471
|
-
}
|
|
2472
|
-
}
|
|
2473
|
-
else {
|
|
2474
|
-
selectionOuterG === null || selectionOuterG === void 0 ? void 0 : selectionOuterG.remove();
|
|
2475
|
-
}
|
|
2476
|
-
});
|
|
2477
|
-
}
|
|
2478
|
-
}
|
|
2479
|
-
catch (error) {
|
|
2480
|
-
console.error(error);
|
|
2481
|
-
}
|
|
2482
|
-
}
|
|
2483
|
-
onChange();
|
|
2484
|
-
};
|
|
2485
|
-
board.setPluginOptions(PlaitPluginKey.withSelection, {
|
|
2486
|
-
isMultiple: true,
|
|
2487
|
-
isDisabledSelect: false
|
|
2488
|
-
});
|
|
2489
|
-
return board;
|
|
2490
|
-
}
|
|
2491
|
-
function getTemporaryElements(board) {
|
|
2492
|
-
return BOARD_TO_TEMPORARY_ELEMENTS.get(board);
|
|
2493
|
-
}
|
|
2494
|
-
function deleteTemporaryElements(board) {
|
|
2495
|
-
BOARD_TO_TEMPORARY_ELEMENTS.delete(board);
|
|
2496
|
-
}
|
|
2497
|
-
function isSelectionMoving(board) {
|
|
2498
|
-
return !!BOARD_TO_IS_SELECTION_MOVING.get(board);
|
|
2499
|
-
}
|
|
2500
|
-
function setSelectionMoving(board) {
|
|
2501
|
-
PlaitBoard.getBoardContainer(board).classList.add('selection-moving');
|
|
2502
|
-
BOARD_TO_IS_SELECTION_MOVING.set(board, true);
|
|
2503
|
-
}
|
|
2504
|
-
function clearSelectionMoving(board) {
|
|
2505
|
-
PlaitBoard.getBoardContainer(board).classList.remove('selection-moving');
|
|
2506
|
-
BOARD_TO_IS_SELECTION_MOVING.delete(board);
|
|
2507
|
-
}
|
|
2508
|
-
function createSelectionOuterG(board, selectElements) {
|
|
2509
|
-
const { x, y, width, height } = getRectangleByElements(board, selectElements, false);
|
|
2510
|
-
const rough = PlaitBoard.getRoughSVG(board);
|
|
2511
|
-
return rough.rectangle(x - 2.5, y - 2.5, width + 5, height + 5, {
|
|
2512
|
-
stroke: SELECTION_BORDER_COLOR,
|
|
2513
|
-
strokeWidth: 1,
|
|
2514
|
-
fillStyle: 'solid'
|
|
2515
|
-
});
|
|
2516
|
-
}
|
|
2517
|
-
|
|
2518
|
-
function withViewport(board) {
|
|
2519
|
-
const { onChange } = board;
|
|
2520
|
-
const throttleUpdate = debounce(() => {
|
|
2521
|
-
initializeViewBox(board);
|
|
2522
|
-
updateViewportOffset(board);
|
|
2523
|
-
}, 500, { leading: true });
|
|
2524
|
-
board.onChange = () => {
|
|
2525
|
-
const isSetViewport = board.operations.some(op => op.type === 'set_viewport');
|
|
2526
|
-
const isOnlySetSelection = board.operations.some(op => op.type === 'set_selection');
|
|
2527
|
-
if (isOnlySetSelection) {
|
|
2528
|
-
return onChange();
|
|
2529
|
-
}
|
|
2530
|
-
if (isSetViewport && isFromScrolling(board)) {
|
|
2531
|
-
setIsFromScrolling(board, false);
|
|
2532
|
-
return onChange();
|
|
2533
|
-
}
|
|
2534
|
-
if (isSetViewport) {
|
|
2535
|
-
initializeViewBox(board);
|
|
2536
|
-
updateViewportOffset(board);
|
|
2537
|
-
}
|
|
2538
|
-
else {
|
|
2539
|
-
throttleUpdate();
|
|
2540
|
-
}
|
|
2541
|
-
onChange();
|
|
2542
|
-
};
|
|
2543
|
-
return board;
|
|
2544
|
-
}
|
|
2545
|
-
|
|
2546
|
-
function withMoving(board) {
|
|
2547
|
-
const { pointerDown, pointerMove, globalPointerUp, globalPointerMove } = board;
|
|
2548
|
-
let offsetX = 0;
|
|
2549
|
-
let offsetY = 0;
|
|
2550
|
-
let isPreventDefault = false;
|
|
2551
|
-
let startPoint;
|
|
2552
|
-
let activeElements = [];
|
|
2553
|
-
board.pointerDown = (event) => {
|
|
2554
|
-
const host = BOARD_TO_HOST.get(board);
|
|
2555
|
-
const point = transformPoint(board, toPoint(event.x, event.y, host));
|
|
2556
|
-
const range = { anchor: point, focus: point };
|
|
2557
|
-
let movableElements = board.children.filter(item => board.isMovable(item));
|
|
2558
|
-
if (movableElements.length) {
|
|
2559
|
-
startPoint = point;
|
|
2560
|
-
const selectedRootElements = getSelectedElements(board).filter(item => movableElements.includes(item));
|
|
2561
|
-
const hitElement = getHitElementOfRoot(board, movableElements, range);
|
|
2562
|
-
if (hitElement && selectedRootElements.includes(hitElement)) {
|
|
2563
|
-
activeElements = selectedRootElements;
|
|
2564
|
-
}
|
|
2565
|
-
else if (hitElement) {
|
|
2566
|
-
activeElements = [hitElement];
|
|
2567
|
-
}
|
|
2568
|
-
}
|
|
2569
|
-
pointerDown(event);
|
|
2570
|
-
};
|
|
2571
|
-
board.pointerMove = (event) => {
|
|
2572
|
-
if (startPoint && activeElements.length && !PlaitBoard.hasBeenTextEditing(board)) {
|
|
2573
|
-
if (!isPreventDefault) {
|
|
2574
|
-
isPreventDefault = true;
|
|
2575
|
-
}
|
|
2576
|
-
const host = BOARD_TO_HOST.get(board);
|
|
2577
|
-
const endPoint = transformPoint(board, toPoint(event.x, event.y, host));
|
|
2578
|
-
offsetX = endPoint[0] - startPoint[0];
|
|
2579
|
-
offsetY = endPoint[1] - startPoint[1];
|
|
2580
|
-
const offsetBuffer = 5;
|
|
2581
|
-
if (Math.abs(offsetX) > offsetBuffer || Math.abs(offsetY) > offsetBuffer) {
|
|
2582
|
-
throttleRAF(() => {
|
|
2583
|
-
const currentElements = activeElements.map(activeElement => {
|
|
2584
|
-
const points = activeElement.points || [];
|
|
2585
|
-
const [x, y] = activeElement.points[0];
|
|
2586
|
-
const newPoints = points.map(p => [p[0] + offsetX, p[1] + offsetY]);
|
|
2587
|
-
const index = board.children.findIndex(item => item.id === activeElement.id);
|
|
2588
|
-
Transforms.setNode(board, {
|
|
2589
|
-
points: newPoints
|
|
2590
|
-
}, [index]);
|
|
2591
|
-
MERGING.set(board, true);
|
|
2592
|
-
return PlaitNode.get(board, [index]);
|
|
2593
|
-
});
|
|
2594
|
-
PlaitBoard.getBoardContainer(board).classList.add('element-moving');
|
|
2595
|
-
addMovingElements(board, currentElements);
|
|
2596
|
-
});
|
|
2597
|
-
}
|
|
2598
|
-
}
|
|
2599
|
-
if (isPreventDefault) {
|
|
2600
|
-
// 阻止 move 过程中触发画布滚动行为
|
|
2601
|
-
event.preventDefault();
|
|
2602
|
-
}
|
|
2603
|
-
pointerMove(event);
|
|
2604
|
-
};
|
|
2605
|
-
board.globalPointerMove = (event) => {
|
|
2606
|
-
if (startPoint) {
|
|
2607
|
-
const inPlaitBoardElement = isInPlaitBoard(board, event.x, event.y);
|
|
2608
|
-
if (!inPlaitBoardElement) {
|
|
2609
|
-
cancelMove(board);
|
|
2610
|
-
}
|
|
2611
|
-
}
|
|
2612
|
-
globalPointerMove(event);
|
|
2613
|
-
};
|
|
2614
|
-
board.globalPointerUp = event => {
|
|
2615
|
-
isPreventDefault = false;
|
|
2616
|
-
if (startPoint) {
|
|
2617
|
-
cancelMove(board);
|
|
2618
|
-
}
|
|
2619
|
-
globalPointerUp(event);
|
|
2620
|
-
};
|
|
2621
|
-
function cancelMove(board) {
|
|
2622
|
-
startPoint = null;
|
|
2623
|
-
offsetX = 0;
|
|
2624
|
-
offsetY = 0;
|
|
2625
|
-
activeElements = [];
|
|
2626
|
-
removeMovingElements(board);
|
|
2627
|
-
MERGING.set(board, false);
|
|
2628
|
-
PlaitBoard.getBoardContainer(board).classList.remove('element-moving');
|
|
2629
|
-
}
|
|
2630
|
-
return board;
|
|
2631
|
-
}
|
|
2632
|
-
|
|
2633
|
-
const withOptions = (board) => {
|
|
2634
|
-
const pluginOptions = new Map();
|
|
2635
|
-
const newBoard = board;
|
|
2636
|
-
newBoard.getPluginOptions = key => {
|
|
2637
|
-
return pluginOptions.get(key);
|
|
2638
|
-
};
|
|
2639
|
-
newBoard.setPluginOptions = (key, options) => {
|
|
2640
|
-
const oldOptions = newBoard.getPluginOptions(key) || {};
|
|
2641
|
-
pluginOptions.set(key, Object.assign(Object.assign({}, oldOptions), options));
|
|
2642
|
-
};
|
|
2643
|
-
return newBoard;
|
|
2644
|
-
};
|
|
2645
|
-
|
|
2646
|
-
class PlaitIslandBaseComponent {
|
|
2647
|
-
constructor(cdr) {
|
|
2648
|
-
this.cdr = cdr;
|
|
2649
|
-
}
|
|
2650
|
-
initialize(board) {
|
|
2651
|
-
this.board = board;
|
|
2652
|
-
this.markForCheck();
|
|
2653
|
-
}
|
|
2654
|
-
markForCheck() {
|
|
2655
|
-
this.cdr.markForCheck();
|
|
2656
|
-
}
|
|
2657
|
-
}
|
|
2658
|
-
PlaitIslandBaseComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: PlaitIslandBaseComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive });
|
|
2659
|
-
PlaitIslandBaseComponent.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.5", type: PlaitIslandBaseComponent, host: { classAttribute: "plait-island-container" }, ngImport: i0 });
|
|
2660
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: PlaitIslandBaseComponent, decorators: [{
|
|
2661
|
-
type: Directive,
|
|
2662
|
-
args: [{
|
|
2663
|
-
host: {
|
|
2664
|
-
class: 'plait-island-container'
|
|
2665
|
-
}
|
|
2666
|
-
}]
|
|
2667
|
-
}], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; } });
|
|
2668
|
-
class PlaitIslandPopoverBaseComponent {
|
|
2669
|
-
initialize(board) {
|
|
2670
|
-
this.board = board;
|
|
2671
|
-
const onChange = board.onChange;
|
|
2672
|
-
board.onChange = () => {
|
|
2673
|
-
onChange();
|
|
2674
|
-
if (hasOnBoardChange(this)) {
|
|
2675
|
-
this.onBoardChange();
|
|
2676
|
-
}
|
|
2677
|
-
};
|
|
2678
|
-
this.onChange = onChange;
|
|
2679
|
-
}
|
|
2680
|
-
ngOnInit() {
|
|
2681
|
-
if (!this.board) {
|
|
2682
|
-
throw new Error('can not find board instance');
|
|
2683
|
-
}
|
|
2684
|
-
this.initialize(this.board);
|
|
2685
|
-
this.islandOnInit();
|
|
2686
|
-
}
|
|
2687
|
-
ngOnDestroy() {
|
|
2688
|
-
this.board.onChange = this.onChange;
|
|
2689
|
-
this.islandOnDestroy();
|
|
2690
|
-
}
|
|
2691
|
-
}
|
|
2692
|
-
PlaitIslandPopoverBaseComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: PlaitIslandPopoverBaseComponent, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
2693
|
-
PlaitIslandPopoverBaseComponent.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.5", type: PlaitIslandPopoverBaseComponent, inputs: { board: "board" }, host: { classAttribute: "plait-island-popover-container" }, ngImport: i0 });
|
|
2694
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: PlaitIslandPopoverBaseComponent, decorators: [{
|
|
2695
|
-
type: Directive,
|
|
2696
|
-
args: [{
|
|
2697
|
-
host: {
|
|
2698
|
-
class: 'plait-island-popover-container'
|
|
2699
|
-
}
|
|
2700
|
-
}]
|
|
2701
|
-
}], propDecorators: { board: [{
|
|
2702
|
-
type: Input
|
|
2703
|
-
}] } });
|
|
2704
|
-
const hasOnBoardChange = (value) => {
|
|
2705
|
-
if (value.onBoardChange) {
|
|
2706
|
-
return true;
|
|
2707
|
-
}
|
|
2708
|
-
else {
|
|
2709
|
-
return false;
|
|
2710
|
-
}
|
|
2711
|
-
};
|
|
2712
|
-
|
|
2713
|
-
const withHotkey = (board) => {
|
|
2714
|
-
const { keydown, globalKeydown } = board;
|
|
2715
|
-
board.keydown = (event) => {
|
|
2716
|
-
const options = board.getPluginOptions(PlaitPluginKey.withSelection);
|
|
2717
|
-
if (!PlaitBoard.isReadonly(board) && options.isMultiple && isHotkey('mod+a', event)) {
|
|
2718
|
-
event.preventDefault();
|
|
2719
|
-
let elements = [];
|
|
2720
|
-
depthFirstRecursion(board, node => {
|
|
2721
|
-
if (PlaitBoard.isBoard(node)) {
|
|
2722
|
-
return;
|
|
2723
|
-
}
|
|
2724
|
-
elements.push(node);
|
|
2725
|
-
}, node => {
|
|
2726
|
-
if (PlaitBoard.isBoard(node) || board.isRecursion(node)) {
|
|
2727
|
-
return true;
|
|
2728
|
-
}
|
|
2729
|
-
else {
|
|
2730
|
-
return false;
|
|
2731
|
-
}
|
|
2732
|
-
}, true);
|
|
2733
|
-
Transforms.setSelectionWithTemporaryElements(board, elements);
|
|
2734
|
-
return;
|
|
2735
|
-
}
|
|
2736
|
-
keydown(event);
|
|
2737
|
-
};
|
|
2738
|
-
board.globalKeydown = (event) => {
|
|
2739
|
-
if (PlaitBoard.getMovingPointInBoard(board) || PlaitBoard.isMovingPointInBoard(board)) {
|
|
2740
|
-
if (isHotkey(['mod+=', 'mod++'], { byKey: true })(event)) {
|
|
2741
|
-
event.preventDefault();
|
|
2742
|
-
BoardTransforms.updateZoom(board, board.viewport.zoom + 0.1, false);
|
|
2743
|
-
return;
|
|
2744
|
-
}
|
|
2745
|
-
if (isHotkey(['mod+shift+=', 'mod+shift++'], { byKey: true })(event)) {
|
|
2746
|
-
event.preventDefault();
|
|
2747
|
-
BoardTransforms.fitViewport(board);
|
|
2748
|
-
return;
|
|
2749
|
-
}
|
|
2750
|
-
if (isHotkey(['mod+-', 'mod+shift+-'])(event)) {
|
|
2751
|
-
event.preventDefault();
|
|
2752
|
-
BoardTransforms.updateZoom(board, board.viewport.zoom - 0.1);
|
|
2753
|
-
return;
|
|
2754
|
-
}
|
|
2755
|
-
if (isHotkey(['mod+0', 'mod+shift+0'], { byKey: true })(event)) {
|
|
2756
|
-
event.preventDefault();
|
|
2757
|
-
BoardTransforms.updateZoom(board, 1);
|
|
2758
|
-
return;
|
|
2759
|
-
}
|
|
2760
|
-
}
|
|
2761
|
-
globalKeydown(event);
|
|
2762
|
-
};
|
|
2763
|
-
return board;
|
|
2764
|
-
};
|
|
2765
|
-
|
|
2766
|
-
class PlaitContextService {
|
|
2767
|
-
constructor() {
|
|
2768
|
-
this.uploadingFiles = [];
|
|
2769
|
-
}
|
|
2770
|
-
getUploadingFile(url) {
|
|
2771
|
-
return this.uploadingFiles.find(file => file.url === url);
|
|
2772
|
-
}
|
|
2773
|
-
setUploadingFile(file) {
|
|
2774
|
-
return this.uploadingFiles.push(file);
|
|
2775
|
-
}
|
|
2776
|
-
removeUploadingFile(fileEntry) {
|
|
2777
|
-
this.uploadingFiles = this.uploadingFiles.filter(file => file.url !== fileEntry.url);
|
|
2778
|
-
}
|
|
2779
|
-
}
|
|
2780
|
-
PlaitContextService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: PlaitContextService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2781
|
-
PlaitContextService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: PlaitContextService });
|
|
2782
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: PlaitContextService, decorators: [{
|
|
2783
|
-
type: Injectable
|
|
2784
|
-
}] });
|
|
2785
|
-
|
|
2786
|
-
class PlaitElementComponent {
|
|
2787
|
-
constructor(renderer2, viewContainerRef) {
|
|
2788
|
-
this.renderer2 = renderer2;
|
|
2789
|
-
this.viewContainerRef = viewContainerRef;
|
|
2790
|
-
this.initialized = false;
|
|
2791
|
-
}
|
|
2792
|
-
ngOnInit() {
|
|
2793
|
-
this.initialize();
|
|
2794
|
-
this.drawElement();
|
|
2795
|
-
}
|
|
2796
|
-
initialize() {
|
|
2797
|
-
NODE_TO_INDEX.set(this.element, this.index);
|
|
2798
|
-
NODE_TO_PARENT.set(this.element, this.parent);
|
|
2799
|
-
this.initialized = true;
|
|
2800
|
-
}
|
|
2801
|
-
drawElement() {
|
|
2802
|
-
const context = this.getContext();
|
|
2803
|
-
const result = this.board.drawElement(context);
|
|
2804
|
-
if (Array.isArray(result)) {
|
|
2805
|
-
}
|
|
2806
|
-
else {
|
|
2807
|
-
const componentRef = this.viewContainerRef.createComponent(result);
|
|
2808
|
-
const instance = componentRef.instance;
|
|
2809
|
-
instance.context = context;
|
|
2810
|
-
this.insertG(instance.rootG ? instance.rootG : instance.g);
|
|
2811
|
-
this.instance = instance;
|
|
2812
|
-
}
|
|
2813
|
-
}
|
|
2814
|
-
insertG(g) {
|
|
2815
|
-
if (PlaitBoard.isBoard(this.parent)) {
|
|
2816
|
-
this.parentG.append(g);
|
|
2817
|
-
}
|
|
2818
|
-
else {
|
|
2819
|
-
let siblingG = PlaitElement.getComponent(this.parent).g;
|
|
2820
|
-
if (this.index > 0) {
|
|
2821
|
-
const brotherElement = this.parent.children[this.index - 1];
|
|
2822
|
-
const lastElement = PlaitNode.last(this.board, PlaitBoard.findPath(this.board, brotherElement));
|
|
2823
|
-
let component = PlaitElement.getComponent(lastElement) || PlaitElement.getComponent(brotherElement);
|
|
2824
|
-
siblingG = component.g;
|
|
2825
|
-
}
|
|
2826
|
-
this.parentG.insertBefore(g, siblingG);
|
|
2827
|
-
}
|
|
2828
|
-
}
|
|
2829
|
-
ngOnChanges(simpleChanges) {
|
|
2830
|
-
if (this.initialized) {
|
|
2831
|
-
NODE_TO_INDEX.set(this.element, this.index);
|
|
2832
|
-
NODE_TO_PARENT.set(this.element, this.parent);
|
|
2833
|
-
const elementChanged = simpleChanges['element'];
|
|
2834
|
-
const context = this.getContext();
|
|
2835
|
-
if (elementChanged && isSelectedElement(this.board, elementChanged.previousValue)) {
|
|
2836
|
-
context.selected = true;
|
|
2837
|
-
removeSelectedElement(this.board, elementChanged.previousValue);
|
|
2838
|
-
addSelectedElement(this.board, this.element);
|
|
2839
|
-
}
|
|
2840
|
-
if (this.instance) {
|
|
2841
|
-
this.instance.context = context;
|
|
2842
|
-
}
|
|
2843
|
-
}
|
|
2844
|
-
}
|
|
2845
|
-
getContext() {
|
|
2846
|
-
const isSelected = isSelectedElement(this.board, this.element);
|
|
2847
|
-
const context = {
|
|
2848
|
-
element: this.element,
|
|
2849
|
-
parent: this.parent,
|
|
2850
|
-
board: this.board,
|
|
2851
|
-
selected: isSelected,
|
|
2852
|
-
effect: this.effect
|
|
2853
|
-
};
|
|
2854
|
-
return context;
|
|
2855
|
-
}
|
|
2856
|
-
ngOnDestroy() {
|
|
2857
|
-
this.board.destroyElement(this.getContext());
|
|
2858
|
-
}
|
|
2859
|
-
}
|
|
2860
|
-
PlaitElementComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: PlaitElementComponent, deps: [{ token: i0.Renderer2 }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
2861
|
-
PlaitElementComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.5", type: PlaitElementComponent, selector: "plait-element", inputs: { index: "index", element: "element", parent: "parent", board: "board", effect: "effect", parentG: "parentG" }, usesOnChanges: true, ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2862
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: PlaitElementComponent, decorators: [{
|
|
2863
|
-
type: Component,
|
|
2864
|
-
args: [{
|
|
2865
|
-
selector: 'plait-element',
|
|
2866
|
-
template: '',
|
|
2867
|
-
changeDetection: ChangeDetectionStrategy.OnPush
|
|
2868
|
-
}]
|
|
2869
|
-
}], ctorParameters: function () { return [{ type: i0.Renderer2 }, { type: i0.ViewContainerRef }]; }, propDecorators: { index: [{
|
|
2870
|
-
type: Input
|
|
2871
|
-
}], element: [{
|
|
2872
|
-
type: Input
|
|
2873
|
-
}], parent: [{
|
|
2874
|
-
type: Input
|
|
2875
|
-
}], board: [{
|
|
2876
|
-
type: Input
|
|
2877
|
-
}], effect: [{
|
|
2878
|
-
type: Input
|
|
2879
|
-
}], parentG: [{
|
|
2880
|
-
type: Input
|
|
2881
|
-
}] } });
|
|
2882
|
-
|
|
2883
|
-
class PlaitChildrenElement {
|
|
2884
|
-
constructor() {
|
|
2885
|
-
this.trackBy = (index, element) => {
|
|
2886
|
-
return element.id;
|
|
2887
|
-
};
|
|
2888
|
-
}
|
|
2889
|
-
ngOnInit() {
|
|
2890
|
-
if (!this.parent) {
|
|
2891
|
-
this.parent = this.board;
|
|
2892
|
-
}
|
|
2893
|
-
if (!this.parentG) {
|
|
2894
|
-
this.parentG = PlaitBoard.getElementHost(this.board);
|
|
2895
|
-
}
|
|
2896
|
-
}
|
|
2897
|
-
}
|
|
2898
|
-
PlaitChildrenElement.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: PlaitChildrenElement, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2899
|
-
PlaitChildrenElement.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.5", type: PlaitChildrenElement, selector: "plait-children", inputs: { board: "board", parent: "parent", effect: "effect", parentG: "parentG" }, ngImport: i0, template: `
|
|
2900
|
-
<plait-element
|
|
2901
|
-
*ngFor="let item of parent.children; let index = index; trackBy: trackBy"
|
|
2902
|
-
[index]="index"
|
|
2903
|
-
[element]="item"
|
|
2904
|
-
[parent]="parent"
|
|
2905
|
-
[board]="board"
|
|
2906
|
-
[effect]="effect"
|
|
2907
|
-
[parentG]="parentG"
|
|
2908
|
-
></plait-element>
|
|
2909
|
-
`, isInline: true, dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: PlaitElementComponent, selector: "plait-element", inputs: ["index", "element", "parent", "board", "effect", "parentG"] }] });
|
|
2910
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: PlaitChildrenElement, decorators: [{
|
|
2911
|
-
type: Component,
|
|
2912
|
-
args: [{
|
|
2913
|
-
selector: 'plait-children',
|
|
2914
|
-
template: `
|
|
2915
|
-
<plait-element
|
|
2916
|
-
*ngFor="let item of parent.children; let index = index; trackBy: trackBy"
|
|
2917
|
-
[index]="index"
|
|
2918
|
-
[element]="item"
|
|
2919
|
-
[parent]="parent"
|
|
2920
|
-
[board]="board"
|
|
2921
|
-
[effect]="effect"
|
|
2922
|
-
[parentG]="parentG"
|
|
2923
|
-
></plait-element>
|
|
2924
|
-
`
|
|
2925
|
-
}]
|
|
2926
|
-
}], ctorParameters: function () { return []; }, propDecorators: { board: [{
|
|
2927
|
-
type: Input
|
|
2928
|
-
}], parent: [{
|
|
2929
|
-
type: Input
|
|
2930
|
-
}], effect: [{
|
|
2931
|
-
type: Input
|
|
2932
|
-
}], parentG: [{
|
|
2933
|
-
type: Input
|
|
2934
|
-
}] } });
|
|
2935
|
-
|
|
2936
|
-
const ElementHostClass = 'element-host';
|
|
2937
|
-
const ElementUpperHostClass = 'element-upper-host';
|
|
2938
|
-
const ElementActiveHostClass = 'element-active-host';
|
|
2939
|
-
class PlaitBoardComponent {
|
|
2940
|
-
get host() {
|
|
2941
|
-
return this.svg.nativeElement;
|
|
2942
|
-
}
|
|
2943
|
-
get hostClass() {
|
|
2944
|
-
return `${HOST_CLASS_NAME} pointer-${this.board.pointer} theme-${this.board.theme.themeColorMode} ${this.getBrowserClassName()}`;
|
|
2945
|
-
}
|
|
2946
|
-
getBrowserClassName() {
|
|
2947
|
-
if (IS_SAFARI) {
|
|
2948
|
-
return 'safari';
|
|
2949
|
-
}
|
|
2950
|
-
if (IS_CHROME) {
|
|
2951
|
-
return 'chrome';
|
|
2952
|
-
}
|
|
2953
|
-
if (IS_FIREFOX) {
|
|
2954
|
-
return 'firefox';
|
|
2955
|
-
}
|
|
2956
|
-
return '';
|
|
2957
|
-
}
|
|
2958
|
-
get readonly() {
|
|
2959
|
-
return this.board.options.readonly;
|
|
2960
|
-
}
|
|
2961
|
-
get isFocused() {
|
|
2962
|
-
return PlaitBoard.isFocus(this.board);
|
|
2963
|
-
}
|
|
2964
|
-
get disabledScrollOnNonFocus() {
|
|
2965
|
-
return this.board.options.disabledScrollOnNonFocus && !PlaitBoard.isFocus(this.board);
|
|
2966
|
-
}
|
|
2967
|
-
get nativeElement() {
|
|
2968
|
-
return this.elementRef.nativeElement;
|
|
2969
|
-
}
|
|
2970
|
-
constructor(cdr, viewContainerRef, elementRef, ngZone) {
|
|
2971
|
-
this.cdr = cdr;
|
|
2972
|
-
this.viewContainerRef = viewContainerRef;
|
|
2973
|
-
this.elementRef = elementRef;
|
|
2974
|
-
this.ngZone = ngZone;
|
|
2975
|
-
this.hasInitialized = false;
|
|
2976
|
-
this.effect = {};
|
|
2977
|
-
this.destroy$ = new Subject();
|
|
2978
|
-
this.plaitValue = [];
|
|
2979
|
-
this.plaitPlugins = [];
|
|
2980
|
-
this.plaitChange = new EventEmitter();
|
|
2981
|
-
this.plaitBoardInitialized = new EventEmitter();
|
|
2982
|
-
this.trackBy = (index, element) => {
|
|
2983
|
-
return element.id;
|
|
2984
|
-
};
|
|
2985
|
-
}
|
|
2986
|
-
ngOnInit() {
|
|
2987
|
-
const elementHost = this.host.querySelector(`.${ElementHostClass}`);
|
|
2988
|
-
const elementUpperHost = this.host.querySelector(`.${ElementUpperHostClass}`);
|
|
2989
|
-
const elementActiveHost = this.host.querySelector(`.${ElementActiveHostClass}`);
|
|
2990
|
-
const roughSVG = rough.svg(this.host, {
|
|
2991
|
-
options: { roughness: 0, strokeWidth: 1 }
|
|
2992
|
-
});
|
|
2993
|
-
this.roughSVG = roughSVG;
|
|
2994
|
-
this.initializePlugins();
|
|
2995
|
-
this.ngZone.runOutsideAngular(() => {
|
|
2996
|
-
this.initializeHookListener();
|
|
2997
|
-
this.viewportScrollListener();
|
|
2998
|
-
this.elementResizeListener();
|
|
2999
|
-
fromEvent(document, 'mouseleave')
|
|
3000
|
-
.pipe(takeUntil(this.destroy$))
|
|
3001
|
-
.subscribe((event) => {
|
|
3002
|
-
BOARD_TO_MOVING_POINT.delete(this.board);
|
|
3003
|
-
});
|
|
3004
|
-
});
|
|
3005
|
-
BOARD_TO_COMPONENT.set(this.board, this);
|
|
3006
|
-
BOARD_TO_ROUGH_SVG.set(this.board, roughSVG);
|
|
3007
|
-
BOARD_TO_HOST.set(this.board, this.host);
|
|
3008
|
-
BOARD_TO_ELEMENT_HOST.set(this.board, {
|
|
3009
|
-
host: elementHost,
|
|
3010
|
-
upperHost: elementUpperHost,
|
|
3011
|
-
activeHost: elementActiveHost
|
|
3012
|
-
});
|
|
3013
|
-
BOARD_TO_ON_CHANGE.set(this.board, () => {
|
|
3014
|
-
this.ngZone.run(() => {
|
|
3015
|
-
this.detect();
|
|
3016
|
-
const changeEvent = {
|
|
3017
|
-
children: this.board.children,
|
|
3018
|
-
operations: this.board.operations,
|
|
3019
|
-
viewport: this.board.viewport,
|
|
3020
|
-
selection: this.board.selection,
|
|
3021
|
-
theme: this.board.theme
|
|
3022
|
-
};
|
|
3023
|
-
this.updateIslands();
|
|
3024
|
-
this.plaitChange.emit(changeEvent);
|
|
3025
|
-
});
|
|
3026
|
-
});
|
|
3027
|
-
this.hasInitialized = true;
|
|
3028
|
-
}
|
|
3029
|
-
ngAfterContentInit() {
|
|
3030
|
-
this.initializeIslands();
|
|
3031
|
-
}
|
|
3032
|
-
detect() {
|
|
3033
|
-
this.effect = {};
|
|
3034
|
-
this.cdr.detectChanges();
|
|
3035
|
-
}
|
|
3036
|
-
ngOnChanges(changes) {
|
|
3037
|
-
if (this.hasInitialized) {
|
|
3038
|
-
const valueChange = changes['plaitValue'];
|
|
3039
|
-
const options = changes['plaitOptions'];
|
|
3040
|
-
if (valueChange)
|
|
3041
|
-
this.board.children = valueChange.currentValue;
|
|
3042
|
-
if (options)
|
|
3043
|
-
this.board.options = options.currentValue;
|
|
3044
|
-
this.cdr.markForCheck();
|
|
3045
|
-
}
|
|
3046
|
-
}
|
|
3047
|
-
ngAfterViewInit() {
|
|
3048
|
-
this.plaitBoardInitialized.emit(this.board);
|
|
3049
|
-
initializeViewportContainer(this.board);
|
|
3050
|
-
initializeViewBox(this.board);
|
|
3051
|
-
initializeViewportOffset(this.board);
|
|
3052
|
-
}
|
|
3053
|
-
initializePlugins() {
|
|
3054
|
-
let board = withHotkey(withHandPointer(withHistory(withSelection(withMoving(withBoard(withViewport(withOptions(createBoard(this.plaitValue, this.plaitOptions)))))))));
|
|
3055
|
-
this.plaitPlugins.forEach(plugin => {
|
|
3056
|
-
board = plugin(board);
|
|
3057
|
-
});
|
|
3058
|
-
this.board = board;
|
|
3059
|
-
if (this.plaitViewport) {
|
|
3060
|
-
this.board.viewport = this.plaitViewport;
|
|
3061
|
-
}
|
|
3062
|
-
if (this.plaitTheme) {
|
|
3063
|
-
this.board.theme = this.plaitTheme;
|
|
3064
|
-
}
|
|
3065
|
-
}
|
|
3066
|
-
initializeHookListener() {
|
|
3067
|
-
fromEvent(this.host, 'mousedown')
|
|
3068
|
-
.pipe(takeUntil(this.destroy$))
|
|
3069
|
-
.subscribe((event) => {
|
|
3070
|
-
this.board.mousedown(event);
|
|
3071
|
-
});
|
|
3072
|
-
fromEvent(this.host, 'pointerdown')
|
|
3073
|
-
.pipe(takeUntil(this.destroy$))
|
|
3074
|
-
.subscribe((event) => {
|
|
3075
|
-
this.board.pointerDown(event);
|
|
3076
|
-
});
|
|
3077
|
-
fromEvent(this.host, 'mousemove')
|
|
3078
|
-
.pipe(takeUntil(this.destroy$))
|
|
3079
|
-
.subscribe((event) => {
|
|
3080
|
-
BOARD_TO_MOVING_POINT_IN_BOARD.set(this.board, [event.x, event.y]);
|
|
3081
|
-
this.board.mousemove(event);
|
|
3082
|
-
});
|
|
3083
|
-
fromEvent(this.host, 'pointermove')
|
|
3084
|
-
.pipe(takeUntil(this.destroy$))
|
|
3085
|
-
.subscribe((event) => {
|
|
3086
|
-
BOARD_TO_MOVING_POINT_IN_BOARD.set(this.board, [event.x, event.y]);
|
|
3087
|
-
this.board.pointerMove(event);
|
|
3088
|
-
});
|
|
3089
|
-
fromEvent(this.host, 'mouseleave')
|
|
3090
|
-
.pipe(takeUntil(this.destroy$))
|
|
3091
|
-
.subscribe((event) => {
|
|
3092
|
-
BOARD_TO_MOVING_POINT_IN_BOARD.delete(this.board);
|
|
3093
|
-
this.board.mouseleave(event);
|
|
3094
|
-
});
|
|
3095
|
-
fromEvent(this.host, 'pointerleave')
|
|
3096
|
-
.pipe(takeUntil(this.destroy$))
|
|
3097
|
-
.subscribe((event) => {
|
|
3098
|
-
BOARD_TO_MOVING_POINT_IN_BOARD.delete(this.board);
|
|
3099
|
-
this.board.pointerLeave(event);
|
|
3100
|
-
});
|
|
3101
|
-
fromEvent(document, 'mousemove')
|
|
3102
|
-
.pipe(takeUntil(this.destroy$))
|
|
3103
|
-
.subscribe((event) => {
|
|
3104
|
-
BOARD_TO_MOVING_POINT.set(this.board, [event.x, event.y]);
|
|
3105
|
-
this.board.globalMousemove(event);
|
|
3106
|
-
});
|
|
3107
|
-
fromEvent(document, 'pointermove')
|
|
3108
|
-
.pipe(takeUntil(this.destroy$))
|
|
3109
|
-
.subscribe((event) => {
|
|
3110
|
-
BOARD_TO_MOVING_POINT.set(this.board, [event.x, event.y]);
|
|
3111
|
-
this.board.globalPointerMove(event);
|
|
3112
|
-
});
|
|
3113
|
-
fromEvent(this.host, 'mouseup')
|
|
3114
|
-
.pipe(takeUntil(this.destroy$))
|
|
3115
|
-
.subscribe((event) => {
|
|
3116
|
-
this.board.mouseup(event);
|
|
3117
|
-
});
|
|
3118
|
-
fromEvent(this.host, 'pointerup')
|
|
3119
|
-
.pipe(takeUntil(this.destroy$))
|
|
3120
|
-
.subscribe((event) => {
|
|
3121
|
-
this.board.pointerUp(event);
|
|
3122
|
-
});
|
|
3123
|
-
fromEvent(document, 'mouseup')
|
|
3124
|
-
.pipe(takeUntil(this.destroy$))
|
|
3125
|
-
.subscribe((event) => {
|
|
3126
|
-
this.board.globalMouseup(event);
|
|
3127
|
-
});
|
|
3128
|
-
fromEvent(document, 'pointerup')
|
|
3129
|
-
.pipe(takeUntil(this.destroy$))
|
|
3130
|
-
.subscribe((event) => {
|
|
3131
|
-
this.board.globalPointerUp(event);
|
|
3132
|
-
});
|
|
3133
|
-
fromEvent(this.host, 'dblclick')
|
|
3134
|
-
.pipe(takeUntil(this.destroy$), filter(() => this.isFocused && !PlaitBoard.hasBeenTextEditing(this.board)))
|
|
3135
|
-
.subscribe((event) => {
|
|
3136
|
-
this.board.dblclick(event);
|
|
3137
|
-
});
|
|
3138
|
-
fromEvent(document, 'keydown')
|
|
3139
|
-
.pipe(takeUntil(this.destroy$), tap(event => {
|
|
3140
|
-
this.board.globalKeydown(event);
|
|
3141
|
-
}), filter(event => this.isFocused && !PlaitBoard.hasBeenTextEditing(this.board) && !hasInputOrTextareaTarget(event.target)))
|
|
3142
|
-
.subscribe((event) => {
|
|
3143
|
-
const selectedElements = getSelectedElements(this.board);
|
|
3144
|
-
if (selectedElements.length > 0 && (hotkeys.isDeleteBackward(event) || hotkeys.isDeleteForward(event))) {
|
|
3145
|
-
this.board.deleteFragment(null);
|
|
3146
|
-
}
|
|
3147
|
-
this.board.keydown(event);
|
|
3148
|
-
});
|
|
3149
|
-
fromEvent(document, 'keyup')
|
|
3150
|
-
.pipe(takeUntil(this.destroy$), filter(() => this.isFocused && !PlaitBoard.hasBeenTextEditing(this.board)))
|
|
3151
|
-
.subscribe((event) => {
|
|
3152
|
-
var _a;
|
|
3153
|
-
(_a = this.board) === null || _a === void 0 ? void 0 : _a.keyup(event);
|
|
3154
|
-
});
|
|
3155
|
-
fromEvent(document, 'copy')
|
|
3156
|
-
.pipe(takeUntil(this.destroy$), filter(() => this.isFocused && !PlaitBoard.hasBeenTextEditing(this.board)))
|
|
3157
|
-
.subscribe((event) => {
|
|
3158
|
-
const selectedElements = getSelectedElements(this.board);
|
|
3159
|
-
event.preventDefault();
|
|
3160
|
-
const rectangle = getRectangleByElements(this.board, selectedElements, false);
|
|
3161
|
-
this.board.setFragment(event.clipboardData, rectangle);
|
|
3162
|
-
});
|
|
3163
|
-
fromEvent(document, 'paste')
|
|
3164
|
-
.pipe(takeUntil(this.destroy$), filter(() => this.isFocused && !PlaitBoard.isReadonly(this.board) && !PlaitBoard.hasBeenTextEditing(this.board)))
|
|
3165
|
-
.subscribe((clipboardEvent) => {
|
|
3166
|
-
const mousePoint = PlaitBoard.getMovingPointInBoard(this.board);
|
|
3167
|
-
if (mousePoint) {
|
|
3168
|
-
const targetPoint = transformPoint(this.board, toPoint(mousePoint[0], mousePoint[1], this.host));
|
|
3169
|
-
this.board.insertFragment(clipboardEvent.clipboardData, targetPoint);
|
|
3170
|
-
}
|
|
3171
|
-
});
|
|
3172
|
-
fromEvent(document, 'cut')
|
|
3173
|
-
.pipe(takeUntil(this.destroy$), filter(() => this.isFocused && !PlaitBoard.isReadonly(this.board) && !PlaitBoard.hasBeenTextEditing(this.board)))
|
|
3174
|
-
.subscribe((event) => {
|
|
3175
|
-
const selectedElements = getSelectedElements(this.board);
|
|
3176
|
-
event.preventDefault();
|
|
3177
|
-
const rectangle = getRectangleByElements(this.board, selectedElements, false);
|
|
3178
|
-
this.board.setFragment(event.clipboardData, rectangle);
|
|
3179
|
-
this.board.deleteFragment(event.clipboardData);
|
|
3180
|
-
});
|
|
3181
|
-
}
|
|
3182
|
-
viewportScrollListener() {
|
|
3183
|
-
this.ngZone.runOutsideAngular(() => {
|
|
3184
|
-
fromEvent(this.viewportContainer.nativeElement, 'scroll')
|
|
3185
|
-
.pipe(takeUntil(this.destroy$), filter(() => {
|
|
3186
|
-
if (isFromViewportChange(this.board)) {
|
|
3187
|
-
setIsFromViewportChange(this.board, false);
|
|
3188
|
-
return false;
|
|
3189
|
-
}
|
|
3190
|
-
return true;
|
|
3191
|
-
}))
|
|
3192
|
-
.subscribe((event) => {
|
|
3193
|
-
const { scrollLeft, scrollTop } = event.target;
|
|
3194
|
-
const zoom = this.board.viewport.zoom;
|
|
3195
|
-
const viewBox = getViewBox(this.board, zoom);
|
|
3196
|
-
const origination = [scrollLeft / zoom + viewBox[0], scrollTop / zoom + viewBox[1]];
|
|
3197
|
-
if (Point.isEquals(origination, this.board.viewport.origination)) {
|
|
3198
|
-
return;
|
|
3199
|
-
}
|
|
3200
|
-
BoardTransforms.updateViewport(this.board, origination);
|
|
3201
|
-
setIsFromScrolling(this.board, true);
|
|
3202
|
-
});
|
|
3203
|
-
});
|
|
3204
|
-
this.ngZone.runOutsideAngular(() => {
|
|
3205
|
-
fromEvent(this.viewportContainer.nativeElement, 'touchmove', { passive: false }).subscribe((event) => {
|
|
3206
|
-
if (isPreventTouchMove(this.board)) {
|
|
3207
|
-
event.preventDefault();
|
|
3208
|
-
}
|
|
3209
|
-
});
|
|
3210
|
-
});
|
|
3211
|
-
}
|
|
3212
|
-
elementResizeListener() {
|
|
3213
|
-
this.resizeObserver = new ResizeObserver(() => {
|
|
3214
|
-
initializeViewportContainer(this.board);
|
|
3215
|
-
initializeViewBox(this.board);
|
|
3216
|
-
updateViewportOffset(this.board);
|
|
3217
|
-
});
|
|
3218
|
-
this.resizeObserver.observe(this.nativeElement);
|
|
3219
|
-
}
|
|
3220
|
-
initializeIslands() {
|
|
3221
|
-
var _a;
|
|
3222
|
-
(_a = this.islands) === null || _a === void 0 ? void 0 : _a.forEach(island => {
|
|
3223
|
-
island.initialize(this.board);
|
|
3224
|
-
});
|
|
3225
|
-
}
|
|
3226
|
-
updateIslands() {
|
|
3227
|
-
var _a;
|
|
3228
|
-
(_a = this.islands) === null || _a === void 0 ? void 0 : _a.forEach(island => {
|
|
3229
|
-
if (hasOnBoardChange(island)) {
|
|
3230
|
-
island.onBoardChange();
|
|
3231
|
-
}
|
|
3232
|
-
island.markForCheck();
|
|
3233
|
-
});
|
|
3234
|
-
}
|
|
3235
|
-
ngOnDestroy() {
|
|
3236
|
-
var _a;
|
|
3237
|
-
this.destroy$.next();
|
|
3238
|
-
this.destroy$.complete();
|
|
3239
|
-
this.resizeObserver && ((_a = this.resizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect());
|
|
3240
|
-
BOARD_TO_ROUGH_SVG.delete(this.board);
|
|
3241
|
-
BOARD_TO_COMPONENT.delete(this.board);
|
|
3242
|
-
BOARD_TO_ROUGH_SVG.delete(this.board);
|
|
3243
|
-
BOARD_TO_HOST.delete(this.board);
|
|
3244
|
-
BOARD_TO_ELEMENT_HOST.delete(this.board);
|
|
3245
|
-
BOARD_TO_ON_CHANGE.delete(this.board);
|
|
3246
|
-
}
|
|
3247
|
-
markForCheck() {
|
|
3248
|
-
this.cdr.markForCheck();
|
|
3249
|
-
this.ngZone.run(() => {
|
|
3250
|
-
this.updateIslands();
|
|
3251
|
-
});
|
|
3252
|
-
}
|
|
3253
|
-
}
|
|
3254
|
-
PlaitBoardComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: PlaitBoardComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.ViewContainerRef }, { token: i0.ElementRef }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
|
|
3255
|
-
PlaitBoardComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.5", type: PlaitBoardComponent, selector: "plait-board", inputs: { plaitValue: "plaitValue", plaitViewport: "plaitViewport", plaitPlugins: "plaitPlugins", plaitOptions: "plaitOptions", plaitTheme: "plaitTheme" }, outputs: { plaitChange: "plaitChange", plaitBoardInitialized: "plaitBoardInitialized" }, host: { properties: { "class": "this.hostClass", "class.readonly": "this.readonly", "class.focused": "this.isFocused", "class.disabled-scroll": "this.disabledScrollOnNonFocus" } }, providers: [PlaitContextService], queries: [{ propertyName: "islands", predicate: PlaitIslandBaseComponent, descendants: true }], viewQueries: [{ propertyName: "svg", first: true, predicate: ["svg"], descendants: true, static: true }, { propertyName: "viewportContainer", first: true, predicate: ["viewportContainer"], descendants: true, read: ElementRef, static: true }], usesOnChanges: true, ngImport: i0, template: `
|
|
3256
|
-
<div class="viewport-container" #viewportContainer>
|
|
3257
|
-
<svg #svg width="100%" height="100%" style="position: relative;" class="board-host-svg">
|
|
3258
|
-
<g class="element-host"></g>
|
|
3259
|
-
<g class="element-upper-host"></g>
|
|
3260
|
-
<g class="element-active-host"></g>
|
|
3261
|
-
</svg>
|
|
3262
|
-
<plait-children [board]="board" [effect]="effect"></plait-children>
|
|
3263
|
-
</div>
|
|
3264
|
-
<ng-content></ng-content>
|
|
3265
|
-
`, isInline: true, dependencies: [{ kind: "component", type: PlaitChildrenElement, selector: "plait-children", inputs: ["board", "parent", "effect", "parentG"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3266
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: PlaitBoardComponent, decorators: [{
|
|
3267
|
-
type: Component,
|
|
3268
|
-
args: [{
|
|
3269
|
-
selector: 'plait-board',
|
|
3270
|
-
template: `
|
|
3271
|
-
<div class="viewport-container" #viewportContainer>
|
|
3272
|
-
<svg #svg width="100%" height="100%" style="position: relative;" class="board-host-svg">
|
|
3273
|
-
<g class="element-host"></g>
|
|
3274
|
-
<g class="element-upper-host"></g>
|
|
3275
|
-
<g class="element-active-host"></g>
|
|
3276
|
-
</svg>
|
|
3277
|
-
<plait-children [board]="board" [effect]="effect"></plait-children>
|
|
3278
|
-
</div>
|
|
3279
|
-
<ng-content></ng-content>
|
|
3280
|
-
`,
|
|
3281
|
-
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
3282
|
-
providers: [PlaitContextService]
|
|
3283
|
-
}]
|
|
3284
|
-
}], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i0.ViewContainerRef }, { type: i0.ElementRef }, { type: i0.NgZone }]; }, propDecorators: { plaitValue: [{
|
|
3285
|
-
type: Input
|
|
3286
|
-
}], plaitViewport: [{
|
|
3287
|
-
type: Input
|
|
3288
|
-
}], plaitPlugins: [{
|
|
3289
|
-
type: Input
|
|
3290
|
-
}], plaitOptions: [{
|
|
3291
|
-
type: Input
|
|
3292
|
-
}], plaitTheme: [{
|
|
3293
|
-
type: Input
|
|
3294
|
-
}], plaitChange: [{
|
|
3295
|
-
type: Output
|
|
3296
|
-
}], plaitBoardInitialized: [{
|
|
3297
|
-
type: Output
|
|
3298
|
-
}], hostClass: [{
|
|
3299
|
-
type: HostBinding,
|
|
3300
|
-
args: ['class']
|
|
3301
|
-
}], readonly: [{
|
|
3302
|
-
type: HostBinding,
|
|
3303
|
-
args: ['class.readonly']
|
|
3304
|
-
}], isFocused: [{
|
|
3305
|
-
type: HostBinding,
|
|
3306
|
-
args: ['class.focused']
|
|
3307
|
-
}], disabledScrollOnNonFocus: [{
|
|
3308
|
-
type: HostBinding,
|
|
3309
|
-
args: ['class.disabled-scroll']
|
|
3310
|
-
}], svg: [{
|
|
3311
|
-
type: ViewChild,
|
|
3312
|
-
args: ['svg', { static: true }]
|
|
3313
|
-
}], viewportContainer: [{
|
|
3314
|
-
type: ViewChild,
|
|
3315
|
-
args: ['viewportContainer', { read: ElementRef, static: true }]
|
|
3316
|
-
}], islands: [{
|
|
3317
|
-
type: ContentChildren,
|
|
3318
|
-
args: [PlaitIslandBaseComponent, { descendants: true }]
|
|
3319
|
-
}] } });
|
|
3320
|
-
|
|
3321
|
-
const COMPONENTS = [PlaitBoardComponent, PlaitChildrenElement, PlaitElementComponent];
|
|
3322
|
-
class PlaitModule {
|
|
3323
|
-
}
|
|
3324
|
-
PlaitModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: PlaitModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
3325
|
-
PlaitModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.5", ngImport: i0, type: PlaitModule, declarations: [PlaitBoardComponent, PlaitChildrenElement, PlaitElementComponent], imports: [CommonModule], exports: [PlaitBoardComponent, PlaitChildrenElement, PlaitElementComponent] });
|
|
3326
|
-
PlaitModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: PlaitModule, imports: [CommonModule] });
|
|
3327
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: PlaitModule, decorators: [{
|
|
3328
|
-
type: NgModule,
|
|
3329
|
-
args: [{
|
|
3330
|
-
declarations: [...COMPONENTS],
|
|
3331
|
-
imports: [CommonModule],
|
|
3332
|
-
exports: [...COMPONENTS]
|
|
3333
|
-
}]
|
|
3334
|
-
}] });
|
|
3335
|
-
|
|
3336
|
-
/**
|
|
3337
|
-
* 1.create board instance
|
|
3338
|
-
* 2.build fake node weak map
|
|
3339
|
-
*/
|
|
3340
|
-
const createTestingBoard = (plugins, children, options = { readonly: false, hideScrollbar: true, disabledScrollOnNonFocus: false }) => {
|
|
3341
|
-
let board = createBoard(children, options);
|
|
3342
|
-
plugins.forEach(plugin => {
|
|
3343
|
-
board = plugin(board);
|
|
3344
|
-
});
|
|
3345
|
-
return board;
|
|
3346
|
-
};
|
|
3347
|
-
|
|
3348
|
-
const fakeNodeWeakMap = (object) => {
|
|
3349
|
-
const children = object.children || [];
|
|
3350
|
-
children.forEach((value, index) => {
|
|
3351
|
-
NODE_TO_PARENT.set(value, object);
|
|
3352
|
-
NODE_TO_INDEX.set(value, index);
|
|
3353
|
-
fakeNodeWeakMap(value);
|
|
3354
|
-
});
|
|
3355
|
-
};
|
|
3356
|
-
const clearNodeWeakMap = (object) => {
|
|
3357
|
-
const children = object.children || [];
|
|
3358
|
-
children.forEach(value => {
|
|
3359
|
-
NODE_TO_PARENT.delete(value);
|
|
3360
|
-
NODE_TO_INDEX.delete(value);
|
|
3361
|
-
clearNodeWeakMap(value);
|
|
3362
|
-
});
|
|
3363
|
-
};
|
|
3364
|
-
|
|
3365
|
-
/**
|
|
3366
|
-
* @license
|
|
3367
|
-
* Copyright Google LLC All Rights Reserved.
|
|
3368
|
-
*
|
|
3369
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
3370
|
-
* found in the LICENSE file at https://angular.io/license
|
|
3371
|
-
*/
|
|
3372
|
-
/** Used to generate unique IDs for events. */
|
|
3373
|
-
let uniqueIds = 0;
|
|
3374
|
-
/**
|
|
3375
|
-
* Creates a browser MouseEvent with the specified options.
|
|
3376
|
-
* @docs-private
|
|
3377
|
-
*/
|
|
3378
|
-
function createMouseEvent(type, clientX = 0, clientY = 0, offsetX = 1, offsetY = 1, button = 0, modifiers = {}) {
|
|
3379
|
-
// Note: We cannot determine the position of the mouse event based on the screen
|
|
3380
|
-
// because the dimensions and position of the browser window are not available
|
|
3381
|
-
// To provide reasonable `screenX` and `screenY` coordinates, we simply use the
|
|
3382
|
-
// client coordinates as if the browser is opened in fullscreen.
|
|
3383
|
-
const screenX = clientX;
|
|
3384
|
-
const screenY = clientY;
|
|
3385
|
-
const event = new MouseEvent(type, {
|
|
3386
|
-
bubbles: true,
|
|
3387
|
-
cancelable: true,
|
|
3388
|
-
composed: true,
|
|
3389
|
-
view: window,
|
|
3390
|
-
detail: 0,
|
|
3391
|
-
relatedTarget: null,
|
|
3392
|
-
screenX,
|
|
3393
|
-
screenY,
|
|
3394
|
-
clientX,
|
|
3395
|
-
clientY,
|
|
3396
|
-
ctrlKey: modifiers.control,
|
|
3397
|
-
altKey: modifiers.alt,
|
|
3398
|
-
shiftKey: modifiers.shift,
|
|
3399
|
-
metaKey: modifiers.meta,
|
|
3400
|
-
button: button,
|
|
3401
|
-
buttons: 1
|
|
3402
|
-
});
|
|
3403
|
-
// The `MouseEvent` constructor doesn't allow us to pass these properties into the constructor.
|
|
3404
|
-
// Override them to `1`, because they're used for fake screen reader event detection.
|
|
3405
|
-
if (offsetX != null) {
|
|
3406
|
-
defineReadonlyEventProperty(event, 'offsetX', offsetX);
|
|
3407
|
-
}
|
|
3408
|
-
if (offsetY != null) {
|
|
3409
|
-
defineReadonlyEventProperty(event, 'offsetY', offsetY);
|
|
3410
|
-
}
|
|
3411
|
-
return event;
|
|
3412
|
-
}
|
|
3413
|
-
/**
|
|
3414
|
-
* Creates a browser `PointerEvent` with the specified options. Pointer events
|
|
3415
|
-
* by default will appear as if they are the primary pointer of their type.
|
|
3416
|
-
* https://www.w3.org/TR/pointerevents2/#dom-pointerevent-isprimary.
|
|
3417
|
-
*
|
|
3418
|
-
* For example, if pointer events for a multi-touch interaction are created, the non-primary
|
|
3419
|
-
* pointer touches would need to be represented by non-primary pointer events.
|
|
3420
|
-
*
|
|
3421
|
-
* @docs-private
|
|
3422
|
-
*/
|
|
3423
|
-
function createPointerEvent(type, clientX = 0, clientY = 0, offsetX, offsetY, options = { isPrimary: true }) {
|
|
3424
|
-
const event = new PointerEvent(type, Object.assign({ bubbles: true, cancelable: true, composed: true, view: window, clientX,
|
|
3425
|
-
clientY }, options));
|
|
3426
|
-
if (offsetX != null) {
|
|
3427
|
-
defineReadonlyEventProperty(event, 'offsetX', offsetX);
|
|
3428
|
-
}
|
|
3429
|
-
if (offsetY != null) {
|
|
3430
|
-
defineReadonlyEventProperty(event, 'offsetY', offsetY);
|
|
3431
|
-
}
|
|
3432
|
-
return event;
|
|
3433
|
-
}
|
|
3434
|
-
/**
|
|
3435
|
-
* Creates a browser TouchEvent with the specified pointer coordinates.
|
|
3436
|
-
* @docs-private
|
|
3437
|
-
*/
|
|
3438
|
-
function createTouchEvent(type, pageX = 0, pageY = 0, clientX = 0, clientY = 0) {
|
|
3439
|
-
// We cannot use the `TouchEvent` or `Touch` because Firefox and Safari lack support.
|
|
3440
|
-
// TODO: Switch to the constructor API when it is available for Firefox and Safari.
|
|
3441
|
-
const event = document.createEvent('UIEvent');
|
|
3442
|
-
const touchDetails = { pageX, pageY, clientX, clientY, identifier: uniqueIds++ };
|
|
3443
|
-
// TS3.6 removes the initUIEvent method and suggests porting to "new UIEvent()".
|
|
3444
|
-
event.initUIEvent(type, true, true, window, 0);
|
|
3445
|
-
// Most of the browsers don't have a "initTouchEvent" method that can be used to define
|
|
3446
|
-
// the touch details.
|
|
3447
|
-
defineReadonlyEventProperty(event, 'touches', [touchDetails]);
|
|
3448
|
-
defineReadonlyEventProperty(event, 'targetTouches', [touchDetails]);
|
|
3449
|
-
defineReadonlyEventProperty(event, 'changedTouches', [touchDetails]);
|
|
3450
|
-
return event;
|
|
3451
|
-
}
|
|
3452
|
-
/**
|
|
3453
|
-
* Creates a keyboard event with the specified key and modifiers.
|
|
3454
|
-
* @docs-private
|
|
3455
|
-
*/
|
|
3456
|
-
function createKeyboardEvent(type, keyCode = 0, key = '', modifiers = {}) {
|
|
3457
|
-
return new KeyboardEvent(type, {
|
|
3458
|
-
bubbles: true,
|
|
3459
|
-
cancelable: true,
|
|
3460
|
-
composed: true,
|
|
3461
|
-
view: window,
|
|
3462
|
-
keyCode: keyCode,
|
|
3463
|
-
key: key,
|
|
3464
|
-
shiftKey: modifiers.shift,
|
|
3465
|
-
metaKey: modifiers.meta,
|
|
3466
|
-
altKey: modifiers.alt,
|
|
3467
|
-
ctrlKey: modifiers.control
|
|
3468
|
-
});
|
|
3469
|
-
}
|
|
3470
|
-
/**
|
|
3471
|
-
* Creates a fake event object with any desired event type.
|
|
3472
|
-
* @docs-private
|
|
3473
|
-
*/
|
|
3474
|
-
function createFakeEvent(type, bubbles = false, cancelable = true, composed = true) {
|
|
3475
|
-
return new Event(type, { bubbles, cancelable, composed });
|
|
3476
|
-
}
|
|
3477
|
-
/**
|
|
3478
|
-
* Defines a readonly property on the given event object. Readonly properties on an event object
|
|
3479
|
-
* are always set as configurable as that matches default readonly properties for DOM event objects.
|
|
3480
|
-
*/
|
|
3481
|
-
function defineReadonlyEventProperty(event, propertyName, value) {
|
|
3482
|
-
Object.defineProperty(event, propertyName, { get: () => value, configurable: true });
|
|
3483
|
-
}
|
|
3484
|
-
function createModModifierKeys() {
|
|
3485
|
-
const modifiers = IS_MAC ? { meta: true } : { control: true };
|
|
3486
|
-
return modifiers;
|
|
3487
|
-
}
|
|
3488
|
-
|
|
3489
|
-
/*
|
|
3490
|
-
* Public API Surface of plait
|
|
3491
|
-
*/
|
|
3492
|
-
|
|
3493
|
-
/**
|
|
3494
|
-
* Generated bundle index. Do not edit.
|
|
3495
|
-
*/
|
|
3496
|
-
|
|
3497
|
-
export { A, ALT, APOSTROPHE, ATTACHED_ELEMENT_CLASS_NAME, AT_SIGN, B, BACKSLASH, BACKSPACE, BOARD_TO_COMPONENT, BOARD_TO_ELEMENT_HOST, BOARD_TO_HOST, BOARD_TO_IS_SELECTION_MOVING, BOARD_TO_MOVING_ELEMENT, BOARD_TO_MOVING_POINT, BOARD_TO_MOVING_POINT_IN_BOARD, BOARD_TO_ON_CHANGE, BOARD_TO_ROUGH_SVG, BOARD_TO_SELECTED_ELEMENT, BOARD_TO_TEMPORARY_ELEMENTS, BOARD_TO_VIEWPORT_ORIGINATION, BoardTransforms, C, CAPS_LOCK, CLIP_BOARD_FORMAT_KEY, CLOSE_SQUARE_BRACKET, COMMA, CONTEXT_MENU, CONTROL, ColorfulThemeColor, D, DASH, DELETE, DOWN_ARROW, DarkThemeColor, DefaultThemeColor, E, EIGHT, ELEMENT_TO_COMPONENT, END, ENTER, EQUALS, ESCAPE, F, F1, F10, F11, F12, F2, F3, F4, F5, F6, F7, F8, F9, FF_EQUALS, FF_MINUS, FF_MUTE, FF_SEMICOLON, FF_VOLUME_DOWN, FF_VOLUME_UP, FIRST_MEDIA, FIVE, FLUSHING, FOUR, G, H, HOME, HOST_CLASS_NAME, I, INSERT, IS_APPLE, IS_BOARD_CACHE, IS_CHROME, IS_CHROME_LEGACY, IS_EDGE_LEGACY, IS_FIREFOX, IS_IOS, IS_MAC, IS_PREVENT_TOUCH_MOVE, IS_SAFARI, IS_TEXT_EDITABLE, J, K, L, LAST_MEDIA, LEFT_ARROW, M, MAC_ENTER, MAC_META, MAC_WK_CMD_LEFT, MAC_WK_CMD_RIGHT, MAX_RADIUS, MERGING, META, MUTE, N, NINE, NODE_TO_INDEX, NODE_TO_PARENT, NS, NUMPAD_DIVIDE, NUMPAD_EIGHT, NUMPAD_FIVE, NUMPAD_FOUR, NUMPAD_MINUS, NUMPAD_MULTIPLY, NUMPAD_NINE, NUMPAD_ONE, NUMPAD_PERIOD, NUMPAD_PLUS, NUMPAD_SEVEN, NUMPAD_SIX, NUMPAD_THREE, NUMPAD_TWO, NUMPAD_ZERO, NUM_CENTER, NUM_LOCK, O, ONE, OPEN_SQUARE_BRACKET, P, PAGE_DOWN, PAGE_UP, PATH_REFS, PAUSE, PERIOD, PLUS_SIGN, POINTER_BUTTON, PRESS_AND_MOVE_BUFFER, PRINT_SCREEN, Path, PlaitBoard, PlaitBoardComponent, PlaitChildrenElement, PlaitContextService, PlaitElement, PlaitElementComponent, PlaitHistoryBoard, PlaitIslandBaseComponent, PlaitIslandPopoverBaseComponent, PlaitModule, PlaitNode, PlaitOperation, PlaitPluginElementComponent, PlaitPluginKey, PlaitPointerType, Point, Q, QUESTION_MARK, R, RIGHT_ARROW, RectangleClient, ResizeCursorClass, RetroThemeColor, S, SAVING, SCROLL_BAR_WIDTH, SCROLL_LOCK, SELECTION_BORDER_COLOR, SELECTION_FILL_COLOR, SEMICOLON, SEVEN, SHIFT, SINGLE_QUOTE, SIX, SLASH, SPACE, Selection, SoftThemeColor, StarryThemeColor, T, TAB, THREE, TILDE, TWO, ThemeColorMode, ThemeColors, Transforms, U, UP_ARROW, V, VOLUME_DOWN, VOLUME_UP, Viewport, W, X, Y, Z, ZERO, addMovingElements, addSelectedElement, arrowPoints, cacheMovingElements, cacheSelectedElements, clampZoomLevel, clearNodeWeakMap, clearSelectedElement, clearSelectionMoving, clearViewportOrigination, createFakeEvent, createForeignObject, createG, createKeyboardEvent, createModModifierKeys, createMouseEvent, createPath, createPointerEvent, createSVG, createSelectionOuterG, createTestingBoard, createText, createTouchEvent, debounce, deleteTemporaryElements, depthFirstRecursion, distanceBetweenPointAndPoint, distanceBetweenPointAndRectangle, distanceBetweenPointAndSegment, distanceBetweenPointAndSegments, downloadImage, drawArrow, drawBezierPath, drawCircle, drawLine, drawLinearPath, drawRoundRectangle, fakeNodeWeakMap, getBoardRectangle, getClipboardByKey, getClipboardDataByMedia, getDataFromClipboard, getElementHostBBox, getHitElementOfRoot, getHitElements, getIsRecursionFunc, getMovingElements, getRealScrollBarWidth, getRectangleByElements, getSelectedElements, getTemporaryElements, getTextFromClipboard, getViewBox, getViewBoxCenterPoint, getViewportContainerRect, getViewportOrigination, hasBeforeContextChange, hasInputOrTextareaTarget, hasOnBoardChange, hasOnContextChanged, hotkeys, idCreator, initializeViewBox, initializeViewportContainer, initializeViewportOffset, inverse, isDOMElement, isDOMNode, isFromScrolling, isFromViewportChange, isHitElements, isInPlaitBoard, isLineHitLine, isMainPointer, isNullOrUndefined, isPolylineHitRectangle, isPreventTouchMove, isSecondaryPointer, isSelectedElement, isSelectionMoving, isSetViewportOperation, normalizePoint, preventTouchMove, removeMovingElements, removeSelectedElement, rotate, scrollToRectangle, setClipboardData, setClipboardDataByMedia, setClipboardDataByText, setIsFromScrolling, setIsFromViewportChange, setSVGViewBox, setSelectionMoving, shouldClear, shouldMerge, shouldSave, throttleRAF, toImage, toPoint, transformPoint, transformPoints, updateForeignObject, updateViewportContainerScroll, updateViewportOffset, updateViewportOrigination, withMoving, withOptions, withSelection };
|
|
3498
|
-
//# sourceMappingURL=plait-core.mjs.map
|