@plait/mind 0.2.0-next.8 → 0.2.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/constants/abstract-node.d.ts +4 -0
- package/constants/default.d.ts +1 -2
- package/constants/index.d.ts +4 -1
- package/constants/node-rule.d.ts +1 -0
- package/constants/node-style.d.ts +17 -0
- package/constants/node-topic-style.d.ts +4 -0
- package/draw/richtext.d.ts +1 -1
- package/esm2020/constants/abstract-node.mjs +5 -0
- package/esm2020/constants/default.mjs +2 -3
- package/esm2020/constants/index.mjs +5 -2
- package/esm2020/constants/node-rule.mjs +2 -0
- package/esm2020/constants/node-style.mjs +19 -0
- package/esm2020/constants/node-topic-style.mjs +5 -0
- package/esm2020/draw/abstract.mjs +4 -3
- package/esm2020/draw/indented-link.mjs +15 -15
- package/esm2020/draw/link/abstract-link.mjs +6 -4
- package/esm2020/draw/link/logic-link.mjs +10 -8
- package/esm2020/draw/link.mjs +8 -7
- package/esm2020/draw/richtext.mjs +10 -8
- package/esm2020/draw/shape.mjs +5 -5
- package/esm2020/drawer/quick-insert.drawer.mjs +13 -14
- package/esm2020/interfaces/abstract.mjs +1 -1
- package/esm2020/interfaces/element.mjs +20 -1
- package/esm2020/interfaces/node.mjs +1 -10
- package/esm2020/layout-option.mjs +3 -3
- package/esm2020/node.component.mjs +43 -34
- package/esm2020/plugins/emoji/emoji.drawer.mjs +4 -8
- package/esm2020/plugins/emoji/emoji.mjs +31 -3
- package/esm2020/plugins/with-abstract.mjs +2 -2
- package/esm2020/plugins/with-dnd.mjs +23 -123
- package/esm2020/plugins/with-mind.mjs +37 -29
- package/esm2020/queries/get-available-sublayouts-by-element.mjs +5 -10
- package/esm2020/queries/get-branch-layouts.mjs +7 -7
- package/esm2020/queries/get-correct-layout-by-element.mjs +28 -31
- package/esm2020/queries/get-layout-by-element.mjs +11 -9
- package/esm2020/queries/index.mjs +1 -3
- package/esm2020/transforms/abstract-node.mjs +68 -0
- package/esm2020/transforms/index.mjs +6 -2
- package/esm2020/transforms/layout.mjs +3 -3
- package/esm2020/transforms/node.mjs +2 -2
- package/esm2020/utils/abstract/common.mjs +90 -70
- package/esm2020/utils/abstract/resize.mjs +3 -3
- package/esm2020/utils/clipboard.mjs +54 -14
- package/esm2020/utils/direction-corrector.mjs +11 -11
- package/esm2020/utils/dnd.mjs +122 -0
- package/esm2020/utils/draw-placeholder.mjs +11 -9
- package/esm2020/utils/drop-target-corrector.mjs +11 -10
- package/esm2020/utils/index.mjs +1 -2
- package/esm2020/utils/layout.mjs +1 -1
- package/esm2020/utils/mind.mjs +30 -72
- package/esm2020/utils/node-space.mjs +23 -18
- package/esm2020/utils/node-style/branch.mjs +34 -20
- package/esm2020/utils/node-style/common.mjs +13 -0
- package/esm2020/utils/node-style/index.mjs +3 -2
- package/esm2020/utils/node-style/shape.mjs +21 -0
- package/esm2020/utils/path.mjs +4 -3
- package/fesm2015/plait-mind.mjs +862 -713
- package/fesm2015/plait-mind.mjs.map +1 -1
- package/fesm2020/plait-mind.mjs +865 -711
- package/fesm2020/plait-mind.mjs.map +1 -1
- package/interfaces/abstract.d.ts +3 -0
- package/interfaces/element.d.ts +7 -2
- package/interfaces/node.d.ts +0 -1
- package/node.component.d.ts +0 -1
- package/package.json +1 -1
- package/plugins/emoji/emoji.d.ts +5 -1
- package/plugins/with-dnd.d.ts +0 -9
- package/queries/get-available-sublayouts-by-element.d.ts +2 -6
- package/queries/get-branch-layouts.d.ts +2 -1
- package/queries/get-correct-layout-by-element.d.ts +2 -1
- package/queries/index.d.ts +3 -4
- package/styles/styles.scss +19 -19
- package/transforms/abstract-node.d.ts +6 -0
- package/transforms/index.d.ts +3 -0
- package/utils/abstract/common.d.ts +6 -8
- package/utils/direction-corrector.d.ts +2 -1
- package/utils/dnd.d.ts +16 -0
- package/utils/drop-target-corrector.d.ts +2 -1
- package/utils/index.d.ts +0 -1
- package/utils/mind.d.ts +4 -5
- package/utils/node-space.d.ts +5 -4
- package/utils/node-style/branch.d.ts +6 -1
- package/utils/node-style/common.d.ts +3 -0
- package/utils/node-style/index.d.ts +2 -1
- package/utils/node-style/shape.d.ts +4 -0
- package/constants/node.d.ts +0 -17
- package/esm2020/constants/node.mjs +0 -19
- package/esm2020/queries/get-layout-parent-by-element.mjs +0 -17
- package/esm2020/utils/node-style/node.mjs +0 -22
- package/esm2020/utils/shape.mjs +0 -17
- package/queries/get-layout-parent-by-element.d.ts +0 -8
- package/utils/node-style/node.d.ts +0 -3
- package/utils/shape.d.ts +0 -3
package/fesm2020/plait-mind.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
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 { distanceBetweenPointAndRectangle,
|
|
5
|
-
import { AbstractNode,
|
|
4
|
+
import { distanceBetweenPointAndRectangle, PlaitBoard, PlaitNode, NODE_TO_PARENT, Path, ELEMENT_TO_COMPONENT, PlaitElement, Transforms, idCreator, isNullOrUndefined, clearSelectedElement, addSelectedElement, drawRoundRectangle, getRectangleByElements, RectangleClient, getSelectedElements, createG, drawAbstractRoundRectangle, PlaitPluginElementComponent, PlaitPointerType, NODE_TO_INDEX, createText, IS_TEXT_EDITABLE, MERGING, transformPoint, toPoint, depthFirstRecursion, PlaitModule, distanceBetweenPointAndPoint, updateForeignObject as updateForeignObject$1, CLIP_BOARD_FORMAT_KEY, BOARD_TO_HOST, Selection, removeSelectedElement, PlaitHistoryBoard, hotkeys } from '@plait/core';
|
|
5
|
+
import { MindLayoutType, AbstractNode, getAbstractLayout, isIndentedLayout, isStandardLayout, isHorizontalLogicLayout, isVerticalLogicLayout, isTopLayout, isLeftLayout, isBottomLayout, isRightLayout, isHorizontalLayout, getNonAbstractChildren, getCorrectStartEnd, ConnectingPosition, GlobalLayout } from '@plait/layouts';
|
|
6
6
|
import { getSizeByText, ROOT_DEFAULT_HEIGHT, TEXT_DEFAULT_HEIGHT, drawRichtext, updateForeignObject, 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';
|
|
@@ -16,34 +16,44 @@ const ELEMENT_TO_NODE = new WeakMap();
|
|
|
16
16
|
|
|
17
17
|
const BASE = 4;
|
|
18
18
|
const PRIMARY_COLOR = '#6698FF';
|
|
19
|
-
const MINDMAP_KEY = 'plait-mindmap';
|
|
20
|
-
const MAX_RADIUS = BASE * 4;
|
|
21
19
|
const TRANSPARENT = 'transparent';
|
|
22
20
|
const GRAY_COLOR = '#AAAAAA';
|
|
23
21
|
const STROKE_WIDTH = 3;
|
|
22
|
+
const BRANCH_WIDTH = 3;
|
|
24
23
|
const EXTEND_OFFSET = 8;
|
|
25
24
|
const EXTEND_RADIUS = 16;
|
|
26
25
|
const QUICK_INSERT_CIRCLE_OFFSET = 9;
|
|
27
26
|
const QUICK_INSERT_CIRCLE_COLOR = '#6698FF';
|
|
28
27
|
const QUICK_INSERT_INNER_CROSS_COLOR = 'white';
|
|
29
28
|
|
|
29
|
+
const DefaultAbstractNodeStyle = {
|
|
30
|
+
strokeColor: GRAY_COLOR,
|
|
31
|
+
strokeWidth: 2,
|
|
32
|
+
branchColor: GRAY_COLOR,
|
|
33
|
+
branchWidth: 2,
|
|
34
|
+
fill: '#FFFFFF'
|
|
35
|
+
};
|
|
36
|
+
const DefaultNodeStyle = {
|
|
37
|
+
strokeWidth: 3,
|
|
38
|
+
branchWidth: 3,
|
|
39
|
+
fill: '#FFFFFF'
|
|
40
|
+
};
|
|
41
|
+
const DefaultRootStyle = {
|
|
42
|
+
fill: '#F5F5F5',
|
|
43
|
+
strokeColor: '#F5F5F5',
|
|
44
|
+
};
|
|
45
|
+
const BRANCH_COLORS = ['#A287E1', '#6F81DB', '#6EC4C4', '#DFB85D', '#B1C774', '#77C386', '#C28976', '#E48484', '#E482D4', '#69B1E4'];
|
|
46
|
+
|
|
30
47
|
const TOPIC_COLOR = '#333';
|
|
31
48
|
const TOPIC_FONT_SIZE = 14;
|
|
32
|
-
const NODE_FILL = '#FFFFFF';
|
|
33
|
-
const ROOT_NODE_FILL = '#F5F5F5';
|
|
34
|
-
const ROOT_NODE_STROKE = '#F5F5F5';
|
|
35
49
|
const ROOT_TOPIC_FONT_SIZE = 18;
|
|
50
|
+
const TOPIC_DEFAULT_MAX_WORD_COUNT = 34;
|
|
51
|
+
|
|
36
52
|
const NODE_MIN_WIDTH = 18;
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
(function (MindNodeShape) {
|
|
40
|
-
MindNodeShape["roundRectangle"] = "round-rectangle";
|
|
41
|
-
MindNodeShape["underline"] = "underline";
|
|
42
|
-
})(MindNodeShape || (MindNodeShape = {}));
|
|
43
|
-
const ABSTRACT_HANDLE_COLOR = '#6698FF80'; //PRIMARY_COLOR 50% 透明度
|
|
53
|
+
|
|
54
|
+
const ABSTRACT_HANDLE_COLOR = '#6698FF80'; //primary color 50% opacity
|
|
44
55
|
const ABSTRACT_INCLUDED_OUTLINE_OFFSET = 3.5;
|
|
45
56
|
const ABSTRACT_HANDLE_LENGTH = 10;
|
|
46
|
-
const TOPIC_DEFAULT_MAX_WORD_COUNT = 34;
|
|
47
57
|
const ABSTRACT_HANDLE_MASK_WIDTH = 8;
|
|
48
58
|
|
|
49
59
|
function getRectangleByNode(node) {
|
|
@@ -74,34 +84,35 @@ function hitMindElement(board, point, element) {
|
|
|
74
84
|
* 2. correct layout by incorrect layout direction
|
|
75
85
|
* @param element
|
|
76
86
|
*/
|
|
77
|
-
const getCorrectLayoutByElement = (element) => {
|
|
78
|
-
const
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
const component = PlaitElement.getComponent(element);
|
|
85
|
-
let layout = element.layout;
|
|
86
|
-
let parentComponent = null;
|
|
87
|
-
let parent = component.parent.origin;
|
|
88
|
-
while (!layout && parent) {
|
|
89
|
-
parentComponent = PlaitElement.getComponent(parent);
|
|
90
|
-
layout = parentComponent.node.origin.layout;
|
|
91
|
-
parent = parentComponent.parent?.origin;
|
|
92
|
-
}
|
|
93
|
-
if ((AbstractNode.isAbstract(element) || isChildOfAbstract(MindElement.getNode(element))) &&
|
|
94
|
-
isIndentedLayout(layout)) {
|
|
95
|
-
return getAbstractLayout(layout);
|
|
87
|
+
const getCorrectLayoutByElement = (board, element) => {
|
|
88
|
+
const ancestors = MindElement.getAncestors(board, element);
|
|
89
|
+
ancestors.unshift(element);
|
|
90
|
+
const root = ancestors[ancestors.length - 1];
|
|
91
|
+
let rootLayout = getRootLayout(root);
|
|
92
|
+
if (PlaitMind.isMind(element)) {
|
|
93
|
+
return rootLayout;
|
|
96
94
|
}
|
|
97
|
-
|
|
95
|
+
const node = MindElement.getNode(element);
|
|
96
|
+
let correctRootLayout = rootLayout;
|
|
98
97
|
if (rootLayout === MindLayoutType.standard) {
|
|
99
|
-
correctRootLayout =
|
|
98
|
+
correctRootLayout = node.left ? MindLayoutType.left : MindLayoutType.right;
|
|
100
99
|
}
|
|
101
|
-
|
|
100
|
+
let layout = null;
|
|
101
|
+
const elementWithLayout = ancestors.find(value => value.layout || AbstractNode.isAbstract(value));
|
|
102
|
+
if (elementWithLayout) {
|
|
103
|
+
if (AbstractNode.isAbstract(elementWithLayout)) {
|
|
104
|
+
const parent = MindElement.getParent(elementWithLayout);
|
|
105
|
+
const parentLayout = getCorrectLayoutByElement(board, parent);
|
|
106
|
+
layout = getAbstractLayout(parentLayout);
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
layout = elementWithLayout?.layout;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
if (layout === MindLayoutType.standard || !layout) {
|
|
102
113
|
return correctRootLayout;
|
|
103
114
|
}
|
|
104
|
-
|
|
115
|
+
else {
|
|
105
116
|
const incorrectDirection = getInCorrectLayoutDirection(correctRootLayout, layout);
|
|
106
117
|
if (incorrectDirection) {
|
|
107
118
|
return correctLayoutByDirection(layout, incorrectDirection);
|
|
@@ -110,36 +121,28 @@ const getCorrectLayoutByElement = (element) => {
|
|
|
110
121
|
return layout;
|
|
111
122
|
}
|
|
112
123
|
}
|
|
113
|
-
else {
|
|
114
|
-
return correctRootLayout;
|
|
115
|
-
}
|
|
116
124
|
};
|
|
117
125
|
|
|
118
|
-
const getBranchLayouts = (element) => {
|
|
126
|
+
const getBranchLayouts = (board, element) => {
|
|
119
127
|
const layouts = [];
|
|
120
128
|
if (element.layout) {
|
|
121
|
-
//getCorrectLayoutByElement含有递归操作,
|
|
122
|
-
layouts.unshift(getCorrectLayoutByElement(element));
|
|
129
|
+
// TODO: getCorrectLayoutByElement 含有递归操作,getBranchLayouts 本身也有递归操作,有待优化
|
|
130
|
+
layouts.unshift(getCorrectLayoutByElement(board, element));
|
|
123
131
|
}
|
|
124
|
-
let parent =
|
|
132
|
+
let parent = MindElement.findParent(element);
|
|
125
133
|
while (parent) {
|
|
126
134
|
if (parent.layout) {
|
|
127
135
|
layouts.unshift(parent.layout);
|
|
128
136
|
}
|
|
129
|
-
parent =
|
|
137
|
+
parent = MindElement.findParent(parent);
|
|
130
138
|
}
|
|
131
139
|
return layouts;
|
|
132
140
|
};
|
|
133
141
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
* @param element
|
|
137
|
-
* @returns MindLayoutType[]
|
|
138
|
-
*/
|
|
139
|
-
const getAvailableSubLayoutsByElement = (element) => {
|
|
140
|
-
const parentElement = findParentElement(element);
|
|
142
|
+
const getAvailableSubLayoutsByElement = (board, element) => {
|
|
143
|
+
const parentElement = MindElement.findParent(element);
|
|
141
144
|
if (parentElement) {
|
|
142
|
-
const branchLayouts = getBranchLayouts(parentElement);
|
|
145
|
+
const branchLayouts = getBranchLayouts(board, parentElement);
|
|
143
146
|
if (branchLayouts[0] === MindLayoutType.standard) {
|
|
144
147
|
const node = MindElement.getNode(element);
|
|
145
148
|
branchLayouts[0] = node.left ? MindLayoutType.left : MindLayoutType.right;
|
|
@@ -155,20 +158,107 @@ const getAvailableSubLayoutsByElement = (element) => {
|
|
|
155
158
|
return undefined;
|
|
156
159
|
};
|
|
157
160
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
161
|
+
const getBranchDirectionsByLayouts = (branchLayouts) => {
|
|
162
|
+
const branchDirections = [];
|
|
163
|
+
branchLayouts.forEach(l => {
|
|
164
|
+
const directions = LayoutDirectionsMap[l];
|
|
165
|
+
directions.forEach(d => {
|
|
166
|
+
if (!branchDirections.includes(d) && !branchDirections.includes(getLayoutReverseDirection(d))) {
|
|
167
|
+
branchDirections.push(d);
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
return branchDirections;
|
|
172
|
+
};
|
|
173
|
+
const isCorrectLayout = (root, layout) => {
|
|
174
|
+
const rootLayout = root.layout || getDefaultLayout();
|
|
175
|
+
return !getInCorrectLayoutDirection(rootLayout, layout);
|
|
176
|
+
};
|
|
177
|
+
const isMixedLayout = (parentLayout, layout) => {
|
|
178
|
+
return (!isIndentedLayout(parentLayout) && isIndentedLayout(layout)) || (isIndentedLayout(parentLayout) && !isIndentedLayout(layout));
|
|
179
|
+
};
|
|
180
|
+
const getInCorrectLayoutDirection = (rootLayout, layout) => {
|
|
181
|
+
const directions = LayoutDirectionsMap[rootLayout];
|
|
182
|
+
const subLayoutDirections = LayoutDirectionsMap[layout];
|
|
183
|
+
if (!subLayoutDirections) {
|
|
184
|
+
throw new Error(`unexpected layout: ${layout} on correct layout`);
|
|
185
|
+
}
|
|
186
|
+
return subLayoutDirections.find(d => directions.includes(getLayoutReverseDirection(d)));
|
|
187
|
+
};
|
|
188
|
+
const correctLayoutByDirection = (layout, direction) => {
|
|
189
|
+
const isHorizontal = direction === LayoutDirection.left || direction === LayoutDirection.right ? true : false;
|
|
190
|
+
let inverseDirectionLayout = MindLayoutType.standard;
|
|
191
|
+
switch (layout) {
|
|
192
|
+
case MindLayoutType.left:
|
|
193
|
+
inverseDirectionLayout = MindLayoutType.right;
|
|
194
|
+
break;
|
|
195
|
+
case MindLayoutType.right:
|
|
196
|
+
inverseDirectionLayout = MindLayoutType.left;
|
|
197
|
+
break;
|
|
198
|
+
case MindLayoutType.downward:
|
|
199
|
+
inverseDirectionLayout = MindLayoutType.upward;
|
|
200
|
+
break;
|
|
201
|
+
case MindLayoutType.upward:
|
|
202
|
+
inverseDirectionLayout = MindLayoutType.downward;
|
|
203
|
+
break;
|
|
204
|
+
case MindLayoutType.rightBottomIndented:
|
|
205
|
+
inverseDirectionLayout = isHorizontal ? MindLayoutType.leftBottomIndented : MindLayoutType.rightTopIndented;
|
|
206
|
+
break;
|
|
207
|
+
case MindLayoutType.leftBottomIndented:
|
|
208
|
+
inverseDirectionLayout = isHorizontal ? MindLayoutType.rightBottomIndented : MindLayoutType.leftTopIndented;
|
|
209
|
+
break;
|
|
210
|
+
case MindLayoutType.rightTopIndented:
|
|
211
|
+
inverseDirectionLayout = isHorizontal ? MindLayoutType.leftTopIndented : MindLayoutType.rightBottomIndented;
|
|
212
|
+
break;
|
|
213
|
+
case MindLayoutType.leftTopIndented:
|
|
214
|
+
inverseDirectionLayout = isHorizontal ? MindLayoutType.rightTopIndented : MindLayoutType.leftBottomIndented;
|
|
215
|
+
break;
|
|
216
|
+
}
|
|
217
|
+
return inverseDirectionLayout;
|
|
218
|
+
};
|
|
219
|
+
const getLayoutDirection$1 = (root) => {
|
|
220
|
+
const layout = root.layout || getDefaultLayout();
|
|
221
|
+
return LayoutDirectionsMap[layout];
|
|
222
|
+
};
|
|
223
|
+
const getDefaultLayout = () => {
|
|
224
|
+
return MindLayoutType.standard;
|
|
225
|
+
};
|
|
226
|
+
const getAvailableSubLayoutsByLayoutDirections = (directions) => {
|
|
227
|
+
const result = [];
|
|
228
|
+
const reverseDirections = directions.map(getLayoutReverseDirection);
|
|
229
|
+
for (const key in MindLayoutType) {
|
|
230
|
+
const layout = MindLayoutType[key];
|
|
231
|
+
const layoutDirections = LayoutDirectionsMap[layout];
|
|
232
|
+
if (layoutDirections) {
|
|
233
|
+
const hasSameDirection = layoutDirections.some(d => directions.includes(d));
|
|
234
|
+
const hasReverseDirection = layoutDirections.some(r => reverseDirections.includes(r));
|
|
235
|
+
if (hasSameDirection && !hasReverseDirection) {
|
|
236
|
+
result.push(layout);
|
|
237
|
+
}
|
|
168
238
|
}
|
|
169
|
-
parent = findParentElement(parent);
|
|
170
239
|
}
|
|
171
|
-
return
|
|
240
|
+
return result;
|
|
241
|
+
};
|
|
242
|
+
const getLayoutReverseDirection = (layoutDirection) => {
|
|
243
|
+
let reverseDirection = LayoutDirection.right;
|
|
244
|
+
switch (layoutDirection) {
|
|
245
|
+
case LayoutDirection.top:
|
|
246
|
+
reverseDirection = LayoutDirection.bottom;
|
|
247
|
+
break;
|
|
248
|
+
case LayoutDirection.bottom:
|
|
249
|
+
reverseDirection = LayoutDirection.top;
|
|
250
|
+
break;
|
|
251
|
+
case LayoutDirection.right:
|
|
252
|
+
reverseDirection = LayoutDirection.left;
|
|
253
|
+
break;
|
|
254
|
+
case LayoutDirection.left:
|
|
255
|
+
reverseDirection = LayoutDirection.right;
|
|
256
|
+
break;
|
|
257
|
+
}
|
|
258
|
+
return reverseDirection;
|
|
259
|
+
};
|
|
260
|
+
const getRootLayout = (root) => {
|
|
261
|
+
return root.layout || getDefaultLayout();
|
|
172
262
|
};
|
|
173
263
|
|
|
174
264
|
const getLayoutByElement = (element) => {
|
|
@@ -176,17 +266,18 @@ const getLayoutByElement = (element) => {
|
|
|
176
266
|
if (layout) {
|
|
177
267
|
return layout;
|
|
178
268
|
}
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
269
|
+
const parent = !PlaitMind.isMind(element) && MindElement.getParent(element);
|
|
270
|
+
if (AbstractNode.isAbstract(element) && parent) {
|
|
271
|
+
return getAbstractLayout(getLayoutByElement(parent));
|
|
272
|
+
}
|
|
273
|
+
if (parent) {
|
|
274
|
+
return getLayoutByElement(parent);
|
|
183
275
|
}
|
|
184
|
-
return
|
|
276
|
+
return getDefaultLayout();
|
|
185
277
|
};
|
|
186
278
|
|
|
187
279
|
const MindQueries = {
|
|
188
280
|
getAvailableSubLayoutsByElement,
|
|
189
|
-
getLayoutParentByElement,
|
|
190
281
|
getBranchLayouts,
|
|
191
282
|
getLayoutByElement,
|
|
192
283
|
getCorrectLayoutByElement
|
|
@@ -223,6 +314,13 @@ const MindElement = {
|
|
|
223
314
|
const parent = NODE_TO_PARENT.get(node);
|
|
224
315
|
return parent;
|
|
225
316
|
},
|
|
317
|
+
findParent(node) {
|
|
318
|
+
if (PlaitMind.isMind(node)) {
|
|
319
|
+
return undefined;
|
|
320
|
+
}
|
|
321
|
+
const parent = NODE_TO_PARENT.get(node);
|
|
322
|
+
return parent;
|
|
323
|
+
},
|
|
226
324
|
getRoot(board, element) {
|
|
227
325
|
const path = PlaitBoard.findPath(board, element);
|
|
228
326
|
return PlaitNode.get(board, path.slice(0, 1));
|
|
@@ -245,6 +343,13 @@ const MindElement = {
|
|
|
245
343
|
}
|
|
246
344
|
return node;
|
|
247
345
|
},
|
|
346
|
+
findParentNode(element) {
|
|
347
|
+
if (PlaitMind.isMind(element)) {
|
|
348
|
+
return undefined;
|
|
349
|
+
}
|
|
350
|
+
const parent = MindElement.getParent(element);
|
|
351
|
+
return MindElement.getNode(parent);
|
|
352
|
+
},
|
|
248
353
|
hasEmojis(element) {
|
|
249
354
|
if (element.data.emojis) {
|
|
250
355
|
return true;
|
|
@@ -257,6 +362,11 @@ const MindElement = {
|
|
|
257
362
|
return element.data.emojis;
|
|
258
363
|
}
|
|
259
364
|
};
|
|
365
|
+
var MindElementShape;
|
|
366
|
+
(function (MindElementShape) {
|
|
367
|
+
MindElementShape["roundRectangle"] = "round-rectangle";
|
|
368
|
+
MindElementShape["underline"] = "underline";
|
|
369
|
+
})(MindElementShape || (MindElementShape = {}));
|
|
260
370
|
|
|
261
371
|
const MindNode = {
|
|
262
372
|
get(root, path) {
|
|
@@ -269,15 +379,6 @@ const MindNode = {
|
|
|
269
379
|
node = node.children[p];
|
|
270
380
|
}
|
|
271
381
|
return node;
|
|
272
|
-
},
|
|
273
|
-
isEquals(node, otherNode) {
|
|
274
|
-
const hasSameSize = node.x === otherNode.x && node.y === otherNode.y && node.width === otherNode.width && node.height === otherNode.height;
|
|
275
|
-
const hasSameOrigin = node.origin === otherNode.origin;
|
|
276
|
-
let hasSameParentOriginChildren = false;
|
|
277
|
-
if (node.parent && otherNode.parent) {
|
|
278
|
-
hasSameParentOriginChildren = node.parent.origin.children == otherNode.parent.origin.children;
|
|
279
|
-
}
|
|
280
|
-
return hasSameSize && hasSameOrigin && hasSameParentOriginChildren;
|
|
281
382
|
}
|
|
282
383
|
};
|
|
283
384
|
|
|
@@ -311,109 +412,6 @@ var AbstractResizeState;
|
|
|
311
412
|
AbstractResizeState["end"] = "end";
|
|
312
413
|
})(AbstractResizeState || (AbstractResizeState = {}));
|
|
313
414
|
|
|
314
|
-
const getBranchDirectionsByLayouts = (branchLayouts) => {
|
|
315
|
-
const branchDirections = [];
|
|
316
|
-
branchLayouts.forEach(l => {
|
|
317
|
-
const directions = LayoutDirectionsMap[l];
|
|
318
|
-
directions.forEach(d => {
|
|
319
|
-
if (!branchDirections.includes(d) && !branchDirections.includes(getLayoutReverseDirection(d))) {
|
|
320
|
-
branchDirections.push(d);
|
|
321
|
-
}
|
|
322
|
-
});
|
|
323
|
-
});
|
|
324
|
-
return branchDirections;
|
|
325
|
-
};
|
|
326
|
-
const isCorrectLayout = (root, layout) => {
|
|
327
|
-
const rootLayout = root.layout || getDefaultLayout();
|
|
328
|
-
return !getInCorrectLayoutDirection(rootLayout, layout);
|
|
329
|
-
};
|
|
330
|
-
const isMixedLayout = (parentLayout, layout) => {
|
|
331
|
-
return (!isIndentedLayout(parentLayout) && isIndentedLayout(layout)) || (isIndentedLayout(parentLayout) && !isIndentedLayout(layout));
|
|
332
|
-
};
|
|
333
|
-
const getInCorrectLayoutDirection = (rootLayout, layout) => {
|
|
334
|
-
const directions = LayoutDirectionsMap[rootLayout];
|
|
335
|
-
const subLayoutDirections = LayoutDirectionsMap[layout];
|
|
336
|
-
if (!subLayoutDirections) {
|
|
337
|
-
throw new Error(`unexpected layout: ${layout} on correct layout`);
|
|
338
|
-
}
|
|
339
|
-
return subLayoutDirections.find(d => directions.includes(getLayoutReverseDirection(d)));
|
|
340
|
-
};
|
|
341
|
-
const correctLayoutByDirection = (layout, direction) => {
|
|
342
|
-
const isHorizontal = direction === LayoutDirection.left || direction === LayoutDirection.right ? true : false;
|
|
343
|
-
let inverseDirectionLayout = MindLayoutType.standard;
|
|
344
|
-
switch (layout) {
|
|
345
|
-
case MindLayoutType.left:
|
|
346
|
-
inverseDirectionLayout = MindLayoutType.right;
|
|
347
|
-
break;
|
|
348
|
-
case MindLayoutType.right:
|
|
349
|
-
inverseDirectionLayout = MindLayoutType.left;
|
|
350
|
-
break;
|
|
351
|
-
case MindLayoutType.downward:
|
|
352
|
-
inverseDirectionLayout = MindLayoutType.upward;
|
|
353
|
-
break;
|
|
354
|
-
case MindLayoutType.upward:
|
|
355
|
-
inverseDirectionLayout = MindLayoutType.downward;
|
|
356
|
-
break;
|
|
357
|
-
case MindLayoutType.rightBottomIndented:
|
|
358
|
-
inverseDirectionLayout = isHorizontal ? MindLayoutType.leftBottomIndented : MindLayoutType.rightTopIndented;
|
|
359
|
-
break;
|
|
360
|
-
case MindLayoutType.leftBottomIndented:
|
|
361
|
-
inverseDirectionLayout = isHorizontal ? MindLayoutType.rightBottomIndented : MindLayoutType.leftTopIndented;
|
|
362
|
-
break;
|
|
363
|
-
case MindLayoutType.rightTopIndented:
|
|
364
|
-
inverseDirectionLayout = isHorizontal ? MindLayoutType.leftTopIndented : MindLayoutType.rightBottomIndented;
|
|
365
|
-
break;
|
|
366
|
-
case MindLayoutType.leftTopIndented:
|
|
367
|
-
inverseDirectionLayout = isHorizontal ? MindLayoutType.rightTopIndented : MindLayoutType.leftBottomIndented;
|
|
368
|
-
break;
|
|
369
|
-
}
|
|
370
|
-
return inverseDirectionLayout;
|
|
371
|
-
};
|
|
372
|
-
const getLayoutDirection$1 = (root) => {
|
|
373
|
-
const layout = root.layout || getDefaultLayout();
|
|
374
|
-
return LayoutDirectionsMap[layout];
|
|
375
|
-
};
|
|
376
|
-
const getDefaultLayout = () => {
|
|
377
|
-
return MindLayoutType.standard;
|
|
378
|
-
};
|
|
379
|
-
const getAvailableSubLayoutsByLayoutDirections = (directions) => {
|
|
380
|
-
const result = [];
|
|
381
|
-
const reverseDirections = directions.map(getLayoutReverseDirection);
|
|
382
|
-
for (const key in MindLayoutType) {
|
|
383
|
-
const layout = MindLayoutType[key];
|
|
384
|
-
const layoutDirections = LayoutDirectionsMap[layout];
|
|
385
|
-
if (layoutDirections) {
|
|
386
|
-
const hasSameDirection = layoutDirections.some(d => directions.includes(d));
|
|
387
|
-
const hasReverseDirection = layoutDirections.some(r => reverseDirections.includes(r));
|
|
388
|
-
if (hasSameDirection && !hasReverseDirection) {
|
|
389
|
-
result.push(layout);
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
|
-
return result;
|
|
394
|
-
};
|
|
395
|
-
const getLayoutReverseDirection = (layoutDirection) => {
|
|
396
|
-
let reverseDirection = LayoutDirection.right;
|
|
397
|
-
switch (layoutDirection) {
|
|
398
|
-
case LayoutDirection.top:
|
|
399
|
-
reverseDirection = LayoutDirection.bottom;
|
|
400
|
-
break;
|
|
401
|
-
case LayoutDirection.bottom:
|
|
402
|
-
reverseDirection = LayoutDirection.top;
|
|
403
|
-
break;
|
|
404
|
-
case LayoutDirection.right:
|
|
405
|
-
reverseDirection = LayoutDirection.left;
|
|
406
|
-
break;
|
|
407
|
-
case LayoutDirection.left:
|
|
408
|
-
reverseDirection = LayoutDirection.right;
|
|
409
|
-
break;
|
|
410
|
-
}
|
|
411
|
-
return reverseDirection;
|
|
412
|
-
};
|
|
413
|
-
const getRootLayout = (root) => {
|
|
414
|
-
return root.layout || getDefaultLayout();
|
|
415
|
-
};
|
|
416
|
-
|
|
417
415
|
function enterNodeEditing(element) {
|
|
418
416
|
const component = ELEMENT_TO_COMPONENT.get(element);
|
|
419
417
|
component.startEditText(false, false);
|
|
@@ -443,13 +441,137 @@ const separateChildren = (parentElement) => {
|
|
|
443
441
|
return { leftChildren, rightChildren };
|
|
444
442
|
};
|
|
445
443
|
const isSetAbstract = (element) => {
|
|
446
|
-
|
|
444
|
+
const parent = MindElement.getParent(element);
|
|
445
|
+
return !!getCorrespondingAbstract(parent, element);
|
|
447
446
|
};
|
|
448
447
|
const canSetAbstract = (element) => {
|
|
449
448
|
return !PlaitElement.isRootElement(element) && !AbstractNode.isAbstract(element) && !isSetAbstract(element);
|
|
450
449
|
};
|
|
451
|
-
const
|
|
452
|
-
|
|
450
|
+
const getCorrespondingAbstract = (parent, element) => {
|
|
451
|
+
if (!parent)
|
|
452
|
+
return undefined;
|
|
453
|
+
const elementIndex = parent.children.indexOf(element);
|
|
454
|
+
return parent.children.find(child => {
|
|
455
|
+
return AbstractNode.isAbstract(child) && elementIndex >= child.start && elementIndex <= child.end;
|
|
456
|
+
});
|
|
457
|
+
};
|
|
458
|
+
const getBehindAbstracts = (parent, element) => {
|
|
459
|
+
const index = parent.children.indexOf(element);
|
|
460
|
+
return parent.children.filter(child => AbstractNode.isAbstract(child) && child.start > index);
|
|
461
|
+
};
|
|
462
|
+
const getOverallAbstracts = (board, elements) => {
|
|
463
|
+
const overallAbstracts = [];
|
|
464
|
+
elements
|
|
465
|
+
.filter(value => !AbstractNode.isAbstract(value) && !PlaitMind.isMind(value))
|
|
466
|
+
.forEach(value => {
|
|
467
|
+
const parent = MindElement.getParent(value);
|
|
468
|
+
const abstract = getCorrespondingAbstract(parent, value);
|
|
469
|
+
if (abstract && overallAbstracts.indexOf(abstract) === -1) {
|
|
470
|
+
const { start, end } = abstract;
|
|
471
|
+
const parent = MindElement.getParent(value);
|
|
472
|
+
const isOverall = parent.children.slice(start, end + 1).every(includedElement => elements.indexOf(includedElement) > -1);
|
|
473
|
+
if (isOverall) {
|
|
474
|
+
overallAbstracts.push(abstract);
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
});
|
|
478
|
+
return overallAbstracts;
|
|
479
|
+
};
|
|
480
|
+
const insertElementHandleAbstract = (board, path,
|
|
481
|
+
//由此区分拖拽和新增到概要概括最后一个节点
|
|
482
|
+
isExtendPreviousNode = true, abstractRefs = new Map()) => {
|
|
483
|
+
const parent = PlaitNode.parent(board, path);
|
|
484
|
+
const hasPreviousNode = path[path.length - 1] !== 0;
|
|
485
|
+
let behindAbstracts;
|
|
486
|
+
if (!hasPreviousNode) {
|
|
487
|
+
behindAbstracts = parent.children.filter(child => AbstractNode.isAbstract(child));
|
|
488
|
+
}
|
|
489
|
+
else {
|
|
490
|
+
const selectedElement = PlaitNode.get(board, Path.previous(path));
|
|
491
|
+
behindAbstracts = getBehindAbstracts(parent, selectedElement);
|
|
492
|
+
}
|
|
493
|
+
if (behindAbstracts.length) {
|
|
494
|
+
behindAbstracts.forEach(abstract => {
|
|
495
|
+
let newProperties = abstractRefs.get(abstract);
|
|
496
|
+
if (!newProperties) {
|
|
497
|
+
newProperties = { start: 0, end: 0 };
|
|
498
|
+
abstractRefs.set(abstract, newProperties);
|
|
499
|
+
}
|
|
500
|
+
newProperties.start = newProperties.start + 1;
|
|
501
|
+
newProperties.end = newProperties.end + 1;
|
|
502
|
+
});
|
|
503
|
+
}
|
|
504
|
+
if (!hasPreviousNode) {
|
|
505
|
+
return abstractRefs;
|
|
506
|
+
}
|
|
507
|
+
const selectedElement = PlaitNode.get(board, Path.previous(path));
|
|
508
|
+
const correspondingAbstract = getCorrespondingAbstract(parent, selectedElement);
|
|
509
|
+
const isDragToLast = !isExtendPreviousNode && correspondingAbstract && correspondingAbstract.end === path[path.length - 1] - 1;
|
|
510
|
+
if (correspondingAbstract && !isDragToLast) {
|
|
511
|
+
let newProperties = abstractRefs.get(correspondingAbstract);
|
|
512
|
+
if (!newProperties) {
|
|
513
|
+
newProperties = { start: 0, end: 0 };
|
|
514
|
+
abstractRefs.set(correspondingAbstract, newProperties);
|
|
515
|
+
}
|
|
516
|
+
newProperties.end = newProperties.end + 1;
|
|
517
|
+
}
|
|
518
|
+
return abstractRefs;
|
|
519
|
+
};
|
|
520
|
+
const deleteElementHandleAbstract = (board, deletableElements, abstractRefs = new Map()) => {
|
|
521
|
+
deletableElements.forEach(node => {
|
|
522
|
+
if (!PlaitMind.isMind(node)) {
|
|
523
|
+
const parent = PlaitNode.parent(board, PlaitBoard.findPath(board, node));
|
|
524
|
+
const behindAbstracts = getBehindAbstracts(parent, node).filter(abstract => !deletableElements.includes(abstract));
|
|
525
|
+
if (behindAbstracts.length) {
|
|
526
|
+
behindAbstracts.forEach(abstract => {
|
|
527
|
+
let newProperties = abstractRefs.get(abstract);
|
|
528
|
+
if (!newProperties) {
|
|
529
|
+
newProperties = { start: 0, end: 0 };
|
|
530
|
+
abstractRefs.set(abstract, newProperties);
|
|
531
|
+
}
|
|
532
|
+
newProperties.start = newProperties.start - 1;
|
|
533
|
+
newProperties.end = newProperties.end - 1;
|
|
534
|
+
});
|
|
535
|
+
}
|
|
536
|
+
const correspondingAbstract = getCorrespondingAbstract(parent, node);
|
|
537
|
+
if (correspondingAbstract && !deletableElements.includes(correspondingAbstract)) {
|
|
538
|
+
let newProperties = abstractRefs.get(correspondingAbstract);
|
|
539
|
+
if (!newProperties) {
|
|
540
|
+
newProperties = { start: 0, end: 0 };
|
|
541
|
+
abstractRefs.set(correspondingAbstract, newProperties);
|
|
542
|
+
}
|
|
543
|
+
newProperties.end = newProperties.end - 1;
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
});
|
|
547
|
+
return abstractRefs;
|
|
548
|
+
};
|
|
549
|
+
|
|
550
|
+
const setAbstractsByRefs = (board, abstractRefs) => {
|
|
551
|
+
abstractRefs.forEach((newProperty, element) => {
|
|
552
|
+
const start = element.start + newProperty.start;
|
|
553
|
+
const end = element.end + newProperty.end;
|
|
554
|
+
const path = PlaitBoard.findPath(board, element);
|
|
555
|
+
if (start > end) {
|
|
556
|
+
Transforms.removeNode(board, path);
|
|
557
|
+
}
|
|
558
|
+
else {
|
|
559
|
+
Transforms.setNode(board, { start, end }, path);
|
|
560
|
+
}
|
|
561
|
+
});
|
|
562
|
+
};
|
|
563
|
+
const setAbstractByStandardLayout = (board, element) => {
|
|
564
|
+
const rightNodeCount = element.rightNodeCount;
|
|
565
|
+
const abstract = element.children.find(child => {
|
|
566
|
+
return AbstractNode.isAbstract(child) && child.end >= rightNodeCount && child.start < rightNodeCount;
|
|
567
|
+
});
|
|
568
|
+
if (abstract) {
|
|
569
|
+
const path = PlaitBoard.findPath(board, abstract);
|
|
570
|
+
Transforms.setNode(board, { end: rightNodeCount - 1 }, path);
|
|
571
|
+
}
|
|
572
|
+
};
|
|
573
|
+
const insertAbstract = (board, elements) => {
|
|
574
|
+
let elementGroup = getFirstLevelElement(elements);
|
|
453
575
|
const { parentElements, abstractIncludedGroups } = divideElementByParent(elementGroup);
|
|
454
576
|
abstractIncludedGroups.forEach((group, index) => {
|
|
455
577
|
const groupParent = parentElements[index];
|
|
@@ -476,71 +598,119 @@ const setAbstractByElements = (board, groupParent, group) => {
|
|
|
476
598
|
insertAbstractNode(board, path, start, end);
|
|
477
599
|
}
|
|
478
600
|
};
|
|
479
|
-
const insertAbstractNode = (board, path, start, end) => {
|
|
480
|
-
const mindElement = createMindElement('概要', 28, 20, {
|
|
481
|
-
strokeColor:
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
601
|
+
const insertAbstractNode = (board, path, start, end) => {
|
|
602
|
+
const mindElement = createMindElement('概要', 28, 20, {
|
|
603
|
+
strokeColor: DefaultAbstractNodeStyle.strokeColor,
|
|
604
|
+
strokeWidth: DefaultAbstractNodeStyle.branchWidth,
|
|
605
|
+
branchColor: DefaultAbstractNodeStyle.branchColor,
|
|
606
|
+
branchWidth: DefaultAbstractNodeStyle.branchWidth
|
|
607
|
+
});
|
|
608
|
+
mindElement.start = start;
|
|
609
|
+
mindElement.end = end;
|
|
610
|
+
Transforms.insertNode(board, mindElement, path);
|
|
611
|
+
};
|
|
612
|
+
|
|
613
|
+
const setLayout = (board, layout, path) => {
|
|
614
|
+
correctLogicLayoutNode(board, layout, path);
|
|
615
|
+
const element = PlaitNode.get(board, path);
|
|
616
|
+
if (PlaitMind.isMind(element) && isStandardLayout(layout)) {
|
|
617
|
+
MindTransforms.setAbstractByStandardLayout(board, element);
|
|
618
|
+
}
|
|
619
|
+
Transforms.setNode(board, { layout }, path);
|
|
620
|
+
};
|
|
621
|
+
const correctLogicLayoutNode = (board, layout, path) => {
|
|
622
|
+
const node = PlaitNode.get(board, path);
|
|
623
|
+
if (node && layout) {
|
|
624
|
+
node.children?.forEach((value, index) => {
|
|
625
|
+
if (value.layout) {
|
|
626
|
+
if ((isHorizontalLogicLayout(layout) && isVerticalLogicLayout(value.layout)) ||
|
|
627
|
+
(isVerticalLogicLayout(layout) && isHorizontalLogicLayout(value.layout))) {
|
|
628
|
+
Transforms.setNode(board, { layout: null }, [...path, index]);
|
|
629
|
+
}
|
|
630
|
+
if (value.children?.length) {
|
|
631
|
+
correctLogicLayoutNode(board, layout, [...path, index]);
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
});
|
|
635
|
+
}
|
|
636
|
+
};
|
|
637
|
+
|
|
638
|
+
const setTopic = (board, element, topic, width, height) => {
|
|
639
|
+
const newElement = {
|
|
640
|
+
data: { topic },
|
|
641
|
+
width: width < NODE_MIN_WIDTH * board.viewport.zoom ? NODE_MIN_WIDTH : width / board.viewport.zoom,
|
|
642
|
+
height: height / board.viewport.zoom
|
|
643
|
+
};
|
|
644
|
+
if (MindElement.hasEmojis(element)) {
|
|
645
|
+
newElement.data.emojis = element.data.emojis;
|
|
496
646
|
}
|
|
647
|
+
const path = PlaitBoard.findPath(board, element);
|
|
648
|
+
Transforms.setNode(board, newElement, path);
|
|
497
649
|
};
|
|
498
|
-
const
|
|
499
|
-
const
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
});
|
|
650
|
+
const setTopicSize = (board, element, width, height) => {
|
|
651
|
+
const newElement = {
|
|
652
|
+
width: width < NODE_MIN_WIDTH * board.viewport.zoom ? NODE_MIN_WIDTH : width / board.viewport.zoom,
|
|
653
|
+
height: height / board.viewport.zoom
|
|
654
|
+
};
|
|
655
|
+
const path = PlaitBoard.findPath(board, element);
|
|
656
|
+
Transforms.setNode(board, newElement, path);
|
|
506
657
|
};
|
|
507
|
-
const
|
|
508
|
-
const
|
|
509
|
-
const
|
|
510
|
-
|
|
658
|
+
const addEmoji = (board, element, emojiItem) => {
|
|
659
|
+
const emojis = element.data.emojis || [];
|
|
660
|
+
const newEmojis = [...emojis];
|
|
661
|
+
newEmojis.push(emojiItem);
|
|
662
|
+
const newElement = {
|
|
663
|
+
data: { topic: element.data.topic, emojis: newEmojis }
|
|
664
|
+
};
|
|
665
|
+
const path = PlaitBoard.findPath(board, element);
|
|
666
|
+
Transforms.setNode(board, newElement, path);
|
|
511
667
|
};
|
|
512
|
-
const
|
|
513
|
-
const
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
if (abstracts.length) {
|
|
520
|
-
moveAbstractPosition(board, abstracts, 1);
|
|
668
|
+
const removeEmoji = (board, element, emojiItem) => {
|
|
669
|
+
const emojis = element.data.emojis.filter(value => value !== emojiItem);
|
|
670
|
+
const newElement = {
|
|
671
|
+
data: { topic: element.data.topic }
|
|
672
|
+
};
|
|
673
|
+
if (emojis.length > 0) {
|
|
674
|
+
newElement.data.emojis = emojis;
|
|
521
675
|
}
|
|
676
|
+
const path = PlaitBoard.findPath(board, element);
|
|
677
|
+
Transforms.setNode(board, newElement, path);
|
|
522
678
|
};
|
|
523
|
-
const
|
|
524
|
-
|
|
525
|
-
|
|
679
|
+
const replaceEmoji = (board, element, oldEmoji, newEmoji) => {
|
|
680
|
+
const newElement = {
|
|
681
|
+
data: { topic: element.data.topic }
|
|
682
|
+
};
|
|
683
|
+
const newEmojis = element.data.emojis.map(value => {
|
|
684
|
+
if (value === oldEmoji) {
|
|
685
|
+
return newEmoji;
|
|
686
|
+
}
|
|
687
|
+
return value;
|
|
526
688
|
});
|
|
689
|
+
newElement.data.emojis = newEmojis;
|
|
690
|
+
const path = PlaitBoard.findPath(board, element);
|
|
691
|
+
Transforms.setNode(board, newElement, path);
|
|
692
|
+
};
|
|
693
|
+
|
|
694
|
+
const MindTransforms = {
|
|
695
|
+
setLayout,
|
|
696
|
+
setTopic,
|
|
697
|
+
setTopicSize,
|
|
698
|
+
addEmoji,
|
|
699
|
+
removeEmoji,
|
|
700
|
+
replaceEmoji,
|
|
701
|
+
insertAbstract,
|
|
702
|
+
setAbstractsByRefs,
|
|
703
|
+
setAbstractByStandardLayout
|
|
527
704
|
};
|
|
528
705
|
|
|
529
|
-
function findParentElement(element) {
|
|
530
|
-
const component = PlaitElement.getComponent(element);
|
|
531
|
-
if (component && component.parent) {
|
|
532
|
-
return component.parent.origin;
|
|
533
|
-
}
|
|
534
|
-
return undefined;
|
|
535
|
-
}
|
|
536
706
|
function findUpElement(element) {
|
|
537
707
|
let branch;
|
|
538
708
|
let root = element;
|
|
539
|
-
let parent =
|
|
709
|
+
let parent = MindElement.findParent(element);
|
|
540
710
|
while (parent) {
|
|
541
711
|
branch = root;
|
|
542
712
|
root = parent;
|
|
543
|
-
parent =
|
|
713
|
+
parent = MindElement.findParent(parent);
|
|
544
714
|
}
|
|
545
715
|
return { root, branch };
|
|
546
716
|
}
|
|
@@ -551,16 +721,16 @@ const getChildrenCount = (element) => {
|
|
|
551
721
|
return count + element.children.length;
|
|
552
722
|
};
|
|
553
723
|
const isChildElement = (origin, child) => {
|
|
554
|
-
let parent =
|
|
724
|
+
let parent = MindElement.findParent(child);
|
|
555
725
|
while (parent) {
|
|
556
726
|
if (parent === origin) {
|
|
557
727
|
return true;
|
|
558
728
|
}
|
|
559
|
-
parent =
|
|
729
|
+
parent = MindElement.findParent(parent);
|
|
560
730
|
}
|
|
561
731
|
return false;
|
|
562
732
|
};
|
|
563
|
-
const
|
|
733
|
+
const getFirstLevelElement = (elements) => {
|
|
564
734
|
let result = [];
|
|
565
735
|
elements.forEach(element => {
|
|
566
736
|
const isChild = elements.some(node => {
|
|
@@ -650,7 +820,7 @@ const changeRightNodeCount = (board, parentPath, changeNumber) => {
|
|
|
650
820
|
}, parentPath);
|
|
651
821
|
};
|
|
652
822
|
const shouldChangeRightNodeCount = (selectedElement) => {
|
|
653
|
-
const parentElement =
|
|
823
|
+
const parentElement = MindElement.findParent(selectedElement);
|
|
654
824
|
if (parentElement) {
|
|
655
825
|
const nodeIndex = parentElement.children.findIndex(item => item.id === selectedElement.id);
|
|
656
826
|
if (parentElement.isRoot &&
|
|
@@ -663,13 +833,13 @@ const shouldChangeRightNodeCount = (selectedElement) => {
|
|
|
663
833
|
return false;
|
|
664
834
|
};
|
|
665
835
|
const createDefaultMindMapElement = (point, rightNodeCount, layout) => {
|
|
666
|
-
const root = createMindElement('思维导图', 72, ROOT_DEFAULT_HEIGHT, { shape:
|
|
836
|
+
const root = createMindElement('思维导图', 72, ROOT_DEFAULT_HEIGHT, { shape: MindElementShape.roundRectangle, layout });
|
|
667
837
|
root.rightNodeCount = rightNodeCount;
|
|
668
838
|
root.isRoot = true;
|
|
669
839
|
root.type = 'mindmap';
|
|
670
840
|
root.points = [point];
|
|
671
841
|
const children = [1, 1, 1].map(() => {
|
|
672
|
-
return createMindElement('新建节点', 56, TEXT_DEFAULT_HEIGHT, { shape:
|
|
842
|
+
return createMindElement('新建节点', 56, TEXT_DEFAULT_HEIGHT, { shape: MindElementShape.roundRectangle });
|
|
673
843
|
});
|
|
674
844
|
root.children = children;
|
|
675
845
|
return root;
|
|
@@ -706,11 +876,14 @@ const createMindElement = (text, width, height, options) => {
|
|
|
706
876
|
if (options.branchColor) {
|
|
707
877
|
newElement.branchColor = options.branchColor;
|
|
708
878
|
}
|
|
879
|
+
if (!isNullOrUndefined(options.branchWidth)) {
|
|
880
|
+
newElement.branchWidth = options.branchWidth;
|
|
881
|
+
}
|
|
709
882
|
return newElement;
|
|
710
883
|
};
|
|
711
884
|
// layoutLevel 用来表示插入兄弟节点还是子节点
|
|
712
885
|
const insertMindElement = (board, inheritNode, path) => {
|
|
713
|
-
let fill, strokeColor, strokeWidth, shape =
|
|
886
|
+
let fill, strokeColor, strokeWidth, shape = MindElementShape.roundRectangle;
|
|
714
887
|
if (!inheritNode.isRoot) {
|
|
715
888
|
fill = inheritNode.fill;
|
|
716
889
|
strokeColor = inheritNode.strokeColor;
|
|
@@ -733,63 +906,23 @@ const findLastChild = (child) => {
|
|
|
733
906
|
return result;
|
|
734
907
|
};
|
|
735
908
|
const deleteSelectedELements = (board, selectedElements) => {
|
|
909
|
+
const deletableElements = getFirstLevelElement(selectedElements).reverse();
|
|
910
|
+
const abstractRefs = deleteElementHandleAbstract(board, deletableElements);
|
|
911
|
+
MindTransforms.setAbstractsByRefs(board, abstractRefs);
|
|
736
912
|
//翻转,从下到上修改,防止找不到 path
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
deletableElements.forEach(node => {
|
|
741
|
-
if (!PlaitMind.isMind(node)) {
|
|
742
|
-
const behindAbstracts = getBehindAbstracts(node).filter(abstract => !deletableElements.includes(abstract));
|
|
743
|
-
if (behindAbstracts.length) {
|
|
744
|
-
behindAbstracts.forEach(abstract => {
|
|
745
|
-
let newProperties = accumulativeProperties.get(abstract);
|
|
746
|
-
if (!newProperties) {
|
|
747
|
-
newProperties = { start: abstract.start, end: abstract.end };
|
|
748
|
-
accumulativeProperties.set(abstract, newProperties);
|
|
749
|
-
relativeAbstracts.push(abstract);
|
|
750
|
-
}
|
|
751
|
-
newProperties.start = newProperties.start - 1;
|
|
752
|
-
newProperties.end = newProperties.end - 1;
|
|
753
|
-
});
|
|
754
|
-
}
|
|
755
|
-
const correspondingAbstract = getCorrespondingAbstract(node);
|
|
756
|
-
if (correspondingAbstract && !deletableElements.includes(correspondingAbstract)) {
|
|
757
|
-
let newProperties = accumulativeProperties.get(correspondingAbstract);
|
|
758
|
-
if (!newProperties) {
|
|
759
|
-
newProperties = { start: correspondingAbstract.start, end: correspondingAbstract.end };
|
|
760
|
-
accumulativeProperties.set(correspondingAbstract, newProperties);
|
|
761
|
-
relativeAbstracts.push(correspondingAbstract);
|
|
762
|
-
}
|
|
763
|
-
newProperties.end = newProperties.end - 1;
|
|
764
|
-
}
|
|
765
|
-
}
|
|
766
|
-
});
|
|
767
|
-
const abstractHandles = relativeAbstracts.map(value => {
|
|
768
|
-
const newProperties = accumulativeProperties.get(value);
|
|
769
|
-
if (newProperties) {
|
|
770
|
-
const path = PlaitBoard.findPath(board, value);
|
|
771
|
-
return () => {
|
|
772
|
-
if (newProperties.start > newProperties.end) {
|
|
773
|
-
Transforms.removeNode(board, path);
|
|
774
|
-
}
|
|
775
|
-
else {
|
|
776
|
-
Transforms.setNode(board, newProperties, path);
|
|
777
|
-
}
|
|
778
|
-
};
|
|
779
|
-
}
|
|
780
|
-
return () => { };
|
|
781
|
-
});
|
|
782
|
-
const deletableHandles = deletableElements.map(node => {
|
|
783
|
-
const path = PlaitBoard.findPath(board, node);
|
|
913
|
+
deletableElements
|
|
914
|
+
.map(element => {
|
|
915
|
+
const path = PlaitBoard.findPath(board, element);
|
|
784
916
|
return () => {
|
|
785
|
-
if (shouldChangeRightNodeCount(
|
|
786
|
-
changeRightNodeCount(board, path.slice(0,
|
|
917
|
+
if (shouldChangeRightNodeCount(element)) {
|
|
918
|
+
changeRightNodeCount(board, path.slice(0, 1), -1);
|
|
787
919
|
}
|
|
788
920
|
Transforms.removeNode(board, path);
|
|
789
921
|
};
|
|
922
|
+
})
|
|
923
|
+
.forEach(action => {
|
|
924
|
+
action();
|
|
790
925
|
});
|
|
791
|
-
abstractHandles.forEach(action => action());
|
|
792
|
-
deletableHandles.forEach(action => action());
|
|
793
926
|
};
|
|
794
927
|
const divideElementByParent = (elements) => {
|
|
795
928
|
const abstractIncludedGroups = [];
|
|
@@ -808,65 +941,70 @@ const divideElementByParent = (elements) => {
|
|
|
808
941
|
return { parentElements, abstractIncludedGroups };
|
|
809
942
|
};
|
|
810
943
|
|
|
811
|
-
const
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
944
|
+
const getAvailableProperty = (board, element, propertyKey) => {
|
|
945
|
+
const ancestors = MindElement.getAncestors(board, element);
|
|
946
|
+
ancestors.unshift(element);
|
|
947
|
+
const ancestor = ancestors.find(value => value[propertyKey]);
|
|
948
|
+
if (ancestor) {
|
|
949
|
+
return ancestor[propertyKey];
|
|
815
950
|
}
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
if (parent.shape) {
|
|
819
|
-
return parent.shape;
|
|
820
|
-
}
|
|
821
|
-
parent = findParentElement(parent);
|
|
951
|
+
else {
|
|
952
|
+
return undefined;
|
|
822
953
|
}
|
|
823
|
-
return MindNodeShape.roundRectangle;
|
|
824
954
|
};
|
|
825
955
|
|
|
956
|
+
/**
|
|
957
|
+
* Processing of branch color, width, style, etc. of the mind node
|
|
958
|
+
*/
|
|
826
959
|
const getBranchColorByMindElement = (board, element) => {
|
|
827
|
-
const
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
if (
|
|
836
|
-
|
|
837
|
-
const length = COLORS.length;
|
|
838
|
-
const remainder = index % length;
|
|
839
|
-
return COLORS[remainder];
|
|
960
|
+
const branchColor = getAvailableProperty(board, element, 'branchColor');
|
|
961
|
+
return branchColor || getDefaultBranchColor(board, element);
|
|
962
|
+
};
|
|
963
|
+
const getBranchWidthByMindElement = (board, element) => {
|
|
964
|
+
const branchWidth = getAvailableProperty(board, element, 'branchWidth');
|
|
965
|
+
return branchWidth || BRANCH_WIDTH;
|
|
966
|
+
};
|
|
967
|
+
const getAbstractBranchWidth = (board, element) => {
|
|
968
|
+
if (!isNullOrUndefined(element.branchWidth)) {
|
|
969
|
+
return element.branchWidth;
|
|
840
970
|
}
|
|
841
|
-
|
|
842
|
-
|
|
971
|
+
return DefaultAbstractNodeStyle.branchWidth;
|
|
972
|
+
};
|
|
973
|
+
const getAbstractBranchColor = (board, element) => {
|
|
974
|
+
if (element.branchColor) {
|
|
975
|
+
return element.branchColor;
|
|
843
976
|
}
|
|
977
|
+
return DefaultAbstractNodeStyle.branchColor;
|
|
844
978
|
};
|
|
845
979
|
const getNextBranchColor = (root) => {
|
|
846
980
|
const index = root.children.length;
|
|
847
|
-
|
|
981
|
+
return getDefaultBranchColorByIndex(index);
|
|
982
|
+
};
|
|
983
|
+
const getDefaultBranchColor = (board, element) => {
|
|
984
|
+
const path = PlaitBoard.findPath(board, element);
|
|
985
|
+
return getDefaultBranchColorByIndex(path[1]);
|
|
986
|
+
};
|
|
987
|
+
const getDefaultBranchColorByIndex = (index) => {
|
|
988
|
+
const length = BRANCH_COLORS.length;
|
|
848
989
|
const remainder = index % length;
|
|
849
|
-
return
|
|
990
|
+
return BRANCH_COLORS[remainder];
|
|
850
991
|
};
|
|
851
992
|
|
|
852
993
|
const getStrokeByMindElement = (board, element) => {
|
|
994
|
+
if (PlaitMind.isMind(element)) {
|
|
995
|
+
return element.strokeColor || DefaultRootStyle.strokeColor;
|
|
996
|
+
}
|
|
853
997
|
const ancestors = MindElement.getAncestors(board, element);
|
|
854
998
|
ancestors.unshift(element);
|
|
855
999
|
const ancestor = ancestors.find(value => value.strokeColor);
|
|
856
|
-
if (ancestor && ancestor.strokeColor) {
|
|
1000
|
+
if (ancestor && ancestor.strokeColor && !PlaitMind.isMind(ancestor)) {
|
|
857
1001
|
return ancestor.strokeColor;
|
|
858
1002
|
}
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
const remainder = index % length;
|
|
865
|
-
return COLORS[remainder];
|
|
866
|
-
}
|
|
867
|
-
else {
|
|
868
|
-
return ROOT_NODE_STROKE;
|
|
869
|
-
}
|
|
1003
|
+
return getDefaultBranchColor(board, element);
|
|
1004
|
+
};
|
|
1005
|
+
const getShapeByElement = (board, element) => {
|
|
1006
|
+
const shape = getAvailableProperty(board, element, 'shape');
|
|
1007
|
+
return shape || MindElementShape.roundRectangle;
|
|
870
1008
|
};
|
|
871
1009
|
|
|
872
1010
|
function isVirtualKey(e) {
|
|
@@ -883,7 +1021,7 @@ function isVirtualKey(e) {
|
|
|
883
1021
|
|
|
884
1022
|
function drawLink(board, node, child, defaultStroke = null, isHorizontal = true, needDrawUnderline = true) {
|
|
885
1023
|
let beginX, beginY, endX, endY, beginNode = node, endNode = child;
|
|
886
|
-
const layout = MindQueries.getCorrectLayoutByElement(node.origin);
|
|
1024
|
+
const layout = MindQueries.getCorrectLayoutByElement(board, node.origin);
|
|
887
1025
|
if (isHorizontal) {
|
|
888
1026
|
if (!isChildRight(node, child)) {
|
|
889
1027
|
beginNode = child;
|
|
@@ -895,7 +1033,7 @@ function drawLink(board, node, child, defaultStroke = null, isHorizontal = true,
|
|
|
895
1033
|
endY = endNode.y + endNode.height / 2;
|
|
896
1034
|
if (node.parent &&
|
|
897
1035
|
isIndentedLayout(MindQueries.getLayoutByElement(node.parent?.origin)) &&
|
|
898
|
-
|
|
1036
|
+
getShapeByElement(board, node.origin) === MindElementShape.underline) {
|
|
899
1037
|
if (isChildRight(node, child)) {
|
|
900
1038
|
beginY = node.y + node.height - node.vGap;
|
|
901
1039
|
}
|
|
@@ -939,7 +1077,7 @@ function drawLink(board, node, child, defaultStroke = null, isHorizontal = true,
|
|
|
939
1077
|
[endX - (beginNode.hGap + endNode.hGap) / 2, endY],
|
|
940
1078
|
[endX, endY]
|
|
941
1079
|
];
|
|
942
|
-
const shape =
|
|
1080
|
+
const shape = getShapeByElement(board, child.origin);
|
|
943
1081
|
if (!node.origin.isRoot) {
|
|
944
1082
|
if (node.x > child.x) {
|
|
945
1083
|
curve = [
|
|
@@ -970,7 +1108,7 @@ function drawLink(board, node, child, defaultStroke = null, isHorizontal = true,
|
|
|
970
1108
|
curve = [...line, ...curve];
|
|
971
1109
|
}
|
|
972
1110
|
}
|
|
973
|
-
if (needDrawUnderline && shape ===
|
|
1111
|
+
if (needDrawUnderline && shape === MindElementShape.underline) {
|
|
974
1112
|
if (child.left) {
|
|
975
1113
|
const underline = [
|
|
976
1114
|
[beginX - (beginNode.width - beginNode.hGap * 2), beginY],
|
|
@@ -1039,15 +1177,16 @@ const drawPlaceholderDropNodeG = (board, dropTarget, fakeDropNodeG) => {
|
|
|
1039
1177
|
if (dropTarget.detectResult && ['right', 'left'].includes(dropTarget.detectResult)) {
|
|
1040
1178
|
drawStraightDropNodeG(board, targetRect, dropTarget.detectResult, targetComponent, fakeDropNodeG);
|
|
1041
1179
|
}
|
|
1042
|
-
|
|
1043
|
-
|
|
1180
|
+
const targetParent = MindElement.findParent(targetComponent.element);
|
|
1181
|
+
if (targetParent && dropTarget.detectResult && ['top', 'bottom'].includes(dropTarget.detectResult)) {
|
|
1182
|
+
const parentComponent = PlaitElement.getComponent(targetParent);
|
|
1044
1183
|
const targetIndex = parentComponent.node.origin.children.indexOf(targetComponent.node.origin);
|
|
1045
1184
|
drawCurvePlaceholderDropNodeG(board, targetRect, dropTarget.detectResult, targetIndex, targetComponent, parentComponent, fakeDropNodeG);
|
|
1046
1185
|
}
|
|
1047
1186
|
};
|
|
1048
1187
|
const drawCurvePlaceholderDropNodeG = (board, targetRect, detectResult, targetIndex, targetComponent, parentComponent, fakeDropNodeG) => {
|
|
1049
|
-
const parentNodeLayout = MindQueries.getCorrectLayoutByElement(parentComponent.node.origin);
|
|
1050
|
-
const layout = MindQueries.getCorrectLayoutByElement(targetComponent.node.parent.origin);
|
|
1188
|
+
const parentNodeLayout = MindQueries.getCorrectLayoutByElement(board, parentComponent.node.origin);
|
|
1189
|
+
const layout = MindQueries.getCorrectLayoutByElement(board, targetComponent.node.parent.origin);
|
|
1051
1190
|
const strokeWidth = targetComponent.node.origin.branchWidth ? targetComponent.node.origin.branchWidth : STROKE_WIDTH;
|
|
1052
1191
|
let fakeX = targetComponent.node.x, fakeY = targetRect.y - 30, fakeRectangleStartX = targetRect.x, fakeRectangleEndX = targetRect.x + 30, fakeRectangleStartY = fakeY, fakeRectangleEndY = fakeRectangleStartY + 12, width = 30;
|
|
1053
1192
|
if (isLeftLayout(layout)) {
|
|
@@ -1082,7 +1221,7 @@ const drawCurvePlaceholderDropNodeG = (board, targetRect, detectResult, targetIn
|
|
|
1082
1221
|
}
|
|
1083
1222
|
if (isVerticalLogicLayout(layout)) {
|
|
1084
1223
|
parentComponent = targetComponent;
|
|
1085
|
-
targetComponent = PlaitElement.getComponent(targetComponent.
|
|
1224
|
+
targetComponent = PlaitElement.getComponent(MindElement.getParent(targetComponent.element));
|
|
1086
1225
|
fakeX = parentComponent.node.x;
|
|
1087
1226
|
width = parentComponent.node.width;
|
|
1088
1227
|
const vGap = BASE * 6 + strokeWidth;
|
|
@@ -1178,8 +1317,8 @@ const drawStraightDropNodeG = (board, targetRect, detectResult, targetComponent,
|
|
|
1178
1317
|
height,
|
|
1179
1318
|
strokeWidth
|
|
1180
1319
|
};
|
|
1181
|
-
const parentLayout = MindQueries.getCorrectLayoutByElement(targetComponent.node.origin.isRoot ? targetComponent.node.origin : targetComponent.node.parent.origin);
|
|
1182
|
-
const layout = MindQueries.getCorrectLayoutByElement(targetComponent.node.origin);
|
|
1320
|
+
const parentLayout = MindQueries.getCorrectLayoutByElement(board, targetComponent.node.origin.isRoot ? targetComponent.node.origin : targetComponent.node.parent.origin);
|
|
1321
|
+
const layout = MindQueries.getCorrectLayoutByElement(board, targetComponent.node.origin);
|
|
1183
1322
|
if (!isMixedLayout(parentLayout, layout)) {
|
|
1184
1323
|
// 构造一条直线
|
|
1185
1324
|
let linePoints = [
|
|
@@ -1203,7 +1342,7 @@ const drawStraightDropNodeG = (board, targetRect, detectResult, targetComponent,
|
|
|
1203
1342
|
* b. 最后一个节点的右侧:固定值(来源于 getMainAxle,第二级节点:BASE * 8,其他 BASE * 3 + strokeWidth / 2);
|
|
1204
1343
|
*/
|
|
1205
1344
|
fakeY = targetComponent.node.y;
|
|
1206
|
-
const parentComponent = PlaitElement.getComponent(targetComponent.
|
|
1345
|
+
const parentComponent = PlaitElement.getComponent(MindElement.getParent(targetComponent.element));
|
|
1207
1346
|
const targetIndex = parentComponent.node.origin.children.indexOf(targetComponent.node.origin);
|
|
1208
1347
|
if (detectResult === 'left') {
|
|
1209
1348
|
let offsetX = 0;
|
|
@@ -1389,29 +1528,29 @@ const directionDetector = (targetNode, centerPoint) => {
|
|
|
1389
1528
|
return null;
|
|
1390
1529
|
};
|
|
1391
1530
|
|
|
1392
|
-
const directionCorrector = (node, detectResults) => {
|
|
1393
|
-
if (!node.origin.isRoot) {
|
|
1394
|
-
const
|
|
1395
|
-
if (isStandardLayout(
|
|
1531
|
+
const directionCorrector = (board, node, detectResults) => {
|
|
1532
|
+
if (!node.origin.isRoot && !AbstractNode.isAbstract(node.origin)) {
|
|
1533
|
+
const parentLayout = MindQueries.getCorrectLayoutByElement(board, node?.parent.origin);
|
|
1534
|
+
if (isStandardLayout(parentLayout)) {
|
|
1396
1535
|
const idx = node.parent.children.findIndex(x => x === node);
|
|
1397
1536
|
const isLeft = idx >= (node.parent.origin.rightNodeCount || 0);
|
|
1398
1537
|
return getAllowedDirection(detectResults, [isLeft ? 'right' : 'left']);
|
|
1399
1538
|
}
|
|
1400
|
-
if (isLeftLayout(
|
|
1539
|
+
if (isLeftLayout(parentLayout)) {
|
|
1401
1540
|
return getAllowedDirection(detectResults, ['right']);
|
|
1402
1541
|
}
|
|
1403
|
-
if (isRightLayout(
|
|
1542
|
+
if (isRightLayout(parentLayout)) {
|
|
1404
1543
|
return getAllowedDirection(detectResults, ['left']);
|
|
1405
1544
|
}
|
|
1406
|
-
if (
|
|
1545
|
+
if (parentLayout === MindLayoutType.upward) {
|
|
1407
1546
|
return getAllowedDirection(detectResults, ['bottom']);
|
|
1408
1547
|
}
|
|
1409
|
-
if (
|
|
1548
|
+
if (parentLayout === MindLayoutType.downward) {
|
|
1410
1549
|
return getAllowedDirection(detectResults, ['top']);
|
|
1411
1550
|
}
|
|
1412
1551
|
}
|
|
1413
1552
|
else {
|
|
1414
|
-
const layout = MindQueries.getCorrectLayoutByElement(node?.origin);
|
|
1553
|
+
const layout = MindQueries.getCorrectLayoutByElement(board, node?.origin);
|
|
1415
1554
|
if (isStandardLayout(layout)) {
|
|
1416
1555
|
return getAllowedDirection(detectResults, ['top', 'bottom']);
|
|
1417
1556
|
}
|
|
@@ -1442,17 +1581,18 @@ const getAllowedDirection = (detectResults, illegalDirections) => {
|
|
|
1442
1581
|
};
|
|
1443
1582
|
|
|
1444
1583
|
/* 根据布局调整 target 以及 direction */
|
|
1445
|
-
const readjustmentDropTarget = (dropTarget) => {
|
|
1584
|
+
const readjustmentDropTarget = (board, dropTarget) => {
|
|
1446
1585
|
const { target, detectResult } = dropTarget;
|
|
1447
1586
|
const newDropTarget = { target, detectResult };
|
|
1448
1587
|
const targetComponent = PlaitElement.getComponent(target);
|
|
1449
1588
|
if (targetComponent.node.children.length > 0 && dropTarget.detectResult) {
|
|
1450
|
-
const layout = MindQueries.getCorrectLayoutByElement(targetComponent.node.origin);
|
|
1451
|
-
const parentLayout = MindQueries.getCorrectLayoutByElement(targetComponent.node.origin.isRoot ? targetComponent.node.origin : targetComponent.node.parent.origin);
|
|
1589
|
+
const layout = MindQueries.getCorrectLayoutByElement(board, targetComponent.node.origin);
|
|
1590
|
+
const parentLayout = MindQueries.getCorrectLayoutByElement(board, targetComponent.node.origin.isRoot ? targetComponent.node.origin : targetComponent.node.parent.origin);
|
|
1591
|
+
const children = getNonAbstractChildren(targetComponent.node);
|
|
1452
1592
|
if (['right', 'left'].includes(dropTarget.detectResult)) {
|
|
1453
1593
|
if (!isMixedLayout(parentLayout, layout)) {
|
|
1454
1594
|
if (targetComponent.node.origin.isRoot) {
|
|
1455
|
-
const layout = MindQueries.getCorrectLayoutByElement(targetComponent.node.origin);
|
|
1595
|
+
const layout = MindQueries.getCorrectLayoutByElement(board, targetComponent.node.origin);
|
|
1456
1596
|
// 标准布局,根节点
|
|
1457
1597
|
if (isStandardLayout(layout)) {
|
|
1458
1598
|
const rightNodeCount = targetComponent.node.origin.rightNodeCount;
|
|
@@ -1486,14 +1626,14 @@ const readjustmentDropTarget = (dropTarget) => {
|
|
|
1486
1626
|
return newDropTarget;
|
|
1487
1627
|
}
|
|
1488
1628
|
// 剩下是水平布局的默认情况:插入最后一个子节点的下方
|
|
1489
|
-
const lastChildNodeIndex =
|
|
1629
|
+
const lastChildNodeIndex = children.length - 1;
|
|
1490
1630
|
newDropTarget.target = targetComponent.node.children[lastChildNodeIndex].origin;
|
|
1491
1631
|
newDropTarget.detectResult = 'bottom';
|
|
1492
1632
|
}
|
|
1493
1633
|
else {
|
|
1494
1634
|
// 处理左右布局下的混合布局
|
|
1495
1635
|
if ([MindLayoutType.left, MindLayoutType.right].includes(parentLayout)) {
|
|
1496
|
-
const layout = MindQueries.getCorrectLayoutByElement(targetComponent.node.origin);
|
|
1636
|
+
const layout = MindQueries.getCorrectLayoutByElement(board, targetComponent.node.origin);
|
|
1497
1637
|
if (isIndentedLayout(layout)) {
|
|
1498
1638
|
newDropTarget.target = targetComponent.node.children[0].origin;
|
|
1499
1639
|
newDropTarget.detectResult = isTopLayout(layout) ? 'bottom' : 'top';
|
|
@@ -1510,9 +1650,9 @@ const readjustmentDropTarget = (dropTarget) => {
|
|
|
1510
1650
|
return newDropTarget;
|
|
1511
1651
|
}
|
|
1512
1652
|
// 上下布局,插到右边
|
|
1513
|
-
const parentLayout = MindQueries.getCorrectLayoutByElement(targetComponent.node.origin.isRoot ? targetComponent.node.origin : targetComponent.node.parent.origin);
|
|
1653
|
+
const parentLayout = MindQueries.getCorrectLayoutByElement(board, targetComponent.node.origin.isRoot ? targetComponent.node.origin : targetComponent.node.parent.origin);
|
|
1514
1654
|
if (isVerticalLogicLayout(parentLayout)) {
|
|
1515
|
-
const lastChildNodeIndex =
|
|
1655
|
+
const lastChildNodeIndex = children.length - 1;
|
|
1516
1656
|
newDropTarget.target = targetComponent.node.children[lastChildNodeIndex].origin;
|
|
1517
1657
|
newDropTarget.detectResult = 'right';
|
|
1518
1658
|
return newDropTarget;
|
|
@@ -1623,7 +1763,7 @@ const getLocationScope = (board, handlePosition, parentChildren, element, parent
|
|
|
1623
1763
|
}
|
|
1624
1764
|
};
|
|
1625
1765
|
const getHitAbstractHandle = (board, element, point) => {
|
|
1626
|
-
const nodeLayout = MindQueries.getCorrectLayoutByElement(element);
|
|
1766
|
+
const nodeLayout = MindQueries.getCorrectLayoutByElement(board, element);
|
|
1627
1767
|
const isHorizontal = isHorizontalLayout(nodeLayout);
|
|
1628
1768
|
const parentElement = MindElement.getParent(element);
|
|
1629
1769
|
const includedElements = parentElement.children.slice(element.start, element.end + 1);
|
|
@@ -1710,24 +1850,25 @@ function handleTouchedAbstract(board, touchedAbstract, endPoint) {
|
|
|
1710
1850
|
}
|
|
1711
1851
|
|
|
1712
1852
|
function drawIndentedLink(board, node, child, defaultStroke = null, needDrawUnderline = true) {
|
|
1713
|
-
const
|
|
1853
|
+
const branchWidth = getBranchWidthByMindElement(board, child.origin);
|
|
1854
|
+
const branchColor = defaultStroke || getBranchColorByMindElement(board, child.origin);
|
|
1855
|
+
const isUnderlineShape = getShapeByElement(board, child.origin) === MindElementShape.underline;
|
|
1714
1856
|
let beginX, beginY, endX, endY, beginNode = node, endNode = child;
|
|
1715
1857
|
const beginRectangle = getRectangleByNode(beginNode);
|
|
1716
1858
|
const endRectangle = getRectangleByNode(endNode);
|
|
1717
1859
|
beginX = beginNode.x + beginNode.width / 2;
|
|
1718
1860
|
beginY = isChildUp(node, child) ? beginRectangle.y : beginRectangle.y + beginRectangle.height;
|
|
1719
1861
|
endX = node.left ? endNode.x + endNode.hGap + endRectangle.width : endNode.x + endNode.hGap;
|
|
1720
|
-
endY =
|
|
1862
|
+
endY = isUnderlineShape ? endNode.y + endNode.height - endNode.vGap : endNode.y + endNode.height / 2;
|
|
1721
1863
|
//根据位置,设置正负参数
|
|
1722
1864
|
let plusMinus = isChildUp(node, child) ? (node.left ? [-1, -1] : [1, -1]) : node.left ? [-1, 1] : [1, 1];
|
|
1723
|
-
const layout = MindQueries.getCorrectLayoutByElement(node.origin);
|
|
1724
|
-
const strokeWidth = child.origin.branchWidth ? child.origin.branchWidth : STROKE_WIDTH;
|
|
1865
|
+
const layout = MindQueries.getCorrectLayoutByElement(board, node.origin);
|
|
1725
1866
|
if (beginNode.origin.isRoot) {
|
|
1726
1867
|
if (layout === MindLayoutType.leftBottomIndented || layout === MindLayoutType.rightBottomIndented) {
|
|
1727
|
-
beginY +=
|
|
1868
|
+
beginY += branchWidth;
|
|
1728
1869
|
}
|
|
1729
1870
|
if (layout === MindLayoutType.leftTopIndented || layout === MindLayoutType.rightTopIndented) {
|
|
1730
|
-
beginY -=
|
|
1871
|
+
beginY -= branchWidth;
|
|
1731
1872
|
}
|
|
1732
1873
|
}
|
|
1733
1874
|
let curve = [
|
|
@@ -1738,13 +1879,12 @@ function drawIndentedLink(board, node, child, defaultStroke = null, needDrawUnde
|
|
|
1738
1879
|
[beginX, endY - (endNode.hGap * plusMinus[1]) / 5],
|
|
1739
1880
|
[beginX + (endNode.hGap * plusMinus[0]) / 4, endY],
|
|
1740
1881
|
[beginX + (endNode.hGap * plusMinus[0] * 3) / 5, endY],
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1882
|
+
isUnderlineShape && needDrawUnderline ? [endX + (endNode.width - endNode.hGap * 2) * plusMinus[0], endY] : [endX, endY],
|
|
1883
|
+
isUnderlineShape && needDrawUnderline ? [endX + (endNode.width - endNode.hGap * 2) * plusMinus[0], endY] : [endX, endY],
|
|
1884
|
+
isUnderlineShape && needDrawUnderline ? [endX + (endNode.width - endNode.hGap * 2) * plusMinus[0], endY] : [endX, endY]
|
|
1744
1885
|
];
|
|
1745
|
-
const stroke = defaultStroke || getBranchColorByMindElement(board, child.origin);
|
|
1746
1886
|
const points = pointsOnBezierCurves(curve);
|
|
1747
|
-
return PlaitBoard.getRoughSVG(board).curve(points, { stroke, strokeWidth });
|
|
1887
|
+
return PlaitBoard.getRoughSVG(board).curve(points, { stroke: branchColor, strokeWidth: branchWidth });
|
|
1748
1888
|
}
|
|
1749
1889
|
|
|
1750
1890
|
var HorizontalPlacement;
|
|
@@ -1859,10 +1999,12 @@ const transformPlacement = (placement, direction) => {
|
|
|
1859
1999
|
|
|
1860
2000
|
function drawLogicLink(board, node, parent, isHorizontal) {
|
|
1861
2001
|
const branchColor = getBranchColorByMindElement(board, node.origin);
|
|
1862
|
-
const
|
|
2002
|
+
const branchWidth = getBranchWidthByMindElement(board, node.origin);
|
|
1863
2003
|
const hasStraightLine = !parent.origin.isRoot;
|
|
1864
|
-
const
|
|
1865
|
-
const
|
|
2004
|
+
const parentShape = getShapeByElement(board, parent.origin);
|
|
2005
|
+
const shape = node.origin.shape ? node.origin.shape : parentShape;
|
|
2006
|
+
const hasUnderlineShape = shape === MindElementShape.underline;
|
|
2007
|
+
const hasUnderlineShapeOfParent = parentShape === MindElementShape.underline;
|
|
1866
2008
|
const nodeClient = getRectangleByNode(node);
|
|
1867
2009
|
const parentClient = getRectangleByNode(parent);
|
|
1868
2010
|
const linkDirection = getLayoutDirection(node, isHorizontal);
|
|
@@ -1899,10 +2041,10 @@ function drawLogicLink(board, node, parent, isHorizontal) {
|
|
|
1899
2041
|
const underlineEnd = movePoint(endPoint, nodeClient.width, linkDirection);
|
|
1900
2042
|
const underline = hasUnderlineShape && isHorizontal ? [underlineEnd, underlineEnd, underlineEnd] : [];
|
|
1901
2043
|
const points = pointsOnBezierCurves([...straightLine, ...curve, ...underline]);
|
|
1902
|
-
return PlaitBoard.getRoughSVG(board).curve(points, { stroke: branchColor, strokeWidth });
|
|
2044
|
+
return PlaitBoard.getRoughSVG(board).curve(points, { stroke: branchColor, strokeWidth: branchWidth });
|
|
1903
2045
|
}
|
|
1904
2046
|
|
|
1905
|
-
function
|
|
2047
|
+
function getEmojisWidthHeight(board, element) {
|
|
1906
2048
|
const options = board.getMindOptions();
|
|
1907
2049
|
const count = element.data.emojis.length;
|
|
1908
2050
|
const fontSize = getEmojiFontSize(element);
|
|
@@ -1919,6 +2061,31 @@ function getEmojiFontSize(element) {
|
|
|
1919
2061
|
return 14 + 2;
|
|
1920
2062
|
}
|
|
1921
2063
|
}
|
|
2064
|
+
function getEmojiRectangle(board, element) {
|
|
2065
|
+
let { x, y } = getRectangleByNode(MindElement.getNode(element));
|
|
2066
|
+
x = x + NodeSpace.getEmojiLeftSpace(board, element);
|
|
2067
|
+
const { width, height } = getEmojisWidthHeight(board, element);
|
|
2068
|
+
return {
|
|
2069
|
+
x,
|
|
2070
|
+
y,
|
|
2071
|
+
width,
|
|
2072
|
+
height
|
|
2073
|
+
};
|
|
2074
|
+
}
|
|
2075
|
+
function getEmojiForeignRectangle(board, element) {
|
|
2076
|
+
let { x, y } = getRectangleByNode(MindElement.getNode(element));
|
|
2077
|
+
x = x + NodeSpace.getEmojiLeftSpace(board, element);
|
|
2078
|
+
const { width, height } = getEmojisWidthHeight(board, element);
|
|
2079
|
+
return {
|
|
2080
|
+
x,
|
|
2081
|
+
y,
|
|
2082
|
+
width,
|
|
2083
|
+
height: height + NodeSpace.getEmojiTopSpace(element) * 2
|
|
2084
|
+
};
|
|
2085
|
+
}
|
|
2086
|
+
const isHitEmojis = (board, element, point) => {
|
|
2087
|
+
return RectangleClient.isHit(RectangleClient.toRectangleClient([point, point]), getEmojiRectangle(board, element));
|
|
2088
|
+
};
|
|
1922
2089
|
|
|
1923
2090
|
const NodeDefaultSpace = {
|
|
1924
2091
|
horizontal: {
|
|
@@ -1938,26 +2105,30 @@ const RootDefaultSpace = {
|
|
|
1938
2105
|
nodeAndText: BASE * 2
|
|
1939
2106
|
}
|
|
1940
2107
|
};
|
|
1941
|
-
const getHorizontalSpaceBetweenNodeAndText = (element) => {
|
|
2108
|
+
const getHorizontalSpaceBetweenNodeAndText = (board, element) => {
|
|
1942
2109
|
const isMind = PlaitMind.isMind(element);
|
|
1943
2110
|
const nodeAndText = isMind ? RootDefaultSpace.horizontal.nodeAndText : NodeDefaultSpace.horizontal.nodeAndText;
|
|
1944
2111
|
return nodeAndText;
|
|
1945
2112
|
};
|
|
1946
|
-
const getHorizontalSpaceEmojiAndText = (element) => {
|
|
1947
|
-
const isMind = PlaitMind.isMind(element);
|
|
1948
|
-
const emojiAndText = isMind ? RootDefaultSpace.horizontal.emojiAndText : NodeDefaultSpace.horizontal.emojiAndText;
|
|
1949
|
-
return emojiAndText;
|
|
1950
|
-
};
|
|
1951
2113
|
const getVerticalSpaceBetweenNodeAndText = (element) => {
|
|
1952
2114
|
const isMind = PlaitMind.isMind(element);
|
|
1953
2115
|
const nodeAndText = isMind ? RootDefaultSpace.vertical.nodeAndText : NodeDefaultSpace.vertical.nodeAndText;
|
|
1954
2116
|
return nodeAndText;
|
|
1955
2117
|
};
|
|
2118
|
+
const getSpaceEmojiAndText = (element) => {
|
|
2119
|
+
const isMind = PlaitMind.isMind(element);
|
|
2120
|
+
const emojiAndText = isMind ? RootDefaultSpace.horizontal.emojiAndText : NodeDefaultSpace.horizontal.emojiAndText;
|
|
2121
|
+
return emojiAndText;
|
|
2122
|
+
};
|
|
1956
2123
|
const NodeSpace = {
|
|
1957
2124
|
getNodeWidth(board, element) {
|
|
1958
|
-
const nodeAndText = getHorizontalSpaceBetweenNodeAndText(element);
|
|
2125
|
+
const nodeAndText = getHorizontalSpaceBetweenNodeAndText(board, element);
|
|
1959
2126
|
if (MindElement.hasEmojis(element)) {
|
|
1960
|
-
return
|
|
2127
|
+
return (NodeSpace.getEmojiLeftSpace(board, element) +
|
|
2128
|
+
getEmojisWidthHeight(board, element).width +
|
|
2129
|
+
getSpaceEmojiAndText(element) +
|
|
2130
|
+
element.width +
|
|
2131
|
+
nodeAndText);
|
|
1961
2132
|
}
|
|
1962
2133
|
return nodeAndText + element.width + nodeAndText;
|
|
1963
2134
|
},
|
|
@@ -1965,31 +2136,32 @@ const NodeSpace = {
|
|
|
1965
2136
|
const nodeAndText = getVerticalSpaceBetweenNodeAndText(element);
|
|
1966
2137
|
return nodeAndText + element.height + nodeAndText;
|
|
1967
2138
|
},
|
|
1968
|
-
|
|
1969
|
-
const nodeAndText = getHorizontalSpaceBetweenNodeAndText(element);
|
|
2139
|
+
getTextLeftSpace(board, element) {
|
|
2140
|
+
const nodeAndText = getHorizontalSpaceBetweenNodeAndText(board, element);
|
|
1970
2141
|
if (MindElement.hasEmojis(element)) {
|
|
1971
|
-
return
|
|
2142
|
+
return NodeSpace.getEmojiLeftSpace(board, element) + getEmojisWidthHeight(board, element).width + getSpaceEmojiAndText(element);
|
|
1972
2143
|
}
|
|
1973
2144
|
else {
|
|
1974
2145
|
return nodeAndText;
|
|
1975
2146
|
}
|
|
1976
2147
|
},
|
|
1977
|
-
|
|
2148
|
+
getTextTopSpace(element) {
|
|
1978
2149
|
const nodeAndText = getVerticalSpaceBetweenNodeAndText(element);
|
|
1979
2150
|
return nodeAndText;
|
|
1980
2151
|
},
|
|
1981
|
-
|
|
1982
|
-
const
|
|
1983
|
-
|
|
2152
|
+
getEmojiLeftSpace(board, element) {
|
|
2153
|
+
const options = board.getMindOptions();
|
|
2154
|
+
const nodeAndText = getHorizontalSpaceBetweenNodeAndText(board, element);
|
|
2155
|
+
return nodeAndText - options.emojiPadding;
|
|
1984
2156
|
},
|
|
1985
|
-
|
|
2157
|
+
getEmojiTopSpace(element) {
|
|
1986
2158
|
const nodeAndText = getVerticalSpaceBetweenNodeAndText(element);
|
|
1987
2159
|
return nodeAndText;
|
|
1988
2160
|
}
|
|
1989
2161
|
};
|
|
1990
2162
|
|
|
1991
2163
|
function drawMindNodeRichtext(board, node, viewContainerRef) {
|
|
1992
|
-
const { x, y } = getRichtextRectangleByNode(board, node);
|
|
2164
|
+
const { x, y, width, height } = getRichtextRectangleByNode(board, node);
|
|
1993
2165
|
const classList = [];
|
|
1994
2166
|
if (node.origin.isRoot) {
|
|
1995
2167
|
classList.push('root-node');
|
|
@@ -2002,7 +2174,7 @@ function drawMindNodeRichtext(board, node, viewContainerRef) {
|
|
|
2002
2174
|
classList.push('child-node');
|
|
2003
2175
|
}
|
|
2004
2176
|
// COMPAT: last character can not show in safari browser
|
|
2005
|
-
return drawRichtext(x, y,
|
|
2177
|
+
return drawRichtext(x, y, width, height, node.origin.data.topic, viewContainerRef, classList);
|
|
2006
2178
|
}
|
|
2007
2179
|
function updateMindNodeTopicSize(board, node, g, isEditable) {
|
|
2008
2180
|
const { x, y, width, height } = getRichtextRectangleByNode(board, node);
|
|
@@ -2012,21 +2184,23 @@ function updateMindNodeTopicSize(board, node, g, isEditable) {
|
|
|
2012
2184
|
}
|
|
2013
2185
|
else {
|
|
2014
2186
|
// COMPAT: last character can not show in safari browser
|
|
2015
|
-
updateForeignObject(g,
|
|
2187
|
+
updateForeignObject(g, width, height, x, y);
|
|
2016
2188
|
}
|
|
2017
2189
|
}
|
|
2018
2190
|
function getRichtextRectangleByNode(board, node) {
|
|
2019
|
-
let { x, y
|
|
2020
|
-
x = x + NodeSpace.
|
|
2021
|
-
y = y + NodeSpace.
|
|
2022
|
-
|
|
2191
|
+
let { x, y } = getRectangleByNode(node);
|
|
2192
|
+
x = x + NodeSpace.getTextLeftSpace(board, node.origin);
|
|
2193
|
+
y = y + NodeSpace.getTextTopSpace(node.origin);
|
|
2194
|
+
const width = Math.ceil(node.origin.width);
|
|
2195
|
+
const height = Math.ceil(node.origin.height);
|
|
2196
|
+
return { height, width, x, y };
|
|
2023
2197
|
}
|
|
2024
2198
|
|
|
2025
2199
|
function drawRectangleNode(board, node) {
|
|
2026
2200
|
const { x, y, width, height } = getRectangleByNode(node);
|
|
2027
|
-
const fill = node.origin.fill ? node.origin.fill : node.origin.isRoot ?
|
|
2201
|
+
const fill = node.origin.fill ? node.origin.fill : node.origin.isRoot ? DefaultRootStyle.fill : DefaultNodeStyle.fill;
|
|
2028
2202
|
const stroke = getStrokeByMindElement(board, node.origin);
|
|
2029
|
-
const strokeWidth = node.origin.strokeWidth ? node.origin.strokeWidth :
|
|
2203
|
+
const strokeWidth = node.origin.strokeWidth ? node.origin.strokeWidth : DefaultNodeStyle.strokeWidth;
|
|
2030
2204
|
const nodeG = drawRoundRectangle(PlaitBoard.getRoughSVG(board), x, y, x + width, y + height, {
|
|
2031
2205
|
stroke,
|
|
2032
2206
|
strokeWidth,
|
|
@@ -2038,6 +2212,8 @@ function drawRectangleNode(board, node) {
|
|
|
2038
2212
|
|
|
2039
2213
|
function drawAbstractLink(board, node, isHorizontal) {
|
|
2040
2214
|
const linkPadding = 15;
|
|
2215
|
+
const branchWidth = getAbstractBranchWidth(board, node.origin);
|
|
2216
|
+
const branchColor = getAbstractBranchColor(board, node.origin);
|
|
2041
2217
|
const parent = node.parent;
|
|
2042
2218
|
const abstractRectangle = getRectangleByNode(node);
|
|
2043
2219
|
let includedElements = parent.children.slice(node.origin.start, node.origin.end + 1).map(node => {
|
|
@@ -2067,8 +2243,8 @@ function drawAbstractLink(board, node, isHorizontal) {
|
|
|
2067
2243
|
let c2 = movePoint(bezierEndPoint, curveDistance, linkDirection);
|
|
2068
2244
|
let bezierConnectorPoint = movePoint(abstractConnectorPoint, -linkPadding, linkDirection);
|
|
2069
2245
|
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]}`, {
|
|
2070
|
-
stroke:
|
|
2071
|
-
strokeWidth:
|
|
2246
|
+
stroke: branchColor,
|
|
2247
|
+
strokeWidth: branchWidth
|
|
2072
2248
|
});
|
|
2073
2249
|
return link;
|
|
2074
2250
|
}
|
|
@@ -2114,10 +2290,8 @@ class EmojisDrawer {
|
|
|
2114
2290
|
if (MindElement.hasEmojis(element)) {
|
|
2115
2291
|
this.g = createG();
|
|
2116
2292
|
this.g.classList.add('emojis');
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
const { width, height } = getEmojisRectangle(this.board, element);
|
|
2120
|
-
const foreignObject = createForeignObject(x, y, width, height + NodeSpace.getEmojiVerticalSpace(element) * 2);
|
|
2293
|
+
const foreignRectangle = getEmojiForeignRectangle(this.board, element);
|
|
2294
|
+
const foreignObject = createForeignObject(foreignRectangle.x, foreignRectangle.y, foreignRectangle.width, foreignRectangle.height);
|
|
2121
2295
|
this.g.append(foreignObject);
|
|
2122
2296
|
const container = document.createElement('div');
|
|
2123
2297
|
container.classList.add('node-emojis-container');
|
|
@@ -2126,117 +2300,27 @@ class EmojisDrawer {
|
|
|
2126
2300
|
const drawer = new EmojiDrawer(this.board, this.viewContainerRef);
|
|
2127
2301
|
drawer.draw(emojiItem, element);
|
|
2128
2302
|
return drawer;
|
|
2129
|
-
});
|
|
2130
|
-
this.emojiDrawers.forEach(drawer => {
|
|
2131
|
-
container.append(drawer.nativeElement);
|
|
2132
|
-
});
|
|
2133
|
-
return this.g;
|
|
2134
|
-
}
|
|
2135
|
-
return undefined;
|
|
2136
|
-
}
|
|
2137
|
-
destroy() {
|
|
2138
|
-
if (this.g) {
|
|
2139
|
-
this.g.remove();
|
|
2140
|
-
}
|
|
2141
|
-
this.emojiDrawers.forEach(drawer => drawer.destroy());
|
|
2142
|
-
this.emojiDrawers = [];
|
|
2143
|
-
}
|
|
2144
|
-
}
|
|
2145
|
-
|
|
2146
|
-
const setLayout = (board, layout, path) => {
|
|
2147
|
-
correctLogicLayoutNode(board, layout, path);
|
|
2148
|
-
const element = PlaitNode.get(board, path);
|
|
2149
|
-
if (PlaitMind.isMind(element) && isStandardLayout(layout)) {
|
|
2150
|
-
handleAbstractIncluded(board, element);
|
|
2151
|
-
}
|
|
2152
|
-
Transforms.setNode(board, { layout }, path);
|
|
2153
|
-
};
|
|
2154
|
-
const correctLogicLayoutNode = (board, layout, path) => {
|
|
2155
|
-
const node = PlaitNode.get(board, path);
|
|
2156
|
-
if (node && layout) {
|
|
2157
|
-
node.children?.forEach((value, index) => {
|
|
2158
|
-
if (value.layout) {
|
|
2159
|
-
if ((isHorizontalLogicLayout(layout) && isVerticalLogicLayout(value.layout)) ||
|
|
2160
|
-
(isVerticalLogicLayout(layout) && isHorizontalLogicLayout(value.layout))) {
|
|
2161
|
-
Transforms.setNode(board, { layout: null }, [...path, index]);
|
|
2162
|
-
}
|
|
2163
|
-
if (value.children?.length) {
|
|
2164
|
-
correctLogicLayoutNode(board, layout, [...path, index]);
|
|
2165
|
-
}
|
|
2166
|
-
}
|
|
2167
|
-
});
|
|
2168
|
-
}
|
|
2169
|
-
};
|
|
2170
|
-
|
|
2171
|
-
const setTopic = (board, element, topic, width, height) => {
|
|
2172
|
-
const newElement = {
|
|
2173
|
-
data: { topic },
|
|
2174
|
-
width: width < NODE_MIN_WIDTH * board.viewport.zoom ? NODE_MIN_WIDTH : width / board.viewport.zoom,
|
|
2175
|
-
height: height / board.viewport.zoom
|
|
2176
|
-
};
|
|
2177
|
-
if (MindElement.hasEmojis(element)) {
|
|
2178
|
-
newElement.data.emojis = element.data.emojis;
|
|
2179
|
-
}
|
|
2180
|
-
const path = PlaitBoard.findPath(board, element);
|
|
2181
|
-
Transforms.setNode(board, newElement, path);
|
|
2182
|
-
};
|
|
2183
|
-
const setTopicSize = (board, element, width, height) => {
|
|
2184
|
-
const newElement = {
|
|
2185
|
-
width: width < NODE_MIN_WIDTH * board.viewport.zoom ? NODE_MIN_WIDTH : width / board.viewport.zoom,
|
|
2186
|
-
height: height / board.viewport.zoom
|
|
2187
|
-
};
|
|
2188
|
-
const path = PlaitBoard.findPath(board, element);
|
|
2189
|
-
Transforms.setNode(board, newElement, path);
|
|
2190
|
-
};
|
|
2191
|
-
const addEmoji = (board, element, emojiItem) => {
|
|
2192
|
-
const emojis = element.data.emojis || [];
|
|
2193
|
-
const newEmojis = [...emojis];
|
|
2194
|
-
newEmojis.push(emojiItem);
|
|
2195
|
-
const newElement = {
|
|
2196
|
-
data: { topic: element.data.topic, emojis: newEmojis }
|
|
2197
|
-
};
|
|
2198
|
-
const path = PlaitBoard.findPath(board, element);
|
|
2199
|
-
Transforms.setNode(board, newElement, path);
|
|
2200
|
-
};
|
|
2201
|
-
const removeEmoji = (board, element, emojiItem) => {
|
|
2202
|
-
const emojis = element.data.emojis.filter(value => value !== emojiItem);
|
|
2203
|
-
const newElement = {
|
|
2204
|
-
data: { topic: element.data.topic }
|
|
2205
|
-
};
|
|
2206
|
-
if (emojis.length > 0) {
|
|
2207
|
-
newElement.data.emojis = emojis;
|
|
2208
|
-
}
|
|
2209
|
-
const path = PlaitBoard.findPath(board, element);
|
|
2210
|
-
Transforms.setNode(board, newElement, path);
|
|
2211
|
-
};
|
|
2212
|
-
const replaceEmoji = (board, element, oldEmoji, newEmoji) => {
|
|
2213
|
-
const newElement = {
|
|
2214
|
-
data: { topic: element.data.topic }
|
|
2215
|
-
};
|
|
2216
|
-
const newEmojis = element.data.emojis.map(value => {
|
|
2217
|
-
if (value === oldEmoji) {
|
|
2218
|
-
return newEmoji;
|
|
2303
|
+
});
|
|
2304
|
+
this.emojiDrawers.forEach(drawer => {
|
|
2305
|
+
container.append(drawer.nativeElement);
|
|
2306
|
+
});
|
|
2307
|
+
return this.g;
|
|
2219
2308
|
}
|
|
2220
|
-
return
|
|
2221
|
-
}
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
}
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
setTopicSize,
|
|
2231
|
-
addEmoji,
|
|
2232
|
-
removeEmoji,
|
|
2233
|
-
replaceEmoji
|
|
2234
|
-
};
|
|
2309
|
+
return undefined;
|
|
2310
|
+
}
|
|
2311
|
+
destroy() {
|
|
2312
|
+
if (this.g) {
|
|
2313
|
+
this.g.remove();
|
|
2314
|
+
}
|
|
2315
|
+
this.emojiDrawers.forEach(drawer => drawer.destroy());
|
|
2316
|
+
this.emojiDrawers = [];
|
|
2317
|
+
}
|
|
2318
|
+
}
|
|
2235
2319
|
|
|
2236
2320
|
function drawAbstractIncludedOutline(board, roughSVG, element, activeHandlePosition, resizingLocation) {
|
|
2237
2321
|
const abstractIncludedG = createG();
|
|
2238
2322
|
const parentElement = MindElement.getParent(element);
|
|
2239
|
-
const nodeLayout = MindQueries.getCorrectLayoutByElement(element);
|
|
2323
|
+
const nodeLayout = MindQueries.getCorrectLayoutByElement(board, element);
|
|
2240
2324
|
const isHorizontal = isHorizontalLayout(nodeLayout);
|
|
2241
2325
|
const includedElements = parentElement.children.slice(element.start, element.end + 1);
|
|
2242
2326
|
let abstractRectangle = getRectangleByElements(board, includedElements, true);
|
|
@@ -2316,7 +2400,8 @@ function hasAfterDraw(value) {
|
|
|
2316
2400
|
}
|
|
2317
2401
|
|
|
2318
2402
|
function findNewChildNodePath(board, element) {
|
|
2319
|
-
|
|
2403
|
+
const children = getNonAbstractChildren(element);
|
|
2404
|
+
return PlaitBoard.findPath(board, element).concat(children.length);
|
|
2320
2405
|
}
|
|
2321
2406
|
function findNewSiblingNodePath(board, element) {
|
|
2322
2407
|
const path = PlaitBoard.findPath(board, element);
|
|
@@ -2344,16 +2429,16 @@ class QuickInsertDrawer extends BaseDrawer {
|
|
|
2344
2429
|
* 3. 上、上左、上右
|
|
2345
2430
|
* 4. 下、下左、下右
|
|
2346
2431
|
*/
|
|
2347
|
-
const shape =
|
|
2432
|
+
const shape = getShapeByElement(this.board, element);
|
|
2348
2433
|
// 形状是矩形要偏移边框的线宽
|
|
2349
|
-
const
|
|
2434
|
+
const branchWidth = getBranchWidthByMindElement(this.board, element);
|
|
2350
2435
|
let offsetBorderLineWidth = 0;
|
|
2351
|
-
if (shape ===
|
|
2352
|
-
offsetBorderLineWidth =
|
|
2436
|
+
if (shape === MindElementShape.roundRectangle && offset === 0) {
|
|
2437
|
+
offsetBorderLineWidth = branchWidth;
|
|
2353
2438
|
}
|
|
2354
2439
|
let offsetRootBorderLineWidth = 0;
|
|
2355
2440
|
if (element.isRoot) {
|
|
2356
|
-
offsetRootBorderLineWidth =
|
|
2441
|
+
offsetRootBorderLineWidth = branchWidth;
|
|
2357
2442
|
}
|
|
2358
2443
|
// 当没有子节点时,需要缩小的偏移量
|
|
2359
2444
|
const extraOffset = 3;
|
|
@@ -2448,21 +2533,21 @@ class QuickInsertDrawer extends BaseDrawer {
|
|
|
2448
2533
|
offsetRootBorderLineWidth
|
|
2449
2534
|
}
|
|
2450
2535
|
};
|
|
2451
|
-
if (shape ===
|
|
2536
|
+
if (shape === MindElementShape.roundRectangle || element.isRoot) {
|
|
2452
2537
|
underlineCoordinates[MindLayoutType.left].startY -= height * 0.5;
|
|
2453
2538
|
underlineCoordinates[MindLayoutType.left].endY -= height * 0.5;
|
|
2454
2539
|
underlineCoordinates[MindLayoutType.right].startY -= height * 0.5;
|
|
2455
2540
|
underlineCoordinates[MindLayoutType.right].endY -= height * 0.5;
|
|
2456
2541
|
}
|
|
2457
2542
|
const branchColor = PlaitMind.isMind(element) ? getNextBranchColor(element) : getBranchColorByMindElement(this.board, element);
|
|
2458
|
-
let nodeLayout = MindQueries.getCorrectLayoutByElement(element);
|
|
2543
|
+
let nodeLayout = MindQueries.getCorrectLayoutByElement(this.board, element);
|
|
2459
2544
|
if (element.isRoot && isStandardLayout(nodeLayout)) {
|
|
2460
2545
|
const root = element;
|
|
2461
2546
|
nodeLayout = root.children.length >= root.rightNodeCount ? MindLayoutType.left : MindLayoutType.right;
|
|
2462
2547
|
}
|
|
2463
2548
|
const underlineCoordinate = underlineCoordinates[nodeLayout];
|
|
2464
2549
|
if (underlineCoordinate) {
|
|
2465
|
-
const underline = PlaitBoard.getRoughSVG(this.board).line(underlineCoordinate.startX, underlineCoordinate.startY, underlineCoordinate.endX, underlineCoordinate.endY, { stroke: branchColor, strokeWidth });
|
|
2550
|
+
const underline = PlaitBoard.getRoughSVG(this.board).line(underlineCoordinate.startX, underlineCoordinate.startY, underlineCoordinate.endX, underlineCoordinate.endY, { stroke: branchColor, strokeWidth: branchWidth });
|
|
2466
2551
|
const circleCoordinates = {
|
|
2467
2552
|
startX: underlineCoordinate.endX,
|
|
2468
2553
|
startY: underlineCoordinate.endY
|
|
@@ -2540,10 +2625,7 @@ class MindNodeComponent extends PlaitPluginElementComponent {
|
|
|
2540
2625
|
this.emojisDrawer = new EmojisDrawer(this.board, this.viewContainerRef);
|
|
2541
2626
|
this.quickInsertDrawer = new QuickInsertDrawer(this.board);
|
|
2542
2627
|
super.ngOnInit();
|
|
2543
|
-
this.node =
|
|
2544
|
-
if (!PlaitMind.isMind(this.element)) {
|
|
2545
|
-
this.parent = MindElement.getNode(MindElement.getParent(this.element));
|
|
2546
|
-
}
|
|
2628
|
+
this.node = MindElement.getNode(this.element);
|
|
2547
2629
|
this.index = NODE_TO_INDEX.get(this.element) || 0;
|
|
2548
2630
|
this.roughSVG = PlaitBoard.getRoughSVG(this.board);
|
|
2549
2631
|
this.parentG = PlaitElement.getComponent(MindElement.getRoot(this.board, this.element)).rootG;
|
|
@@ -2558,21 +2640,18 @@ class MindNodeComponent extends PlaitPluginElementComponent {
|
|
|
2558
2640
|
this.drawQuickInsert();
|
|
2559
2641
|
}
|
|
2560
2642
|
onContextChanged(value, previous) {
|
|
2561
|
-
const newNode =
|
|
2562
|
-
if (!PlaitMind.isMind(this.element)) {
|
|
2563
|
-
this.parent = MindElement.getNode(MindElement.getParent(this.element));
|
|
2564
|
-
}
|
|
2643
|
+
const newNode = MindElement.getNode(value.element);
|
|
2565
2644
|
// resolve move node richtext lose issue
|
|
2566
2645
|
if (this.node !== newNode) {
|
|
2567
2646
|
if (this.foreignObject && this.foreignObject.children.length <= 0) {
|
|
2568
2647
|
this.foreignObject?.appendChild(this.richtextComponentRef?.instance.editable);
|
|
2569
2648
|
}
|
|
2570
2649
|
}
|
|
2571
|
-
const
|
|
2650
|
+
const isEqualNode = RectangleClient.isEqual(this.node, newNode);
|
|
2572
2651
|
this.node = newNode;
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
|
|
2652
|
+
if (!isEqualNode || value.element !== previous.element) {
|
|
2653
|
+
this.drawActiveG();
|
|
2654
|
+
this.updateActiveClass();
|
|
2576
2655
|
this.drawShape();
|
|
2577
2656
|
this.drawLink();
|
|
2578
2657
|
this.updateRichtext();
|
|
@@ -2581,6 +2660,20 @@ class MindNodeComponent extends PlaitPluginElementComponent {
|
|
|
2581
2660
|
this.drawQuickInsert();
|
|
2582
2661
|
this.drawEmojis();
|
|
2583
2662
|
}
|
|
2663
|
+
else {
|
|
2664
|
+
if (value.selected !== previous.selected) {
|
|
2665
|
+
this.drawActiveG();
|
|
2666
|
+
this.updateActiveClass();
|
|
2667
|
+
}
|
|
2668
|
+
if (!PlaitMind.isMind(value.element)) {
|
|
2669
|
+
const parent = MindElement.getParent(previous.element);
|
|
2670
|
+
const newParent = MindElement.getParent(value.element);
|
|
2671
|
+
const hasSameChildren = parent.children.length === newParent.children.length;
|
|
2672
|
+
if (!hasSameChildren) {
|
|
2673
|
+
this.drawLink();
|
|
2674
|
+
}
|
|
2675
|
+
}
|
|
2676
|
+
}
|
|
2584
2677
|
}
|
|
2585
2678
|
drawEmojis() {
|
|
2586
2679
|
const g = this.emojisDrawer.drawEmojis(this.element);
|
|
@@ -2600,9 +2693,9 @@ class MindNodeComponent extends PlaitPluginElementComponent {
|
|
|
2600
2693
|
}
|
|
2601
2694
|
drawShape() {
|
|
2602
2695
|
this.destroyShape();
|
|
2603
|
-
const shape =
|
|
2696
|
+
const shape = getShapeByElement(this.board, this.node.origin);
|
|
2604
2697
|
switch (shape) {
|
|
2605
|
-
case
|
|
2698
|
+
case MindElementShape.roundRectangle:
|
|
2606
2699
|
this.shapeG = drawRectangleNode(this.board, this.node);
|
|
2607
2700
|
this.g.prepend(this.shapeG);
|
|
2608
2701
|
break;
|
|
@@ -2617,29 +2710,29 @@ class MindNodeComponent extends PlaitPluginElementComponent {
|
|
|
2617
2710
|
}
|
|
2618
2711
|
}
|
|
2619
2712
|
drawLink() {
|
|
2620
|
-
if (
|
|
2713
|
+
if (PlaitMind.isMind(this.element)) {
|
|
2621
2714
|
return;
|
|
2622
2715
|
}
|
|
2716
|
+
const parent = MindElement.getParent(this.element);
|
|
2717
|
+
const parentNode = MindElement.getNode(parent);
|
|
2623
2718
|
if (this.linkG) {
|
|
2624
2719
|
this.linkG.remove();
|
|
2625
2720
|
}
|
|
2626
|
-
const layout = MindQueries.getLayoutByElement(
|
|
2721
|
+
const layout = MindQueries.getLayoutByElement(parent);
|
|
2627
2722
|
if (AbstractNode.isAbstract(this.node.origin)) {
|
|
2628
2723
|
this.linkG = drawAbstractLink(this.board, this.node, isHorizontalLayout(layout));
|
|
2629
2724
|
}
|
|
2630
|
-
else if (MindElement.isIndentedLayout(
|
|
2631
|
-
this.linkG = drawIndentedLink(this.board,
|
|
2725
|
+
else if (MindElement.isIndentedLayout(parent)) {
|
|
2726
|
+
this.linkG = drawIndentedLink(this.board, parentNode, this.node);
|
|
2632
2727
|
}
|
|
2633
2728
|
else {
|
|
2634
|
-
this.linkG = drawLogicLink(this.board, this.node,
|
|
2729
|
+
this.linkG = drawLogicLink(this.board, this.node, parentNode, isHorizontalLayout(layout));
|
|
2635
2730
|
}
|
|
2636
2731
|
this.g.append(this.linkG);
|
|
2637
2732
|
}
|
|
2638
2733
|
destroyLine() {
|
|
2639
|
-
if (this.
|
|
2640
|
-
|
|
2641
|
-
this.linkG.remove();
|
|
2642
|
-
}
|
|
2734
|
+
if (this.linkG) {
|
|
2735
|
+
this.linkG.remove();
|
|
2643
2736
|
}
|
|
2644
2737
|
}
|
|
2645
2738
|
drawMaskG() {
|
|
@@ -2789,9 +2882,9 @@ class MindNodeComponent extends PlaitPluginElementComponent {
|
|
|
2789
2882
|
});
|
|
2790
2883
|
const { x, y, width, height } = getRectangleByNode(this.node);
|
|
2791
2884
|
const stroke = getBranchColorByMindElement(this.board, this.element);
|
|
2792
|
-
const
|
|
2885
|
+
const branchWidth = getBranchWidthByMindElement(this.board, this.element);
|
|
2793
2886
|
const extendY = y + height / 2;
|
|
2794
|
-
const nodeLayout = MindQueries.getCorrectLayoutByElement(this.element);
|
|
2887
|
+
const nodeLayout = MindQueries.getCorrectLayoutByElement(this.board, this.element);
|
|
2795
2888
|
let extendLineXY = [
|
|
2796
2889
|
[x + width, extendY],
|
|
2797
2890
|
[x + width + EXTEND_OFFSET, extendY]
|
|
@@ -2803,7 +2896,7 @@ class MindNodeComponent extends PlaitPluginElementComponent {
|
|
|
2803
2896
|
let circleOffset = [EXTEND_RADIUS / 2, 0];
|
|
2804
2897
|
if (isHorizontalLayout(nodeLayout) && !isIndentedLayout(nodeLayout)) {
|
|
2805
2898
|
extendLineYOffset =
|
|
2806
|
-
|
|
2899
|
+
getShapeByElement(this.board, this.node.origin) === MindElementShape.roundRectangle
|
|
2807
2900
|
? [0, 0]
|
|
2808
2901
|
: [height / 2, height / 2];
|
|
2809
2902
|
if (isLeftLayout(nodeLayout)) {
|
|
@@ -2835,7 +2928,7 @@ class MindNodeComponent extends PlaitPluginElementComponent {
|
|
|
2835
2928
|
[extendLineXY[1][0] + extendLineXOffset[1], extendLineXY[1][1] + extendLineYOffset[1]]
|
|
2836
2929
|
];
|
|
2837
2930
|
const extendLine = this.roughSVG.line(extendLineXY[0][0], extendLineXY[0][1], extendLineXY[1][0], extendLineXY[1][1], {
|
|
2838
|
-
strokeWidth,
|
|
2931
|
+
strokeWidth: branchWidth,
|
|
2839
2932
|
stroke
|
|
2840
2933
|
});
|
|
2841
2934
|
//绘制箭头
|
|
@@ -2872,7 +2965,7 @@ class MindNodeComponent extends PlaitPluginElementComponent {
|
|
|
2872
2965
|
const hideCircleG = this.roughSVG.circle(extendLineXY[1][0] + circleOffset[0], extendLineXY[1][1] + circleOffset[1], EXTEND_RADIUS - 1, {
|
|
2873
2966
|
fill: '#fff',
|
|
2874
2967
|
stroke,
|
|
2875
|
-
strokeWidth,
|
|
2968
|
+
strokeWidth: branchWidth,
|
|
2876
2969
|
fillStyle: 'solid'
|
|
2877
2970
|
});
|
|
2878
2971
|
collapseG.appendChild(hideCircleG);
|
|
@@ -3109,7 +3202,7 @@ const getLayoutOptions = (board) => {
|
|
|
3109
3202
|
}
|
|
3110
3203
|
},
|
|
3111
3204
|
getVerticalConnectingPosition(element, parent) {
|
|
3112
|
-
if (element.shape ===
|
|
3205
|
+
if (element.shape === MindElementShape.underline && parent && isHorizontalLogicLayout(parent.layout)) {
|
|
3113
3206
|
return ConnectingPosition.bottom;
|
|
3114
3207
|
}
|
|
3115
3208
|
return undefined;
|
|
@@ -3178,6 +3271,122 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImpor
|
|
|
3178
3271
|
}]
|
|
3179
3272
|
}] });
|
|
3180
3273
|
|
|
3274
|
+
const isValidTarget = (origin, target) => {
|
|
3275
|
+
return origin !== target && !isChildElement(origin, target);
|
|
3276
|
+
};
|
|
3277
|
+
const addActiveOnDragOrigin = (activeElement, isOrigin = true) => {
|
|
3278
|
+
const activeComponent = PlaitElement.getComponent(activeElement);
|
|
3279
|
+
if (isOrigin) {
|
|
3280
|
+
activeComponent.g.classList.add('dragging-origin');
|
|
3281
|
+
}
|
|
3282
|
+
else {
|
|
3283
|
+
activeComponent.g.classList.add('dragging-child');
|
|
3284
|
+
}
|
|
3285
|
+
!activeElement.isCollapsed &&
|
|
3286
|
+
activeElement.children.forEach(child => {
|
|
3287
|
+
addActiveOnDragOrigin(child, false);
|
|
3288
|
+
});
|
|
3289
|
+
};
|
|
3290
|
+
const removeActiveOnDragOrigin = (activeElement, isOrigin = true) => {
|
|
3291
|
+
const activeComponent = PlaitElement.getComponent(activeElement);
|
|
3292
|
+
if (isOrigin) {
|
|
3293
|
+
activeComponent.g.classList.remove('dragging-origin');
|
|
3294
|
+
}
|
|
3295
|
+
else {
|
|
3296
|
+
activeComponent.g.classList.remove('dragging-child');
|
|
3297
|
+
}
|
|
3298
|
+
!activeElement.isCollapsed &&
|
|
3299
|
+
activeElement.children.forEach(child => {
|
|
3300
|
+
removeActiveOnDragOrigin(child, false);
|
|
3301
|
+
});
|
|
3302
|
+
};
|
|
3303
|
+
const updatePathByLayoutAndDropTarget = (targetPath, layout, dropTarget) => {
|
|
3304
|
+
// 上下布局:左右是兄弟节点,上下是子节点
|
|
3305
|
+
if (isVerticalLogicLayout(layout)) {
|
|
3306
|
+
if (isTopLayout(layout) && dropTarget.detectResult === 'top') {
|
|
3307
|
+
targetPath.push(dropTarget.target.children.length);
|
|
3308
|
+
}
|
|
3309
|
+
if (isBottomLayout(layout) && dropTarget.detectResult === 'bottom') {
|
|
3310
|
+
targetPath.push(dropTarget.target.children.length);
|
|
3311
|
+
}
|
|
3312
|
+
// 如果是左,位置不变,右则插入到下一个兄弟节点
|
|
3313
|
+
if (dropTarget.detectResult === 'right') {
|
|
3314
|
+
targetPath = Path.next(targetPath);
|
|
3315
|
+
}
|
|
3316
|
+
}
|
|
3317
|
+
// 水平布局/标准布局:上下是兄弟节点,左右是子节点
|
|
3318
|
+
if (isHorizontalLogicLayout(layout)) {
|
|
3319
|
+
if (dropTarget.detectResult === 'right') {
|
|
3320
|
+
targetPath.push(dropTarget.target.children.length);
|
|
3321
|
+
}
|
|
3322
|
+
if (dropTarget.detectResult === 'left') {
|
|
3323
|
+
targetPath.push(dropTarget.target.children.length);
|
|
3324
|
+
}
|
|
3325
|
+
// 如果是上,位置不变,下插入到下一个兄弟节点
|
|
3326
|
+
if (dropTarget.detectResult === 'bottom') {
|
|
3327
|
+
targetPath = Path.next(targetPath);
|
|
3328
|
+
}
|
|
3329
|
+
}
|
|
3330
|
+
// 缩进布局:上下是兄弟节点,左右是子节点,但上(左上/右上),探测到上是子节点,下则位置不变,反之同理。
|
|
3331
|
+
if (isIndentedLayout(layout)) {
|
|
3332
|
+
if (isTopLayout(layout) && dropTarget.detectResult === 'top') {
|
|
3333
|
+
targetPath = Path.next(targetPath);
|
|
3334
|
+
}
|
|
3335
|
+
if (isBottomLayout(layout) && dropTarget.detectResult === 'bottom') {
|
|
3336
|
+
targetPath = Path.next(targetPath);
|
|
3337
|
+
}
|
|
3338
|
+
if (isLeftLayout(layout) && dropTarget.detectResult === 'left') {
|
|
3339
|
+
targetPath.push(dropTarget.target.children.length);
|
|
3340
|
+
}
|
|
3341
|
+
if (isRightLayout(layout) && dropTarget.detectResult === 'right') {
|
|
3342
|
+
targetPath.push(dropTarget.target.children.length);
|
|
3343
|
+
}
|
|
3344
|
+
}
|
|
3345
|
+
return targetPath;
|
|
3346
|
+
};
|
|
3347
|
+
const updateRightNodeCount = (board, activeComponent, targetComponent, detectResult) => {
|
|
3348
|
+
let rightNodeCount;
|
|
3349
|
+
const mindElement = findUpElement(targetComponent.node.origin).root;
|
|
3350
|
+
const mindComponent = ELEMENT_TO_COMPONENT.get(mindElement);
|
|
3351
|
+
const activeIndex = mindComponent?.root.children.indexOf(activeComponent.node);
|
|
3352
|
+
const targetIndex = mindComponent?.root.children.indexOf(targetComponent.node);
|
|
3353
|
+
const activeParent = MindElement.getParent(activeComponent.element);
|
|
3354
|
+
const targetParent = MindElement.findParent(targetComponent.element);
|
|
3355
|
+
const isActiveOnRight = activeIndex !== -1 && activeIndex <= activeParent.rightNodeCount - 1;
|
|
3356
|
+
const isTargetOnRight = targetParent && targetIndex !== -1 && targetIndex <= targetParent.rightNodeCount - 1;
|
|
3357
|
+
const isBothOnRight = isActiveOnRight && isTargetOnRight;
|
|
3358
|
+
const rootChildCount = mindComponent.root.children?.length;
|
|
3359
|
+
const rootRightNodeCount = mindComponent?.root.origin.rightNodeCount;
|
|
3360
|
+
if (!isBothOnRight) {
|
|
3361
|
+
if (isActiveOnRight) {
|
|
3362
|
+
rightNodeCount = rootChildCount < rootRightNodeCount ? rootChildCount - 1 : rootRightNodeCount - 1;
|
|
3363
|
+
Transforms.setNode(board, { rightNodeCount }, PlaitBoard.findPath(board, activeParent));
|
|
3364
|
+
}
|
|
3365
|
+
if (isTargetOnRight && detectResult !== 'right') {
|
|
3366
|
+
rightNodeCount = rootChildCount < rootRightNodeCount ? rootRightNodeCount : rootRightNodeCount + 1;
|
|
3367
|
+
const parent = MindElement.getParent(targetComponent.element);
|
|
3368
|
+
Transforms.setNode(board, { rightNodeCount }, PlaitBoard.findPath(board, parent));
|
|
3369
|
+
}
|
|
3370
|
+
//二级子节点拖动到根节点左侧
|
|
3371
|
+
if (targetComponent.node.origin.isRoot && detectResult === 'left' && activeIndex === -1) {
|
|
3372
|
+
rightNodeCount = rootChildCount;
|
|
3373
|
+
Transforms.setNode(board, { rightNodeCount }, PlaitBoard.findPath(board, targetComponent.element));
|
|
3374
|
+
}
|
|
3375
|
+
}
|
|
3376
|
+
};
|
|
3377
|
+
const IS_DRAGGING = new WeakMap();
|
|
3378
|
+
const isDragging = (board) => {
|
|
3379
|
+
return !!IS_DRAGGING.get(board);
|
|
3380
|
+
};
|
|
3381
|
+
const setIsDragging = (board, state) => {
|
|
3382
|
+
IS_DRAGGING.set(board, state);
|
|
3383
|
+
};
|
|
3384
|
+
const updateAbstractInDnd = (board, deletableElements, originPath) => {
|
|
3385
|
+
const refs = insertElementHandleAbstract(board, originPath, false);
|
|
3386
|
+
deleteElementHandleAbstract(board, deletableElements, refs);
|
|
3387
|
+
MindTransforms.setAbstractsByRefs(board, refs);
|
|
3388
|
+
};
|
|
3389
|
+
|
|
3181
3390
|
const DRAG_MOVE_BUFFER = 5;
|
|
3182
3391
|
const withDnd = (board) => {
|
|
3183
3392
|
const { mousedown, mousemove, globalMouseup, keydown } = board;
|
|
@@ -3199,8 +3408,8 @@ const withDnd = (board) => {
|
|
|
3199
3408
|
return;
|
|
3200
3409
|
}
|
|
3201
3410
|
if (PlaitMind.isMind(value)) {
|
|
3202
|
-
const
|
|
3203
|
-
const root =
|
|
3411
|
+
const mindComponent = ELEMENT_TO_COMPONENT.get(value);
|
|
3412
|
+
const root = mindComponent.root;
|
|
3204
3413
|
root.eachNode((node) => {
|
|
3205
3414
|
if (activeElement) {
|
|
3206
3415
|
return;
|
|
@@ -3249,7 +3458,6 @@ const withDnd = (board) => {
|
|
|
3249
3458
|
const offsetX = endPoint[0] - startPoint[0];
|
|
3250
3459
|
const offsetY = endPoint[1] - startPoint[1];
|
|
3251
3460
|
const activeComponent = PlaitElement.getComponent(activeElement);
|
|
3252
|
-
const roughSVG = PlaitBoard.getRoughSVG(board);
|
|
3253
3461
|
const fakeDraggingNode = {
|
|
3254
3462
|
...activeComponent.node,
|
|
3255
3463
|
children: [],
|
|
@@ -3259,9 +3467,16 @@ const withDnd = (board) => {
|
|
|
3259
3467
|
const textRectangle = getRichtextRectangleByNode(board, activeComponent.node);
|
|
3260
3468
|
const fakeNodeG = drawRectangleNode(board, fakeDraggingNode);
|
|
3261
3469
|
const richtextG = activeComponent.richtextG?.cloneNode(true);
|
|
3262
|
-
updateForeignObject(richtextG, textRectangle.width
|
|
3470
|
+
updateForeignObject$1(richtextG, textRectangle.width, textRectangle.height, textRectangle.x + offsetX, textRectangle.y + offsetY);
|
|
3263
3471
|
fakeDragNodeG?.append(fakeNodeG);
|
|
3264
3472
|
fakeDragNodeG?.append(richtextG);
|
|
3473
|
+
// draw emojis
|
|
3474
|
+
if (MindElement.hasEmojis(activeElement)) {
|
|
3475
|
+
const fakeEmojisG = activeComponent.emojisDrawer.g.cloneNode(true);
|
|
3476
|
+
const foreignRectangle = getEmojiForeignRectangle(board, activeElement);
|
|
3477
|
+
updateForeignObject$1(fakeEmojisG, foreignRectangle.width, foreignRectangle.height, foreignRectangle.x + offsetX, foreignRectangle.y + offsetY);
|
|
3478
|
+
fakeDragNodeG?.append(fakeEmojisG);
|
|
3479
|
+
}
|
|
3265
3480
|
// drop position detect
|
|
3266
3481
|
const { x, y } = getRectangleByNode(fakeDraggingNode);
|
|
3267
3482
|
const detectCenterPoint = [x + textRectangle.width / 2, y + textRectangle.height / 2];
|
|
@@ -3279,7 +3494,7 @@ const withDnd = (board) => {
|
|
|
3279
3494
|
}
|
|
3280
3495
|
const directions = directionDetector(node, detectCenterPoint);
|
|
3281
3496
|
if (directions) {
|
|
3282
|
-
detectResult = directionCorrector(node, directions);
|
|
3497
|
+
detectResult = directionCorrector(board, node, directions);
|
|
3283
3498
|
}
|
|
3284
3499
|
dropTarget = null;
|
|
3285
3500
|
if (detectResult && isValidTarget(activeComponent.node.origin, node.origin)) {
|
|
@@ -3289,7 +3504,7 @@ const withDnd = (board) => {
|
|
|
3289
3504
|
}
|
|
3290
3505
|
});
|
|
3291
3506
|
if (dropTarget?.target) {
|
|
3292
|
-
dropTarget = readjustmentDropTarget(dropTarget);
|
|
3507
|
+
dropTarget = readjustmentDropTarget(board, dropTarget);
|
|
3293
3508
|
drawPlaceholderDropNodeG(board, dropTarget, fakeDropNodeG);
|
|
3294
3509
|
}
|
|
3295
3510
|
}
|
|
@@ -3301,12 +3516,13 @@ const withDnd = (board) => {
|
|
|
3301
3516
|
const activeComponent = PlaitElement.getComponent(activeElement);
|
|
3302
3517
|
const targetComponent = PlaitElement.getComponent(dropTarget.target);
|
|
3303
3518
|
let targetPath = PlaitBoard.findPath(board, targetComponent.element);
|
|
3304
|
-
const
|
|
3305
|
-
const
|
|
3306
|
-
const layout = MindQueries.getCorrectLayoutByElement(
|
|
3519
|
+
const mindElement = findUpElement(dropTarget.target).root;
|
|
3520
|
+
const mindComponent = ELEMENT_TO_COMPONENT.get(mindElement);
|
|
3521
|
+
const layout = MindQueries.getCorrectLayoutByElement(board, mindComponent?.root.origin);
|
|
3307
3522
|
targetPath = updatePathByLayoutAndDropTarget(targetPath, layout, dropTarget);
|
|
3308
3523
|
const originPath = PlaitBoard.findPath(board, activeComponent.element);
|
|
3309
3524
|
let newElement = { isCollapsed: false }, rightTargetPath = PlaitBoard.findPath(board, targetComponent.element);
|
|
3525
|
+
updateAbstractInDnd(board, [activeElement], targetPath);
|
|
3310
3526
|
if (isStandardLayout(layout)) {
|
|
3311
3527
|
updateRightNodeCount(board, activeComponent, targetComponent, dropTarget.detectResult);
|
|
3312
3528
|
}
|
|
@@ -3339,124 +3555,51 @@ const withDnd = (board) => {
|
|
|
3339
3555
|
};
|
|
3340
3556
|
return board;
|
|
3341
3557
|
};
|
|
3342
|
-
const isValidTarget = (origin, target) => {
|
|
3343
|
-
return origin !== target && !isChildElement(origin, target);
|
|
3344
|
-
};
|
|
3345
|
-
const addActiveOnDragOrigin = (activeElement, isOrigin = true) => {
|
|
3346
|
-
const activeComponent = PlaitElement.getComponent(activeElement);
|
|
3347
|
-
if (isOrigin) {
|
|
3348
|
-
activeComponent.g.classList.add('dragging-origin');
|
|
3349
|
-
}
|
|
3350
|
-
else {
|
|
3351
|
-
activeComponent.g.classList.add('dragging-child');
|
|
3352
|
-
}
|
|
3353
|
-
!activeElement.isCollapsed &&
|
|
3354
|
-
activeElement.children.forEach(child => {
|
|
3355
|
-
addActiveOnDragOrigin(child, false);
|
|
3356
|
-
});
|
|
3357
|
-
};
|
|
3358
|
-
const removeActiveOnDragOrigin = (activeElement, isOrigin = true) => {
|
|
3359
|
-
const activeComponent = PlaitElement.getComponent(activeElement);
|
|
3360
|
-
if (isOrigin) {
|
|
3361
|
-
activeComponent.g.classList.remove('dragging-origin');
|
|
3362
|
-
}
|
|
3363
|
-
else {
|
|
3364
|
-
activeComponent.g.classList.remove('dragging-child');
|
|
3365
|
-
}
|
|
3366
|
-
!activeElement.isCollapsed &&
|
|
3367
|
-
activeElement.children.forEach(child => {
|
|
3368
|
-
removeActiveOnDragOrigin(child, false);
|
|
3369
|
-
});
|
|
3370
|
-
};
|
|
3371
|
-
const updatePathByLayoutAndDropTarget = (targetPath, layout, dropTarget) => {
|
|
3372
|
-
// 上下布局:左右是兄弟节点,上下是子节点
|
|
3373
|
-
if (isVerticalLogicLayout(layout)) {
|
|
3374
|
-
if (isTopLayout(layout) && dropTarget.detectResult === 'top') {
|
|
3375
|
-
targetPath.push(dropTarget.target.children.length);
|
|
3376
|
-
}
|
|
3377
|
-
if (isBottomLayout(layout) && dropTarget.detectResult === 'bottom') {
|
|
3378
|
-
targetPath.push(dropTarget.target.children.length);
|
|
3379
|
-
}
|
|
3380
|
-
// 如果是左,位置不变,右则插入到下一个兄弟节点
|
|
3381
|
-
if (dropTarget.detectResult === 'right') {
|
|
3382
|
-
targetPath = Path.next(targetPath);
|
|
3383
|
-
}
|
|
3384
|
-
}
|
|
3385
|
-
// 水平布局/标准布局:上下是兄弟节点,左右是子节点
|
|
3386
|
-
if (isHorizontalLogicLayout(layout)) {
|
|
3387
|
-
if (dropTarget.detectResult === 'right') {
|
|
3388
|
-
targetPath.push(dropTarget.target.children.length);
|
|
3389
|
-
}
|
|
3390
|
-
if (dropTarget.detectResult === 'left') {
|
|
3391
|
-
targetPath.push(dropTarget.target.children.length);
|
|
3392
|
-
}
|
|
3393
|
-
// 如果是上,位置不变,下插入到下一个兄弟节点
|
|
3394
|
-
if (dropTarget.detectResult === 'bottom') {
|
|
3395
|
-
targetPath = Path.next(targetPath);
|
|
3396
|
-
}
|
|
3397
|
-
}
|
|
3398
|
-
// 缩进布局:上下是兄弟节点,左右是子节点,但上(左上/右上),探测到上是子节点,下则位置不变,反之同理。
|
|
3399
|
-
if (isIndentedLayout(layout)) {
|
|
3400
|
-
if (isTopLayout(layout) && dropTarget.detectResult === 'top') {
|
|
3401
|
-
targetPath = Path.next(targetPath);
|
|
3402
|
-
}
|
|
3403
|
-
if (isBottomLayout(layout) && dropTarget.detectResult === 'bottom') {
|
|
3404
|
-
targetPath = Path.next(targetPath);
|
|
3405
|
-
}
|
|
3406
|
-
if (isLeftLayout(layout) && dropTarget.detectResult === 'left') {
|
|
3407
|
-
targetPath.push(dropTarget.target.children.length);
|
|
3408
|
-
}
|
|
3409
|
-
if (isRightLayout(layout) && dropTarget.detectResult === 'right') {
|
|
3410
|
-
targetPath.push(dropTarget.target.children.length);
|
|
3411
|
-
}
|
|
3412
|
-
}
|
|
3413
|
-
return targetPath;
|
|
3414
|
-
};
|
|
3415
|
-
const updateRightNodeCount = (board, activeComponent, targetComponent, detectResult) => {
|
|
3416
|
-
let rightNodeCount;
|
|
3417
|
-
const mindmapElement = findUpElement(targetComponent.node.origin).root;
|
|
3418
|
-
const mindmapComponent = ELEMENT_TO_COMPONENT.get(mindmapElement);
|
|
3419
|
-
const activeIndex = mindmapComponent?.root.children.indexOf(activeComponent.node);
|
|
3420
|
-
const targetIndex = mindmapComponent?.root.children.indexOf(targetComponent.node);
|
|
3421
|
-
const isActiveOnRight = activeIndex !== -1 && activeIndex <= activeComponent.parent.origin.rightNodeCount - 1;
|
|
3422
|
-
const isTargetOnRight = targetComponent.parent && targetIndex !== -1 && targetIndex <= targetComponent.parent.origin.rightNodeCount - 1;
|
|
3423
|
-
const isBothOnRight = isActiveOnRight && isTargetOnRight;
|
|
3424
|
-
const rootChildCount = mindmapComponent.root.children?.length;
|
|
3425
|
-
const rootRightNodeCount = mindmapComponent?.root.origin.rightNodeCount;
|
|
3426
|
-
if (!isBothOnRight) {
|
|
3427
|
-
if (isActiveOnRight) {
|
|
3428
|
-
rightNodeCount = rootChildCount < rootRightNodeCount ? rootChildCount - 1 : rootRightNodeCount - 1;
|
|
3429
|
-
Transforms.setNode(board, { rightNodeCount }, PlaitBoard.findPath(board, activeComponent.parent.origin));
|
|
3430
|
-
}
|
|
3431
|
-
if (isTargetOnRight && detectResult !== 'right') {
|
|
3432
|
-
rightNodeCount = rootChildCount < rootRightNodeCount ? rootRightNodeCount : rootRightNodeCount + 1;
|
|
3433
|
-
Transforms.setNode(board, { rightNodeCount }, PlaitBoard.findPath(board, targetComponent.parent.origin));
|
|
3434
|
-
}
|
|
3435
|
-
//二级子节点拖动到根节点左侧
|
|
3436
|
-
if (targetComponent.node.origin.isRoot && detectResult === 'left' && activeIndex === -1) {
|
|
3437
|
-
rightNodeCount = rootChildCount;
|
|
3438
|
-
Transforms.setNode(board, { rightNodeCount }, PlaitBoard.findPath(board, targetComponent.element));
|
|
3439
|
-
}
|
|
3440
|
-
}
|
|
3441
|
-
};
|
|
3442
|
-
const IS_DRAGGING = new WeakMap();
|
|
3443
|
-
const isDragging = (board) => {
|
|
3444
|
-
return !!IS_DRAGGING.get(board);
|
|
3445
|
-
};
|
|
3446
|
-
const setIsDragging = (board, state) => {
|
|
3447
|
-
IS_DRAGGING.set(board, state);
|
|
3448
|
-
};
|
|
3449
3558
|
|
|
3450
3559
|
const buildClipboardData = (board, selectedElements) => {
|
|
3451
3560
|
let result = [];
|
|
3452
|
-
|
|
3453
|
-
const
|
|
3454
|
-
|
|
3561
|
+
// get overall abstract
|
|
3562
|
+
const overallAbstracts = getOverallAbstracts(board, selectedElements);
|
|
3563
|
+
// keep correct order
|
|
3564
|
+
const newSelectedElements = selectedElements.filter((value) => !overallAbstracts.includes(value));
|
|
3565
|
+
newSelectedElements.push(...overallAbstracts);
|
|
3566
|
+
// get correct start and end in selected elements
|
|
3567
|
+
function getCorrectStartEnd(abstract) {
|
|
3568
|
+
const parent = MindElement.getParent(abstract);
|
|
3569
|
+
const startElement = parent.children[abstract.start];
|
|
3570
|
+
const index = selectedElements.indexOf(startElement);
|
|
3571
|
+
return { start: index, end: index + (abstract.end - abstract.start) };
|
|
3572
|
+
}
|
|
3573
|
+
const selectedMindNodes = newSelectedElements.map(value => MindElement.getNode(value));
|
|
3574
|
+
const nodesRectangle = getRectangleByElements(board, newSelectedElements, true);
|
|
3575
|
+
newSelectedElements.forEach((element, index) => {
|
|
3576
|
+
// handle relative location
|
|
3455
3577
|
const nodeRectangle = getRectangleByNode(selectedMindNodes[index]);
|
|
3456
|
-
|
|
3457
|
-
|
|
3458
|
-
|
|
3459
|
-
|
|
3578
|
+
const points = [[nodeRectangle.x - nodesRectangle.x, nodeRectangle.y - nodesRectangle.y]];
|
|
3579
|
+
// handle invalid abstract
|
|
3580
|
+
if (AbstractNode.isAbstract(element) && overallAbstracts.includes(element)) {
|
|
3581
|
+
const { start, end } = getCorrectStartEnd(element);
|
|
3582
|
+
result.push({
|
|
3583
|
+
...element,
|
|
3584
|
+
points,
|
|
3585
|
+
start,
|
|
3586
|
+
end
|
|
3587
|
+
});
|
|
3588
|
+
}
|
|
3589
|
+
else {
|
|
3590
|
+
if (AbstractNode.isAbstract(element)) {
|
|
3591
|
+
let newElement = { ...element, points };
|
|
3592
|
+
delete newElement.start;
|
|
3593
|
+
delete newElement.end;
|
|
3594
|
+
result.push(newElement);
|
|
3595
|
+
}
|
|
3596
|
+
else {
|
|
3597
|
+
result.push({
|
|
3598
|
+
...element,
|
|
3599
|
+
points: points
|
|
3600
|
+
});
|
|
3601
|
+
}
|
|
3602
|
+
}
|
|
3460
3603
|
});
|
|
3461
3604
|
return result;
|
|
3462
3605
|
};
|
|
@@ -3482,17 +3625,22 @@ const insertClipboardData = (board, elements, targetPoint) => {
|
|
|
3482
3625
|
let newElement, path;
|
|
3483
3626
|
const selectedElements = getSelectedElements(board);
|
|
3484
3627
|
let newELements = [];
|
|
3628
|
+
const hasTargetParent = selectedElements.length === 1;
|
|
3629
|
+
const targetParent = selectedElements[0];
|
|
3630
|
+
const targetParentPath = targetParent && PlaitBoard.findPath(board, targetParent);
|
|
3631
|
+
const nonAbstractChildrenLength = targetParent && getNonAbstractChildren(targetParent).length;
|
|
3485
3632
|
elements.forEach((item, index) => {
|
|
3486
3633
|
newElement = copyNewNode(item);
|
|
3487
|
-
if (
|
|
3634
|
+
if (hasTargetParent) {
|
|
3488
3635
|
if (item.isRoot) {
|
|
3489
3636
|
newElement = transformRootToNode(board, newElement);
|
|
3490
3637
|
}
|
|
3491
|
-
|
|
3492
|
-
|
|
3638
|
+
// handle abstract start and end
|
|
3639
|
+
if (AbstractNode.isAbstract(newElement)) {
|
|
3640
|
+
newElement.start = newElement.start + nonAbstractChildrenLength;
|
|
3641
|
+
newElement.end = newElement.end + nonAbstractChildrenLength;
|
|
3493
3642
|
}
|
|
3494
|
-
|
|
3495
|
-
path = selectedElementPath.concat((selectedElements[0].children || []).length + index);
|
|
3643
|
+
path = [...targetParentPath, nonAbstractChildrenLength + index];
|
|
3496
3644
|
}
|
|
3497
3645
|
else {
|
|
3498
3646
|
const point = [targetPoint[0] + item.points[0][0], targetPoint[1] + item.points[0][1]];
|
|
@@ -3552,7 +3700,7 @@ const withAbstract = (board) => {
|
|
|
3552
3700
|
event.preventDefault();
|
|
3553
3701
|
const abstractComponent = PlaitElement.getComponent(activeAbstractElement);
|
|
3554
3702
|
const element = abstractComponent.element;
|
|
3555
|
-
const nodeLayout = MindQueries.getCorrectLayoutByElement(activeAbstractElement);
|
|
3703
|
+
const nodeLayout = MindQueries.getCorrectLayoutByElement(board, activeAbstractElement);
|
|
3556
3704
|
const isHorizontal = isHorizontalLayout(nodeLayout);
|
|
3557
3705
|
const parentElement = MindElement.getParent(element);
|
|
3558
3706
|
let children = parentElement.children;
|
|
@@ -3655,7 +3803,11 @@ const withMind = (board) => {
|
|
|
3655
3803
|
board.isHitSelection = (element, range) => {
|
|
3656
3804
|
if (MindElement.isMindElement(board, element) && board.selection) {
|
|
3657
3805
|
const client = getRectangleByNode(MindElement.getNode(element));
|
|
3658
|
-
|
|
3806
|
+
const isHit = RectangleClient.isHit(RectangleClient.toRectangleClient([range.anchor, range.focus]), client);
|
|
3807
|
+
if (isHit && MindElement.hasEmojis(element) && Selection.isCollapsed(range) && isHitEmojis(board, element, range.anchor)) {
|
|
3808
|
+
return false;
|
|
3809
|
+
}
|
|
3810
|
+
return isHit;
|
|
3659
3811
|
}
|
|
3660
3812
|
return isHitSelection(element, range);
|
|
3661
3813
|
};
|
|
@@ -3692,7 +3844,8 @@ const withMind = (board) => {
|
|
|
3692
3844
|
if (shouldChangeRightNodeCount(selectedElement)) {
|
|
3693
3845
|
changeRightNodeCount(board, selectedElementPath.slice(0, 1), 1);
|
|
3694
3846
|
}
|
|
3695
|
-
|
|
3847
|
+
const abstractRefs = insertElementHandleAbstract(board, Path.next(selectedElementPath));
|
|
3848
|
+
MindTransforms.setAbstractsByRefs(board, abstractRefs);
|
|
3696
3849
|
insertMindElement(board, selectedElement, findNewSiblingNodePath(board, selectedElement));
|
|
3697
3850
|
}
|
|
3698
3851
|
return;
|
|
@@ -3700,31 +3853,32 @@ const withMind = (board) => {
|
|
|
3700
3853
|
if (hotkeys.isDeleteBackward(event) || hotkeys.isDeleteForward(event)) {
|
|
3701
3854
|
event.preventDefault();
|
|
3702
3855
|
deleteSelectedELements(board, selectedElements);
|
|
3703
|
-
let
|
|
3704
|
-
const firstLevelElements =
|
|
3856
|
+
let activeElement;
|
|
3857
|
+
const firstLevelElements = getFirstLevelElement(selectedElements);
|
|
3858
|
+
if (AbstractNode.isAbstract(firstLevelElements[0])) {
|
|
3859
|
+
const parent = MindElement.getParent(firstLevelElements[0]);
|
|
3860
|
+
activeElement = parent.children[firstLevelElements[0].start];
|
|
3861
|
+
}
|
|
3705
3862
|
const firstElement = firstLevelElements[0];
|
|
3706
|
-
const
|
|
3707
|
-
const
|
|
3708
|
-
|
|
3709
|
-
return findParentElement(element) && findParentElement(firstLevelElements[0]) === findParentElement(element);
|
|
3863
|
+
const firstElementParent = MindElement.findParent(firstElement);
|
|
3864
|
+
const hasSameParent = firstLevelElements.every(element => {
|
|
3865
|
+
return MindElement.findParent(element) === firstElementParent;
|
|
3710
3866
|
});
|
|
3711
|
-
if (
|
|
3712
|
-
const
|
|
3713
|
-
|
|
3714
|
-
|
|
3867
|
+
if (firstElementParent && hasSameParent && !activeElement) {
|
|
3868
|
+
const firstElementIndex = firstElementParent.children.indexOf(firstElement);
|
|
3869
|
+
const childrenCount = firstElementParent.children.length;
|
|
3870
|
+
// active parent element
|
|
3871
|
+
if (childrenCount === firstLevelElements.length) {
|
|
3872
|
+
activeElement = firstElementParent;
|
|
3715
3873
|
}
|
|
3716
|
-
else
|
|
3717
|
-
|
|
3718
|
-
|
|
3719
|
-
|
|
3720
|
-
lastNode = firstComponent?.parent.children[nodeIndex - 1];
|
|
3874
|
+
else {
|
|
3875
|
+
if (firstElementIndex > 0) {
|
|
3876
|
+
activeElement = firstElementParent.children[firstElementIndex - 1];
|
|
3877
|
+
}
|
|
3721
3878
|
}
|
|
3722
3879
|
}
|
|
3723
|
-
if (
|
|
3724
|
-
|
|
3725
|
-
}
|
|
3726
|
-
if (lastNode) {
|
|
3727
|
-
addSelectedElement(board, lastNode.origin);
|
|
3880
|
+
if (activeElement) {
|
|
3881
|
+
addSelectedElement(board, activeElement);
|
|
3728
3882
|
}
|
|
3729
3883
|
return;
|
|
3730
3884
|
}
|
|
@@ -3751,8 +3905,8 @@ const withMind = (board) => {
|
|
|
3751
3905
|
const point = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
|
|
3752
3906
|
board.children
|
|
3753
3907
|
.filter(value => PlaitMind.isMind(value))
|
|
3754
|
-
.forEach(
|
|
3755
|
-
depthFirstRecursion(
|
|
3908
|
+
.forEach(mindMap => {
|
|
3909
|
+
depthFirstRecursion(mindMap, node => {
|
|
3756
3910
|
if (!PlaitBoard.hasBeenTextEditing(board) && hitMindElement(board, point, node)) {
|
|
3757
3911
|
enterNodeEditing(node);
|
|
3758
3912
|
}
|
|
@@ -3764,7 +3918,7 @@ const withMind = (board) => {
|
|
|
3764
3918
|
dblclick(event);
|
|
3765
3919
|
};
|
|
3766
3920
|
board.setFragment = (data) => {
|
|
3767
|
-
const selectedElements =
|
|
3921
|
+
const selectedElements = getFirstLevelElement(getSelectedElements(board));
|
|
3768
3922
|
if (selectedElements.length) {
|
|
3769
3923
|
const elements = buildClipboardData(board, selectedElements);
|
|
3770
3924
|
setClipboardData(data, elements);
|
|
@@ -3838,5 +3992,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImpor
|
|
|
3838
3992
|
* Generated bundle index. Do not edit.
|
|
3839
3993
|
*/
|
|
3840
3994
|
|
|
3841
|
-
export { ABSTRACT_HANDLE_COLOR, ABSTRACT_HANDLE_LENGTH, ABSTRACT_HANDLE_MASK_WIDTH, ABSTRACT_INCLUDED_OUTLINE_OFFSET, AbstractHandlePosition, AbstractResizeState, BASE,
|
|
3995
|
+
export { ABSTRACT_HANDLE_COLOR, ABSTRACT_HANDLE_LENGTH, ABSTRACT_HANDLE_MASK_WIDTH, ABSTRACT_INCLUDED_OUTLINE_OFFSET, AbstractHandlePosition, AbstractResizeState, BASE, BRANCH_COLORS, BRANCH_WIDTH, DefaultAbstractNodeStyle, DefaultNodeStyle, DefaultRootStyle, ELEMENT_TO_NODE, EXTEND_OFFSET, EXTEND_RADIUS, GRAY_COLOR, LayoutDirection, LayoutDirectionsMap, MindElement, MindElementShape, MindEmojiBaseComponent, MindModule, MindNode, MindNodeComponent, 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, canSetAbstract, changeRightNodeCount, copyNewNode, correctLayoutByDirection, createDefaultMindMapElement, createMindElement, deleteElementHandleAbstract, deleteSelectedELements, directionCorrector, directionDetector, divideElementByParent, drawCurvePlaceholderDropNodeG, drawIndentNodeG, drawPlaceholderDropNodeG, drawStraightDropNodeG, extractNodesText, findLastChild, findLocationLeftIndex, findUpElement, getAbstractBranchColor, getAbstractBranchWidth, getAbstractHandleRectangle, getAllowedDirection, getAvailableSubLayoutsByLayoutDirections, getBehindAbstracts, getBranchColorByMindElement, getBranchDirectionsByLayouts, getBranchWidthByMindElement, getChildrenCount, getCorrespondingAbstract, getDefaultBranchColor, getDefaultBranchColorByIndex, getDefaultLayout, getEmojiFontSize, getEmojiForeignRectangle, getEmojiRectangle, getEmojisWidthHeight, getFirstLevelElement, getHitAbstractHandle, getHorizontalFakeY, getInCorrectLayoutDirection, getIndentedFakePoint, getLayoutDirection$1 as getLayoutDirection, getLayoutReverseDirection, getLocationScope, getNextBranchColor, getOverallAbstracts, getRectangleByNode, getRectangleByResizingLocation, getRootLayout, getShapeByElement, getStrokeByMindElement, handleTouchedAbstract, hitMindElement, insertElementHandleAbstract, insertMindElement, isChildElement, isChildRight, isChildUp, isCorrectLayout, isHitEmojis, isMixedLayout, isSetAbstract, isVirtualKey, readjustmentDropTarget, separateChildren, shouldChangeRightNodeCount, transformAbstractToNode, transformNodeToRoot, transformRootToNode, withExtendMind, withMind };
|
|
3842
3996
|
//# sourceMappingURL=plait-mind.mjs.map
|