@plait/mind 0.3.0 → 0.4.0
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/drawer/{emoji.drawer.d.ts → emojis.drawer.d.ts} +2 -1
- package/esm2020/base/emoji-base.component.mjs +3 -3
- package/esm2020/drawer/emojis.drawer.mjs +73 -0
- package/esm2020/interfaces/element.mjs +6 -1
- package/esm2020/mind.component.mjs +3 -3
- package/esm2020/mind.module.mjs +4 -4
- package/esm2020/node.component.mjs +11 -15
- package/esm2020/plugins/with-abstract-resize.mjs +6 -2
- package/esm2020/plugins/with-mind-create.mjs +5 -4
- package/esm2020/plugins/with-mind.mjs +9 -4
- package/esm2020/plugins/with-node-dnd.mjs +13 -12
- package/esm2020/transforms/index.mjs +4 -3
- package/esm2020/transforms/node.mjs +11 -8
- package/esm2020/utils/dnd/common.mjs +29 -1
- package/esm2020/utils/dnd/detector.mjs +1 -7
- package/esm2020/utils/draw/abstract-outline.mjs +75 -0
- package/esm2020/utils/draw/node-dnd.mjs +133 -0
- package/esm2020/utils/draw/node-link/abstract-link.mjs +54 -0
- package/esm2020/utils/draw/node-link/draw-link.mjs +9 -0
- package/esm2020/utils/draw/node-link/indented-link.mjs +54 -0
- package/esm2020/utils/draw/node-link/logic-link.mjs +67 -0
- package/esm2020/utils/draw/node-shape.mjs +21 -0
- package/esm2020/utils/draw/node-topic.mjs +32 -0
- package/esm2020/utils/index.mjs +4 -2
- package/esm2020/utils/mind.mjs +2 -27
- package/esm2020/utils/node/common.mjs +6 -0
- package/esm2020/utils/node/index.mjs +4 -0
- package/esm2020/utils/node/right-node-count.mjs +45 -0
- package/esm2020/utils/node-style/branch.mjs +6 -1
- package/fesm2015/plait-mind.mjs +985 -911
- package/fesm2015/plait-mind.mjs.map +1 -1
- package/fesm2020/plait-mind.mjs +1005 -931
- package/fesm2020/plait-mind.mjs.map +1 -1
- package/interfaces/element.d.ts +5 -0
- package/node.component.d.ts +1 -1
- package/package.json +1 -1
- package/transforms/index.d.ts +1 -0
- package/transforms/node.d.ts +2 -0
- package/utils/dnd/common.d.ts +5 -1
- package/utils/dnd/detector.d.ts +0 -6
- package/{draw/abstract.d.ts → utils/draw/abstract-outline.d.ts} +2 -2
- package/utils/{dnd/draw.d.ts → draw/node-dnd.d.ts} +1 -5
- package/{draw/link → utils/draw/node-link}/abstract-link.d.ts +1 -1
- package/utils/draw/node-link/draw-link.d.ts +3 -0
- package/{draw → utils/draw/node-link}/indented-link.d.ts +1 -1
- package/utils/draw/node-link/logic-link.d.ts +3 -0
- package/{draw/node.d.ts → utils/draw/node-shape.d.ts} +2 -2
- package/{draw/topic.d.ts → utils/draw/node-topic.d.ts} +3 -3
- package/utils/index.d.ts +3 -1
- package/utils/mind.d.ts +0 -2
- package/utils/{node.d.ts → node/common.d.ts} +1 -1
- package/utils/node/index.d.ts +3 -0
- package/utils/node/right-node-count.d.ts +9 -0
- package/utils/node-style/branch.d.ts +1 -0
- package/draw/link/logic-link.d.ts +0 -3
- package/esm2020/draw/abstract.mjs +0 -75
- package/esm2020/draw/indented-link.mjs +0 -45
- package/esm2020/draw/link/abstract-link.mjs +0 -38
- package/esm2020/draw/link/logic-link.mjs +0 -54
- package/esm2020/draw/node.mjs +0 -21
- package/esm2020/draw/topic.mjs +0 -32
- package/esm2020/drawer/emoji.drawer.mjs +0 -73
- package/esm2020/utils/dnd/draw.mjs +0 -161
- package/esm2020/utils/node.mjs +0 -6
package/fesm2020/plait-mind.mjs
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
2
|
import { Component, ChangeDetectionStrategy, NgModule, Directive, Input } from '@angular/core';
|
|
3
3
|
import * as i2 from '@plait/core';
|
|
4
|
-
import {
|
|
5
|
-
import { MindLayoutType,
|
|
4
|
+
import { distanceBetweenPointAndRectangle, RectangleClient, PlaitElement, PlaitBoard, idCreator, isNullOrUndefined, Transforms, clearSelectedElement, addSelectedElement, depthFirstRecursion, Path, drawRoundRectangle, drawLinearPath, createG, PlaitNode, getRectangleByElements, getSelectedElements, NODE_TO_PARENT, drawAbstractRoundRectangle, PlaitPluginElementComponent, PlaitPointerType, NODE_TO_INDEX, createText, IS_TEXT_EDITABLE, MERGING, transformPoint, toPoint, PlaitModule, distanceBetweenPointAndPoint, CLIP_BOARD_FORMAT_KEY, isMainPointer, BOARD_TO_HOST, throttleRAF, updateForeignObject as updateForeignObject$1, BoardTransforms, Selection, removeSelectedElement, PlaitHistoryBoard, hotkeys } from '@plait/core';
|
|
5
|
+
import { MindLayoutType, isIndentedLayout, getNonAbstractChildren, isStandardLayout, AbstractNode, isLeftLayout, isRightLayout, isTopLayout, isVerticalLogicLayout, isHorizontalLogicLayout, isBottomLayout, isHorizontalLayout, getCorrectStartEnd, getAbstractLayout, ConnectingPosition, GlobalLayout } from '@plait/layouts';
|
|
6
6
|
import { getSizeByText, ROOT_DEFAULT_HEIGHT, TEXT_DEFAULT_HEIGHT, updateForeignObject, drawRichtext, createForeignObject, updateRichText, setFullSelectionAndFocus, getRichtextContentSize, hasEditableTarget, RichtextModule } from '@plait/richtext';
|
|
7
7
|
import { fromEvent, Subject, timer } from 'rxjs';
|
|
8
8
|
import { take, takeUntil, filter, debounceTime } from 'rxjs/operators';
|
|
9
9
|
import { Node, Path as Path$1, Editor, Operation } from 'slate';
|
|
10
|
-
import { pointsOnBezierCurves } from 'points-on-curve';
|
|
11
10
|
import { isKeyHotkey } from 'is-hotkey';
|
|
11
|
+
import { pointsOnBezierCurves } from 'points-on-curve';
|
|
12
12
|
import * as i1 from '@angular/common';
|
|
13
13
|
import { CommonModule } from '@angular/common';
|
|
14
14
|
|
|
@@ -93,117 +93,310 @@ var MindPointerType;
|
|
|
93
93
|
MindPointerType["mind"] = "mind";
|
|
94
94
|
})(MindPointerType || (MindPointerType = {}));
|
|
95
95
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
*
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
96
|
+
function getRectangleByNode(node) {
|
|
97
|
+
const x = node.x + node.hGap;
|
|
98
|
+
let y = node.y + node.vGap;
|
|
99
|
+
const width = node.width - node.hGap * 2;
|
|
100
|
+
const height = node.height - node.vGap * 2;
|
|
101
|
+
return {
|
|
102
|
+
x,
|
|
103
|
+
y,
|
|
104
|
+
width,
|
|
105
|
+
height
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
function getRectangleByElement(board, originPoint, element) {
|
|
109
|
+
const nodeRectangle = {
|
|
110
|
+
x: originPoint[0],
|
|
111
|
+
y: originPoint[1],
|
|
112
|
+
width: NodeSpace.getNodeWidth(board, element),
|
|
113
|
+
height: NodeSpace.getNodeHeight(board, element)
|
|
114
|
+
};
|
|
115
|
+
return nodeRectangle;
|
|
116
|
+
}
|
|
117
|
+
function isHitMindElement(board, point, element) {
|
|
110
118
|
const node = MindElement.getNode(element);
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
correctRootLayout = node.left ? MindLayoutType.left : MindLayoutType.right;
|
|
119
|
+
if (node && distanceBetweenPointAndRectangle(point[0], point[1], getRectangleByNode(node)) === 0) {
|
|
120
|
+
return true;
|
|
114
121
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
if (elementWithLayout) {
|
|
118
|
-
if (AbstractNode.isAbstract(elementWithLayout)) {
|
|
119
|
-
const parent = MindElement.getParent(elementWithLayout);
|
|
120
|
-
const parentLayout = getCorrectLayoutByElement(board, parent);
|
|
121
|
-
layout = getAbstractLayout(parentLayout);
|
|
122
|
-
}
|
|
123
|
-
else {
|
|
124
|
-
layout = elementWithLayout?.layout;
|
|
125
|
-
}
|
|
122
|
+
else {
|
|
123
|
+
return false;
|
|
126
124
|
}
|
|
127
|
-
|
|
128
|
-
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function getEmojisWidthHeight(board, element) {
|
|
128
|
+
const options = board.getMindOptions();
|
|
129
|
+
const count = element.data.emojis.length;
|
|
130
|
+
const fontSize = getEmojiFontSize(element);
|
|
131
|
+
return {
|
|
132
|
+
width: fontSize * count + count * 2 * options.emojiPadding + (count - 1) * options.spaceBetweenEmojis,
|
|
133
|
+
height: element.height
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
function getEmojiFontSize(element) {
|
|
137
|
+
if (PlaitMind.isMind(element)) {
|
|
138
|
+
return 18 + 2;
|
|
129
139
|
}
|
|
130
140
|
else {
|
|
131
|
-
|
|
132
|
-
if (incorrectDirection) {
|
|
133
|
-
return correctLayoutByDirection(layout, incorrectDirection);
|
|
134
|
-
}
|
|
135
|
-
else {
|
|
136
|
-
return layout;
|
|
137
|
-
}
|
|
141
|
+
return 14 + 2;
|
|
138
142
|
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function getEmojiRectangle(board, element) {
|
|
146
|
+
let { x, y } = getRectangleByNode(MindElement.getNode(element));
|
|
147
|
+
x = x + NodeSpace.getEmojiLeftSpace(board, element);
|
|
148
|
+
const { width, height } = getEmojisWidthHeight(board, element);
|
|
149
|
+
return {
|
|
150
|
+
x,
|
|
151
|
+
y,
|
|
152
|
+
width,
|
|
153
|
+
height
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
function getEmojiForeignRectangle(board, element) {
|
|
157
|
+
let { x, y } = getRectangleByNode(MindElement.getNode(element));
|
|
158
|
+
x = x + NodeSpace.getEmojiLeftSpace(board, element);
|
|
159
|
+
const { width, height } = getEmojisWidthHeight(board, element);
|
|
160
|
+
return {
|
|
161
|
+
x,
|
|
162
|
+
y,
|
|
163
|
+
width,
|
|
164
|
+
height: height + NodeSpace.getEmojiTopSpace(element) * 2
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
const isHitEmojis = (board, element, point) => {
|
|
168
|
+
return RectangleClient.isHit(RectangleClient.toRectangleClient([point, point]), getEmojiRectangle(board, element));
|
|
139
169
|
};
|
|
140
170
|
|
|
141
|
-
|
|
142
|
-
const
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
171
|
+
function enterNodeEditing(element) {
|
|
172
|
+
const component = PlaitElement.getComponent(element);
|
|
173
|
+
component.startEditText(false, false);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const adjustRootToNode = (board, node) => {
|
|
177
|
+
const newNode = { ...node };
|
|
178
|
+
delete newNode.isRoot;
|
|
179
|
+
delete newNode.rightNodeCount;
|
|
180
|
+
delete newNode.type;
|
|
181
|
+
const text = Node.string(node.data.topic.children[0]) || ' ';
|
|
182
|
+
const { width, height } = getSizeByText(text, PlaitBoard.getViewportContainer(board), TOPIC_DEFAULT_MAX_WORD_COUNT);
|
|
183
|
+
newNode.width = Math.max(width, NODE_MIN_WIDTH);
|
|
184
|
+
newNode.height = height;
|
|
185
|
+
if (newNode.layout === MindLayoutType.standard) {
|
|
186
|
+
delete newNode.layout;
|
|
153
187
|
}
|
|
154
|
-
return
|
|
188
|
+
return newNode;
|
|
155
189
|
};
|
|
156
|
-
|
|
157
|
-
const
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
const parentDirections = getBranchDirectionsByLayouts(parentLayout);
|
|
169
|
-
const parentAvailableSubLayouts = getAvailableSubLayoutsByLayoutDirections(parentDirections);
|
|
170
|
-
availableSubLayouts = availableSubLayouts.filter(layout => parentAvailableSubLayouts.some(parentAvailableSubLayout => parentAvailableSubLayout === layout));
|
|
171
|
-
return availableSubLayouts;
|
|
190
|
+
const adjustAbstractToNode = (node) => {
|
|
191
|
+
const newNode = { ...node };
|
|
192
|
+
delete newNode.start;
|
|
193
|
+
delete newNode.end;
|
|
194
|
+
return newNode;
|
|
195
|
+
};
|
|
196
|
+
const adjustNodeToRoot = (board, node) => {
|
|
197
|
+
const newElement = { ...node };
|
|
198
|
+
let text = Node.string(newElement.data.topic);
|
|
199
|
+
if (!text) {
|
|
200
|
+
text = '思维导图';
|
|
201
|
+
newElement.data.topic = { children: [{ text }] };
|
|
172
202
|
}
|
|
173
|
-
|
|
203
|
+
delete newElement?.strokeColor;
|
|
204
|
+
delete newElement?.fill;
|
|
205
|
+
delete newElement?.shape;
|
|
206
|
+
delete newElement?.strokeWidth;
|
|
207
|
+
const { width, height } = getSizeByText(text, PlaitBoard.getViewportContainer(board), TOPIC_DEFAULT_MAX_WORD_COUNT, ROOT_TOPIC_FONT_SIZE);
|
|
208
|
+
newElement.width = Math.max(width, NODE_MIN_WIDTH);
|
|
209
|
+
newElement.height = height;
|
|
210
|
+
return {
|
|
211
|
+
...newElement,
|
|
212
|
+
layout: newElement.layout ?? MindLayoutType.right,
|
|
213
|
+
isCollapsed: false,
|
|
214
|
+
isRoot: true,
|
|
215
|
+
type: 'mindmap'
|
|
216
|
+
};
|
|
174
217
|
};
|
|
175
218
|
|
|
176
|
-
const
|
|
177
|
-
const
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
if (!branchDirections.includes(d) && !branchDirections.includes(getLayoutReverseDirection(d))) {
|
|
182
|
-
branchDirections.push(d);
|
|
183
|
-
}
|
|
184
|
-
});
|
|
185
|
-
});
|
|
186
|
-
return branchDirections;
|
|
187
|
-
};
|
|
188
|
-
const isCorrectLayout = (root, layout) => {
|
|
189
|
-
const rootLayout = root.layout || getDefaultLayout();
|
|
190
|
-
return !getInCorrectLayoutDirection(rootLayout, layout);
|
|
219
|
+
const createEmptyMind = (board, point) => {
|
|
220
|
+
const element = createMindElement('', 0, 0, { layout: MindLayoutType.right });
|
|
221
|
+
const rootElement = adjustNodeToRoot(board, element);
|
|
222
|
+
rootElement.points = [point];
|
|
223
|
+
return rootElement;
|
|
191
224
|
};
|
|
192
|
-
const
|
|
193
|
-
|
|
225
|
+
const createDefaultMind = (point, rightNodeCount, layout) => {
|
|
226
|
+
const root = createMindElement('思维导图', 72, ROOT_DEFAULT_HEIGHT, { shape: MindElementShape.roundRectangle, layout });
|
|
227
|
+
root.rightNodeCount = rightNodeCount;
|
|
228
|
+
root.isRoot = true;
|
|
229
|
+
root.type = 'mindmap';
|
|
230
|
+
root.points = [point];
|
|
231
|
+
const children = [1, 1, 1].map(() => {
|
|
232
|
+
return createMindElement('新建节点', 56, TEXT_DEFAULT_HEIGHT, { shape: MindElementShape.roundRectangle });
|
|
233
|
+
});
|
|
234
|
+
root.children = children;
|
|
235
|
+
return root;
|
|
194
236
|
};
|
|
195
|
-
const
|
|
196
|
-
const
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
237
|
+
const createMindElement = (text, width, height, options) => {
|
|
238
|
+
const newElement = {
|
|
239
|
+
id: idCreator(),
|
|
240
|
+
data: {
|
|
241
|
+
topic: { children: [{ text }] }
|
|
242
|
+
},
|
|
243
|
+
children: [],
|
|
244
|
+
width,
|
|
245
|
+
height,
|
|
246
|
+
fill: options.fill,
|
|
247
|
+
strokeColor: options.strokeColor,
|
|
248
|
+
strokeWidth: options.strokeWidth,
|
|
249
|
+
shape: options.shape
|
|
250
|
+
};
|
|
251
|
+
if (options.fill) {
|
|
252
|
+
newElement.fill = options.fill;
|
|
200
253
|
}
|
|
201
|
-
|
|
254
|
+
if (options.strokeColor) {
|
|
255
|
+
newElement.strokeColor = options.strokeColor;
|
|
256
|
+
}
|
|
257
|
+
if (!isNullOrUndefined(options.strokeWidth)) {
|
|
258
|
+
newElement.strokeWidth = options.strokeWidth;
|
|
259
|
+
}
|
|
260
|
+
if (options.shape) {
|
|
261
|
+
newElement.shape = options.shape;
|
|
262
|
+
}
|
|
263
|
+
if (options.layout) {
|
|
264
|
+
newElement.layout = options.layout;
|
|
265
|
+
}
|
|
266
|
+
if (options.branchColor) {
|
|
267
|
+
newElement.branchColor = options.branchColor;
|
|
268
|
+
}
|
|
269
|
+
if (!isNullOrUndefined(options.branchWidth)) {
|
|
270
|
+
newElement.branchWidth = options.branchWidth;
|
|
271
|
+
}
|
|
272
|
+
return newElement;
|
|
202
273
|
};
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
274
|
+
|
|
275
|
+
const getChildrenCount = (element) => {
|
|
276
|
+
const count = element.children.reduce((p, c) => {
|
|
277
|
+
return p + getChildrenCount(c);
|
|
278
|
+
}, 0);
|
|
279
|
+
return count + element.children.length;
|
|
280
|
+
};
|
|
281
|
+
const isChildElement = (origin, child) => {
|
|
282
|
+
let parent = MindElement.findParent(child);
|
|
283
|
+
while (parent) {
|
|
284
|
+
if (parent === origin) {
|
|
285
|
+
return true;
|
|
286
|
+
}
|
|
287
|
+
parent = MindElement.findParent(parent);
|
|
288
|
+
}
|
|
289
|
+
return false;
|
|
290
|
+
};
|
|
291
|
+
const getFirstLevelElement = (elements) => {
|
|
292
|
+
let result = [];
|
|
293
|
+
elements.forEach(element => {
|
|
294
|
+
const isChild = elements.some(node => {
|
|
295
|
+
return isChildElement(node, element);
|
|
296
|
+
});
|
|
297
|
+
if (!isChild) {
|
|
298
|
+
result.push(element);
|
|
299
|
+
}
|
|
300
|
+
});
|
|
301
|
+
return result;
|
|
302
|
+
};
|
|
303
|
+
const isChildRight = (node, child) => {
|
|
304
|
+
return node.x < child.x;
|
|
305
|
+
};
|
|
306
|
+
const isChildUp = (node, child) => {
|
|
307
|
+
return node.y > child.y;
|
|
308
|
+
};
|
|
309
|
+
const copyNewNode = (node) => {
|
|
310
|
+
const newNode = { ...node };
|
|
311
|
+
newNode.id = idCreator();
|
|
312
|
+
newNode.children = [];
|
|
313
|
+
for (const childNode of node.children) {
|
|
314
|
+
newNode.children.push(copyNewNode(childNode));
|
|
315
|
+
}
|
|
316
|
+
return newNode;
|
|
317
|
+
};
|
|
318
|
+
const extractNodesText = (node) => {
|
|
319
|
+
let str = '';
|
|
320
|
+
if (node) {
|
|
321
|
+
str += Node.string(node.data.topic.children[0]) + ' ';
|
|
322
|
+
for (const childNode of node.children) {
|
|
323
|
+
str += extractNodesText(childNode);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
return str;
|
|
327
|
+
};
|
|
328
|
+
// layoutLevel 用来表示插入兄弟节点还是子节点
|
|
329
|
+
const insertMindElement = (board, inheritNode, path) => {
|
|
330
|
+
let fill, strokeColor, strokeWidth, shape = MindElementShape.roundRectangle;
|
|
331
|
+
if (!inheritNode.isRoot) {
|
|
332
|
+
fill = inheritNode.fill;
|
|
333
|
+
strokeColor = inheritNode.strokeColor;
|
|
334
|
+
strokeWidth = inheritNode.strokeWidth;
|
|
335
|
+
}
|
|
336
|
+
shape = inheritNode.shape;
|
|
337
|
+
const newElement = createMindElement('', NODE_MIN_WIDTH, TEXT_DEFAULT_HEIGHT, { fill, strokeColor, strokeWidth, shape });
|
|
338
|
+
Transforms.insertNode(board, newElement, path);
|
|
339
|
+
clearSelectedElement(board);
|
|
340
|
+
addSelectedElement(board, newElement);
|
|
341
|
+
setTimeout(() => {
|
|
342
|
+
enterNodeEditing(newElement);
|
|
343
|
+
});
|
|
344
|
+
};
|
|
345
|
+
const findLastChild = (child) => {
|
|
346
|
+
let result = child;
|
|
347
|
+
while (result.children.length !== 0) {
|
|
348
|
+
result = result.children[result.children.length - 1];
|
|
349
|
+
}
|
|
350
|
+
return result;
|
|
351
|
+
};
|
|
352
|
+
const divideElementByParent = (elements) => {
|
|
353
|
+
const abstractIncludedGroups = [];
|
|
354
|
+
const parentElements = [];
|
|
355
|
+
for (let i = 0; i < elements.length; i++) {
|
|
356
|
+
const parent = MindElement.getParent(elements[i]);
|
|
357
|
+
const parentIndex = parentElements.indexOf(parent);
|
|
358
|
+
if (parentIndex === -1) {
|
|
359
|
+
parentElements.push(parent);
|
|
360
|
+
abstractIncludedGroups.push([elements[i]]);
|
|
361
|
+
}
|
|
362
|
+
else {
|
|
363
|
+
abstractIncludedGroups[parentIndex].push(elements[i]);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
return { parentElements, abstractIncludedGroups };
|
|
367
|
+
};
|
|
368
|
+
|
|
369
|
+
const getBranchDirectionsByLayouts = (branchLayouts) => {
|
|
370
|
+
const branchDirections = [];
|
|
371
|
+
branchLayouts.forEach(l => {
|
|
372
|
+
const directions = LayoutDirectionsMap[l];
|
|
373
|
+
directions.forEach(d => {
|
|
374
|
+
if (!branchDirections.includes(d) && !branchDirections.includes(getLayoutReverseDirection(d))) {
|
|
375
|
+
branchDirections.push(d);
|
|
376
|
+
}
|
|
377
|
+
});
|
|
378
|
+
});
|
|
379
|
+
return branchDirections;
|
|
380
|
+
};
|
|
381
|
+
const isCorrectLayout = (root, layout) => {
|
|
382
|
+
const rootLayout = root.layout || getDefaultLayout();
|
|
383
|
+
return !getInCorrectLayoutDirection(rootLayout, layout);
|
|
384
|
+
};
|
|
385
|
+
const isMixedLayout = (parentLayout, layout) => {
|
|
386
|
+
return (!isIndentedLayout(parentLayout) && isIndentedLayout(layout)) || (isIndentedLayout(parentLayout) && !isIndentedLayout(layout));
|
|
387
|
+
};
|
|
388
|
+
const getInCorrectLayoutDirection = (rootLayout, layout) => {
|
|
389
|
+
const directions = LayoutDirectionsMap[rootLayout];
|
|
390
|
+
const subLayoutDirections = LayoutDirectionsMap[layout];
|
|
391
|
+
if (!subLayoutDirections) {
|
|
392
|
+
throw new Error(`unexpected layout: ${layout} on correct layout`);
|
|
393
|
+
}
|
|
394
|
+
return subLayoutDirections.find(d => directions.includes(getLayoutReverseDirection(d)));
|
|
395
|
+
};
|
|
396
|
+
const correctLayoutByDirection = (layout, direction) => {
|
|
397
|
+
const isHorizontal = direction === LayoutDirection.left || direction === LayoutDirection.right ? true : false;
|
|
398
|
+
let inverseDirectionLayout = MindLayoutType.standard;
|
|
399
|
+
switch (layout) {
|
|
207
400
|
case MindLayoutType.left:
|
|
208
401
|
inverseDirectionLayout = MindLayoutType.right;
|
|
209
402
|
break;
|
|
@@ -276,528 +469,44 @@ const getRootLayout = (root) => {
|
|
|
276
469
|
return root.layout || getDefaultLayout();
|
|
277
470
|
};
|
|
278
471
|
|
|
279
|
-
const
|
|
280
|
-
const
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
if (AbstractNode.isAbstract(element) && parent) {
|
|
286
|
-
return getAbstractLayout(getLayoutByElement(parent));
|
|
472
|
+
const getAvailableProperty = (board, element, propertyKey) => {
|
|
473
|
+
const ancestors = MindElement.getAncestors(board, element);
|
|
474
|
+
ancestors.unshift(element);
|
|
475
|
+
const ancestor = ancestors.find(value => value[propertyKey]);
|
|
476
|
+
if (ancestor) {
|
|
477
|
+
return ancestor[propertyKey];
|
|
287
478
|
}
|
|
288
|
-
|
|
289
|
-
return
|
|
479
|
+
else {
|
|
480
|
+
return undefined;
|
|
290
481
|
}
|
|
291
|
-
return getDefaultLayout();
|
|
292
482
|
};
|
|
293
483
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
484
|
+
/**
|
|
485
|
+
* Processing of branch color, width, style, etc. of the mind node
|
|
486
|
+
*/
|
|
487
|
+
const getBranchColorByMindElement = (board, element) => {
|
|
488
|
+
const branchColor = getAvailableProperty(board, element, 'branchColor');
|
|
489
|
+
return branchColor || getDefaultBranchColor(board, element);
|
|
299
490
|
};
|
|
300
|
-
|
|
301
|
-
const
|
|
302
|
-
|
|
303
|
-
|
|
491
|
+
const getBranchShapeByMindElement = (board, element) => {
|
|
492
|
+
const branchShape = getAvailableProperty(board, element, 'branchShape');
|
|
493
|
+
return branchShape || BranchShape.bight;
|
|
494
|
+
};
|
|
495
|
+
const getBranchWidthByMindElement = (board, element) => {
|
|
496
|
+
const branchWidth = getAvailableProperty(board, element, 'branchWidth');
|
|
497
|
+
return branchWidth || BRANCH_WIDTH;
|
|
498
|
+
};
|
|
499
|
+
const getAbstractBranchWidth = (board, element) => {
|
|
500
|
+
if (!isNullOrUndefined(element.branchWidth)) {
|
|
501
|
+
return element.branchWidth;
|
|
304
502
|
}
|
|
503
|
+
return DefaultAbstractNodeStyle.branchWidth;
|
|
305
504
|
};
|
|
306
|
-
const
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
return _layout === layout;
|
|
310
|
-
},
|
|
311
|
-
isIndentedLayout(value) {
|
|
312
|
-
const _layout = MindQueries.getLayoutByElement(value);
|
|
313
|
-
return isIndentedLayout(_layout);
|
|
314
|
-
},
|
|
315
|
-
isMindElement(board, element) {
|
|
316
|
-
const path = PlaitBoard.findPath(board, element);
|
|
317
|
-
const rootElement = PlaitNode.get(board, path.slice(0, 1));
|
|
318
|
-
if (PlaitMind.isMind(rootElement)) {
|
|
319
|
-
return true;
|
|
320
|
-
}
|
|
321
|
-
else {
|
|
322
|
-
return false;
|
|
323
|
-
}
|
|
324
|
-
},
|
|
325
|
-
getParent(node) {
|
|
326
|
-
if (PlaitMind.isMind(node)) {
|
|
327
|
-
throw new Error('mind root node can not get parent');
|
|
328
|
-
}
|
|
329
|
-
const parent = NODE_TO_PARENT.get(node);
|
|
330
|
-
return parent;
|
|
331
|
-
},
|
|
332
|
-
findParent(node) {
|
|
333
|
-
if (PlaitMind.isMind(node)) {
|
|
334
|
-
return undefined;
|
|
335
|
-
}
|
|
336
|
-
const parent = NODE_TO_PARENT.get(node);
|
|
337
|
-
return parent;
|
|
338
|
-
},
|
|
339
|
-
getRoot(board, element) {
|
|
340
|
-
const path = PlaitBoard.findPath(board, element);
|
|
341
|
-
return PlaitNode.get(board, path.slice(0, 1));
|
|
342
|
-
},
|
|
343
|
-
getAncestors(board, element) {
|
|
344
|
-
const path = PlaitBoard.findPath(board, element);
|
|
345
|
-
const parents = [];
|
|
346
|
-
for (const p of Path.ancestors(path, { reverse: true })) {
|
|
347
|
-
const n = PlaitNode.get(board, p);
|
|
348
|
-
if (n && !PlaitBoard.isBoard(n)) {
|
|
349
|
-
parents.push(n);
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
return parents;
|
|
353
|
-
},
|
|
354
|
-
getNode(element) {
|
|
355
|
-
const node = ELEMENT_TO_NODE.get(element);
|
|
356
|
-
if (!node) {
|
|
357
|
-
throw new Error(`can not get node from ${JSON.stringify(element)}`);
|
|
358
|
-
}
|
|
359
|
-
return node;
|
|
360
|
-
},
|
|
361
|
-
findParentNode(element) {
|
|
362
|
-
if (PlaitMind.isMind(element)) {
|
|
363
|
-
return undefined;
|
|
364
|
-
}
|
|
365
|
-
const parent = MindElement.getParent(element);
|
|
366
|
-
return MindElement.getNode(parent);
|
|
367
|
-
},
|
|
368
|
-
hasEmojis(element) {
|
|
369
|
-
if (element.data.emojis) {
|
|
370
|
-
return true;
|
|
371
|
-
}
|
|
372
|
-
else {
|
|
373
|
-
return false;
|
|
374
|
-
}
|
|
375
|
-
},
|
|
376
|
-
getEmojis(element) {
|
|
377
|
-
return element.data.emojis;
|
|
505
|
+
const getAbstractBranchColor = (board, element) => {
|
|
506
|
+
if (element.branchColor) {
|
|
507
|
+
return element.branchColor;
|
|
378
508
|
}
|
|
379
|
-
|
|
380
|
-
var MindElementShape;
|
|
381
|
-
(function (MindElementShape) {
|
|
382
|
-
MindElementShape["roundRectangle"] = "round-rectangle";
|
|
383
|
-
MindElementShape["underline"] = "underline";
|
|
384
|
-
})(MindElementShape || (MindElementShape = {}));
|
|
385
|
-
|
|
386
|
-
function getEmojisWidthHeight(board, element) {
|
|
387
|
-
const options = board.getMindOptions();
|
|
388
|
-
const count = element.data.emojis.length;
|
|
389
|
-
const fontSize = getEmojiFontSize(element);
|
|
390
|
-
return {
|
|
391
|
-
width: fontSize * count + count * 2 * options.emojiPadding + (count - 1) * options.spaceBetweenEmojis,
|
|
392
|
-
height: element.height
|
|
393
|
-
};
|
|
394
|
-
}
|
|
395
|
-
function getEmojiFontSize(element) {
|
|
396
|
-
if (PlaitMind.isMind(element)) {
|
|
397
|
-
return 18 + 2;
|
|
398
|
-
}
|
|
399
|
-
else {
|
|
400
|
-
return 14 + 2;
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
const NodeDefaultSpace = {
|
|
405
|
-
horizontal: {
|
|
406
|
-
nodeAndText: BASE * 3,
|
|
407
|
-
emojiAndText: BASE * 1.5
|
|
408
|
-
},
|
|
409
|
-
vertical: {
|
|
410
|
-
nodeAndText: BASE * 1.5
|
|
411
|
-
}
|
|
412
|
-
};
|
|
413
|
-
const RootDefaultSpace = {
|
|
414
|
-
horizontal: {
|
|
415
|
-
nodeAndText: BASE * 4,
|
|
416
|
-
emojiAndText: BASE * 2
|
|
417
|
-
},
|
|
418
|
-
vertical: {
|
|
419
|
-
nodeAndText: BASE * 2
|
|
420
|
-
}
|
|
421
|
-
};
|
|
422
|
-
const getHorizontalSpaceBetweenNodeAndText = (board, element) => {
|
|
423
|
-
const isMind = PlaitMind.isMind(element);
|
|
424
|
-
const nodeAndText = isMind ? RootDefaultSpace.horizontal.nodeAndText : NodeDefaultSpace.horizontal.nodeAndText;
|
|
425
|
-
return nodeAndText;
|
|
426
|
-
};
|
|
427
|
-
const getVerticalSpaceBetweenNodeAndText = (element) => {
|
|
428
|
-
const isMind = PlaitMind.isMind(element);
|
|
429
|
-
const nodeAndText = isMind ? RootDefaultSpace.vertical.nodeAndText : NodeDefaultSpace.vertical.nodeAndText;
|
|
430
|
-
return nodeAndText;
|
|
431
|
-
};
|
|
432
|
-
const getSpaceEmojiAndText = (element) => {
|
|
433
|
-
const isMind = PlaitMind.isMind(element);
|
|
434
|
-
const emojiAndText = isMind ? RootDefaultSpace.horizontal.emojiAndText : NodeDefaultSpace.horizontal.emojiAndText;
|
|
435
|
-
return emojiAndText;
|
|
436
|
-
};
|
|
437
|
-
const NodeSpace = {
|
|
438
|
-
getNodeWidth(board, element) {
|
|
439
|
-
const nodeAndText = getHorizontalSpaceBetweenNodeAndText(board, element);
|
|
440
|
-
if (MindElement.hasEmojis(element)) {
|
|
441
|
-
return (NodeSpace.getEmojiLeftSpace(board, element) +
|
|
442
|
-
getEmojisWidthHeight(board, element).width +
|
|
443
|
-
getSpaceEmojiAndText(element) +
|
|
444
|
-
element.width +
|
|
445
|
-
nodeAndText);
|
|
446
|
-
}
|
|
447
|
-
return nodeAndText + element.width + nodeAndText;
|
|
448
|
-
},
|
|
449
|
-
getNodeHeight(board, element) {
|
|
450
|
-
const nodeAndText = getVerticalSpaceBetweenNodeAndText(element);
|
|
451
|
-
return nodeAndText + element.height + nodeAndText;
|
|
452
|
-
},
|
|
453
|
-
getTextLeftSpace(board, element) {
|
|
454
|
-
const nodeAndText = getHorizontalSpaceBetweenNodeAndText(board, element);
|
|
455
|
-
if (MindElement.hasEmojis(element)) {
|
|
456
|
-
return NodeSpace.getEmojiLeftSpace(board, element) + getEmojisWidthHeight(board, element).width + getSpaceEmojiAndText(element);
|
|
457
|
-
}
|
|
458
|
-
else {
|
|
459
|
-
return nodeAndText;
|
|
460
|
-
}
|
|
461
|
-
},
|
|
462
|
-
getTextTopSpace(element) {
|
|
463
|
-
const nodeAndText = getVerticalSpaceBetweenNodeAndText(element);
|
|
464
|
-
return nodeAndText;
|
|
465
|
-
},
|
|
466
|
-
getEmojiLeftSpace(board, element) {
|
|
467
|
-
const options = board.getMindOptions();
|
|
468
|
-
const nodeAndText = getHorizontalSpaceBetweenNodeAndText(board, element);
|
|
469
|
-
return nodeAndText - options.emojiPadding;
|
|
470
|
-
},
|
|
471
|
-
getEmojiTopSpace(element) {
|
|
472
|
-
const nodeAndText = getVerticalSpaceBetweenNodeAndText(element);
|
|
473
|
-
return nodeAndText;
|
|
474
|
-
}
|
|
475
|
-
};
|
|
476
|
-
|
|
477
|
-
function getRectangleByNode(node) {
|
|
478
|
-
const x = node.x + node.hGap;
|
|
479
|
-
let y = node.y + node.vGap;
|
|
480
|
-
const width = node.width - node.hGap * 2;
|
|
481
|
-
const height = node.height - node.vGap * 2;
|
|
482
|
-
return {
|
|
483
|
-
x,
|
|
484
|
-
y,
|
|
485
|
-
width,
|
|
486
|
-
height
|
|
487
|
-
};
|
|
488
|
-
}
|
|
489
|
-
function getRectangleByElement(board, originPoint, element) {
|
|
490
|
-
const nodeRectangle = {
|
|
491
|
-
x: originPoint[0],
|
|
492
|
-
y: originPoint[1],
|
|
493
|
-
width: NodeSpace.getNodeWidth(board, element),
|
|
494
|
-
height: NodeSpace.getNodeHeight(board, element)
|
|
495
|
-
};
|
|
496
|
-
return nodeRectangle;
|
|
497
|
-
}
|
|
498
|
-
function isHitMindElement(board, point, element) {
|
|
499
|
-
const node = MindElement.getNode(element);
|
|
500
|
-
if (node && distanceBetweenPointAndRectangle(point[0], point[1], getRectangleByNode(node)) === 0) {
|
|
501
|
-
return true;
|
|
502
|
-
}
|
|
503
|
-
else {
|
|
504
|
-
return false;
|
|
505
|
-
}
|
|
506
|
-
}
|
|
507
|
-
|
|
508
|
-
function getEmojiRectangle(board, element) {
|
|
509
|
-
let { x, y } = getRectangleByNode(MindElement.getNode(element));
|
|
510
|
-
x = x + NodeSpace.getEmojiLeftSpace(board, element);
|
|
511
|
-
const { width, height } = getEmojisWidthHeight(board, element);
|
|
512
|
-
return {
|
|
513
|
-
x,
|
|
514
|
-
y,
|
|
515
|
-
width,
|
|
516
|
-
height
|
|
517
|
-
};
|
|
518
|
-
}
|
|
519
|
-
function getEmojiForeignRectangle(board, element) {
|
|
520
|
-
let { x, y } = getRectangleByNode(MindElement.getNode(element));
|
|
521
|
-
x = x + NodeSpace.getEmojiLeftSpace(board, element);
|
|
522
|
-
const { width, height } = getEmojisWidthHeight(board, element);
|
|
523
|
-
return {
|
|
524
|
-
x,
|
|
525
|
-
y,
|
|
526
|
-
width,
|
|
527
|
-
height: height + NodeSpace.getEmojiTopSpace(element) * 2
|
|
528
|
-
};
|
|
529
|
-
}
|
|
530
|
-
const isHitEmojis = (board, element, point) => {
|
|
531
|
-
return RectangleClient.isHit(RectangleClient.toRectangleClient([point, point]), getEmojiRectangle(board, element));
|
|
532
|
-
};
|
|
533
|
-
|
|
534
|
-
function getTopicRectangleByNode(board, node) {
|
|
535
|
-
let nodeRectangle = getRectangleByNode(node);
|
|
536
|
-
return getTopicRectangleByElement(board, nodeRectangle, node.origin);
|
|
537
|
-
}
|
|
538
|
-
function getTopicRectangleByElement(board, nodeRectangle, element) {
|
|
539
|
-
const x = nodeRectangle.x + NodeSpace.getTextLeftSpace(board, element);
|
|
540
|
-
const y = nodeRectangle.y + NodeSpace.getTextTopSpace(element);
|
|
541
|
-
const width = Math.ceil(element.width);
|
|
542
|
-
const height = Math.ceil(element.height);
|
|
543
|
-
return { height, width, x, y };
|
|
544
|
-
}
|
|
545
|
-
|
|
546
|
-
function enterNodeEditing(element) {
|
|
547
|
-
const component = ELEMENT_TO_COMPONENT.get(element);
|
|
548
|
-
component.startEditText(false, false);
|
|
549
|
-
}
|
|
550
|
-
|
|
551
|
-
const adjustRootToNode = (board, node) => {
|
|
552
|
-
const newNode = { ...node };
|
|
553
|
-
delete newNode.isRoot;
|
|
554
|
-
delete newNode.rightNodeCount;
|
|
555
|
-
delete newNode.type;
|
|
556
|
-
const text = Node.string(node.data.topic.children[0]) || ' ';
|
|
557
|
-
const { width, height } = getSizeByText(text, PlaitBoard.getViewportContainer(board), TOPIC_DEFAULT_MAX_WORD_COUNT);
|
|
558
|
-
newNode.width = Math.max(width, NODE_MIN_WIDTH);
|
|
559
|
-
newNode.height = height;
|
|
560
|
-
if (newNode.layout === MindLayoutType.standard) {
|
|
561
|
-
delete newNode.layout;
|
|
562
|
-
}
|
|
563
|
-
return newNode;
|
|
564
|
-
};
|
|
565
|
-
const adjustAbstractToNode = (node) => {
|
|
566
|
-
const newNode = { ...node };
|
|
567
|
-
delete newNode.start;
|
|
568
|
-
delete newNode.end;
|
|
569
|
-
return newNode;
|
|
570
|
-
};
|
|
571
|
-
const adjustNodeToRoot = (board, node) => {
|
|
572
|
-
const newElement = { ...node };
|
|
573
|
-
let text = Node.string(newElement.data.topic);
|
|
574
|
-
if (!text) {
|
|
575
|
-
text = '思维导图';
|
|
576
|
-
newElement.data.topic = { children: [{ text }] };
|
|
577
|
-
}
|
|
578
|
-
delete newElement?.strokeColor;
|
|
579
|
-
delete newElement?.fill;
|
|
580
|
-
delete newElement?.shape;
|
|
581
|
-
delete newElement?.strokeWidth;
|
|
582
|
-
const { width, height } = getSizeByText(text, PlaitBoard.getViewportContainer(board), TOPIC_DEFAULT_MAX_WORD_COUNT, ROOT_TOPIC_FONT_SIZE);
|
|
583
|
-
newElement.width = Math.max(width, NODE_MIN_WIDTH);
|
|
584
|
-
newElement.height = height;
|
|
585
|
-
return {
|
|
586
|
-
...newElement,
|
|
587
|
-
layout: newElement.layout ?? MindLayoutType.right,
|
|
588
|
-
isCollapsed: false,
|
|
589
|
-
isRoot: true,
|
|
590
|
-
type: 'mindmap'
|
|
591
|
-
};
|
|
592
|
-
};
|
|
593
|
-
|
|
594
|
-
const createEmptyMind = (board, point) => {
|
|
595
|
-
const element = createMindElement('', 0, 0, { layout: MindLayoutType.right });
|
|
596
|
-
const rootElement = adjustNodeToRoot(board, element);
|
|
597
|
-
rootElement.points = [point];
|
|
598
|
-
return rootElement;
|
|
599
|
-
};
|
|
600
|
-
const createDefaultMind = (point, rightNodeCount, layout) => {
|
|
601
|
-
const root = createMindElement('思维导图', 72, ROOT_DEFAULT_HEIGHT, { shape: MindElementShape.roundRectangle, layout });
|
|
602
|
-
root.rightNodeCount = rightNodeCount;
|
|
603
|
-
root.isRoot = true;
|
|
604
|
-
root.type = 'mindmap';
|
|
605
|
-
root.points = [point];
|
|
606
|
-
const children = [1, 1, 1].map(() => {
|
|
607
|
-
return createMindElement('新建节点', 56, TEXT_DEFAULT_HEIGHT, { shape: MindElementShape.roundRectangle });
|
|
608
|
-
});
|
|
609
|
-
root.children = children;
|
|
610
|
-
return root;
|
|
611
|
-
};
|
|
612
|
-
const createMindElement = (text, width, height, options) => {
|
|
613
|
-
const newElement = {
|
|
614
|
-
id: idCreator(),
|
|
615
|
-
data: {
|
|
616
|
-
topic: { children: [{ text }] }
|
|
617
|
-
},
|
|
618
|
-
children: [],
|
|
619
|
-
width,
|
|
620
|
-
height,
|
|
621
|
-
fill: options.fill,
|
|
622
|
-
strokeColor: options.strokeColor,
|
|
623
|
-
strokeWidth: options.strokeWidth,
|
|
624
|
-
shape: options.shape
|
|
625
|
-
};
|
|
626
|
-
if (options.fill) {
|
|
627
|
-
newElement.fill = options.fill;
|
|
628
|
-
}
|
|
629
|
-
if (options.strokeColor) {
|
|
630
|
-
newElement.strokeColor = options.strokeColor;
|
|
631
|
-
}
|
|
632
|
-
if (!isNullOrUndefined(options.strokeWidth)) {
|
|
633
|
-
newElement.strokeWidth = options.strokeWidth;
|
|
634
|
-
}
|
|
635
|
-
if (options.shape) {
|
|
636
|
-
newElement.shape = options.shape;
|
|
637
|
-
}
|
|
638
|
-
if (options.layout) {
|
|
639
|
-
newElement.layout = options.layout;
|
|
640
|
-
}
|
|
641
|
-
if (options.branchColor) {
|
|
642
|
-
newElement.branchColor = options.branchColor;
|
|
643
|
-
}
|
|
644
|
-
if (!isNullOrUndefined(options.branchWidth)) {
|
|
645
|
-
newElement.branchWidth = options.branchWidth;
|
|
646
|
-
}
|
|
647
|
-
return newElement;
|
|
648
|
-
};
|
|
649
|
-
|
|
650
|
-
const getChildrenCount = (element) => {
|
|
651
|
-
const count = element.children.reduce((p, c) => {
|
|
652
|
-
return p + getChildrenCount(c);
|
|
653
|
-
}, 0);
|
|
654
|
-
return count + element.children.length;
|
|
655
|
-
};
|
|
656
|
-
const isChildElement = (origin, child) => {
|
|
657
|
-
let parent = MindElement.findParent(child);
|
|
658
|
-
while (parent) {
|
|
659
|
-
if (parent === origin) {
|
|
660
|
-
return true;
|
|
661
|
-
}
|
|
662
|
-
parent = MindElement.findParent(parent);
|
|
663
|
-
}
|
|
664
|
-
return false;
|
|
665
|
-
};
|
|
666
|
-
const getFirstLevelElement = (elements) => {
|
|
667
|
-
let result = [];
|
|
668
|
-
elements.forEach(element => {
|
|
669
|
-
const isChild = elements.some(node => {
|
|
670
|
-
return isChildElement(node, element);
|
|
671
|
-
});
|
|
672
|
-
if (!isChild) {
|
|
673
|
-
result.push(element);
|
|
674
|
-
}
|
|
675
|
-
});
|
|
676
|
-
return result;
|
|
677
|
-
};
|
|
678
|
-
const isChildRight = (node, child) => {
|
|
679
|
-
return node.x < child.x;
|
|
680
|
-
};
|
|
681
|
-
const isChildUp = (node, child) => {
|
|
682
|
-
return node.y > child.y;
|
|
683
|
-
};
|
|
684
|
-
const copyNewNode = (node) => {
|
|
685
|
-
const newNode = { ...node };
|
|
686
|
-
newNode.id = idCreator();
|
|
687
|
-
newNode.children = [];
|
|
688
|
-
for (const childNode of node.children) {
|
|
689
|
-
newNode.children.push(copyNewNode(childNode));
|
|
690
|
-
}
|
|
691
|
-
return newNode;
|
|
692
|
-
};
|
|
693
|
-
const extractNodesText = (node) => {
|
|
694
|
-
let str = '';
|
|
695
|
-
if (node) {
|
|
696
|
-
str += Node.string(node.data.topic.children[0]) + ' ';
|
|
697
|
-
for (const childNode of node.children) {
|
|
698
|
-
str += extractNodesText(childNode);
|
|
699
|
-
}
|
|
700
|
-
}
|
|
701
|
-
return str;
|
|
702
|
-
};
|
|
703
|
-
const changeRightNodeCount = (board, parentPath, changeNumber) => {
|
|
704
|
-
const _rightNodeCount = board.children[parentPath[0]].rightNodeCount;
|
|
705
|
-
Transforms.setNode(board, {
|
|
706
|
-
rightNodeCount: changeNumber >= 0
|
|
707
|
-
? _rightNodeCount + changeNumber
|
|
708
|
-
: _rightNodeCount + changeNumber < 0
|
|
709
|
-
? 0
|
|
710
|
-
: _rightNodeCount + changeNumber
|
|
711
|
-
}, parentPath);
|
|
712
|
-
};
|
|
713
|
-
const isInRightBranchOfStandardLayout = (selectedElement) => {
|
|
714
|
-
const parentElement = MindElement.findParent(selectedElement);
|
|
715
|
-
if (parentElement) {
|
|
716
|
-
const nodeIndex = parentElement.children.findIndex(item => item.id === selectedElement.id);
|
|
717
|
-
if (parentElement.isRoot &&
|
|
718
|
-
getRootLayout(parentElement) === MindLayoutType.standard &&
|
|
719
|
-
parentElement.rightNodeCount &&
|
|
720
|
-
nodeIndex <= parentElement.rightNodeCount - 1) {
|
|
721
|
-
return true;
|
|
722
|
-
}
|
|
723
|
-
}
|
|
724
|
-
return false;
|
|
725
|
-
};
|
|
726
|
-
// layoutLevel 用来表示插入兄弟节点还是子节点
|
|
727
|
-
const insertMindElement = (board, inheritNode, path) => {
|
|
728
|
-
let fill, strokeColor, strokeWidth, shape = MindElementShape.roundRectangle;
|
|
729
|
-
if (!inheritNode.isRoot) {
|
|
730
|
-
fill = inheritNode.fill;
|
|
731
|
-
strokeColor = inheritNode.strokeColor;
|
|
732
|
-
strokeWidth = inheritNode.strokeWidth;
|
|
733
|
-
}
|
|
734
|
-
shape = inheritNode.shape;
|
|
735
|
-
const newElement = createMindElement('', NODE_MIN_WIDTH, TEXT_DEFAULT_HEIGHT, { fill, strokeColor, strokeWidth, shape });
|
|
736
|
-
Transforms.insertNode(board, newElement, path);
|
|
737
|
-
clearSelectedElement(board);
|
|
738
|
-
addSelectedElement(board, newElement);
|
|
739
|
-
setTimeout(() => {
|
|
740
|
-
enterNodeEditing(newElement);
|
|
741
|
-
});
|
|
742
|
-
};
|
|
743
|
-
const findLastChild = (child) => {
|
|
744
|
-
let result = child;
|
|
745
|
-
while (result.children.length !== 0) {
|
|
746
|
-
result = result.children[result.children.length - 1];
|
|
747
|
-
}
|
|
748
|
-
return result;
|
|
749
|
-
};
|
|
750
|
-
const divideElementByParent = (elements) => {
|
|
751
|
-
const abstractIncludedGroups = [];
|
|
752
|
-
const parentElements = [];
|
|
753
|
-
for (let i = 0; i < elements.length; i++) {
|
|
754
|
-
const parent = MindElement.getParent(elements[i]);
|
|
755
|
-
const parentIndex = parentElements.indexOf(parent);
|
|
756
|
-
if (parentIndex === -1) {
|
|
757
|
-
parentElements.push(parent);
|
|
758
|
-
abstractIncludedGroups.push([elements[i]]);
|
|
759
|
-
}
|
|
760
|
-
else {
|
|
761
|
-
abstractIncludedGroups[parentIndex].push(elements[i]);
|
|
762
|
-
}
|
|
763
|
-
}
|
|
764
|
-
return { parentElements, abstractIncludedGroups };
|
|
765
|
-
};
|
|
766
|
-
|
|
767
|
-
const getAvailableProperty = (board, element, propertyKey) => {
|
|
768
|
-
const ancestors = MindElement.getAncestors(board, element);
|
|
769
|
-
ancestors.unshift(element);
|
|
770
|
-
const ancestor = ancestors.find(value => value[propertyKey]);
|
|
771
|
-
if (ancestor) {
|
|
772
|
-
return ancestor[propertyKey];
|
|
773
|
-
}
|
|
774
|
-
else {
|
|
775
|
-
return undefined;
|
|
776
|
-
}
|
|
777
|
-
};
|
|
778
|
-
|
|
779
|
-
/**
|
|
780
|
-
* Processing of branch color, width, style, etc. of the mind node
|
|
781
|
-
*/
|
|
782
|
-
const getBranchColorByMindElement = (board, element) => {
|
|
783
|
-
const branchColor = getAvailableProperty(board, element, 'branchColor');
|
|
784
|
-
return branchColor || getDefaultBranchColor(board, element);
|
|
785
|
-
};
|
|
786
|
-
const getBranchWidthByMindElement = (board, element) => {
|
|
787
|
-
const branchWidth = getAvailableProperty(board, element, 'branchWidth');
|
|
788
|
-
return branchWidth || BRANCH_WIDTH;
|
|
789
|
-
};
|
|
790
|
-
const getAbstractBranchWidth = (board, element) => {
|
|
791
|
-
if (!isNullOrUndefined(element.branchWidth)) {
|
|
792
|
-
return element.branchWidth;
|
|
793
|
-
}
|
|
794
|
-
return DefaultAbstractNodeStyle.branchWidth;
|
|
795
|
-
};
|
|
796
|
-
const getAbstractBranchColor = (board, element) => {
|
|
797
|
-
if (element.branchColor) {
|
|
798
|
-
return element.branchColor;
|
|
799
|
-
}
|
|
800
|
-
return DefaultAbstractNodeStyle.branchColor;
|
|
509
|
+
return DefaultAbstractNodeStyle.branchColor;
|
|
801
510
|
};
|
|
802
511
|
const getNextBranchColor = (root) => {
|
|
803
512
|
const index = root.children.length;
|
|
@@ -875,13 +584,32 @@ const isDragging = (board) => {
|
|
|
875
584
|
const setIsDragging = (board, state) => {
|
|
876
585
|
IS_DRAGGING.set(board, state);
|
|
877
586
|
};
|
|
587
|
+
const hasPreviousOrNextOfDropPath = (parent, target, dropPath) => {
|
|
588
|
+
const children = getNonAbstractChildren(parent);
|
|
589
|
+
let hasPreviousNode = dropPath[dropPath.length - 1] !== 0;
|
|
590
|
+
let hasNextNode = dropPath[dropPath.length - 1] !== (children?.length || 0);
|
|
591
|
+
if (PlaitMind.isMind(parent) && isStandardLayout(getRootLayout(parent))) {
|
|
592
|
+
const dropStandardRightBottom = target === parent.children[parent.rightNodeCount - 1] && dropPath[dropPath.length - 1] === parent.rightNodeCount;
|
|
593
|
+
const dropStandardLeftTop = target === parent.children[parent.rightNodeCount] && dropPath[dropPath.length - 1] === parent.rightNodeCount;
|
|
594
|
+
if (dropStandardRightBottom) {
|
|
595
|
+
hasPreviousNode = true;
|
|
596
|
+
hasNextNode = false;
|
|
597
|
+
}
|
|
598
|
+
if (dropStandardLeftTop) {
|
|
599
|
+
hasPreviousNode = false;
|
|
600
|
+
hasNextNode = true;
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
if (parent.isCollapsed) {
|
|
604
|
+
hasNextNode = false;
|
|
605
|
+
hasPreviousNode = false;
|
|
606
|
+
}
|
|
607
|
+
return {
|
|
608
|
+
hasPreviousNode,
|
|
609
|
+
hasNextNode
|
|
610
|
+
};
|
|
611
|
+
};
|
|
878
612
|
|
|
879
|
-
/**
|
|
880
|
-
*
|
|
881
|
-
* @param targetNode
|
|
882
|
-
* @param centerPoint
|
|
883
|
-
* @returns DetectResult[] | null
|
|
884
|
-
*/
|
|
885
613
|
const directionCorrector = (board, node, detectResults) => {
|
|
886
614
|
if (!node.origin.isRoot && !AbstractNode.isAbstract(node.origin)) {
|
|
887
615
|
const parentLayout = MindQueries.getCorrectLayoutByElement(board, node?.parent.origin);
|
|
@@ -1283,7 +1011,55 @@ const transformPlacement = (placement, direction) => {
|
|
|
1283
1011
|
}
|
|
1284
1012
|
};
|
|
1285
1013
|
|
|
1286
|
-
function
|
|
1014
|
+
function drawIndentedLink(board, node, child, defaultStroke = null, needDrawUnderline = true, defaultStrokeWidth) {
|
|
1015
|
+
const branchShape = getBranchShapeByMindElement(board, node.origin);
|
|
1016
|
+
const branchWidth = defaultStrokeWidth || getBranchWidthByMindElement(board, child.origin);
|
|
1017
|
+
const branchColor = defaultStroke || getBranchColorByMindElement(board, child.origin);
|
|
1018
|
+
const isUnderlineShape = getShapeByElement(board, child.origin) === MindElementShape.underline;
|
|
1019
|
+
let beginX, beginY, endX, endY, beginNode = node, endNode = child;
|
|
1020
|
+
const beginRectangle = getRectangleByNode(beginNode);
|
|
1021
|
+
const endRectangle = getRectangleByNode(endNode);
|
|
1022
|
+
beginX = beginNode.x + beginNode.width / 2;
|
|
1023
|
+
beginY = isChildUp(node, child) ? beginRectangle.y : beginRectangle.y + beginRectangle.height;
|
|
1024
|
+
endX = node.left ? endNode.x + endNode.hGap + endRectangle.width : endNode.x + endNode.hGap;
|
|
1025
|
+
endY = isUnderlineShape ? endNode.y + endNode.height - endNode.vGap : endNode.y + endNode.height / 2;
|
|
1026
|
+
//根据位置,设置正负参数
|
|
1027
|
+
let plusMinus = isChildUp(node, child) ? (node.left ? [-1, -1] : [1, -1]) : node.left ? [-1, 1] : [1, 1];
|
|
1028
|
+
const layout = MindQueries.getCorrectLayoutByElement(board, node.origin);
|
|
1029
|
+
if (beginNode.origin.isRoot) {
|
|
1030
|
+
if (layout === MindLayoutType.leftBottomIndented || layout === MindLayoutType.rightBottomIndented) {
|
|
1031
|
+
beginY += branchWidth;
|
|
1032
|
+
}
|
|
1033
|
+
if (layout === MindLayoutType.leftTopIndented || layout === MindLayoutType.rightTopIndented) {
|
|
1034
|
+
beginY -= branchWidth;
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
1037
|
+
let curve = [
|
|
1038
|
+
[beginX, beginY],
|
|
1039
|
+
[beginX, beginY],
|
|
1040
|
+
[beginX, beginY],
|
|
1041
|
+
[beginX, endY - (endNode.hGap * 3 * plusMinus[1]) / 5],
|
|
1042
|
+
[beginX, endY - (endNode.hGap * plusMinus[1]) / 5],
|
|
1043
|
+
[beginX + (endNode.hGap * plusMinus[0]) / 4, endY],
|
|
1044
|
+
[beginX + (endNode.hGap * plusMinus[0] * 3) / 5, endY],
|
|
1045
|
+
isUnderlineShape && needDrawUnderline ? [endX + (endNode.width - endNode.hGap * 2) * plusMinus[0], endY] : [endX, endY],
|
|
1046
|
+
isUnderlineShape && needDrawUnderline ? [endX + (endNode.width - endNode.hGap * 2) * plusMinus[0], endY] : [endX, endY],
|
|
1047
|
+
isUnderlineShape && needDrawUnderline ? [endX + (endNode.width - endNode.hGap * 2) * plusMinus[0], endY] : [endX, endY]
|
|
1048
|
+
];
|
|
1049
|
+
if (branchShape === BranchShape.polyline) {
|
|
1050
|
+
const polylinePoints = [
|
|
1051
|
+
[beginX, beginY],
|
|
1052
|
+
[beginX, endY],
|
|
1053
|
+
[endX, endY]
|
|
1054
|
+
];
|
|
1055
|
+
return drawLinearPath(polylinePoints, { stroke: branchColor, strokeWidth: branchWidth });
|
|
1056
|
+
}
|
|
1057
|
+
const points = pointsOnBezierCurves(curve);
|
|
1058
|
+
return PlaitBoard.getRoughSVG(board).curve(points, { stroke: branchColor, strokeWidth: branchWidth });
|
|
1059
|
+
}
|
|
1060
|
+
|
|
1061
|
+
function drawLogicLink(board, parent, node, isHorizontal, defaultStroke = null, defaultStrokeWidth) {
|
|
1062
|
+
const branchShape = getBranchShapeByMindElement(board, parent.origin);
|
|
1287
1063
|
const branchColor = defaultStroke || getBranchColorByMindElement(board, node.origin);
|
|
1288
1064
|
const branchWidth = defaultStrokeWidth || getBranchWidthByMindElement(board, node.origin);
|
|
1289
1065
|
const hasStraightLine = !parent.origin.isRoot;
|
|
@@ -1327,9 +1103,27 @@ function drawLogicLink(board, node, parent, isHorizontal, defaultStroke = null,
|
|
|
1327
1103
|
const underlineEnd = moveXOfPoint(endPoint, nodeClient.width, linkDirection);
|
|
1328
1104
|
const underline = hasUnderlineShape && isHorizontal ? [underlineEnd, underlineEnd, underlineEnd] : [];
|
|
1329
1105
|
const points = pointsOnBezierCurves([...straightLine, ...curve, ...underline]);
|
|
1106
|
+
if (branchShape === BranchShape.polyline) {
|
|
1107
|
+
const buffer = 8;
|
|
1108
|
+
const movePoint = moveXOfPoint(beginPoint2, buffer, linkDirection);
|
|
1109
|
+
const polylinePoints = [
|
|
1110
|
+
...straightLine,
|
|
1111
|
+
movePoint,
|
|
1112
|
+
isHorizontal ? [movePoint[0], endPoint[1]] : [endPoint[0], movePoint[1]],
|
|
1113
|
+
endPoint,
|
|
1114
|
+
...underline
|
|
1115
|
+
];
|
|
1116
|
+
return drawLinearPath(polylinePoints, { stroke: branchColor, strokeWidth: branchWidth });
|
|
1117
|
+
}
|
|
1330
1118
|
return PlaitBoard.getRoughSVG(board).curve(points, { stroke: branchColor, strokeWidth: branchWidth });
|
|
1331
1119
|
}
|
|
1332
1120
|
|
|
1121
|
+
function drawLink(board, parentNode, node, isHorizontal, needDrawUnderline, defaultStroke, defaultStrokeWidth) {
|
|
1122
|
+
return MindElement.isIndentedLayout(parentNode.origin)
|
|
1123
|
+
? drawIndentedLink(board, parentNode, node, defaultStroke, needDrawUnderline, defaultStrokeWidth)
|
|
1124
|
+
: drawLogicLink(board, parentNode, node, isHorizontal, defaultStroke, defaultStrokeWidth);
|
|
1125
|
+
}
|
|
1126
|
+
|
|
1333
1127
|
const drawFakeDragNode = (board, activeComponent, offsetX, offsetY) => {
|
|
1334
1128
|
const dragFakeNodeG = createG();
|
|
1335
1129
|
dragFakeNodeG.classList.add('dragging', 'fake-node', 'plait-board-attached');
|
|
@@ -1342,17 +1136,17 @@ const drawFakeDragNode = (board, activeComponent, offsetX, offsetY) => {
|
|
|
1342
1136
|
const textRectangle = getTopicRectangleByNode(board, activeComponent.node);
|
|
1343
1137
|
const fakeNodeG = drawRoundRectangleByNode(board, fakeDraggingNode);
|
|
1344
1138
|
const richtextG = activeComponent.richtextG?.cloneNode(true);
|
|
1345
|
-
updateForeignObject(richtextG, textRectangle.width
|
|
1139
|
+
updateForeignObject(richtextG, textRectangle.width, textRectangle.height, textRectangle.x + offsetX, textRectangle.y + offsetY);
|
|
1346
1140
|
dragFakeNodeG?.append(fakeNodeG);
|
|
1347
1141
|
dragFakeNodeG?.append(richtextG);
|
|
1348
1142
|
return dragFakeNodeG;
|
|
1349
1143
|
};
|
|
1350
|
-
const
|
|
1144
|
+
const drawFakeDropNode = (board, target, path) => {
|
|
1351
1145
|
const fakeDropNodeG = createG();
|
|
1352
1146
|
const parent = PlaitNode.get(board, Path.parent(path));
|
|
1353
1147
|
const layout = MindQueries.getLayoutByElement(parent);
|
|
1354
1148
|
const isHorizontal = isHorizontalLayout(layout);
|
|
1355
|
-
const { hasNextNode, hasPreviousNode } =
|
|
1149
|
+
const { hasNextNode, hasPreviousNode } = hasPreviousOrNextOfDropPath(parent, target, path);
|
|
1356
1150
|
const width = 30;
|
|
1357
1151
|
const height = 12;
|
|
1358
1152
|
let fakeNode, centerPoint, basicNode, linkDirection;
|
|
@@ -1441,40 +1235,13 @@ const drawFakeDropNodeByPath = (board, target, path) => {
|
|
|
1441
1235
|
const fakeRectangleG = drawRoundRectangle(PlaitBoard.getRoughSVG(board), fakeNode.x, fakeNode.y, fakeNode.x + width, fakeNode.y + height, {
|
|
1442
1236
|
stroke: PRIMARY_COLOR,
|
|
1443
1237
|
strokeWidth: 2,
|
|
1444
|
-
fill: PRIMARY_COLOR,
|
|
1445
|
-
fillStyle: 'solid'
|
|
1446
|
-
});
|
|
1447
|
-
const link = MindElement.
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
fakeDropNodeG
|
|
1451
|
-
fakeDropNodeG?.appendChild(fakeRectangleG);
|
|
1452
|
-
return fakeDropNodeG;
|
|
1453
|
-
};
|
|
1454
|
-
const getPreviousAndNextByPath = (parent, target, path) => {
|
|
1455
|
-
const children = getNonAbstractChildren(parent);
|
|
1456
|
-
let hasPreviousNode = path[path.length - 1] !== 0;
|
|
1457
|
-
let hasNextNode = path[path.length - 1] !== (children?.length || 0);
|
|
1458
|
-
if (PlaitMind.isMind(parent) && isStandardLayout(getRootLayout(parent))) {
|
|
1459
|
-
const dropStandardRightBottom = target === parent.children[parent.rightNodeCount - 1] && path[path.length - 1] === parent.rightNodeCount;
|
|
1460
|
-
const dropStandardLeftTop = target === parent.children[parent.rightNodeCount] && path[path.length - 1] === parent.rightNodeCount;
|
|
1461
|
-
if (dropStandardRightBottom) {
|
|
1462
|
-
hasPreviousNode = true;
|
|
1463
|
-
hasNextNode = false;
|
|
1464
|
-
}
|
|
1465
|
-
if (dropStandardLeftTop) {
|
|
1466
|
-
hasPreviousNode = false;
|
|
1467
|
-
hasNextNode = true;
|
|
1468
|
-
}
|
|
1469
|
-
}
|
|
1470
|
-
if (parent.isCollapsed) {
|
|
1471
|
-
hasNextNode = false;
|
|
1472
|
-
hasPreviousNode = false;
|
|
1473
|
-
}
|
|
1474
|
-
return {
|
|
1475
|
-
hasPreviousNode,
|
|
1476
|
-
hasNextNode
|
|
1477
|
-
};
|
|
1238
|
+
fill: PRIMARY_COLOR,
|
|
1239
|
+
fillStyle: 'solid'
|
|
1240
|
+
});
|
|
1241
|
+
const link = drawLink(board, MindElement.getNode(parent), fakeNode, isHorizontal, false, PRIMARY_COLOR, STROKE_WIDTH);
|
|
1242
|
+
fakeDropNodeG?.appendChild(link);
|
|
1243
|
+
fakeDropNodeG?.appendChild(fakeRectangleG);
|
|
1244
|
+
return fakeDropNodeG;
|
|
1478
1245
|
};
|
|
1479
1246
|
|
|
1480
1247
|
const separateChildren = (parentElement) => {
|
|
@@ -1595,285 +1362,565 @@ isExtendPreviousNode = true, effectedAbstracts = new Map()) => {
|
|
|
1595
1362
|
newProperties.end = newProperties.end + step;
|
|
1596
1363
|
});
|
|
1597
1364
|
}
|
|
1598
|
-
if (!hasPreviousNode) {
|
|
1599
|
-
return effectedAbstracts;
|
|
1365
|
+
if (!hasPreviousNode) {
|
|
1366
|
+
return effectedAbstracts;
|
|
1367
|
+
}
|
|
1368
|
+
const selectedElement = PlaitNode.get(board, Path.previous(path));
|
|
1369
|
+
const correspondingAbstract = getCorrespondingAbstract(selectedElement);
|
|
1370
|
+
const isDragToLast = !isExtendPreviousNode && correspondingAbstract && correspondingAbstract.end === path[path.length - 1] - 1;
|
|
1371
|
+
if (correspondingAbstract && !isDragToLast) {
|
|
1372
|
+
let newProperties = effectedAbstracts.get(correspondingAbstract);
|
|
1373
|
+
if (!newProperties) {
|
|
1374
|
+
newProperties = { start: 0, end: 0 };
|
|
1375
|
+
effectedAbstracts.set(correspondingAbstract, newProperties);
|
|
1376
|
+
}
|
|
1377
|
+
newProperties.end = newProperties.end + step;
|
|
1378
|
+
}
|
|
1379
|
+
return effectedAbstracts;
|
|
1380
|
+
};
|
|
1381
|
+
const deleteElementHandleAbstract = (board, deletableElements, effectedAbstracts = new Map()) => {
|
|
1382
|
+
deletableElements.forEach(node => {
|
|
1383
|
+
if (!PlaitMind.isMind(node)) {
|
|
1384
|
+
const behindAbstracts = getBehindAbstracts(node).filter(abstract => !deletableElements.includes(abstract));
|
|
1385
|
+
if (behindAbstracts.length) {
|
|
1386
|
+
behindAbstracts.forEach(abstract => {
|
|
1387
|
+
let newProperties = effectedAbstracts.get(abstract);
|
|
1388
|
+
if (!newProperties) {
|
|
1389
|
+
newProperties = { start: 0, end: 0 };
|
|
1390
|
+
effectedAbstracts.set(abstract, newProperties);
|
|
1391
|
+
}
|
|
1392
|
+
newProperties.start = newProperties.start - 1;
|
|
1393
|
+
newProperties.end = newProperties.end - 1;
|
|
1394
|
+
});
|
|
1395
|
+
}
|
|
1396
|
+
const correspondingAbstract = getCorrespondingAbstract(node);
|
|
1397
|
+
if (correspondingAbstract && !deletableElements.includes(correspondingAbstract)) {
|
|
1398
|
+
let newProperties = effectedAbstracts.get(correspondingAbstract);
|
|
1399
|
+
if (!newProperties) {
|
|
1400
|
+
newProperties = { start: 0, end: 0 };
|
|
1401
|
+
effectedAbstracts.set(correspondingAbstract, newProperties);
|
|
1402
|
+
}
|
|
1403
|
+
newProperties.end = newProperties.end - 1;
|
|
1404
|
+
}
|
|
1405
|
+
}
|
|
1406
|
+
});
|
|
1407
|
+
return effectedAbstracts;
|
|
1408
|
+
};
|
|
1409
|
+
|
|
1410
|
+
var AbstractHandlePosition;
|
|
1411
|
+
(function (AbstractHandlePosition) {
|
|
1412
|
+
AbstractHandlePosition["start"] = "start";
|
|
1413
|
+
AbstractHandlePosition["end"] = "end";
|
|
1414
|
+
})(AbstractHandlePosition || (AbstractHandlePosition = {}));
|
|
1415
|
+
var AbstractResizeState;
|
|
1416
|
+
(function (AbstractResizeState) {
|
|
1417
|
+
AbstractResizeState["start"] = "start";
|
|
1418
|
+
AbstractResizeState["resizing"] = "resizing";
|
|
1419
|
+
AbstractResizeState["end"] = "end";
|
|
1420
|
+
})(AbstractResizeState || (AbstractResizeState = {}));
|
|
1421
|
+
|
|
1422
|
+
const getRectangleByResizingLocation = (abstractRectangle, location, activeHandlePosition, isHorizontal) => {
|
|
1423
|
+
if (isHorizontal) {
|
|
1424
|
+
if (activeHandlePosition === AbstractHandlePosition.start) {
|
|
1425
|
+
return {
|
|
1426
|
+
...abstractRectangle,
|
|
1427
|
+
y: location,
|
|
1428
|
+
height: abstractRectangle.height + abstractRectangle.y - location
|
|
1429
|
+
};
|
|
1430
|
+
}
|
|
1431
|
+
else {
|
|
1432
|
+
return {
|
|
1433
|
+
...abstractRectangle,
|
|
1434
|
+
height: location - abstractRectangle.y
|
|
1435
|
+
};
|
|
1436
|
+
}
|
|
1437
|
+
}
|
|
1438
|
+
else {
|
|
1439
|
+
if (activeHandlePosition === AbstractHandlePosition.start) {
|
|
1440
|
+
return {
|
|
1441
|
+
...abstractRectangle,
|
|
1442
|
+
x: location,
|
|
1443
|
+
width: abstractRectangle.width + abstractRectangle.x - location
|
|
1444
|
+
};
|
|
1445
|
+
}
|
|
1446
|
+
else {
|
|
1447
|
+
return {
|
|
1448
|
+
...abstractRectangle,
|
|
1449
|
+
width: location - abstractRectangle.x
|
|
1450
|
+
};
|
|
1451
|
+
}
|
|
1452
|
+
}
|
|
1453
|
+
};
|
|
1454
|
+
const getLocationScope = (board, handlePosition, parentChildren, element, parent, isHorizontal) => {
|
|
1455
|
+
const node = MindElement.getNode(element);
|
|
1456
|
+
const { start, end } = getCorrectStartEnd(node.origin, parent);
|
|
1457
|
+
const startNode = parentChildren[start];
|
|
1458
|
+
const endNode = parentChildren[end];
|
|
1459
|
+
if (handlePosition === AbstractHandlePosition.start) {
|
|
1460
|
+
const abstractNode = parentChildren.filter(child => AbstractNode.isAbstract(child) && child.end < element.start);
|
|
1461
|
+
let minNode;
|
|
1462
|
+
if (abstractNode.length) {
|
|
1463
|
+
const index = abstractNode
|
|
1464
|
+
.map(node => {
|
|
1465
|
+
const { end } = getCorrectStartEnd(node, parent);
|
|
1466
|
+
return end;
|
|
1467
|
+
})
|
|
1468
|
+
.sort((a, b) => b - a)[0];
|
|
1469
|
+
minNode = parentChildren[index + 1];
|
|
1470
|
+
}
|
|
1471
|
+
else {
|
|
1472
|
+
minNode = parentChildren[0];
|
|
1473
|
+
}
|
|
1474
|
+
const minNodeRectangle = getRectangleByElements(board, [minNode], true);
|
|
1475
|
+
const endNodeRectangle = getRectangleByElements(board, [endNode], false);
|
|
1476
|
+
if (isHorizontal) {
|
|
1477
|
+
return {
|
|
1478
|
+
max: endNodeRectangle.y - ABSTRACT_INCLUDED_OUTLINE_OFFSET,
|
|
1479
|
+
min: minNodeRectangle.y - ABSTRACT_INCLUDED_OUTLINE_OFFSET
|
|
1480
|
+
};
|
|
1481
|
+
}
|
|
1482
|
+
else {
|
|
1483
|
+
return {
|
|
1484
|
+
max: endNodeRectangle.x - ABSTRACT_INCLUDED_OUTLINE_OFFSET,
|
|
1485
|
+
min: minNodeRectangle.x - ABSTRACT_INCLUDED_OUTLINE_OFFSET
|
|
1486
|
+
};
|
|
1487
|
+
}
|
|
1488
|
+
}
|
|
1489
|
+
else {
|
|
1490
|
+
const abstractNode = parentChildren.filter(child => AbstractNode.isAbstract(child) && child.start > element.end);
|
|
1491
|
+
let maxNode;
|
|
1492
|
+
if (abstractNode.length) {
|
|
1493
|
+
const index = abstractNode
|
|
1494
|
+
.map(node => {
|
|
1495
|
+
const { start } = getCorrectStartEnd(node, parent);
|
|
1496
|
+
return start;
|
|
1497
|
+
})
|
|
1498
|
+
.sort((a, b) => a - b)[0];
|
|
1499
|
+
maxNode = parentChildren[index - 1];
|
|
1500
|
+
}
|
|
1501
|
+
else {
|
|
1502
|
+
const children = parentChildren.filter(child => !AbstractNode.isAbstract(child));
|
|
1503
|
+
maxNode = parentChildren[children.length - 1];
|
|
1504
|
+
}
|
|
1505
|
+
const maxNodeRectangle = getRectangleByElements(board, [maxNode], true);
|
|
1506
|
+
const startNodeRectangle = getRectangleByElements(board, [startNode], false);
|
|
1507
|
+
if (isHorizontal) {
|
|
1508
|
+
return {
|
|
1509
|
+
max: maxNodeRectangle.y + maxNodeRectangle.height + ABSTRACT_INCLUDED_OUTLINE_OFFSET,
|
|
1510
|
+
min: startNodeRectangle.y + startNodeRectangle.height + ABSTRACT_INCLUDED_OUTLINE_OFFSET
|
|
1511
|
+
};
|
|
1512
|
+
}
|
|
1513
|
+
else {
|
|
1514
|
+
return {
|
|
1515
|
+
max: maxNodeRectangle.x + maxNodeRectangle.width + ABSTRACT_INCLUDED_OUTLINE_OFFSET,
|
|
1516
|
+
min: startNodeRectangle.x + startNodeRectangle.width + ABSTRACT_INCLUDED_OUTLINE_OFFSET
|
|
1517
|
+
};
|
|
1518
|
+
}
|
|
1519
|
+
}
|
|
1520
|
+
};
|
|
1521
|
+
const getHitAbstractHandle = (board, element, point) => {
|
|
1522
|
+
const nodeLayout = MindQueries.getCorrectLayoutByElement(board, element);
|
|
1523
|
+
const isHorizontal = isHorizontalLayout(nodeLayout);
|
|
1524
|
+
const parentElement = MindElement.getParent(element);
|
|
1525
|
+
const includedElements = parentElement.children.slice(element.start, element.end + 1);
|
|
1526
|
+
let abstractRectangle = getRectangleByElements(board, includedElements, true);
|
|
1527
|
+
abstractRectangle = RectangleClient.getOutlineRectangle(abstractRectangle, -ABSTRACT_INCLUDED_OUTLINE_OFFSET);
|
|
1528
|
+
const startHandleRec = getAbstractHandleRectangle(abstractRectangle, isHorizontal, AbstractHandlePosition.start);
|
|
1529
|
+
const endHandleRec = getAbstractHandleRectangle(abstractRectangle, isHorizontal, AbstractHandlePosition.end);
|
|
1530
|
+
const pointRec = RectangleClient.toRectangleClient([point, point]);
|
|
1531
|
+
if (RectangleClient.isHit(pointRec, startHandleRec))
|
|
1532
|
+
return AbstractHandlePosition.start;
|
|
1533
|
+
if (RectangleClient.isHit(pointRec, endHandleRec))
|
|
1534
|
+
return AbstractHandlePosition.end;
|
|
1535
|
+
return undefined;
|
|
1536
|
+
};
|
|
1537
|
+
const getAbstractHandleRectangle = (rectangle, isHorizontal, position) => {
|
|
1538
|
+
let result;
|
|
1539
|
+
if (position === AbstractHandlePosition.start) {
|
|
1540
|
+
const location = isHorizontal ? rectangle.y : rectangle.x;
|
|
1541
|
+
result = getRectangleByResizingLocation(rectangle, location + ABSTRACT_HANDLE_MASK_WIDTH / 2, AbstractHandlePosition.end, isHorizontal);
|
|
1542
|
+
result = getRectangleByResizingLocation(result, location - ABSTRACT_HANDLE_MASK_WIDTH / 2, position, isHorizontal);
|
|
1543
|
+
}
|
|
1544
|
+
else {
|
|
1545
|
+
const location = isHorizontal ? rectangle.y + rectangle.height : rectangle.x + rectangle.width;
|
|
1546
|
+
result = getRectangleByResizingLocation(rectangle, location - ABSTRACT_HANDLE_MASK_WIDTH / 2, AbstractHandlePosition.start, isHorizontal);
|
|
1547
|
+
result = getRectangleByResizingLocation(result, location + ABSTRACT_HANDLE_MASK_WIDTH / 2, position, isHorizontal);
|
|
1548
|
+
}
|
|
1549
|
+
return result;
|
|
1550
|
+
};
|
|
1551
|
+
function findLocationLeftIndex(board, parentChildren, location, isHorizontal) {
|
|
1552
|
+
const children = parentChildren.filter(child => {
|
|
1553
|
+
return !AbstractNode.isAbstract(child);
|
|
1554
|
+
});
|
|
1555
|
+
const recArray = children.map(child => {
|
|
1556
|
+
return getRectangleByElements(board, [child], false);
|
|
1557
|
+
});
|
|
1558
|
+
const firstRec = getRectangleByElements(board, [children[0]], true);
|
|
1559
|
+
const fakeLeftRec = {
|
|
1560
|
+
x: firstRec.x - firstRec.width,
|
|
1561
|
+
y: firstRec.y - firstRec.height,
|
|
1562
|
+
width: firstRec.width,
|
|
1563
|
+
height: firstRec.height
|
|
1564
|
+
};
|
|
1565
|
+
const lastRec = getRectangleByElements(board, [children[children.length - 1]], true);
|
|
1566
|
+
const fakeRightRec = {
|
|
1567
|
+
x: lastRec.x + lastRec.width,
|
|
1568
|
+
y: lastRec.y + lastRec.height,
|
|
1569
|
+
width: lastRec.width,
|
|
1570
|
+
height: lastRec.height
|
|
1571
|
+
};
|
|
1572
|
+
recArray.push(fakeRightRec);
|
|
1573
|
+
recArray.unshift(fakeLeftRec);
|
|
1574
|
+
for (let i = 0; i < recArray.length - 1; i++) {
|
|
1575
|
+
const recXOrY = isHorizontal ? recArray[i].y : recArray[i].x;
|
|
1576
|
+
const recWidthOrHeight = isHorizontal ? recArray[i].height : recArray[i].width;
|
|
1577
|
+
if (location >= recXOrY + recWidthOrHeight / 2 &&
|
|
1578
|
+
location <= recArray[i + 1][isHorizontal ? 'y' : 'x'] + recArray[i + 1][isHorizontal ? 'height' : 'width'] / 2) {
|
|
1579
|
+
return i - 1;
|
|
1580
|
+
}
|
|
1581
|
+
}
|
|
1582
|
+
return 0;
|
|
1583
|
+
}
|
|
1584
|
+
function handleTouchedAbstract(board, touchedAbstract, endPoint) {
|
|
1585
|
+
let touchedHandle;
|
|
1586
|
+
const abstract = getSelectedElements(board)
|
|
1587
|
+
.filter(element => AbstractNode.isAbstract(element))
|
|
1588
|
+
.find(element => {
|
|
1589
|
+
touchedHandle = getHitAbstractHandle(board, element, endPoint);
|
|
1590
|
+
return touchedHandle;
|
|
1591
|
+
});
|
|
1592
|
+
if (touchedAbstract === abstract) {
|
|
1593
|
+
return touchedAbstract;
|
|
1594
|
+
}
|
|
1595
|
+
if (touchedAbstract) {
|
|
1596
|
+
const component = PlaitElement.getComponent(touchedAbstract);
|
|
1597
|
+
component.updateAbstractIncludedOutline();
|
|
1598
|
+
touchedAbstract = undefined;
|
|
1599
|
+
}
|
|
1600
|
+
if (abstract) {
|
|
1601
|
+
touchedAbstract = abstract;
|
|
1602
|
+
const component = PlaitElement.getComponent(touchedAbstract);
|
|
1603
|
+
component.updateAbstractIncludedOutline(touchedHandle);
|
|
1604
|
+
}
|
|
1605
|
+
return touchedAbstract;
|
|
1606
|
+
}
|
|
1607
|
+
|
|
1608
|
+
const isInRightBranchOfStandardLayout = (selectedElement) => {
|
|
1609
|
+
const parentElement = MindElement.findParent(selectedElement);
|
|
1610
|
+
if (parentElement) {
|
|
1611
|
+
const nodeIndex = parentElement.children.findIndex(item => item.id === selectedElement.id);
|
|
1612
|
+
if (parentElement.isRoot &&
|
|
1613
|
+
getRootLayout(parentElement) === MindLayoutType.standard &&
|
|
1614
|
+
parentElement.rightNodeCount &&
|
|
1615
|
+
nodeIndex <= parentElement.rightNodeCount - 1) {
|
|
1616
|
+
return true;
|
|
1617
|
+
}
|
|
1618
|
+
}
|
|
1619
|
+
return false;
|
|
1620
|
+
};
|
|
1621
|
+
const insertElementHandleRightNodeCount = (board, path, insertCount, effectedRightNodeCount = []) => {
|
|
1622
|
+
let index = effectedRightNodeCount.findIndex(ref => Path.equals(ref.path, path));
|
|
1623
|
+
const mind = PlaitNode.get(board, path);
|
|
1624
|
+
if (index === -1) {
|
|
1625
|
+
effectedRightNodeCount.push({ path, rightNodeCount: mind.rightNodeCount + insertCount });
|
|
1600
1626
|
}
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
const isDragToLast = !isExtendPreviousNode && correspondingAbstract && correspondingAbstract.end === path[path.length - 1] - 1;
|
|
1604
|
-
if (correspondingAbstract && !isDragToLast) {
|
|
1605
|
-
let newProperties = effectedAbstracts.get(correspondingAbstract);
|
|
1606
|
-
if (!newProperties) {
|
|
1607
|
-
newProperties = { start: 0, end: 0 };
|
|
1608
|
-
effectedAbstracts.set(correspondingAbstract, newProperties);
|
|
1609
|
-
}
|
|
1610
|
-
newProperties.end = newProperties.end + step;
|
|
1627
|
+
else {
|
|
1628
|
+
effectedRightNodeCount[index].rightNodeCount += insertCount;
|
|
1611
1629
|
}
|
|
1612
|
-
return
|
|
1630
|
+
return effectedRightNodeCount;
|
|
1613
1631
|
};
|
|
1614
|
-
const
|
|
1615
|
-
deletableElements.forEach(
|
|
1616
|
-
if (
|
|
1617
|
-
const
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
newProperties = { start: 0, end: 0 };
|
|
1623
|
-
effectedAbstracts.set(abstract, newProperties);
|
|
1624
|
-
}
|
|
1625
|
-
newProperties.start = newProperties.start - 1;
|
|
1626
|
-
newProperties.end = newProperties.end - 1;
|
|
1627
|
-
});
|
|
1632
|
+
const deleteElementsHandleRightNodeCount = (board, deletableElements, effectedRightNodeCount = []) => {
|
|
1633
|
+
deletableElements.forEach(element => {
|
|
1634
|
+
if (isInRightBranchOfStandardLayout(element)) {
|
|
1635
|
+
const mind = MindElement.getParent(element);
|
|
1636
|
+
const path = PlaitBoard.findPath(board, mind);
|
|
1637
|
+
let index = effectedRightNodeCount.findIndex(ref => Path.equals(ref.path, path));
|
|
1638
|
+
if (index === -1) {
|
|
1639
|
+
effectedRightNodeCount.push({ path, rightNodeCount: mind.rightNodeCount - 1 });
|
|
1628
1640
|
}
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
let newProperties = effectedAbstracts.get(correspondingAbstract);
|
|
1632
|
-
if (!newProperties) {
|
|
1633
|
-
newProperties = { start: 0, end: 0 };
|
|
1634
|
-
effectedAbstracts.set(correspondingAbstract, newProperties);
|
|
1635
|
-
}
|
|
1636
|
-
newProperties.end = newProperties.end - 1;
|
|
1641
|
+
else {
|
|
1642
|
+
effectedRightNodeCount[index].rightNodeCount -= 1;
|
|
1637
1643
|
}
|
|
1638
1644
|
}
|
|
1639
1645
|
});
|
|
1640
|
-
return
|
|
1646
|
+
return effectedRightNodeCount;
|
|
1641
1647
|
};
|
|
1642
1648
|
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
(
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1649
|
+
/**
|
|
1650
|
+
* get correctly layout:
|
|
1651
|
+
* 1. root is standard -> left or right
|
|
1652
|
+
* 2. correct layout by incorrect layout direction
|
|
1653
|
+
* @param element
|
|
1654
|
+
*/
|
|
1655
|
+
const getCorrectLayoutByElement = (board, element) => {
|
|
1656
|
+
const ancestors = MindElement.getAncestors(board, element);
|
|
1657
|
+
ancestors.unshift(element);
|
|
1658
|
+
const root = ancestors[ancestors.length - 1];
|
|
1659
|
+
let rootLayout = getRootLayout(root);
|
|
1660
|
+
if (PlaitMind.isMind(element)) {
|
|
1661
|
+
return rootLayout;
|
|
1662
|
+
}
|
|
1663
|
+
const node = MindElement.getNode(element);
|
|
1664
|
+
let correctRootLayout = rootLayout;
|
|
1665
|
+
if (rootLayout === MindLayoutType.standard) {
|
|
1666
|
+
correctRootLayout = node.left ? MindLayoutType.left : MindLayoutType.right;
|
|
1667
|
+
}
|
|
1668
|
+
let layout = null;
|
|
1669
|
+
const elementWithLayout = ancestors.find(value => value.layout || AbstractNode.isAbstract(value));
|
|
1670
|
+
if (elementWithLayout) {
|
|
1671
|
+
if (AbstractNode.isAbstract(elementWithLayout)) {
|
|
1672
|
+
const parent = MindElement.getParent(elementWithLayout);
|
|
1673
|
+
const parentLayout = getCorrectLayoutByElement(board, parent);
|
|
1674
|
+
layout = getAbstractLayout(parentLayout);
|
|
1663
1675
|
}
|
|
1664
1676
|
else {
|
|
1665
|
-
|
|
1666
|
-
...abstractRectangle,
|
|
1667
|
-
height: location - abstractRectangle.y
|
|
1668
|
-
};
|
|
1677
|
+
layout = elementWithLayout?.layout;
|
|
1669
1678
|
}
|
|
1670
1679
|
}
|
|
1680
|
+
if (layout === MindLayoutType.standard || !layout) {
|
|
1681
|
+
return correctRootLayout;
|
|
1682
|
+
}
|
|
1671
1683
|
else {
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
x: location,
|
|
1676
|
-
width: abstractRectangle.width + abstractRectangle.x - location
|
|
1677
|
-
};
|
|
1684
|
+
const incorrectDirection = getInCorrectLayoutDirection(correctRootLayout, layout);
|
|
1685
|
+
if (incorrectDirection) {
|
|
1686
|
+
return correctLayoutByDirection(layout, incorrectDirection);
|
|
1678
1687
|
}
|
|
1679
1688
|
else {
|
|
1680
|
-
return
|
|
1681
|
-
...abstractRectangle,
|
|
1682
|
-
width: location - abstractRectangle.x
|
|
1683
|
-
};
|
|
1689
|
+
return layout;
|
|
1684
1690
|
}
|
|
1685
1691
|
}
|
|
1686
1692
|
};
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
const
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
const { end } = getCorrectStartEnd(node, parent);
|
|
1699
|
-
return end;
|
|
1700
|
-
})
|
|
1701
|
-
.sort((a, b) => b - a)[0];
|
|
1702
|
-
minNode = parentChildren[index + 1];
|
|
1693
|
+
|
|
1694
|
+
const getBranchLayouts = (board, element) => {
|
|
1695
|
+
const layouts = [];
|
|
1696
|
+
if (element.layout) {
|
|
1697
|
+
// TODO: getCorrectLayoutByElement 含有递归操作,getBranchLayouts 本身也有递归操作,有待优化
|
|
1698
|
+
layouts.unshift(getCorrectLayoutByElement(board, element));
|
|
1699
|
+
}
|
|
1700
|
+
let parent = MindElement.findParent(element);
|
|
1701
|
+
while (parent) {
|
|
1702
|
+
if (parent.layout) {
|
|
1703
|
+
layouts.unshift(parent.layout);
|
|
1703
1704
|
}
|
|
1704
|
-
|
|
1705
|
-
|
|
1705
|
+
parent = MindElement.findParent(parent);
|
|
1706
|
+
}
|
|
1707
|
+
return layouts;
|
|
1708
|
+
};
|
|
1709
|
+
|
|
1710
|
+
const getAvailableSubLayoutsByElement = (board, element) => {
|
|
1711
|
+
const parentElement = MindElement.findParent(element);
|
|
1712
|
+
if (parentElement) {
|
|
1713
|
+
const branchLayouts = getBranchLayouts(board, parentElement);
|
|
1714
|
+
if (branchLayouts[0] === MindLayoutType.standard) {
|
|
1715
|
+
const node = MindElement.getNode(element);
|
|
1716
|
+
branchLayouts[0] = node.left ? MindLayoutType.left : MindLayoutType.right;
|
|
1706
1717
|
}
|
|
1707
|
-
const
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1718
|
+
const currentLayoutDirections = getBranchDirectionsByLayouts(branchLayouts);
|
|
1719
|
+
let availableSubLayouts = getAvailableSubLayoutsByLayoutDirections(currentLayoutDirections);
|
|
1720
|
+
const parentLayout = [branchLayouts[branchLayouts.length - 1]];
|
|
1721
|
+
const parentDirections = getBranchDirectionsByLayouts(parentLayout);
|
|
1722
|
+
const parentAvailableSubLayouts = getAvailableSubLayoutsByLayoutDirections(parentDirections);
|
|
1723
|
+
availableSubLayouts = availableSubLayouts.filter(layout => parentAvailableSubLayouts.some(parentAvailableSubLayout => parentAvailableSubLayout === layout));
|
|
1724
|
+
return availableSubLayouts;
|
|
1725
|
+
}
|
|
1726
|
+
return undefined;
|
|
1727
|
+
};
|
|
1728
|
+
|
|
1729
|
+
const getLayoutByElement = (element) => {
|
|
1730
|
+
const layout = element.layout;
|
|
1731
|
+
if (layout) {
|
|
1732
|
+
return layout;
|
|
1733
|
+
}
|
|
1734
|
+
const parent = !PlaitMind.isMind(element) && MindElement.getParent(element);
|
|
1735
|
+
if (AbstractNode.isAbstract(element) && parent) {
|
|
1736
|
+
return getAbstractLayout(getLayoutByElement(parent));
|
|
1737
|
+
}
|
|
1738
|
+
if (parent) {
|
|
1739
|
+
return getLayoutByElement(parent);
|
|
1740
|
+
}
|
|
1741
|
+
return getDefaultLayout();
|
|
1742
|
+
};
|
|
1743
|
+
|
|
1744
|
+
const MindQueries = {
|
|
1745
|
+
getAvailableSubLayoutsByElement,
|
|
1746
|
+
getBranchLayouts,
|
|
1747
|
+
getLayoutByElement,
|
|
1748
|
+
getCorrectLayoutByElement
|
|
1749
|
+
};
|
|
1750
|
+
|
|
1751
|
+
const PlaitMind = {
|
|
1752
|
+
isMind: (value) => {
|
|
1753
|
+
return value.type === 'mindmap';
|
|
1754
|
+
}
|
|
1755
|
+
};
|
|
1756
|
+
const MindElement = {
|
|
1757
|
+
hasLayout(value, layout) {
|
|
1758
|
+
const _layout = MindQueries.getLayoutByElement(value);
|
|
1759
|
+
return _layout === layout;
|
|
1760
|
+
},
|
|
1761
|
+
isIndentedLayout(value) {
|
|
1762
|
+
const _layout = MindQueries.getLayoutByElement(value);
|
|
1763
|
+
return isIndentedLayout(_layout);
|
|
1764
|
+
},
|
|
1765
|
+
isMindElement(board, element) {
|
|
1766
|
+
const path = PlaitBoard.findPath(board, element);
|
|
1767
|
+
const rootElement = PlaitNode.get(board, path.slice(0, 1));
|
|
1768
|
+
if (PlaitMind.isMind(rootElement)) {
|
|
1769
|
+
return true;
|
|
1714
1770
|
}
|
|
1715
1771
|
else {
|
|
1716
|
-
return
|
|
1717
|
-
max: endNodeRectangle.x - ABSTRACT_INCLUDED_OUTLINE_OFFSET,
|
|
1718
|
-
min: minNodeRectangle.x - ABSTRACT_INCLUDED_OUTLINE_OFFSET
|
|
1719
|
-
};
|
|
1772
|
+
return false;
|
|
1720
1773
|
}
|
|
1721
|
-
}
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1774
|
+
},
|
|
1775
|
+
getParent(node) {
|
|
1776
|
+
if (PlaitMind.isMind(node)) {
|
|
1777
|
+
throw new Error('mind root node can not get parent');
|
|
1778
|
+
}
|
|
1779
|
+
const parent = NODE_TO_PARENT.get(node);
|
|
1780
|
+
return parent;
|
|
1781
|
+
},
|
|
1782
|
+
findParent(node) {
|
|
1783
|
+
if (PlaitMind.isMind(node)) {
|
|
1784
|
+
return undefined;
|
|
1785
|
+
}
|
|
1786
|
+
const parent = NODE_TO_PARENT.get(node);
|
|
1787
|
+
return parent;
|
|
1788
|
+
},
|
|
1789
|
+
getRoot(board, element) {
|
|
1790
|
+
const path = PlaitBoard.findPath(board, element);
|
|
1791
|
+
return PlaitNode.get(board, path.slice(0, 1));
|
|
1792
|
+
},
|
|
1793
|
+
getAncestors(board, element) {
|
|
1794
|
+
const path = PlaitBoard.findPath(board, element);
|
|
1795
|
+
const parents = [];
|
|
1796
|
+
for (const p of Path.ancestors(path, { reverse: true })) {
|
|
1797
|
+
const n = PlaitNode.get(board, p);
|
|
1798
|
+
if (n && !PlaitBoard.isBoard(n)) {
|
|
1799
|
+
parents.push(n);
|
|
1800
|
+
}
|
|
1733
1801
|
}
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1802
|
+
return parents;
|
|
1803
|
+
},
|
|
1804
|
+
getNode(element) {
|
|
1805
|
+
const node = ELEMENT_TO_NODE.get(element);
|
|
1806
|
+
if (!node) {
|
|
1807
|
+
throw new Error(`can not get node from ${JSON.stringify(element)}`);
|
|
1737
1808
|
}
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1809
|
+
return node;
|
|
1810
|
+
},
|
|
1811
|
+
findParentNode(element) {
|
|
1812
|
+
if (PlaitMind.isMind(element)) {
|
|
1813
|
+
return undefined;
|
|
1814
|
+
}
|
|
1815
|
+
const parent = MindElement.getParent(element);
|
|
1816
|
+
return MindElement.getNode(parent);
|
|
1817
|
+
},
|
|
1818
|
+
hasEmojis(element) {
|
|
1819
|
+
if (element.data.emojis) {
|
|
1820
|
+
return true;
|
|
1745
1821
|
}
|
|
1746
1822
|
else {
|
|
1747
|
-
return
|
|
1748
|
-
max: maxNodeRectangle.x + maxNodeRectangle.width + ABSTRACT_INCLUDED_OUTLINE_OFFSET,
|
|
1749
|
-
min: startNodeRectangle.x + startNodeRectangle.width + ABSTRACT_INCLUDED_OUTLINE_OFFSET
|
|
1750
|
-
};
|
|
1823
|
+
return false;
|
|
1751
1824
|
}
|
|
1825
|
+
},
|
|
1826
|
+
getEmojis(element) {
|
|
1827
|
+
return element.data.emojis;
|
|
1752
1828
|
}
|
|
1753
1829
|
};
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
}
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
if (position === AbstractHandlePosition.start) {
|
|
1773
|
-
const location = isHorizontal ? rectangle.y : rectangle.x;
|
|
1774
|
-
result = getRectangleByResizingLocation(rectangle, location + ABSTRACT_HANDLE_MASK_WIDTH / 2, AbstractHandlePosition.end, isHorizontal);
|
|
1775
|
-
result = getRectangleByResizingLocation(result, location - ABSTRACT_HANDLE_MASK_WIDTH / 2, position, isHorizontal);
|
|
1830
|
+
var MindElementShape;
|
|
1831
|
+
(function (MindElementShape) {
|
|
1832
|
+
MindElementShape["roundRectangle"] = "round-rectangle";
|
|
1833
|
+
MindElementShape["underline"] = "underline";
|
|
1834
|
+
})(MindElementShape || (MindElementShape = {}));
|
|
1835
|
+
var BranchShape;
|
|
1836
|
+
(function (BranchShape) {
|
|
1837
|
+
BranchShape["bight"] = "bight";
|
|
1838
|
+
BranchShape["polyline"] = "polyline";
|
|
1839
|
+
})(BranchShape || (BranchShape = {}));
|
|
1840
|
+
|
|
1841
|
+
const NodeDefaultSpace = {
|
|
1842
|
+
horizontal: {
|
|
1843
|
+
nodeAndText: BASE * 3,
|
|
1844
|
+
emojiAndText: BASE * 1.5
|
|
1845
|
+
},
|
|
1846
|
+
vertical: {
|
|
1847
|
+
nodeAndText: BASE * 1.5
|
|
1776
1848
|
}
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1849
|
+
};
|
|
1850
|
+
const RootDefaultSpace = {
|
|
1851
|
+
horizontal: {
|
|
1852
|
+
nodeAndText: BASE * 4,
|
|
1853
|
+
emojiAndText: BASE * 2
|
|
1854
|
+
},
|
|
1855
|
+
vertical: {
|
|
1856
|
+
nodeAndText: BASE * 2
|
|
1781
1857
|
}
|
|
1782
|
-
return result;
|
|
1783
1858
|
};
|
|
1784
|
-
|
|
1785
|
-
const
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
const
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
const recXOrY = isHorizontal ? recArray[i].y : recArray[i].x;
|
|
1809
|
-
const recWidthOrHeight = isHorizontal ? recArray[i].height : recArray[i].width;
|
|
1810
|
-
if (location >= recXOrY + recWidthOrHeight / 2 &&
|
|
1811
|
-
location <= recArray[i + 1][isHorizontal ? 'y' : 'x'] + recArray[i + 1][isHorizontal ? 'height' : 'width'] / 2) {
|
|
1812
|
-
return i - 1;
|
|
1859
|
+
const getHorizontalSpaceBetweenNodeAndText = (board, element) => {
|
|
1860
|
+
const isMind = PlaitMind.isMind(element);
|
|
1861
|
+
const nodeAndText = isMind ? RootDefaultSpace.horizontal.nodeAndText : NodeDefaultSpace.horizontal.nodeAndText;
|
|
1862
|
+
return nodeAndText;
|
|
1863
|
+
};
|
|
1864
|
+
const getVerticalSpaceBetweenNodeAndText = (element) => {
|
|
1865
|
+
const isMind = PlaitMind.isMind(element);
|
|
1866
|
+
const nodeAndText = isMind ? RootDefaultSpace.vertical.nodeAndText : NodeDefaultSpace.vertical.nodeAndText;
|
|
1867
|
+
return nodeAndText;
|
|
1868
|
+
};
|
|
1869
|
+
const getSpaceEmojiAndText = (element) => {
|
|
1870
|
+
const isMind = PlaitMind.isMind(element);
|
|
1871
|
+
const emojiAndText = isMind ? RootDefaultSpace.horizontal.emojiAndText : NodeDefaultSpace.horizontal.emojiAndText;
|
|
1872
|
+
return emojiAndText;
|
|
1873
|
+
};
|
|
1874
|
+
const NodeSpace = {
|
|
1875
|
+
getNodeWidth(board, element) {
|
|
1876
|
+
const nodeAndText = getHorizontalSpaceBetweenNodeAndText(board, element);
|
|
1877
|
+
if (MindElement.hasEmojis(element)) {
|
|
1878
|
+
return (NodeSpace.getEmojiLeftSpace(board, element) +
|
|
1879
|
+
getEmojisWidthHeight(board, element).width +
|
|
1880
|
+
getSpaceEmojiAndText(element) +
|
|
1881
|
+
element.width +
|
|
1882
|
+
nodeAndText);
|
|
1813
1883
|
}
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
});
|
|
1825
|
-
if (touchedAbstract === abstract) {
|
|
1826
|
-
return touchedAbstract;
|
|
1827
|
-
}
|
|
1828
|
-
if (touchedAbstract) {
|
|
1829
|
-
const component = PlaitElement.getComponent(touchedAbstract);
|
|
1830
|
-
component.updateAbstractIncludedOutline();
|
|
1831
|
-
touchedAbstract = undefined;
|
|
1832
|
-
}
|
|
1833
|
-
if (abstract) {
|
|
1834
|
-
touchedAbstract = abstract;
|
|
1835
|
-
const component = PlaitElement.getComponent(touchedAbstract);
|
|
1836
|
-
component.updateAbstractIncludedOutline(touchedHandle);
|
|
1837
|
-
}
|
|
1838
|
-
return touchedAbstract;
|
|
1839
|
-
}
|
|
1840
|
-
|
|
1841
|
-
function drawIndentedLink(board, node, child, defaultStroke = null, needDrawUnderline = true, defaultStrokeWidth) {
|
|
1842
|
-
const branchWidth = defaultStrokeWidth || getBranchWidthByMindElement(board, child.origin);
|
|
1843
|
-
const branchColor = defaultStroke || getBranchColorByMindElement(board, child.origin);
|
|
1844
|
-
const isUnderlineShape = getShapeByElement(board, child.origin) === MindElementShape.underline;
|
|
1845
|
-
let beginX, beginY, endX, endY, beginNode = node, endNode = child;
|
|
1846
|
-
const beginRectangle = getRectangleByNode(beginNode);
|
|
1847
|
-
const endRectangle = getRectangleByNode(endNode);
|
|
1848
|
-
beginX = beginNode.x + beginNode.width / 2;
|
|
1849
|
-
beginY = isChildUp(node, child) ? beginRectangle.y : beginRectangle.y + beginRectangle.height;
|
|
1850
|
-
endX = node.left ? endNode.x + endNode.hGap + endRectangle.width : endNode.x + endNode.hGap;
|
|
1851
|
-
endY = isUnderlineShape ? endNode.y + endNode.height - endNode.vGap : endNode.y + endNode.height / 2;
|
|
1852
|
-
//根据位置,设置正负参数
|
|
1853
|
-
let plusMinus = isChildUp(node, child) ? (node.left ? [-1, -1] : [1, -1]) : node.left ? [-1, 1] : [1, 1];
|
|
1854
|
-
const layout = MindQueries.getCorrectLayoutByElement(board, node.origin);
|
|
1855
|
-
if (beginNode.origin.isRoot) {
|
|
1856
|
-
if (layout === MindLayoutType.leftBottomIndented || layout === MindLayoutType.rightBottomIndented) {
|
|
1857
|
-
beginY += branchWidth;
|
|
1884
|
+
return nodeAndText + element.width + nodeAndText;
|
|
1885
|
+
},
|
|
1886
|
+
getNodeHeight(board, element) {
|
|
1887
|
+
const nodeAndText = getVerticalSpaceBetweenNodeAndText(element);
|
|
1888
|
+
return nodeAndText + element.height + nodeAndText;
|
|
1889
|
+
},
|
|
1890
|
+
getTextLeftSpace(board, element) {
|
|
1891
|
+
const nodeAndText = getHorizontalSpaceBetweenNodeAndText(board, element);
|
|
1892
|
+
if (MindElement.hasEmojis(element)) {
|
|
1893
|
+
return NodeSpace.getEmojiLeftSpace(board, element) + getEmojisWidthHeight(board, element).width + getSpaceEmojiAndText(element);
|
|
1858
1894
|
}
|
|
1859
|
-
|
|
1860
|
-
|
|
1895
|
+
else {
|
|
1896
|
+
return nodeAndText;
|
|
1861
1897
|
}
|
|
1898
|
+
},
|
|
1899
|
+
getTextTopSpace(element) {
|
|
1900
|
+
const nodeAndText = getVerticalSpaceBetweenNodeAndText(element);
|
|
1901
|
+
return nodeAndText;
|
|
1902
|
+
},
|
|
1903
|
+
getEmojiLeftSpace(board, element) {
|
|
1904
|
+
const options = board.getMindOptions();
|
|
1905
|
+
const nodeAndText = getHorizontalSpaceBetweenNodeAndText(board, element);
|
|
1906
|
+
return nodeAndText - options.emojiPadding;
|
|
1907
|
+
},
|
|
1908
|
+
getEmojiTopSpace(element) {
|
|
1909
|
+
const nodeAndText = getVerticalSpaceBetweenNodeAndText(element);
|
|
1910
|
+
return nodeAndText;
|
|
1862
1911
|
}
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
const points = pointsOnBezierCurves(curve);
|
|
1876
|
-
return PlaitBoard.getRoughSVG(board).curve(points, { stroke: branchColor, strokeWidth: branchWidth });
|
|
1912
|
+
};
|
|
1913
|
+
|
|
1914
|
+
function getTopicRectangleByNode(board, node) {
|
|
1915
|
+
let nodeRectangle = getRectangleByNode(node);
|
|
1916
|
+
return getTopicRectangleByElement(board, nodeRectangle, node.origin);
|
|
1917
|
+
}
|
|
1918
|
+
function getTopicRectangleByElement(board, nodeRectangle, element) {
|
|
1919
|
+
const x = nodeRectangle.x + NodeSpace.getTextLeftSpace(board, element);
|
|
1920
|
+
const y = nodeRectangle.y + NodeSpace.getTextTopSpace(element);
|
|
1921
|
+
const width = Math.ceil(element.width);
|
|
1922
|
+
const height = Math.ceil(element.height);
|
|
1923
|
+
return { height, width, x, y };
|
|
1877
1924
|
}
|
|
1878
1925
|
|
|
1879
1926
|
function drawTopicByNode(board, node, viewContainerRef) {
|
|
@@ -1910,6 +1957,7 @@ function drawAbstractLink(board, node, isHorizontal) {
|
|
|
1910
1957
|
const branchWidth = getAbstractBranchWidth(board, node.origin);
|
|
1911
1958
|
const branchColor = getAbstractBranchColor(board, node.origin);
|
|
1912
1959
|
const parent = node.parent;
|
|
1960
|
+
const branchShape = getBranchShapeByMindElement(board, parent.origin);
|
|
1913
1961
|
const abstractRectangle = getRectangleByNode(node);
|
|
1914
1962
|
let includedElements = parent.children.slice(node.origin.start, node.origin.end + 1).map(node => {
|
|
1915
1963
|
return node.origin;
|
|
@@ -1931,6 +1979,20 @@ function drawAbstractLink(board, node, isHorizontal) {
|
|
|
1931
1979
|
bezierEndPoint = moveXOfPoint(bezierEndPoint, linkPadding, linkDirection);
|
|
1932
1980
|
let c2 = moveXOfPoint(bezierEndPoint, curveDistance, linkDirection);
|
|
1933
1981
|
let bezierConnectorPoint = moveXOfPoint(abstractConnectorPoint, -linkPadding, linkDirection);
|
|
1982
|
+
if (branchShape === BranchShape.polyline) {
|
|
1983
|
+
const g = createG();
|
|
1984
|
+
const polyline = drawLinearPath([bezierBeginPoint, c1, bezierConnectorPoint, c2, bezierEndPoint], {
|
|
1985
|
+
stroke: branchColor,
|
|
1986
|
+
strokeWidth: branchWidth
|
|
1987
|
+
});
|
|
1988
|
+
const straightLine = drawLinearPath([abstractConnectorPoint, bezierConnectorPoint], {
|
|
1989
|
+
stroke: branchColor,
|
|
1990
|
+
strokeWidth: branchWidth
|
|
1991
|
+
});
|
|
1992
|
+
g.appendChild(polyline);
|
|
1993
|
+
g.appendChild(straightLine);
|
|
1994
|
+
return g;
|
|
1995
|
+
}
|
|
1934
1996
|
const link = PlaitBoard.getRoughSVG(board).path(`M${bezierBeginPoint[0]},${bezierBeginPoint[1]} Q${c1[0]},${c1[1]} ${bezierConnectorPoint[0]},${bezierConnectorPoint[1]} Q${c2[0]},${c2[1]} ${bezierEndPoint[0]},${bezierEndPoint[1]} M${abstractConnectorPoint[0]},${abstractConnectorPoint[1]} L${bezierConnectorPoint[0]},${bezierConnectorPoint[1]}`, {
|
|
1935
1997
|
stroke: branchColor,
|
|
1936
1998
|
strokeWidth: branchWidth
|
|
@@ -2115,16 +2177,14 @@ const setTopicSize = (board, element, width, height) => {
|
|
|
2115
2177
|
Transforms.setNode(board, newElement, path);
|
|
2116
2178
|
};
|
|
2117
2179
|
const removeElements = (board, elements) => {
|
|
2118
|
-
const deletableElements = getFirstLevelElement(elements)
|
|
2119
|
-
//翻转,从下到上修改,防止找不到 path
|
|
2180
|
+
const deletableElements = getFirstLevelElement(elements);
|
|
2120
2181
|
deletableElements
|
|
2121
2182
|
.map(element => {
|
|
2122
2183
|
const path = PlaitBoard.findPath(board, element);
|
|
2184
|
+
const ref = board.pathRef(path);
|
|
2123
2185
|
return () => {
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
}
|
|
2127
|
-
Transforms.removeNode(board, path);
|
|
2186
|
+
Transforms.removeNode(board, ref.current);
|
|
2187
|
+
ref.unref();
|
|
2128
2188
|
};
|
|
2129
2189
|
})
|
|
2130
2190
|
.forEach(action => {
|
|
@@ -2153,6 +2213,11 @@ const insertAbstractNodes = (board, validAbstractRefs, elements, path) => {
|
|
|
2153
2213
|
});
|
|
2154
2214
|
insertNodes(board, abstracts, abstractPath);
|
|
2155
2215
|
};
|
|
2216
|
+
const setRightNodeCountByRefs = (board, refs) => {
|
|
2217
|
+
refs.forEach(ref => {
|
|
2218
|
+
Transforms.setNode(board, { rightNodeCount: ref.rightNodeCount }, ref.path);
|
|
2219
|
+
});
|
|
2220
|
+
};
|
|
2156
2221
|
|
|
2157
2222
|
const addEmoji = (board, element, emojiItem) => {
|
|
2158
2223
|
const emojis = element.data.emojis || [];
|
|
@@ -2202,7 +2267,8 @@ const MindTransforms = {
|
|
|
2202
2267
|
setAbstractByStandardLayout,
|
|
2203
2268
|
removeElements,
|
|
2204
2269
|
insertNodes,
|
|
2205
|
-
insertAbstractNodes
|
|
2270
|
+
insertAbstractNodes,
|
|
2271
|
+
setRightNodeCountByRefs
|
|
2206
2272
|
};
|
|
2207
2273
|
|
|
2208
2274
|
function drawAbstractIncludedOutline(board, roughSVG, element, activeHandlePosition, resizingLocation) {
|
|
@@ -2608,11 +2674,8 @@ class MindNodeComponent extends PlaitPluginElementComponent {
|
|
|
2608
2674
|
if (AbstractNode.isAbstract(this.node.origin)) {
|
|
2609
2675
|
this.linkG = drawAbstractLink(this.board, this.node, isHorizontalLayout(layout));
|
|
2610
2676
|
}
|
|
2611
|
-
else if (MindElement.isIndentedLayout(parent)) {
|
|
2612
|
-
this.linkG = drawIndentedLink(this.board, parentNode, this.node);
|
|
2613
|
-
}
|
|
2614
2677
|
else {
|
|
2615
|
-
this.linkG =
|
|
2678
|
+
this.linkG = drawLink(this.board, parentNode, this.node, isHorizontalLayout(layout));
|
|
2616
2679
|
}
|
|
2617
2680
|
this.g.append(this.linkG);
|
|
2618
2681
|
}
|
|
@@ -3011,8 +3074,8 @@ class MindNodeComponent extends PlaitPluginElementComponent {
|
|
|
3011
3074
|
}
|
|
3012
3075
|
}
|
|
3013
3076
|
}
|
|
3014
|
-
MindNodeComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.
|
|
3015
|
-
MindNodeComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.
|
|
3077
|
+
MindNodeComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: MindNodeComponent, deps: [{ token: i0.ViewContainerRef }, { token: i0.ChangeDetectorRef }, { token: i0.Renderer2 }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
|
|
3078
|
+
MindNodeComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.5", type: MindNodeComponent, selector: "plait-mind-node", usesInheritance: true, ngImport: i0, template: `
|
|
3016
3079
|
<plait-children
|
|
3017
3080
|
*ngIf="!element.isCollapsed"
|
|
3018
3081
|
[board]="board"
|
|
@@ -3021,7 +3084,7 @@ MindNodeComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", vers
|
|
|
3021
3084
|
[parentG]="parentG"
|
|
3022
3085
|
></plait-children>
|
|
3023
3086
|
`, isInline: true, dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.PlaitChildrenElement, selector: "plait-children", inputs: ["board", "parent", "effect", "parentG"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3024
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.
|
|
3087
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: MindNodeComponent, decorators: [{
|
|
3025
3088
|
type: Component,
|
|
3026
3089
|
args: [{
|
|
3027
3090
|
selector: 'plait-mind-node',
|
|
@@ -3131,11 +3194,11 @@ class PlaitMindComponent extends MindNodeComponent {
|
|
|
3131
3194
|
});
|
|
3132
3195
|
}
|
|
3133
3196
|
}
|
|
3134
|
-
PlaitMindComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.
|
|
3135
|
-
PlaitMindComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.
|
|
3197
|
+
PlaitMindComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: PlaitMindComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
3198
|
+
PlaitMindComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.5", type: PlaitMindComponent, selector: "plait-mind", usesInheritance: true, ngImport: i0, template: `
|
|
3136
3199
|
<plait-children [board]="board" [parent]="element" [effect]="effect" [parentG]="rootG"></plait-children>
|
|
3137
3200
|
`, isInline: true, dependencies: [{ kind: "component", type: i2.PlaitChildrenElement, selector: "plait-children", inputs: ["board", "parent", "effect", "parentG"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3138
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.
|
|
3201
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: PlaitMindComponent, decorators: [{
|
|
3139
3202
|
type: Component,
|
|
3140
3203
|
args: [{
|
|
3141
3204
|
selector: 'plait-mind',
|
|
@@ -3148,10 +3211,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
|
|
|
3148
3211
|
|
|
3149
3212
|
class MindModule {
|
|
3150
3213
|
}
|
|
3151
|
-
MindModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.
|
|
3152
|
-
MindModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.
|
|
3153
|
-
MindModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.
|
|
3154
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.
|
|
3214
|
+
MindModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: MindModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
3215
|
+
MindModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.5", ngImport: i0, type: MindModule, declarations: [PlaitMindComponent, MindNodeComponent], imports: [CommonModule, RichtextModule, PlaitModule], exports: [PlaitMindComponent, MindNodeComponent] });
|
|
3216
|
+
MindModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: MindModule, imports: [CommonModule, RichtextModule, PlaitModule] });
|
|
3217
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: MindModule, decorators: [{
|
|
3155
3218
|
type: NgModule,
|
|
3156
3219
|
args: [{
|
|
3157
3220
|
declarations: [PlaitMindComponent, MindNodeComponent],
|
|
@@ -3220,7 +3283,7 @@ const withDnd = (board) => {
|
|
|
3220
3283
|
dropTarget = detectDropTarget(board, detectPoint, dropTarget, [...activeElements, ...correspondingElements]);
|
|
3221
3284
|
if (dropTarget?.target) {
|
|
3222
3285
|
targetPath = getPathByDropTarget(board, dropTarget);
|
|
3223
|
-
fakeDropNodeG =
|
|
3286
|
+
fakeDropNodeG = drawFakeDropNode(board, dropTarget.target, targetPath);
|
|
3224
3287
|
PlaitBoard.getHost(board).appendChild(fakeDropNodeG);
|
|
3225
3288
|
}
|
|
3226
3289
|
const offsetX = endPoint[0] - startPoint[0];
|
|
@@ -3263,6 +3326,14 @@ const withDnd = (board) => {
|
|
|
3263
3326
|
const effectedAbstracts = deleteElementHandleAbstract(board, elements);
|
|
3264
3327
|
insertElementHandleAbstract(board, targetPath, normalElements.length, false, effectedAbstracts);
|
|
3265
3328
|
MindTransforms.setAbstractsByRefs(board, effectedAbstracts);
|
|
3329
|
+
let refs = deleteElementsHandleRightNodeCount(board, elements);
|
|
3330
|
+
const shouldChangeRoot = isInRightBranchOfStandardLayout(dropTarget?.target) &&
|
|
3331
|
+
targetElementPathRef.current &&
|
|
3332
|
+
(Path.isSibling(targetPath, targetElementPathRef.current) || Path.equals(targetPath, targetElementPathRef.current));
|
|
3333
|
+
if (shouldChangeRoot && targetElementPathRef.current) {
|
|
3334
|
+
refs = insertElementHandleRightNodeCount(board, targetElementPathRef.current.slice(0, 1), normalElements.length, refs);
|
|
3335
|
+
}
|
|
3336
|
+
MindTransforms.setRightNodeCountByRefs(board, refs);
|
|
3266
3337
|
MindTransforms.removeElements(board, elements);
|
|
3267
3338
|
let insertPath = targetPathRef.current;
|
|
3268
3339
|
const parentPath = Path.parent(targetPathRef.current || targetPath);
|
|
@@ -3275,12 +3346,6 @@ const withDnd = (board) => {
|
|
|
3275
3346
|
if (abstractRefs.length) {
|
|
3276
3347
|
MindTransforms.insertAbstractNodes(board, abstractRefs, normalElements, insertPath);
|
|
3277
3348
|
}
|
|
3278
|
-
const shouldChangeRoot = isInRightBranchOfStandardLayout(dropTarget?.target) &&
|
|
3279
|
-
targetElementPathRef.current &&
|
|
3280
|
-
(Path.isSibling(targetPath, targetElementPathRef.current) || Path.equals(targetPath, targetElementPathRef.current));
|
|
3281
|
-
if (shouldChangeRoot && targetElementPathRef.current) {
|
|
3282
|
-
changeRightNodeCount(board, targetElementPathRef.current.slice(0, 1), normalElements.length);
|
|
3283
|
-
}
|
|
3284
3349
|
if (targetElementPathRef.current &&
|
|
3285
3350
|
targetPathRef.current &&
|
|
3286
3351
|
Path.isAncestor(targetElementPathRef.current, targetPathRef.current) &&
|
|
@@ -3289,10 +3354,9 @@ const withDnd = (board) => {
|
|
|
3289
3354
|
}
|
|
3290
3355
|
targetElementPathRef.unref();
|
|
3291
3356
|
targetPathRef.unref();
|
|
3292
|
-
const selectedElements = getSelectedElements(board);
|
|
3293
3357
|
let setActiveElements = [];
|
|
3294
3358
|
depthFirstRecursion(board, node => {
|
|
3295
|
-
const isSelected =
|
|
3359
|
+
const isSelected = activeElements.some(element => element.id === node.id);
|
|
3296
3360
|
if (isSelected) {
|
|
3297
3361
|
setActiveElements.push(node);
|
|
3298
3362
|
}
|
|
@@ -3427,6 +3491,10 @@ const withAbstract = (board) => {
|
|
|
3427
3491
|
let startPoint;
|
|
3428
3492
|
let newProperty;
|
|
3429
3493
|
board.mousedown = (event) => {
|
|
3494
|
+
if (!isMainPointer(event)) {
|
|
3495
|
+
mousedown(event);
|
|
3496
|
+
return;
|
|
3497
|
+
}
|
|
3430
3498
|
const activeAbstractElements = getSelectedElements(board).filter(element => AbstractNode.isAbstract(element));
|
|
3431
3499
|
const host = BOARD_TO_HOST.get(board);
|
|
3432
3500
|
const point = transformPoint(board, toPoint(event.x, event.y, host));
|
|
@@ -3580,6 +3648,7 @@ const withCreateMind = (board) => {
|
|
|
3580
3648
|
const targetPoint = transformPoint(board, toPoint(movingPoint[0], movingPoint[1], PlaitBoard.getHost(board)));
|
|
3581
3649
|
const emptyMind = createEmptyMind(board, targetPoint);
|
|
3582
3650
|
Transforms.insertNode(board, emptyMind, [board.children.length]);
|
|
3651
|
+
addSelectedElement(board, emptyMind);
|
|
3583
3652
|
BoardTransforms.updatePointerType(board, PlaitPointerType.selection);
|
|
3584
3653
|
}
|
|
3585
3654
|
destroy();
|
|
@@ -3673,7 +3742,8 @@ const withMind = (board) => {
|
|
|
3673
3742
|
}
|
|
3674
3743
|
else {
|
|
3675
3744
|
if (isInRightBranchOfStandardLayout(selectedElement)) {
|
|
3676
|
-
|
|
3745
|
+
const refs = insertElementHandleRightNodeCount(board, selectedElementPath.slice(0, 1), 1);
|
|
3746
|
+
MindTransforms.setRightNodeCountByRefs(board, refs);
|
|
3677
3747
|
}
|
|
3678
3748
|
const abstractRefs = insertElementHandleAbstract(board, Path.next(selectedElementPath));
|
|
3679
3749
|
MindTransforms.setAbstractsByRefs(board, abstractRefs);
|
|
@@ -3686,6 +3756,8 @@ const withMind = (board) => {
|
|
|
3686
3756
|
const deletableElements = getFirstLevelElement(selectedElements).reverse();
|
|
3687
3757
|
const abstractRefs = deleteElementHandleAbstract(board, deletableElements);
|
|
3688
3758
|
MindTransforms.setAbstractsByRefs(board, abstractRefs);
|
|
3759
|
+
const refs = deleteElementsHandleRightNodeCount(board, selectedElements);
|
|
3760
|
+
MindTransforms.setRightNodeCountByRefs(board, refs);
|
|
3689
3761
|
MindTransforms.removeElements(board, selectedElements);
|
|
3690
3762
|
let activeElement;
|
|
3691
3763
|
const firstLevelElements = getFirstLevelElement(selectedElements);
|
|
@@ -3791,6 +3863,8 @@ const withMind = (board) => {
|
|
|
3791
3863
|
const deletableElements = getFirstLevelElement(selectedElements).reverse();
|
|
3792
3864
|
const abstractRefs = deleteElementHandleAbstract(board, deletableElements);
|
|
3793
3865
|
MindTransforms.setAbstractsByRefs(board, abstractRefs);
|
|
3866
|
+
const refs = deleteElementsHandleRightNodeCount(board, selectedElements);
|
|
3867
|
+
MindTransforms.setRightNodeCountByRefs(board, refs);
|
|
3794
3868
|
MindTransforms.removeElements(board, selectedElements);
|
|
3795
3869
|
deleteFragment(data);
|
|
3796
3870
|
};
|
|
@@ -3809,9 +3883,9 @@ class MindEmojiBaseComponent {
|
|
|
3809
3883
|
this.elementRef.nativeElement.style.fontSize = `${this.fontSize}px`;
|
|
3810
3884
|
}
|
|
3811
3885
|
}
|
|
3812
|
-
MindEmojiBaseComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.
|
|
3813
|
-
MindEmojiBaseComponent.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.
|
|
3814
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.
|
|
3886
|
+
MindEmojiBaseComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: MindEmojiBaseComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
|
|
3887
|
+
MindEmojiBaseComponent.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.5", type: MindEmojiBaseComponent, inputs: { fontSize: "fontSize", emojiItem: "emojiItem", board: "board", element: "element" }, host: { classAttribute: "mind-node-emoji" }, ngImport: i0 });
|
|
3888
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: MindEmojiBaseComponent, decorators: [{
|
|
3815
3889
|
type: Directive,
|
|
3816
3890
|
args: [{
|
|
3817
3891
|
host: {
|
|
@@ -3836,5 +3910,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
|
|
|
3836
3910
|
* Generated bundle index. Do not edit.
|
|
3837
3911
|
*/
|
|
3838
3912
|
|
|
3839
|
-
export { ABSTRACT_HANDLE_COLOR, ABSTRACT_HANDLE_LENGTH, ABSTRACT_HANDLE_MASK_WIDTH, ABSTRACT_INCLUDED_OUTLINE_OFFSET, AbstractHandlePosition, AbstractResizeState, BASE, BRANCH_COLORS, BRANCH_WIDTH, BaseDrawer, DefaultAbstractNodeStyle, DefaultNodeStyle, DefaultRootStyle, ELEMENT_TO_NODE, EXTEND_OFFSET, EXTEND_RADIUS, GRAY_COLOR, IS_DRAGGING, LayoutDirection, LayoutDirectionsMap, MindElement, MindElementShape, MindEmojiBaseComponent, MindModule, MindNode, MindNodeComponent, MindPointerType, MindQueries, MindTransforms, NODE_MIN_WIDTH, PRIMARY_COLOR, PlaitMind, PlaitMindComponent, QUICK_INSERT_CIRCLE_COLOR, QUICK_INSERT_CIRCLE_OFFSET, QUICK_INSERT_INNER_CROSS_COLOR, ROOT_TOPIC_FONT_SIZE, STROKE_WIDTH, TOPIC_COLOR, TOPIC_DEFAULT_MAX_WORD_COUNT, TOPIC_FONT_SIZE, TRANSPARENT, addActiveOnDragOrigin,
|
|
3913
|
+
export { ABSTRACT_HANDLE_COLOR, ABSTRACT_HANDLE_LENGTH, ABSTRACT_HANDLE_MASK_WIDTH, ABSTRACT_INCLUDED_OUTLINE_OFFSET, AbstractHandlePosition, AbstractResizeState, BASE, BRANCH_COLORS, BRANCH_WIDTH, BaseDrawer, BranchShape, DefaultAbstractNodeStyle, DefaultNodeStyle, DefaultRootStyle, ELEMENT_TO_NODE, EXTEND_OFFSET, EXTEND_RADIUS, GRAY_COLOR, IS_DRAGGING, LayoutDirection, LayoutDirectionsMap, MindElement, MindElementShape, MindEmojiBaseComponent, MindModule, MindNode, MindNodeComponent, MindPointerType, MindQueries, MindTransforms, NODE_MIN_WIDTH, PRIMARY_COLOR, PlaitMind, PlaitMindComponent, QUICK_INSERT_CIRCLE_COLOR, QUICK_INSERT_CIRCLE_OFFSET, QUICK_INSERT_INNER_CROSS_COLOR, ROOT_TOPIC_FONT_SIZE, STROKE_WIDTH, TOPIC_COLOR, TOPIC_DEFAULT_MAX_WORD_COUNT, TOPIC_FONT_SIZE, TRANSPARENT, addActiveOnDragOrigin, adjustAbstractToNode, adjustNodeToRoot, adjustRootToNode, canSetAbstract, copyNewNode, correctLayoutByDirection, createDefaultMind, createEmptyMind, createMindElement, deleteElementHandleAbstract, deleteElementsHandleRightNodeCount, detectDropTarget, directionCorrector, directionDetector, divideElementByParent, drawFakeDragNode, drawFakeDropNode, enterNodeEditing, extractNodesText, findLastChild, findLocationLeftIndex, getAbstractBranchColor, getAbstractBranchWidth, getAbstractHandleRectangle, getAllowedDirection, getAvailableSubLayoutsByLayoutDirections, getBehindAbstracts, getBranchColorByMindElement, getBranchDirectionsByLayouts, getBranchShapeByMindElement, getBranchWidthByMindElement, getChildrenCount, getCorrespondingAbstract, getDefaultBranchColor, getDefaultBranchColorByIndex, getDefaultLayout, getEmojiForeignRectangle, getEmojiRectangle, getFirstLevelElement, getHitAbstractHandle, getInCorrectLayoutDirection, getLayoutDirection$1 as getLayoutDirection, getLayoutReverseDirection, getLocationScope, getNextBranchColor, getOverallAbstracts, getPathByDropTarget, getRectangleByElement, getRectangleByNode, getRectangleByResizingLocation, getRelativeStartEndByAbstractRef, getRootLayout, getShapeByElement, getStrokeByMindElement, getTopicRectangleByElement, getTopicRectangleByNode, getValidAbstractRefs, handleTouchedAbstract, hasAfterDraw, hasPreviousOrNextOfDropPath, insertElementHandleAbstract, insertElementHandleRightNodeCount, insertMindElement, isChildElement, isChildRight, isChildUp, isCorrectLayout, isDragging, isHitEmojis, isHitMindElement, isInRightBranchOfStandardLayout, isMixedLayout, isSetAbstract, isValidTarget, isVirtualKey, readjustmentDropTarget, removeActiveOnDragOrigin, separateChildren, setIsDragging, withMind, withMindExtend };
|
|
3840
3914
|
//# sourceMappingURL=plait-mind.mjs.map
|