@plait/mind 0.9.0 → 0.11.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.
Files changed (54) hide show
  1. package/README.md +132 -13
  2. package/base/base.drawer.d.ts +4 -3
  3. package/constants/default.d.ts +1 -1
  4. package/constants/node-topic-style.d.ts +1 -0
  5. package/drawer/node-active.drawer.d.ts +13 -0
  6. package/drawer/node-collapse.drawer.d.ts +8 -0
  7. package/drawer/{emojis.drawer.d.ts → node-emojis.drawer.d.ts} +1 -1
  8. package/drawer/{quick-insert.drawer.d.ts → node-insert.drawer.d.ts} +2 -2
  9. package/esm2020/base/base.drawer.mjs +13 -1
  10. package/esm2020/constants/default.mjs +2 -2
  11. package/esm2020/constants/node-rule.mjs +1 -1
  12. package/esm2020/constants/node-topic-style.mjs +2 -1
  13. package/esm2020/drawer/node-active.drawer.mjs +43 -0
  14. package/esm2020/drawer/node-collapse.drawer.mjs +108 -0
  15. package/esm2020/drawer/node-emojis.drawer.mjs +72 -0
  16. package/esm2020/drawer/node-insert.drawer.mjs +98 -0
  17. package/esm2020/interfaces/element.mjs +5 -2
  18. package/esm2020/mind.component.mjs +2 -1
  19. package/esm2020/mind.module.mjs +5 -5
  20. package/esm2020/node.component.mjs +57 -424
  21. package/esm2020/plugins/with-abstract-resize.mjs +3 -3
  22. package/esm2020/plugins/with-mind-create.mjs +22 -15
  23. package/esm2020/plugins/with-mind.mjs +9 -8
  24. package/esm2020/plugins/with-node-dnd.mjs +2 -2
  25. package/esm2020/plugins/with-node-hover.mjs +65 -0
  26. package/esm2020/transforms/node.mjs +10 -7
  27. package/esm2020/utils/abstract/resize.mjs +4 -6
  28. package/esm2020/utils/dnd/common.mjs +8 -2
  29. package/esm2020/utils/draw/abstract-outline.mjs +7 -7
  30. package/esm2020/utils/draw/node-dnd.mjs +3 -3
  31. package/esm2020/utils/mind.mjs +4 -4
  32. package/esm2020/utils/node/adjust-node.mjs +4 -5
  33. package/esm2020/utils/node/common.mjs +3 -3
  34. package/esm2020/utils/node/create-node.mjs +4 -3
  35. package/fesm2015/plait-mind.mjs +547 -726
  36. package/fesm2015/plait-mind.mjs.map +1 -1
  37. package/fesm2020/plait-mind.mjs +547 -714
  38. package/fesm2020/plait-mind.mjs.map +1 -1
  39. package/interfaces/element.d.ts +1 -0
  40. package/mind.module.d.ts +2 -2
  41. package/node.component.d.ts +15 -31
  42. package/package.json +1 -1
  43. package/plugins/with-mind-create.d.ts +3 -5
  44. package/plugins/with-node-dnd.d.ts +1 -1
  45. package/plugins/with-node-hover.d.ts +5 -0
  46. package/styles/mixins.scss +13 -15
  47. package/styles/styles.scss +11 -10
  48. package/utils/abstract/resize.d.ts +2 -2
  49. package/utils/draw/abstract-outline.d.ts +0 -1
  50. package/utils/node/common.d.ts +1 -1
  51. package/esm2020/drawer/emojis.drawer.mjs +0 -72
  52. package/esm2020/drawer/quick-insert.drawer.mjs +0 -98
  53. package/esm2020/utils/draw/node-topic.mjs +0 -32
  54. package/utils/draw/node-topic.d.ts +0 -16
@@ -1,55 +1,19 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Component, ChangeDetectionStrategy, NgModule, Directive, Input, HostListener } from '@angular/core';
2
+ import { Component, ChangeDetectionStrategy, NgModule, NgZone, Directive, Input, HostListener } from '@angular/core';
3
3
  import * as i2 from '@plait/core';
4
- import { DefaultThemeColor, ColorfulThemeColor, SoftThemeColor, RetroThemeColor, DarkThemeColor, StarryThemeColor, distanceBetweenPointAndRectangle, RectangleClient, PlaitElement, PlaitBoard, idCreator, isNullOrUndefined, Transforms, clearSelectedElement, addSelectedElement, depthFirstRecursion, Path, drawRoundRectangle, drawLinearPath, createG, updateForeignObject, PlaitNode, getRectangleByElements, getSelectedElements, NODE_TO_PARENT, createForeignObject, drawAbstractRoundRectangle, PlaitPluginElementComponent, PlaitPointerType, NODE_TO_INDEX, createText, IS_TEXT_EDITABLE, MERGING, transformPoint, toPoint, PlaitModule, distanceBetweenPointAndPoint, CLIP_BOARD_FORMAT_KEY, isMainPointer, BOARD_TO_HOST, PlaitPluginKey, throttleRAF, BoardTransforms, removeSelectedElement, PlaitHistoryBoard, hotkeys } from '@plait/core';
4
+ import { DefaultThemeColor, ColorfulThemeColor, SoftThemeColor, RetroThemeColor, DarkThemeColor, StarryThemeColor, RectangleClient, PlaitElement, idCreator, isNullOrUndefined, Transforms, clearSelectedElement, addSelectedElement, PlaitBoard, depthFirstRecursion, Path, drawLinearPath, createG, updateForeignObject, PlaitNode, drawRoundRectangle, getRectangleByElements, getSelectedElements, NODE_TO_PARENT, distanceBetweenPointAndRectangle, createForeignObject, drawAbstractRoundRectangle, createText, PlaitPointerType, PlaitPluginElementComponent, NODE_TO_INDEX, PlaitModule, transformPoint, toPoint, distanceBetweenPointAndPoint, CLIP_BOARD_FORMAT_KEY, isMainPointer, BOARD_TO_HOST, PlaitPluginKey, throttleRAF, BoardTransforms, removeSelectedElement, PlaitHistoryBoard, hotkeys } from '@plait/core';
5
5
  import { MindLayoutType, isIndentedLayout, getNonAbstractChildren, isStandardLayout, AbstractNode, isLeftLayout, isRightLayout, isVerticalLogicLayout, isHorizontalLogicLayout, isTopLayout, isBottomLayout, isHorizontalLayout, getCorrectStartEnd, getAbstractLayout, ConnectingPosition, GlobalLayout } from '@plait/layouts';
6
- import { getSizeByText, ROOT_DEFAULT_HEIGHT, TEXT_DEFAULT_HEIGHT, drawRichtext, updateRichText, setFullSelectionAndFocus, getRichtextContentSize, hasEditableTarget, RichtextModule } from '@plait/richtext';
7
- import { fromEvent, Subject, timer } from 'rxjs';
8
- import { take, takeUntil, filter, debounceTime } from 'rxjs/operators';
9
- import { Node, Path as Path$1, Editor, Operation } from 'slate';
6
+ import { getTextSize, TEXT_DEFAULT_HEIGHT, TextManage, TextModule } from '@plait/text';
7
+ import { fromEvent, Subject } from 'rxjs';
8
+ import { Node, Path as Path$1 } from 'slate';
10
9
  import { isKeyHotkey } from 'is-hotkey';
11
10
  import { pointsOnBezierCurves } from 'points-on-curve';
11
+ import { take, filter } from 'rxjs/operators';
12
12
  import * as i1 from '@angular/common';
13
13
  import { CommonModule } from '@angular/common';
14
14
 
15
15
  const ELEMENT_TO_NODE = new WeakMap();
16
16
 
17
- const BASE = 4;
18
- const PRIMARY_COLOR = '#6698FF';
19
- const TRANSPARENT = 'transparent';
20
- const GRAY_COLOR = '#AAAAAA';
21
- const STROKE_WIDTH = 3;
22
- const BRANCH_WIDTH = 3;
23
- const EXTEND_OFFSET = 8;
24
- const EXTEND_RADIUS = 16;
25
- const QUICK_INSERT_CIRCLE_OFFSET = 9;
26
- const QUICK_INSERT_CIRCLE_COLOR = '#6698FF';
27
- const QUICK_INSERT_INNER_CROSS_COLOR = 'white';
28
-
29
- const DefaultAbstractNodeStyle = {
30
- strokeColor: GRAY_COLOR,
31
- strokeWidth: 2,
32
- branchColor: GRAY_COLOR,
33
- branchWidth: 2
34
- };
35
- const DefaultNodeStyle = {
36
- strokeWidth: 3,
37
- branchWidth: 3,
38
- fill: 'none'
39
- };
40
-
41
- const TOPIC_COLOR = '#333';
42
- const TOPIC_FONT_SIZE = 14;
43
- const ROOT_TOPIC_FONT_SIZE = 18;
44
- const TOPIC_DEFAULT_MAX_WORD_COUNT = 34;
45
-
46
- const NODE_MIN_WIDTH = 18;
47
-
48
- const ABSTRACT_HANDLE_COLOR = '#6698FF80'; //primary color 50% opacity
49
- const ABSTRACT_INCLUDED_OUTLINE_OFFSET = 3.5;
50
- const ABSTRACT_HANDLE_LENGTH = 10;
51
- const ABSTRACT_HANDLE_MASK_WIDTH = 8;
52
-
53
17
  const MindNode = {
54
18
  get(root, path) {
55
19
  let node = root;
@@ -185,36 +149,17 @@ const MindThemeColor = {
185
149
  }
186
150
  };
187
151
 
188
- function getRectangleByNode(node) {
189
- const x = node.x + node.hGap;
190
- let y = node.y + node.vGap;
191
- const width = node.width - node.hGap * 2;
192
- const height = node.height - node.vGap * 2;
193
- return {
194
- x,
195
- y,
196
- width,
197
- height
198
- };
199
- }
200
- function getRectangleByElement(board, originPoint, element) {
201
- const nodeRectangle = {
202
- x: originPoint[0],
203
- y: originPoint[1],
204
- width: NodeSpace.getNodeWidth(board, element),
205
- height: NodeSpace.getNodeHeight(board, element)
206
- };
207
- return nodeRectangle;
208
- }
209
- function isHitMindElement(board, point, element) {
210
- const node = MindElement.getNode(element);
211
- if (node && distanceBetweenPointAndRectangle(point[0], point[1], getRectangleByNode(node)) === 0) {
212
- return true;
213
- }
214
- else {
215
- return false;
216
- }
217
- }
152
+ const BASE = 4;
153
+ const PRIMARY_COLOR = '#6698FF';
154
+ const TRANSPARENT = 'transparent';
155
+ const GRAY_COLOR = '#AAAAAA';
156
+ const STROKE_WIDTH = 3;
157
+ const BRANCH_WIDTH = 3;
158
+ const EXTEND_OFFSET = 8;
159
+ const EXTEND_DIAMETER = 16;
160
+ const QUICK_INSERT_CIRCLE_OFFSET = 9;
161
+ const QUICK_INSERT_CIRCLE_COLOR = '#6698FF';
162
+ const QUICK_INSERT_INNER_CROSS_COLOR = 'white';
218
163
 
219
164
  function getEmojisWidthHeight(board, element) {
220
165
  const options = board.getMindOptions();
@@ -234,6 +179,79 @@ function getEmojiFontSize(element) {
234
179
  }
235
180
  }
236
181
 
182
+ const NodeDefaultSpace = {
183
+ horizontal: {
184
+ nodeAndText: BASE * 3,
185
+ emojiAndText: BASE * 1.5
186
+ },
187
+ vertical: {
188
+ nodeAndText: BASE * 1.5
189
+ }
190
+ };
191
+ const RootDefaultSpace = {
192
+ horizontal: {
193
+ nodeAndText: BASE * 4,
194
+ emojiAndText: BASE * 2
195
+ },
196
+ vertical: {
197
+ nodeAndText: BASE * 2
198
+ }
199
+ };
200
+ const getHorizontalSpaceBetweenNodeAndText = (board, element) => {
201
+ const isMind = PlaitMind.isMind(element);
202
+ const nodeAndText = isMind ? RootDefaultSpace.horizontal.nodeAndText : NodeDefaultSpace.horizontal.nodeAndText;
203
+ return nodeAndText;
204
+ };
205
+ const getVerticalSpaceBetweenNodeAndText = (element) => {
206
+ const isMind = PlaitMind.isMind(element);
207
+ const nodeAndText = isMind ? RootDefaultSpace.vertical.nodeAndText : NodeDefaultSpace.vertical.nodeAndText;
208
+ return nodeAndText;
209
+ };
210
+ const getSpaceEmojiAndText = (element) => {
211
+ const isMind = PlaitMind.isMind(element);
212
+ const emojiAndText = isMind ? RootDefaultSpace.horizontal.emojiAndText : NodeDefaultSpace.horizontal.emojiAndText;
213
+ return emojiAndText;
214
+ };
215
+ const NodeSpace = {
216
+ getNodeWidth(board, element) {
217
+ const nodeAndText = getHorizontalSpaceBetweenNodeAndText(board, element);
218
+ if (MindElement.hasEmojis(element)) {
219
+ return (NodeSpace.getEmojiLeftSpace(board, element) +
220
+ getEmojisWidthHeight(board, element).width +
221
+ getSpaceEmojiAndText(element) +
222
+ element.width +
223
+ nodeAndText);
224
+ }
225
+ return nodeAndText + element.width + nodeAndText;
226
+ },
227
+ getNodeHeight(board, element) {
228
+ const nodeAndText = getVerticalSpaceBetweenNodeAndText(element);
229
+ return nodeAndText + element.height + nodeAndText;
230
+ },
231
+ getTextLeftSpace(board, element) {
232
+ const nodeAndText = getHorizontalSpaceBetweenNodeAndText(board, element);
233
+ if (MindElement.hasEmojis(element)) {
234
+ return NodeSpace.getEmojiLeftSpace(board, element) + getEmojisWidthHeight(board, element).width + getSpaceEmojiAndText(element);
235
+ }
236
+ else {
237
+ return nodeAndText;
238
+ }
239
+ },
240
+ getTextTopSpace(element) {
241
+ const nodeAndText = getVerticalSpaceBetweenNodeAndText(element);
242
+ return nodeAndText;
243
+ },
244
+ getEmojiLeftSpace(board, element) {
245
+ const options = board.getMindOptions();
246
+ const nodeAndText = getHorizontalSpaceBetweenNodeAndText(board, element);
247
+ return nodeAndText - options.emojiPadding;
248
+ },
249
+ getEmojiTopSpace(element) {
250
+ const nodeAndText = getVerticalSpaceBetweenNodeAndText(element);
251
+ return nodeAndText;
252
+ }
253
+ };
254
+
237
255
  function getEmojiRectangle(board, element) {
238
256
  let { x, y } = getRectangleByNode(MindElement.getNode(element));
239
257
  x = x + NodeSpace.getEmojiLeftSpace(board, element);
@@ -260,18 +278,38 @@ const isHitEmojis = (board, element, point) => {
260
278
  return RectangleClient.isHit(RectangleClient.toRectangleClient([point, point]), getEmojiRectangle(board, element));
261
279
  };
262
280
 
263
- function enterNodeEditing(element) {
281
+ function getTopicRectangleByNode(board, node) {
282
+ let nodeRectangle = getRectangleByNode(node);
283
+ return getTopicRectangleByElement(board, nodeRectangle, node.origin);
284
+ }
285
+ function getTopicRectangleByElement(board, nodeRectangle, element) {
286
+ const x = nodeRectangle.x + NodeSpace.getTextLeftSpace(board, element);
287
+ const y = nodeRectangle.y + NodeSpace.getTextTopSpace(element);
288
+ const width = Math.ceil(element.width);
289
+ const height = Math.ceil(element.height);
290
+ return { height, width, x, y };
291
+ }
292
+
293
+ const NODE_MIN_WIDTH = 18;
294
+
295
+ function editTopic(element) {
264
296
  const component = PlaitElement.getComponent(element);
265
- component.startEditText(false, false);
297
+ component.editTopic();
266
298
  }
267
299
 
300
+ const TOPIC_COLOR = '#333';
301
+ const TOPIC_FONT_SIZE = 14;
302
+ const ROOT_TOPIC_FONT_SIZE = 18;
303
+ const ROOT_TOPIC_HEIGHT = 25;
304
+ const TOPIC_DEFAULT_MAX_WORD_COUNT = 34;
305
+
268
306
  const adjustRootToNode = (board, node) => {
269
307
  const newNode = Object.assign({}, node);
270
308
  delete newNode.isRoot;
271
309
  delete newNode.rightNodeCount;
272
310
  delete newNode.type;
273
311
  const text = Node.string(node.data.topic.children[0]) || ' ';
274
- const { width, height } = getSizeByText(text, PlaitBoard.getViewportContainer(board), TOPIC_DEFAULT_MAX_WORD_COUNT);
312
+ const { width, height } = getTextSize(board, text, TOPIC_DEFAULT_MAX_WORD_COUNT);
275
313
  newNode.width = Math.max(width, NODE_MIN_WIDTH);
276
314
  newNode.height = height;
277
315
  if (newNode.layout === MindLayoutType.standard) {
@@ -297,7 +335,7 @@ const adjustNodeToRoot = (board, node) => {
297
335
  newElement === null || newElement === void 0 ? true : delete newElement.fill;
298
336
  newElement === null || newElement === void 0 ? true : delete newElement.shape;
299
337
  newElement === null || newElement === void 0 ? true : delete newElement.strokeWidth;
300
- const { width, height } = getSizeByText(text, PlaitBoard.getViewportContainer(board), TOPIC_DEFAULT_MAX_WORD_COUNT, ROOT_TOPIC_FONT_SIZE);
338
+ const { width, height } = getTextSize(board, text, TOPIC_DEFAULT_MAX_WORD_COUNT, ROOT_TOPIC_FONT_SIZE);
301
339
  newElement.width = Math.max(width, NODE_MIN_WIDTH);
302
340
  newElement.height = height;
303
341
  return Object.assign(Object.assign({}, newElement), { layout: (_a = newElement.layout) !== null && _a !== void 0 ? _a : MindLayoutType.right, isCollapsed: false, isRoot: true, type: 'mindmap' });
@@ -310,7 +348,7 @@ const createEmptyMind = (board, point) => {
310
348
  return rootElement;
311
349
  };
312
350
  const createDefaultMind = (point, rightNodeCount, layout) => {
313
- const root = createMindElement('思维导图', 72, ROOT_DEFAULT_HEIGHT, { layout });
351
+ const root = createMindElement('思维导图', 72, ROOT_TOPIC_HEIGHT, { layout });
314
352
  root.rightNodeCount = rightNodeCount;
315
353
  root.isRoot = true;
316
354
  root.type = 'mindmap';
@@ -417,7 +455,7 @@ const insertMindElement = (board, inheritNode, path) => {
417
455
  clearSelectedElement(board);
418
456
  addSelectedElement(board, newElement);
419
457
  setTimeout(() => {
420
- enterNodeEditing(newElement);
458
+ editTopic(newElement);
421
459
  });
422
460
  };
423
461
  const findLastChild = (child) => {
@@ -547,6 +585,18 @@ const getRootLayout = (root) => {
547
585
  return root.layout || getDefaultLayout();
548
586
  };
549
587
 
588
+ const DefaultAbstractNodeStyle = {
589
+ strokeColor: GRAY_COLOR,
590
+ strokeWidth: 2,
591
+ branchColor: GRAY_COLOR,
592
+ branchWidth: 2
593
+ };
594
+ const DefaultNodeStyle = {
595
+ strokeWidth: 3,
596
+ branchWidth: 3,
597
+ fill: 'none'
598
+ };
599
+
550
600
  const getAvailableProperty = (board, element, propertyKey) => {
551
601
  return element[propertyKey];
552
602
  };
@@ -649,6 +699,12 @@ const isDragging = (board) => {
649
699
  };
650
700
  const setIsDragging = (board, state) => {
651
701
  IS_DRAGGING.set(board, state);
702
+ if (state) {
703
+ PlaitBoard.getBoardContainer(board).classList.add('mind-node-dragging');
704
+ }
705
+ else {
706
+ PlaitBoard.getBoardContainer(board).classList.remove('mind-node-dragging');
707
+ }
652
708
  };
653
709
  const hasPreviousOrNextOfDropPath = (parent, dropTarget, dropPath) => {
654
710
  let children = getNonAbstractChildren(parent);
@@ -862,23 +918,10 @@ const getPathByDropTarget = (board, dropTarget) => {
862
918
  return targetPath;
863
919
  };
864
920
 
865
- function drawRoundRectangleByNode(board, node) {
866
- const rectangle = getRectangleByNode(node);
867
- return drawRoundRectangleByElement(board, rectangle, node.origin);
868
- }
869
- function drawRoundRectangleByElement(board, nodeRectangle, element) {
870
- const defaultRootFill = getMindThemeColor(board).rootFill;
871
- const fill = element.fill ? element.fill : element.isRoot ? defaultRootFill : DefaultNodeStyle.fill;
872
- const stroke = getStrokeByMindElement(board, element);
873
- const strokeWidth = element.strokeWidth ? element.strokeWidth : DefaultNodeStyle.strokeWidth;
874
- const nodeG = drawRoundRectangle(PlaitBoard.getRoughSVG(board), nodeRectangle.x, nodeRectangle.y, nodeRectangle.x + nodeRectangle.width, nodeRectangle.y + nodeRectangle.height, {
875
- stroke,
876
- strokeWidth,
877
- fill,
878
- fillStyle: 'solid'
879
- });
880
- return nodeG;
881
- }
921
+ const ABSTRACT_HANDLE_COLOR = '#6698FF80'; //primary color 50% opacity
922
+ const ABSTRACT_INCLUDED_OUTLINE_OFFSET = 3.5;
923
+ const ABSTRACT_HANDLE_LENGTH = 10;
924
+ const ABSTRACT_HANDLE_MASK_WIDTH = 8;
882
925
 
883
926
  var HorizontalPlacement;
884
927
  (function (HorizontalPlacement) {
@@ -1127,20 +1170,19 @@ function drawLink(board, parentNode, node, isHorizontal, needDrawUnderline, defa
1127
1170
  }
1128
1171
 
1129
1172
  const drawFakeDragNode = (board, element, offsetX, offsetY) => {
1130
- var _a;
1131
1173
  const activeComponent = PlaitElement.getComponent(element);
1132
1174
  const dragFakeNodeG = createG();
1133
1175
  dragFakeNodeG.classList.add('dragging', 'fake-node', 'plait-board-attached');
1134
1176
  const fakeDraggingNode = Object.assign(Object.assign({}, activeComponent.node), { children: [], x: activeComponent.node.x + offsetX, y: activeComponent.node.y + offsetY });
1135
1177
  const textRectangle = getTopicRectangleByNode(board, activeComponent.node);
1136
1178
  const fakeNodeG = drawRoundRectangleByNode(board, fakeDraggingNode);
1137
- const richtextG = (_a = activeComponent.richtextG) === null || _a === void 0 ? void 0 : _a.cloneNode(true);
1179
+ const richtextG = activeComponent.textManage.g.cloneNode(true);
1138
1180
  updateForeignObject(richtextG, textRectangle.width, textRectangle.height, textRectangle.x + offsetX, textRectangle.y + offsetY);
1139
1181
  dragFakeNodeG === null || dragFakeNodeG === void 0 ? void 0 : dragFakeNodeG.append(fakeNodeG);
1140
1182
  dragFakeNodeG === null || dragFakeNodeG === void 0 ? void 0 : dragFakeNodeG.append(richtextG);
1141
1183
  // draw emojis
1142
1184
  if (MindElement.hasEmojis(element)) {
1143
- const fakeEmojisG = activeComponent.emojisDrawer.g.cloneNode(true);
1185
+ const fakeEmojisG = activeComponent.nodeEmojisDrawer.g.cloneNode(true);
1144
1186
  const foreignRectangle = getEmojiForeignRectangle(board, element);
1145
1187
  updateForeignObject(fakeEmojisG, foreignRectangle.width, foreignRectangle.height, foreignRectangle.x + offsetX, foreignRectangle.y + offsetY);
1146
1188
  dragFakeNodeG === null || dragFakeNodeG === void 0 ? void 0 : dragFakeNodeG.append(fakeEmojisG);
@@ -1581,9 +1623,7 @@ function findLocationLeftIndex(board, parentChildren, location, isHorizontal) {
1581
1623
  }
1582
1624
  function handleTouchedAbstract(board, touchedAbstract, endPoint) {
1583
1625
  let touchedHandle;
1584
- const abstract = getSelectedElements(board)
1585
- .filter(element => AbstractNode.isAbstract(element))
1586
- .find(element => {
1626
+ const abstract = getSelectedElements(board).filter(element => AbstractNode.isAbstract(element)).find(element => {
1587
1627
  touchedHandle = getHitAbstractHandle(board, element, endPoint);
1588
1628
  return touchedHandle;
1589
1629
  });
@@ -1592,13 +1632,13 @@ function handleTouchedAbstract(board, touchedAbstract, endPoint) {
1592
1632
  }
1593
1633
  if (touchedAbstract) {
1594
1634
  const component = PlaitElement.getComponent(touchedAbstract);
1595
- component.updateAbstractIncludedOutline();
1635
+ component.activeDrawer.updateAbstractOutline(touchedAbstract);
1596
1636
  touchedAbstract = undefined;
1597
1637
  }
1598
1638
  if (abstract) {
1599
1639
  touchedAbstract = abstract;
1600
1640
  const component = PlaitElement.getComponent(touchedAbstract);
1601
- component.updateAbstractIncludedOutline(touchedHandle);
1641
+ component.activeDrawer.updateAbstractOutline(touchedAbstract, touchedHandle);
1602
1642
  }
1603
1643
  return touchedAbstract;
1604
1644
  }
@@ -1823,6 +1863,9 @@ const MindElement = {
1823
1863
  },
1824
1864
  getEmojis(element) {
1825
1865
  return element.data.emojis;
1866
+ },
1867
+ getEditor(element) {
1868
+ return PlaitElement.getComponent(element).textManage.componentRef.instance.editor;
1826
1869
  }
1827
1870
  };
1828
1871
  var MindElementShape;
@@ -1836,118 +1879,53 @@ var BranchShape;
1836
1879
  BranchShape["polyline"] = "polyline";
1837
1880
  })(BranchShape || (BranchShape = {}));
1838
1881
 
1839
- const NodeDefaultSpace = {
1840
- horizontal: {
1841
- nodeAndText: BASE * 3,
1842
- emojiAndText: BASE * 1.5
1843
- },
1844
- vertical: {
1845
- nodeAndText: BASE * 1.5
1882
+ function getRectangleByNode(node) {
1883
+ const x = node.x + node.hGap;
1884
+ let y = node.y + node.vGap;
1885
+ const width = node.width - node.hGap * 2;
1886
+ const height = node.height - node.vGap * 2;
1887
+ return {
1888
+ x,
1889
+ y,
1890
+ width,
1891
+ height
1892
+ };
1893
+ }
1894
+ function getRectangleByElement(board, originPoint, element) {
1895
+ const nodeRectangle = {
1896
+ x: originPoint[0],
1897
+ y: originPoint[1],
1898
+ width: NodeSpace.getNodeWidth(board, element),
1899
+ height: NodeSpace.getNodeHeight(board, element)
1900
+ };
1901
+ return nodeRectangle;
1902
+ }
1903
+ function isHitMindElement(board, point, element) {
1904
+ const node = MindElement.getNode(element);
1905
+ if (node && distanceBetweenPointAndRectangle(point[0], point[1], getRectangleByNode(node)) === 0) {
1906
+ return true;
1846
1907
  }
1847
- };
1848
- const RootDefaultSpace = {
1849
- horizontal: {
1850
- nodeAndText: BASE * 4,
1851
- emojiAndText: BASE * 2
1852
- },
1853
- vertical: {
1854
- nodeAndText: BASE * 2
1908
+ else {
1909
+ return false;
1855
1910
  }
1856
- };
1857
- const getHorizontalSpaceBetweenNodeAndText = (board, element) => {
1858
- const isMind = PlaitMind.isMind(element);
1859
- const nodeAndText = isMind ? RootDefaultSpace.horizontal.nodeAndText : NodeDefaultSpace.horizontal.nodeAndText;
1860
- return nodeAndText;
1861
- };
1862
- const getVerticalSpaceBetweenNodeAndText = (element) => {
1863
- const isMind = PlaitMind.isMind(element);
1864
- const nodeAndText = isMind ? RootDefaultSpace.vertical.nodeAndText : NodeDefaultSpace.vertical.nodeAndText;
1865
- return nodeAndText;
1866
- };
1867
- const getSpaceEmojiAndText = (element) => {
1868
- const isMind = PlaitMind.isMind(element);
1869
- const emojiAndText = isMind ? RootDefaultSpace.horizontal.emojiAndText : NodeDefaultSpace.horizontal.emojiAndText;
1870
- return emojiAndText;
1871
- };
1872
- const NodeSpace = {
1873
- getNodeWidth(board, element) {
1874
- const nodeAndText = getHorizontalSpaceBetweenNodeAndText(board, element);
1875
- if (MindElement.hasEmojis(element)) {
1876
- return (NodeSpace.getEmojiLeftSpace(board, element) +
1877
- getEmojisWidthHeight(board, element).width +
1878
- getSpaceEmojiAndText(element) +
1879
- element.width +
1880
- nodeAndText);
1881
- }
1882
- return nodeAndText + element.width + nodeAndText;
1883
- },
1884
- getNodeHeight(board, element) {
1885
- const nodeAndText = getVerticalSpaceBetweenNodeAndText(element);
1886
- return nodeAndText + element.height + nodeAndText;
1887
- },
1888
- getTextLeftSpace(board, element) {
1889
- const nodeAndText = getHorizontalSpaceBetweenNodeAndText(board, element);
1890
- if (MindElement.hasEmojis(element)) {
1891
- return NodeSpace.getEmojiLeftSpace(board, element) + getEmojisWidthHeight(board, element).width + getSpaceEmojiAndText(element);
1892
- }
1893
- else {
1894
- return nodeAndText;
1895
- }
1896
- },
1897
- getTextTopSpace(element) {
1898
- const nodeAndText = getVerticalSpaceBetweenNodeAndText(element);
1899
- return nodeAndText;
1900
- },
1901
- getEmojiLeftSpace(board, element) {
1902
- const options = board.getMindOptions();
1903
- const nodeAndText = getHorizontalSpaceBetweenNodeAndText(board, element);
1904
- return nodeAndText - options.emojiPadding;
1905
- },
1906
- getEmojiTopSpace(element) {
1907
- const nodeAndText = getVerticalSpaceBetweenNodeAndText(element);
1908
- return nodeAndText;
1909
- }
1910
- };
1911
-
1912
- function getTopicRectangleByNode(board, node) {
1913
- let nodeRectangle = getRectangleByNode(node);
1914
- return getTopicRectangleByElement(board, nodeRectangle, node.origin);
1915
- }
1916
- function getTopicRectangleByElement(board, nodeRectangle, element) {
1917
- const x = nodeRectangle.x + NodeSpace.getTextLeftSpace(board, element);
1918
- const y = nodeRectangle.y + NodeSpace.getTextTopSpace(element);
1919
- const width = Math.ceil(element.width);
1920
- const height = Math.ceil(element.height);
1921
- return { height, width, x, y };
1922
1911
  }
1923
1912
 
1924
- function drawTopicByNode(board, node, viewContainerRef) {
1925
- const rectangle = getTopicRectangleByNode(board, node);
1926
- return drawTopicByElement(board, rectangle, node.origin, viewContainerRef);
1927
- }
1928
- function drawTopicByElement(board, rectangle, element, viewContainerRef) {
1929
- const containerRef = viewContainerRef || PlaitBoard.getComponent(board).viewContainerRef;
1930
- const classList = [];
1931
- if (element.isRoot) {
1932
- classList.push('root-node');
1933
- classList.push('font-size-18');
1934
- }
1935
- else {
1936
- classList.push('child-node');
1937
- }
1938
- // COMPAT: last character can not show in safari browser
1939
- return drawRichtext(rectangle.x, rectangle.y, rectangle.width, rectangle.height, element.data.topic, containerRef, classList);
1913
+ function drawRoundRectangleByNode(board, node) {
1914
+ const rectangle = getRectangleByNode(node);
1915
+ return drawRoundRectangleByElement(board, rectangle, node.origin);
1940
1916
  }
1941
- function updateMindNodeTopicSize(board, node, g, isEditable) {
1942
- const { x, y, width, height } = getTopicRectangleByNode(board, node);
1943
- if (isEditable) {
1944
- // add 999, avoid changing lines when paste more text
1945
- updateForeignObject(g, width + 999, height + 999, x, y);
1946
- }
1947
- else {
1948
- // COMPAT: last character can not show in safari browser
1949
- updateForeignObject(g, width, height, x, y);
1950
- }
1917
+ function drawRoundRectangleByElement(board, nodeRectangle, element) {
1918
+ const defaultRootFill = getMindThemeColor(board).rootFill;
1919
+ const fill = element.fill ? element.fill : element.isRoot ? defaultRootFill : DefaultNodeStyle.fill;
1920
+ const stroke = getStrokeByMindElement(board, element);
1921
+ const strokeWidth = element.strokeWidth ? element.strokeWidth : DefaultNodeStyle.strokeWidth;
1922
+ const nodeG = drawRoundRectangle(PlaitBoard.getRoughSVG(board), nodeRectangle.x, nodeRectangle.y, nodeRectangle.x + nodeRectangle.width, nodeRectangle.y + nodeRectangle.height, {
1923
+ stroke,
1924
+ strokeWidth,
1925
+ fill,
1926
+ fillStyle: 'solid'
1927
+ });
1928
+ return nodeG;
1951
1929
  }
1952
1930
 
1953
1931
  function drawAbstractLink(board, node, isHorizontal) {
@@ -2028,7 +2006,7 @@ class EmojiDrawer {
2028
2006
  }
2029
2007
  }
2030
2008
  }
2031
- class EmojisDrawer {
2009
+ class NodeEmojisDrawer {
2032
2010
  constructor(board, viewContainerRef) {
2033
2011
  this.board = board;
2034
2012
  this.viewContainerRef = viewContainerRef;
@@ -2156,12 +2134,13 @@ const correctLogicLayoutNode = (board, layout, path) => {
2156
2134
  }
2157
2135
  };
2158
2136
 
2137
+ const normalizeWidthAndHeight = (board, width, height) => {
2138
+ const newWidth = width < NODE_MIN_WIDTH * board.viewport.zoom ? NODE_MIN_WIDTH : width / board.viewport.zoom;
2139
+ const newHeight = height / board.viewport.zoom;
2140
+ return { width: newWidth, height: newHeight };
2141
+ };
2159
2142
  const setTopic = (board, element, topic, width, height) => {
2160
- const newElement = {
2161
- data: { topic },
2162
- width: width < NODE_MIN_WIDTH * board.viewport.zoom ? NODE_MIN_WIDTH : width / board.viewport.zoom,
2163
- height: height / board.viewport.zoom
2164
- };
2143
+ const newElement = Object.assign({ data: { topic } }, normalizeWidthAndHeight(board, width, height));
2165
2144
  if (MindElement.hasEmojis(element)) {
2166
2145
  newElement.data.emojis = element.data.emojis;
2167
2146
  }
@@ -2169,12 +2148,9 @@ const setTopic = (board, element, topic, width, height) => {
2169
2148
  Transforms.setNode(board, newElement, path);
2170
2149
  };
2171
2150
  const setTopicSize = (board, element, width, height) => {
2172
- const newElement = {
2173
- width: width < NODE_MIN_WIDTH * board.viewport.zoom ? NODE_MIN_WIDTH : width / board.viewport.zoom,
2174
- height: height / board.viewport.zoom
2175
- };
2176
- const path = PlaitBoard.findPath(board, element);
2177
- if (newElement.width !== element.width || newElement.height !== element.height) {
2151
+ const newElement = Object.assign({}, normalizeWidthAndHeight(board, width, height));
2152
+ if (element.width !== newElement.width || element.height !== newElement.height) {
2153
+ const path = PlaitBoard.findPath(board, element);
2178
2154
  Transforms.setNode(board, newElement, path);
2179
2155
  }
2180
2156
  };
@@ -2270,75 +2246,22 @@ const MindTransforms = {
2270
2246
  setRightNodeCountByRefs
2271
2247
  };
2272
2248
 
2273
- function drawAbstractIncludedOutline(board, roughSVG, element, activeHandlePosition, resizingLocation) {
2274
- const abstractIncludedG = createG();
2275
- const parentElement = MindElement.getParent(element);
2276
- const nodeLayout = MindQueries.getCorrectLayoutByElement(board, element);
2277
- const isHorizontal = isHorizontalLayout(nodeLayout);
2278
- const includedElements = parentElement.children.slice(element.start, element.end + 1);
2279
- let abstractRectangle = getRectangleByElements(board, includedElements, true);
2280
- abstractRectangle = RectangleClient.getOutlineRectangle(abstractRectangle, -ABSTRACT_INCLUDED_OUTLINE_OFFSET);
2281
- if (resizingLocation) {
2282
- abstractRectangle = getRectangleByResizingLocation(abstractRectangle, resizingLocation, activeHandlePosition, isHorizontal);
2283
- }
2284
- const rectangle = drawAbstractRoundRectangle(roughSVG, abstractRectangle.x, abstractRectangle.y, abstractRectangle.x + abstractRectangle.width, abstractRectangle.y + abstractRectangle.height, isHorizontal, {
2285
- stroke: PRIMARY_COLOR,
2286
- strokeWidth: 1,
2287
- fillStyle: 'solid'
2288
- });
2289
- const startPlacement = [HorizontalPlacement.center, VerticalPlacement.top];
2290
- const endPlacement = [HorizontalPlacement.center, VerticalPlacement.bottom];
2291
- const linkDirection = getLayoutDirection(MindElement.getNode(element), isHorizontal);
2292
- transformPlacement(startPlacement, linkDirection);
2293
- transformPlacement(endPlacement, linkDirection);
2294
- let startCenterPoint = getPointByPlacement(abstractRectangle, startPlacement);
2295
- let endCenterPoint = getPointByPlacement(abstractRectangle, endPlacement);
2296
- const startPoint1 = moveXOfPoint(startCenterPoint, -ABSTRACT_HANDLE_LENGTH / 2, linkDirection);
2297
- const startPoint2 = moveXOfPoint(startCenterPoint, ABSTRACT_HANDLE_LENGTH / 2, linkDirection);
2298
- const endPoint1 = moveXOfPoint(endCenterPoint, -ABSTRACT_HANDLE_LENGTH / 2, linkDirection);
2299
- const endPoint2 = moveXOfPoint(endCenterPoint, ABSTRACT_HANDLE_LENGTH / 2, linkDirection);
2300
- const startHandle = roughSVG.line(startPoint1[0], startPoint1[1], startPoint2[0], startPoint2[1], getHandleOption(activeHandlePosition === AbstractHandlePosition.start));
2301
- const endHandle = roughSVG.line(endPoint1[0], endPoint1[1], endPoint2[0], endPoint2[1], getHandleOption(activeHandlePosition === AbstractHandlePosition.end));
2302
- changeBoardClass(board, activeHandlePosition, isHorizontal);
2303
- startHandle.setAttribute('stroke-linecap', 'round');
2304
- endHandle.setAttribute('stroke-linecap', 'round');
2305
- abstractIncludedG.append(startHandle);
2306
- abstractIncludedG.append(endHandle);
2307
- abstractIncludedG.append(rectangle);
2308
- return abstractIncludedG;
2309
- }
2310
- function getHandleOption(isHover) {
2311
- return isHover
2312
- ? {
2313
- stroke: PRIMARY_COLOR,
2314
- strokeWidth: 4,
2315
- fillStyle: 'solid'
2316
- }
2317
- : {
2318
- stroke: ABSTRACT_HANDLE_COLOR,
2319
- strokeWidth: 3,
2320
- fillStyle: 'solid'
2321
- };
2322
- }
2323
- function changeBoardClass(board, activeHandlePosition, isHorizontal) {
2324
- if (activeHandlePosition) {
2325
- if (isHorizontal) {
2326
- PlaitBoard.getBoardNativeElement(board).classList.add('abstract-resizing-horizontal');
2327
- }
2328
- else {
2329
- PlaitBoard.getBoardNativeElement(board).classList.add('abstract-resizing-vertical');
2330
- }
2331
- }
2332
- else {
2333
- PlaitBoard.getBoardNativeElement(board).classList.remove('abstract-resizing-horizontal');
2334
- PlaitBoard.getBoardNativeElement(board).classList.remove('abstract-resizing-vertical');
2335
- }
2336
- }
2337
-
2338
2249
  class BaseDrawer {
2339
2250
  constructor(board) {
2340
2251
  this.board = board;
2341
2252
  }
2253
+ draw(element, parentG, data) {
2254
+ this.destroy();
2255
+ if (this.canDraw && this.canDraw(element, data)) {
2256
+ const g = this.baseDraw(element, data);
2257
+ if (g) {
2258
+ parentG.append(g);
2259
+ }
2260
+ if (hasAfterDraw(this)) {
2261
+ this.afterDraw(element);
2262
+ }
2263
+ }
2264
+ }
2342
2265
  destroy() {
2343
2266
  if (this.g) {
2344
2267
  this.g.remove();
@@ -2361,14 +2284,14 @@ function findNewSiblingNodePath(board, element) {
2361
2284
  return Path$1.next(path);
2362
2285
  }
2363
2286
 
2364
- class QuickInsertDrawer extends BaseDrawer {
2287
+ class NodeInsertDrawer extends BaseDrawer {
2365
2288
  canDraw(element) {
2366
2289
  if (PlaitBoard.isReadonly(this.board) || (element === null || element === void 0 ? void 0 : element.isCollapsed)) {
2367
2290
  return false;
2368
2291
  }
2369
2292
  return true;
2370
2293
  }
2371
- draw(element) {
2294
+ baseDraw(element) {
2372
2295
  const quickInsertG = createG();
2373
2296
  this.g = quickInsertG;
2374
2297
  quickInsertG.classList.add('quick-insert');
@@ -2394,7 +2317,7 @@ class QuickInsertDrawer extends BaseDrawer {
2394
2317
  }
2395
2318
  let beginPoint = getPointByPlacement(nodeClient, placement);
2396
2319
  if (element.children.length > 0 && !element.isRoot) {
2397
- beginPoint = moveXOfPoint(beginPoint, EXTEND_RADIUS + 8, linkDirection);
2320
+ beginPoint = moveXOfPoint(beginPoint, EXTEND_DIAMETER + 8, linkDirection);
2398
2321
  distance = 5;
2399
2322
  }
2400
2323
  const endPoint = moveXOfPoint(beginPoint, distance, linkDirection);
@@ -2403,7 +2326,7 @@ class QuickInsertDrawer extends BaseDrawer {
2403
2326
  stroke: branchColor,
2404
2327
  strokeWidth: branchWidth
2405
2328
  });
2406
- const circle = PlaitBoard.getRoughSVG(this.board).circle(circleCenter[0], circleCenter[1], EXTEND_RADIUS, {
2329
+ const circle = PlaitBoard.getRoughSVG(this.board).circle(circleCenter[0], circleCenter[1], EXTEND_DIAMETER, {
2407
2330
  fill: QUICK_INSERT_CIRCLE_COLOR,
2408
2331
  stroke: QUICK_INSERT_CIRCLE_COLOR,
2409
2332
  fillStyle: 'solid'
@@ -2444,71 +2367,271 @@ class QuickInsertDrawer extends BaseDrawer {
2444
2367
  }
2445
2368
  }
2446
2369
 
2447
- class MindNodeComponent extends PlaitPluginElementComponent {
2448
- get handActive() {
2449
- return this.board.pointer === PlaitPointerType.hand;
2370
+ function drawAbstractIncludedOutline(board, roughSVG, element, activeHandlePosition, resizingLocation) {
2371
+ const abstractIncludedG = createG();
2372
+ const parentElement = MindElement.getParent(element);
2373
+ const nodeLayout = MindQueries.getCorrectLayoutByElement(board, element);
2374
+ const isHorizontal = isHorizontalLayout(nodeLayout);
2375
+ const includedElements = parentElement.children.slice(element.start, element.end + 1);
2376
+ let abstractRectangle = getRectangleByElements(board, includedElements, true);
2377
+ abstractRectangle = RectangleClient.getOutlineRectangle(abstractRectangle, -ABSTRACT_INCLUDED_OUTLINE_OFFSET);
2378
+ if (resizingLocation) {
2379
+ abstractRectangle = getRectangleByResizingLocation(abstractRectangle, resizingLocation, activeHandlePosition, isHorizontal);
2450
2380
  }
2451
- constructor(viewContainerRef, cdr, render2, ngZone) {
2381
+ const rectangle = drawAbstractRoundRectangle(roughSVG, abstractRectangle.x, abstractRectangle.y, abstractRectangle.x + abstractRectangle.width, abstractRectangle.y + abstractRectangle.height, isHorizontal, {
2382
+ stroke: PRIMARY_COLOR,
2383
+ strokeWidth: 1,
2384
+ fillStyle: 'solid'
2385
+ });
2386
+ const startPlacement = [HorizontalPlacement.center, VerticalPlacement.top];
2387
+ const endPlacement = [HorizontalPlacement.center, VerticalPlacement.bottom];
2388
+ const linkDirection = getLayoutDirection(MindElement.getNode(element), isHorizontal);
2389
+ transformPlacement(startPlacement, linkDirection);
2390
+ transformPlacement(endPlacement, linkDirection);
2391
+ let startCenterPoint = getPointByPlacement(abstractRectangle, startPlacement);
2392
+ let endCenterPoint = getPointByPlacement(abstractRectangle, endPlacement);
2393
+ const startPoint1 = moveXOfPoint(startCenterPoint, -ABSTRACT_HANDLE_LENGTH / 2, linkDirection);
2394
+ const startPoint2 = moveXOfPoint(startCenterPoint, ABSTRACT_HANDLE_LENGTH / 2, linkDirection);
2395
+ const endPoint1 = moveXOfPoint(endCenterPoint, -ABSTRACT_HANDLE_LENGTH / 2, linkDirection);
2396
+ const endPoint2 = moveXOfPoint(endCenterPoint, ABSTRACT_HANDLE_LENGTH / 2, linkDirection);
2397
+ const startHandle = roughSVG.line(startPoint1[0], startPoint1[1], startPoint2[0], startPoint2[1], getHandleOption(activeHandlePosition === AbstractHandlePosition.start));
2398
+ const endHandle = roughSVG.line(endPoint1[0], endPoint1[1], endPoint2[0], endPoint2[1], getHandleOption(activeHandlePosition === AbstractHandlePosition.end));
2399
+ handleBoardClass(board, activeHandlePosition, isHorizontal);
2400
+ startHandle.setAttribute('stroke-linecap', 'round');
2401
+ endHandle.setAttribute('stroke-linecap', 'round');
2402
+ abstractIncludedG.append(startHandle);
2403
+ abstractIncludedG.append(endHandle);
2404
+ abstractIncludedG.append(rectangle);
2405
+ return abstractIncludedG;
2406
+ }
2407
+ function getHandleOption(isHover) {
2408
+ return isHover
2409
+ ? {
2410
+ stroke: PRIMARY_COLOR,
2411
+ strokeWidth: 4,
2412
+ fillStyle: 'solid'
2413
+ }
2414
+ : {
2415
+ stroke: ABSTRACT_HANDLE_COLOR,
2416
+ strokeWidth: 3,
2417
+ fillStyle: 'solid'
2418
+ };
2419
+ }
2420
+ function handleBoardClass(board, activeHandlePosition, isHorizontal) {
2421
+ if (activeHandlePosition) {
2422
+ if (isHorizontal) {
2423
+ PlaitBoard.getBoardContainer(board).classList.add('abstract-resizing-horizontal');
2424
+ }
2425
+ else {
2426
+ PlaitBoard.getBoardContainer(board).classList.add('abstract-resizing-vertical');
2427
+ }
2428
+ }
2429
+ else {
2430
+ PlaitBoard.getBoardContainer(board).classList.remove('abstract-resizing-horizontal');
2431
+ PlaitBoard.getBoardContainer(board).classList.remove('abstract-resizing-vertical');
2432
+ }
2433
+ }
2434
+
2435
+ class NodeActiveDrawer extends BaseDrawer {
2436
+ canDraw(element, data) {
2437
+ if (data.selected) {
2438
+ return true;
2439
+ }
2440
+ else {
2441
+ return false;
2442
+ }
2443
+ }
2444
+ baseDraw(element, data) {
2445
+ const activeG = createG();
2446
+ this.g = activeG;
2447
+ if (AbstractNode.isAbstract(element)) {
2448
+ this.abstractOutlineG = drawAbstractIncludedOutline(this.board, PlaitBoard.getRoughSVG(this.board), element);
2449
+ activeG.append(this.abstractOutlineG);
2450
+ }
2451
+ const node = MindElement.getNode(element);
2452
+ let { x, y, width, height } = getRectangleByNode(node);
2453
+ const strokeG = drawRoundRectangle(PlaitBoard.getRoughSVG(this.board), x - 2, y - 2, x + width + 2, y + height + 2, { stroke: PRIMARY_COLOR, strokeWidth: 2, fill: '' }, true);
2454
+ this.g.appendChild(strokeG);
2455
+ if (!data.isEditing) {
2456
+ const fillG = drawRoundRectangle(PlaitBoard.getRoughSVG(this.board), x - 2, y - 2, x + width + 2, y + height + 2, { stroke: PRIMARY_COLOR, fill: PRIMARY_COLOR, fillStyle: 'solid' }, true);
2457
+ fillG.style.opacity = '0.15';
2458
+ this.g.appendChild(fillG);
2459
+ }
2460
+ return activeG;
2461
+ }
2462
+ updateAbstractOutline(element, activeHandlePosition, resizingLocation) {
2463
+ if (this.abstractOutlineG) {
2464
+ this.abstractOutlineG.remove();
2465
+ }
2466
+ this.abstractOutlineG = drawAbstractIncludedOutline(this.board, PlaitBoard.getRoughSVG(this.board), element, activeHandlePosition, resizingLocation);
2467
+ this.g.append(this.abstractOutlineG);
2468
+ }
2469
+ }
2470
+
2471
+ class CollapseDrawer extends BaseDrawer {
2472
+ canDraw(element) {
2473
+ if (element.children.length && !PlaitMind.isMind(element)) {
2474
+ return true;
2475
+ }
2476
+ return false;
2477
+ }
2478
+ baseDraw(element) {
2479
+ const collapseG = createG();
2480
+ this.g = collapseG;
2481
+ collapseG.classList.add('collapse-container');
2482
+ const node = MindElement.getNode(element);
2483
+ const stroke = getBranchColorByMindElement(this.board, element);
2484
+ const branchWidth = getBranchWidthByMindElement(this.board, element);
2485
+ const layout = MindQueries.getLayoutByElement(element);
2486
+ const isUnderlineShape = getShapeByElement(this.board, element) === MindElementShape.underline;
2487
+ const isHorizontal = isHorizontalLayout(layout);
2488
+ const nodeClient = getRectangleByNode(node);
2489
+ let linkDirection = getLayoutDirection(node, isHorizontal);
2490
+ if (isIndentedLayout(layout)) {
2491
+ linkDirection = isTopLayout(layout) ? LayoutDirection.top : LayoutDirection.bottom;
2492
+ }
2493
+ let placement = [HorizontalPlacement.right, VerticalPlacement.middle];
2494
+ transformPlacement(placement, linkDirection);
2495
+ // underline shape and horizontal
2496
+ if (isHorizontal && isUnderlineShape && !element.isRoot) {
2497
+ placement[1] = VerticalPlacement.bottom;
2498
+ }
2499
+ let startPoint = getPointByPlacement(nodeClient, placement);
2500
+ const endPoint = moveXOfPoint(startPoint, EXTEND_OFFSET, linkDirection);
2501
+ const circleCenter = moveXOfPoint(endPoint, EXTEND_DIAMETER / 2, linkDirection);
2502
+ const arrowPoints = this.getArrowPoints(circleCenter, linkDirection);
2503
+ const arrowLine = drawLinearPath(arrowPoints, {
2504
+ stroke,
2505
+ strokeWidth: 2
2506
+ });
2507
+ const extendLine = PlaitBoard.getRoughSVG(this.board).line(startPoint[0], startPoint[1], endPoint[0], endPoint[1], {
2508
+ strokeWidth: branchWidth,
2509
+ stroke
2510
+ });
2511
+ const badge = PlaitBoard.getRoughSVG(this.board).circle(circleCenter[0], circleCenter[1], EXTEND_DIAMETER, {
2512
+ fill: stroke,
2513
+ stroke,
2514
+ fillStyle: 'solid'
2515
+ });
2516
+ const hideCircleG = PlaitBoard.getRoughSVG(this.board).circle(circleCenter[0], circleCenter[1], EXTEND_DIAMETER, {
2517
+ fill: '#fff',
2518
+ stroke,
2519
+ strokeWidth: branchWidth > 3 ? 3 : branchWidth,
2520
+ fillStyle: 'solid'
2521
+ });
2522
+ if (element.isCollapsed) {
2523
+ let numberOffset = 0;
2524
+ if (getChildrenCount(element) >= 10)
2525
+ numberOffset = -2;
2526
+ if (getChildrenCount(element) === 1)
2527
+ numberOffset = 1;
2528
+ const badgeText = createText(circleCenter[0] - 4 + numberOffset, circleCenter[1] + 4, stroke, `${getChildrenCount(element)}`);
2529
+ badge.setAttribute('style', 'opacity: 0.15');
2530
+ badgeText.setAttribute('style', 'font-size: 12px');
2531
+ collapseG.appendChild(badge);
2532
+ collapseG.appendChild(badgeText);
2533
+ collapseG.appendChild(extendLine);
2534
+ }
2535
+ else {
2536
+ collapseG.appendChild(hideCircleG);
2537
+ collapseG.appendChild(arrowLine);
2538
+ }
2539
+ collapseG.appendChild(extendLine);
2540
+ return collapseG;
2541
+ }
2542
+ afterDraw(element) {
2543
+ if (!this.g) {
2544
+ throw new Error(`can not find quick insert g`);
2545
+ }
2546
+ fromEvent(this.g, 'mouseup')
2547
+ .pipe(filter(() => !PlaitBoard.isPointer(this.board, PlaitPointerType.hand) || !!PlaitBoard.isReadonly(this.board)), take(1))
2548
+ .subscribe(() => {
2549
+ const isCollapsed = !element.isCollapsed;
2550
+ const newElement = { isCollapsed };
2551
+ const path = PlaitBoard.findPath(this.board, element);
2552
+ Transforms.setNode(this.board, newElement, path);
2553
+ });
2554
+ }
2555
+ getArrowPoints(circleCenter, linkDirection) {
2556
+ let arrowTopPoint = moveXOfPoint(circleCenter, 2, linkDirection);
2557
+ arrowTopPoint = moveYOfPoint(arrowTopPoint, 4, linkDirection);
2558
+ const arrowMiddlePoint = moveXOfPoint(circleCenter, -2, linkDirection);
2559
+ let arrowBottomPoint = moveXOfPoint(circleCenter, 2, linkDirection);
2560
+ arrowBottomPoint = moveYOfPoint(arrowBottomPoint, -4, linkDirection);
2561
+ return [arrowTopPoint, arrowMiddlePoint, arrowBottomPoint];
2562
+ }
2563
+ }
2564
+
2565
+ class MindNodeComponent extends PlaitPluginElementComponent {
2566
+ constructor(viewContainerRef, cdr) {
2452
2567
  super(cdr);
2453
2568
  this.viewContainerRef = viewContainerRef;
2454
2569
  this.cdr = cdr;
2455
- this.render2 = render2;
2456
- this.ngZone = ngZone;
2457
- this.isEditable = false;
2458
- this.activeG = [];
2459
2570
  this.shapeG = null;
2460
2571
  this.destroy$ = new Subject();
2461
2572
  this.trackBy = (index, node) => {
2462
2573
  return node.origin.id;
2463
2574
  };
2464
2575
  }
2576
+ initializeDrawer() {
2577
+ this.nodeEmojisDrawer = new NodeEmojisDrawer(this.board, this.viewContainerRef);
2578
+ this.nodeInsertDrawer = new NodeInsertDrawer(this.board);
2579
+ this.activeDrawer = new NodeActiveDrawer(this.board);
2580
+ this.collapseDrawer = new CollapseDrawer(this.board);
2581
+ this.textManage = new TextManage(this.board, this.viewContainerRef, () => {
2582
+ return getTopicRectangleByNode(this.board, this.node);
2583
+ }, (point) => {
2584
+ return isHitMindElement(this.board, point, this.element);
2585
+ }, (textManageRef) => {
2586
+ const width = textManageRef.width;
2587
+ const height = textManageRef.height;
2588
+ if (textManageRef.newValue) {
2589
+ MindTransforms.setTopic(this.board, this.element, textManageRef.newValue, width, height);
2590
+ }
2591
+ else {
2592
+ MindTransforms.setTopicSize(this.board, this.element, width, height);
2593
+ }
2594
+ });
2595
+ }
2465
2596
  ngOnInit() {
2466
- this.emojisDrawer = new EmojisDrawer(this.board, this.viewContainerRef);
2467
- this.quickInsertDrawer = new QuickInsertDrawer(this.board);
2468
2597
  super.ngOnInit();
2598
+ this.initializeDrawer();
2469
2599
  this.node = MindElement.getNode(this.element);
2470
2600
  this.index = NODE_TO_INDEX.get(this.element) || 0;
2471
2601
  this.roughSVG = PlaitBoard.getRoughSVG(this.board);
2472
2602
  this.parentG = PlaitElement.getComponent(MindElement.getRoot(this.board, this.element)).rootG;
2473
2603
  this.drawShape();
2474
2604
  this.drawLink();
2475
- this.drawRichtext();
2476
- this.drawActiveG();
2477
- this.updateActiveClass();
2478
- this.drawMaskG();
2605
+ this.drawText();
2606
+ this.activeDrawer.draw(this.element, this.g, { selected: this.selected, isEditing: this.textManage.isEditing });
2479
2607
  this.drawEmojis();
2480
2608
  this.drawExtend();
2481
- this.drawQuickInsert();
2609
+ }
2610
+ editTopic() {
2611
+ this.activeDrawer.draw(this.element, this.g, { selected: this.selected, isEditing: true });
2612
+ this.textManage.edit(() => {
2613
+ this.activeDrawer.draw(this.element, this.g, { selected: this.selected, isEditing: false });
2614
+ });
2482
2615
  }
2483
2616
  onContextChanged(value, previous) {
2484
- var _a, _b;
2485
2617
  const newNode = MindElement.getNode(value.element);
2486
- // resolve move node richtext lose issue
2487
- if (this.node !== newNode) {
2488
- if (this.foreignObject && this.foreignObject.children.length <= 0) {
2489
- (_a = this.foreignObject) === null || _a === void 0 ? void 0 : _a.appendChild((_b = this.richtextComponentRef) === null || _b === void 0 ? void 0 : _b.instance.editable);
2490
- }
2491
- }
2492
2618
  const isEqualNode = RectangleClient.isEqual(this.node, newNode);
2493
2619
  this.node = newNode;
2494
2620
  const isChangeTheme = this.board.operations.find(op => op.type === 'set_theme');
2495
2621
  if (!isEqualNode || value.element !== previous.element || isChangeTheme) {
2496
- this.drawActiveG();
2497
- this.updateActiveClass();
2622
+ this.activeDrawer.draw(this.element, this.g, { selected: this.selected, isEditing: this.textManage.isEditing });
2498
2623
  this.drawShape();
2499
2624
  this.drawLink();
2500
- this.updateRichtext();
2501
- this.drawMaskG();
2502
- this.drawExtend();
2503
- this.drawQuickInsert();
2504
2625
  this.drawEmojis();
2626
+ this.drawExtend();
2627
+ this.textManage.updateText(this.element.data.topic);
2628
+ this.textManage.updateRectangle();
2505
2629
  }
2506
2630
  else {
2507
2631
  const hasSameSelected = value.selected === previous.selected;
2508
2632
  const hasSameParent = value.parent === previous.parent;
2509
2633
  if (!hasSameSelected) {
2510
- this.drawActiveG();
2511
- this.updateActiveClass();
2634
+ this.activeDrawer.draw(this.element, this.g, { selected: this.selected, isEditing: this.textManage.isEditing });
2512
2635
  }
2513
2636
  if (!hasSameParent) {
2514
2637
  this.drawLink();
@@ -2516,22 +2639,11 @@ class MindNodeComponent extends PlaitPluginElementComponent {
2516
2639
  }
2517
2640
  }
2518
2641
  drawEmojis() {
2519
- const g = this.emojisDrawer.drawEmojis(this.element);
2642
+ const g = this.nodeEmojisDrawer.drawEmojis(this.element);
2520
2643
  if (g) {
2521
2644
  this.g.append(g);
2522
2645
  }
2523
2646
  }
2524
- drawQuickInsert() {
2525
- var _a;
2526
- this.quickInsertDrawer.destroy();
2527
- if (this.quickInsertDrawer.canDraw(this.element)) {
2528
- const g = this.quickInsertDrawer.draw(this.element);
2529
- if (hasAfterDraw(this.quickInsertDrawer)) {
2530
- this.quickInsertDrawer.afterDraw(this.element);
2531
- }
2532
- (_a = this.extendG) === null || _a === void 0 ? void 0 : _a.appendChild(g);
2533
- }
2534
- }
2535
2647
  drawShape() {
2536
2648
  this.destroyShape();
2537
2649
  const shape = getShapeByElement(this.board, this.node.origin);
@@ -2573,393 +2685,33 @@ class MindNodeComponent extends PlaitPluginElementComponent {
2573
2685
  this.linkG.remove();
2574
2686
  }
2575
2687
  }
2576
- drawMaskG() {
2577
- this.destroyMaskG();
2578
- const lineWidthOffset = 2;
2579
- const extendOffset = 15;
2580
- const nodeLayout = MindQueries.getLayoutByElement(this.node.origin);
2581
- const isTop = isTopLayout(nodeLayout);
2582
- const isRight = isRightLayout(nodeLayout);
2583
- const isBottom = isBottomLayout(nodeLayout);
2584
- const isLeft = isLeftLayout(nodeLayout);
2585
- const { x, y, width, height } = getRectangleByNode(this.node);
2586
- let drawX = x;
2587
- let drawY = y;
2588
- let drawWidth = x + width;
2589
- let drawHeight = y + height;
2590
- switch (true) {
2591
- case isTop:
2592
- drawX = x - lineWidthOffset;
2593
- drawY = y - extendOffset;
2594
- drawWidth = x + width + lineWidthOffset;
2595
- drawHeight = y + height + lineWidthOffset;
2596
- break;
2597
- case isBottom:
2598
- drawX = x - lineWidthOffset;
2599
- drawY = y - lineWidthOffset;
2600
- drawWidth = x + width + lineWidthOffset;
2601
- drawHeight = y + height + extendOffset;
2602
- break;
2603
- case isLeft:
2604
- drawX = x - extendOffset;
2605
- drawY = y - lineWidthOffset;
2606
- drawWidth = x + width + lineWidthOffset;
2607
- drawHeight = y + height + lineWidthOffset;
2608
- break;
2609
- case isRight:
2610
- drawX = x - lineWidthOffset;
2611
- drawY = y - lineWidthOffset;
2612
- drawWidth = x + width + extendOffset;
2613
- drawHeight = y + height + lineWidthOffset;
2614
- break;
2615
- }
2616
- this.maskG = drawRoundRectangle(this.roughSVG, drawX, drawY, drawWidth, drawHeight, { stroke: 'none', fill: 'rgba(255,255,255,0)', fillStyle: 'solid' }, true);
2617
- this.maskG.classList.add('mask');
2618
- this.maskG.setAttribute('visibility', 'visible');
2619
- this.g.append(this.maskG);
2620
- if (this.isEditable) {
2621
- this.disabledMaskG();
2622
- }
2623
- fromEvent(this.maskG, 'mouseenter')
2624
- .pipe(takeUntil(this.destroy$), filter(() => {
2625
- return PlaitBoard.isFocus(this.board) && !this.element.isCollapsed && !this.handActive;
2626
- }))
2627
- .subscribe(() => {
2628
- this.g.classList.add('hovered');
2629
- });
2630
- fromEvent(this.maskG, 'mouseleave')
2631
- .pipe(takeUntil(this.destroy$), filter(() => {
2632
- return PlaitBoard.isFocus(this.board) && !this.element.isCollapsed;
2633
- }))
2634
- .subscribe(() => {
2635
- this.g.classList.remove('hovered');
2636
- });
2637
- }
2638
- destroyMaskG() {
2639
- if (this.maskG) {
2640
- this.maskG.remove();
2641
- this.g.classList.remove('hovered');
2642
- }
2643
- }
2644
- enableMaskG() {
2645
- if (this.maskG) {
2646
- this.maskG.setAttribute('visibility', 'visible');
2647
- }
2648
- }
2649
- disabledMaskG() {
2650
- if (this.maskG) {
2651
- this.maskG.setAttribute('visibility', 'hidden');
2652
- }
2653
- }
2654
- drawActiveG() {
2655
- var _a, _b;
2656
- this.destroyActiveG();
2657
- (_a = this.abstractIncludedOutlineG) === null || _a === void 0 ? void 0 : _a.remove();
2658
- if (this.selected) {
2659
- if (AbstractNode.isAbstract(this.element)) {
2660
- this.updateAbstractIncludedOutline();
2661
- }
2662
- let { x, y, width, height } = getRectangleByNode(this.node);
2663
- const selectedStrokeG = drawRoundRectangle(this.roughSVG, x - 2, y - 2, x + width + 2, y + height + 2, { stroke: PRIMARY_COLOR, strokeWidth: 2, fill: '' }, true);
2664
- // 影响 mask 移入移出事件
2665
- selectedStrokeG.style.pointerEvents = 'none';
2666
- this.g.appendChild(selectedStrokeG);
2667
- this.activeG.push(selectedStrokeG);
2668
- if (((_b = this.richtextComponentRef) === null || _b === void 0 ? void 0 : _b.instance.plaitReadonly) === true) {
2669
- const selectedBackgroundG = drawRoundRectangle(this.roughSVG, x - 2, y - 2, x + width + 2, y + height + 2, { stroke: PRIMARY_COLOR, fill: PRIMARY_COLOR, fillStyle: 'solid' }, true);
2670
- selectedBackgroundG.style.opacity = '0.15';
2671
- // 影响双击事件
2672
- selectedBackgroundG.style.pointerEvents = 'none';
2673
- this.g.appendChild(selectedBackgroundG);
2674
- this.activeG.push(selectedBackgroundG, selectedStrokeG);
2675
- }
2676
- }
2677
- }
2678
- destroyActiveG() {
2679
- this.activeG.forEach(g => g.remove());
2680
- this.activeG = [];
2681
- }
2682
- updateActiveClass() {
2683
- if (!this.g) {
2684
- return;
2685
- }
2686
- if (this.selected) {
2687
- this.render2.addClass(this.g, 'active');
2688
- }
2689
- else {
2690
- this.render2.removeClass(this.g, 'active');
2691
- }
2692
- }
2693
- drawRichtext() {
2694
- const { richtextG, richtextComponentRef, foreignObject } = drawTopicByNode(this.board, this.node, this.viewContainerRef);
2695
- this.richtextComponentRef = richtextComponentRef;
2696
- this.richtextG = richtextG;
2697
- this.foreignObject = foreignObject;
2698
- this.render2.addClass(richtextG, 'richtext');
2699
- this.g.append(richtextG);
2700
- }
2701
2688
  drawExtend() {
2702
2689
  this.destroyExtend();
2703
- // create extend
2704
2690
  this.extendG = createG();
2705
- const collapseG = createG();
2706
2691
  this.extendG.classList.add('extend');
2707
- collapseG.classList.add('collapse-container');
2708
2692
  this.g.append(this.extendG);
2709
- this.extendG.append(collapseG);
2710
- if (this.node.origin.isRoot) {
2711
- return;
2712
- }
2713
- // interactive
2714
- fromEvent(collapseG, 'mouseup')
2715
- .pipe(filter(() => !this.handActive || !!PlaitBoard.isReadonly(this.board)), take(1))
2716
- .subscribe(() => {
2717
- const isCollapsed = !this.node.origin.isCollapsed;
2718
- const newElement = { isCollapsed };
2719
- const path = PlaitBoard.findPath(this.board, this.element);
2720
- Transforms.setNode(this.board, newElement, path);
2721
- });
2722
- const { x, y, width, height } = getRectangleByNode(this.node);
2723
- const stroke = getBranchColorByMindElement(this.board, this.element);
2724
- const branchWidth = getBranchWidthByMindElement(this.board, this.element);
2725
- const extendY = y + height / 2;
2726
- const nodeLayout = MindQueries.getCorrectLayoutByElement(this.board, this.element);
2727
- let extendLineXY = [
2728
- [x + width, extendY],
2729
- [x + width + EXTEND_OFFSET, extendY]
2730
- ];
2731
- let arrowYOffset = [-4, 1, -0.6, 4];
2732
- let arrowXOffset = [10, 5.5, 5.5, 10];
2733
- let extendLineXOffset = [0, 0];
2734
- let extendLineYOffset = [0, 0];
2735
- let circleOffset = [EXTEND_RADIUS / 2, 0];
2736
- if (isHorizontalLayout(nodeLayout) && !isIndentedLayout(nodeLayout)) {
2737
- extendLineYOffset =
2738
- getShapeByElement(this.board, this.node.origin) === MindElementShape.roundRectangle
2739
- ? [0, 0]
2740
- : [height / 2, height / 2];
2741
- if (isLeftLayout(nodeLayout)) {
2742
- //左
2743
- extendLineXOffset = [-width, -width - EXTEND_OFFSET * 2];
2744
- circleOffset = [-EXTEND_RADIUS / 2, 0];
2745
- arrowXOffset = [-10, -5.5, -5.5, -10];
2746
- }
2747
- }
2748
- else {
2749
- arrowXOffset = [-4, 0.6, -1, 4];
2750
- if (isTopLayout(nodeLayout)) {
2751
- //上
2752
- extendLineXOffset = [-width / 2, -width / 2 - EXTEND_OFFSET];
2753
- extendLineYOffset = [-height / 2, -height / 2 - EXTEND_OFFSET];
2754
- arrowYOffset = [-10, -5.5, -5.5, -10];
2755
- circleOffset = [0, -EXTEND_RADIUS / 2];
2756
- }
2757
- else {
2758
- //下
2759
- extendLineXOffset = [-width / 2, -width / 2 - EXTEND_OFFSET];
2760
- extendLineYOffset = [height / 2, height / 2 + EXTEND_OFFSET];
2761
- arrowYOffset = [10, 5.5, 5.5, 10];
2762
- circleOffset = [0, EXTEND_RADIUS / 2];
2763
- }
2764
- }
2765
- extendLineXY = [
2766
- [extendLineXY[0][0] + extendLineXOffset[0], extendLineXY[0][1] + extendLineYOffset[0]],
2767
- [extendLineXY[1][0] + extendLineXOffset[1], extendLineXY[1][1] + extendLineYOffset[1]]
2768
- ];
2769
- const extendLine = this.roughSVG.line(extendLineXY[0][0], extendLineXY[0][1], extendLineXY[1][0], extendLineXY[1][1], {
2770
- strokeWidth: branchWidth,
2771
- stroke
2772
- });
2773
- //绘制箭头
2774
- const hideArrowTopLine = this.roughSVG.line(extendLineXY[1][0] + arrowXOffset[0], extendLineXY[1][1] + arrowYOffset[0], extendLineXY[1][0] + arrowXOffset[1], extendLineXY[1][1] + arrowYOffset[1], {
2775
- stroke,
2776
- strokeWidth: 2
2777
- });
2778
- const hideArrowBottomLine = this.roughSVG.line(extendLineXY[1][0] + arrowXOffset[2], extendLineXY[1][1] + arrowYOffset[2], extendLineXY[1][0] + arrowXOffset[3], extendLineXY[1][1] + arrowYOffset[3], {
2779
- stroke,
2780
- strokeWidth: 2
2781
- });
2782
- if (this.node.origin.isCollapsed) {
2783
- const badge = this.roughSVG.circle(extendLineXY[1][0] + circleOffset[0], extendLineXY[1][1] + circleOffset[1], EXTEND_RADIUS, {
2784
- fill: stroke,
2785
- stroke,
2786
- fillStyle: 'solid'
2787
- });
2788
- let numberOffset = 0;
2789
- if (getChildrenCount(this.node.origin) >= 10)
2790
- numberOffset = -2;
2791
- if (getChildrenCount(this.node.origin) === 1)
2792
- numberOffset = 1;
2793
- const badgeText = createText(extendLineXY[1][0] + circleOffset[0] - 4 + numberOffset, extendLineXY[1][1] + circleOffset[1] + 4, stroke, `${getChildrenCount(this.node.origin)}`);
2693
+ if (this.element.isCollapsed) {
2794
2694
  this.g.classList.add('collapsed');
2795
- badge.setAttribute('style', 'opacity: 0.15');
2796
- badgeText.setAttribute('style', 'font-size: 12px');
2797
- collapseG.appendChild(badge);
2798
- collapseG.appendChild(badgeText);
2799
- collapseG.appendChild(extendLine);
2800
2695
  }
2801
2696
  else {
2802
2697
  this.g.classList.remove('collapsed');
2803
- if (this.node.origin.children.length > 0) {
2804
- const hideCircleG = this.roughSVG.circle(extendLineXY[1][0] + circleOffset[0], extendLineXY[1][1] + circleOffset[1], EXTEND_RADIUS - 1, {
2805
- fill: '#fff',
2806
- stroke,
2807
- strokeWidth: branchWidth > 3 ? 3 : branchWidth,
2808
- fillStyle: 'solid'
2809
- });
2810
- collapseG.appendChild(hideCircleG);
2811
- collapseG.appendChild(hideArrowTopLine);
2812
- collapseG.appendChild(hideArrowBottomLine);
2813
- }
2814
2698
  }
2699
+ this.nodeInsertDrawer.draw(this.element, this.extendG);
2700
+ this.collapseDrawer.draw(this.element, this.extendG);
2815
2701
  }
2816
2702
  destroyExtend() {
2817
2703
  if (this.extendG) {
2818
2704
  this.extendG.remove();
2819
2705
  }
2820
2706
  }
2821
- destroyRichtext() {
2822
- if (this.richtextG) {
2823
- this.richtextG.remove();
2824
- }
2825
- if (this.richtextComponentRef) {
2826
- this.richtextComponentRef.destroy();
2827
- }
2828
- }
2829
- updateAbstractIncludedOutline(activeHandlePosition, resizingLocation) {
2830
- var _a;
2831
- (_a = this.abstractIncludedOutlineG) === null || _a === void 0 ? void 0 : _a.remove();
2832
- this.abstractIncludedOutlineG = drawAbstractIncludedOutline(this.board, this.roughSVG, this.element, activeHandlePosition, resizingLocation);
2833
- PlaitBoard.getHost(this.board).append(this.abstractIncludedOutlineG);
2834
- }
2835
- updateRichtext() {
2836
- updateRichText(this.node.origin.data.topic, this.richtextComponentRef);
2837
- updateMindNodeTopicSize(this.board, this.node, this.richtextG, this.isEditable);
2838
- }
2839
- startEditText(isEnd, isClear) {
2840
- if (!this.richtextComponentRef) {
2841
- throw new Error('undefined richtextComponentRef');
2842
- }
2843
- const richtextInstance = this.richtextComponentRef.instance;
2844
- this.isEditable = true;
2845
- IS_TEXT_EDITABLE.set(this.board, true);
2846
- this.disabledMaskG();
2847
- updateMindNodeTopicSize(this.board, this.node, this.richtextG, this.isEditable);
2848
- if (richtextInstance.plaitReadonly) {
2849
- richtextInstance.plaitReadonly = false;
2850
- this.richtextComponentRef.changeDetectorRef.detectChanges();
2851
- this.drawActiveG();
2852
- const location = isEnd ? Editor.end(richtextInstance.editor, [0]) : [0];
2853
- setFullSelectionAndFocus(richtextInstance.editor, location);
2854
- if (isClear) {
2855
- Editor.deleteBackward(richtextInstance.editor);
2856
- }
2857
- // handle invalid width and height (old data)
2858
- let { width, height } = getRichtextContentSize(richtextInstance.editable);
2859
- if (width !== this.element.width || height !== this.element.height) {
2860
- MindTransforms.setTopicSize(this.board, this.element, width, height);
2861
- }
2862
- }
2863
- let richtext = richtextInstance.plaitValue;
2864
- // use debounceTime to wait DOM render complete
2865
- const valueChange$ = richtextInstance.plaitChange
2866
- .pipe(debounceTime(0), filter(event => {
2867
- // 过滤掉 operations 中全是 set_selection 的操作
2868
- return !event.operations.every(op => Operation.isSelectionOperation(op));
2869
- }))
2870
- .subscribe(event => {
2871
- if (richtext === event.value) {
2872
- return;
2873
- }
2874
- this.updateRichtext();
2875
- // 更新富文本、更新宽高
2876
- let { width, height } = getRichtextContentSize(richtextInstance.editable);
2877
- MindTransforms.setTopic(this.board, this.element, event.value, width, height);
2878
- MERGING.set(this.board, true);
2879
- });
2880
- const composition$ = richtextInstance.plaitComposition.pipe(debounceTime(0)).subscribe(event => {
2881
- let { width, height } = getRichtextContentSize(richtextInstance.editable);
2882
- if (width < NODE_MIN_WIDTH) {
2883
- width = NODE_MIN_WIDTH;
2884
- }
2885
- if (event.isComposing && (width !== this.node.origin.width || height !== this.node.origin.height)) {
2886
- const newElement = {
2887
- width: width / this.board.viewport.zoom,
2888
- height: height / this.board.viewport.zoom
2889
- };
2890
- const path = PlaitBoard.findPath(this.board, this.element);
2891
- Transforms.setNode(this.board, newElement, path);
2892
- MERGING.set(this.board, true);
2893
- }
2894
- });
2895
- const mousedown$ = fromEvent(document, 'mousedown').subscribe((event) => {
2896
- const point = transformPoint(this.board, toPoint(event.x, event.y, PlaitBoard.getHost(this.board)));
2897
- const clickInNode = isHitMindElement(this.board, point, this.element);
2898
- if (clickInNode && !hasEditableTarget(richtextInstance.editor, event.target)) {
2899
- event.preventDefault();
2900
- }
2901
- else if (!clickInNode) {
2902
- // handle composition input state, like: Chinese IME Composition Input
2903
- timer(0).subscribe(() => {
2904
- exitHandle();
2905
- this.enableMaskG();
2906
- });
2907
- }
2908
- });
2909
- const editor = richtextInstance.editor;
2910
- const { keydown } = editor;
2911
- editor.keydown = (event) => {
2912
- if (event.isComposing) {
2913
- return;
2914
- }
2915
- if (event.key === 'Escape') {
2916
- event.preventDefault();
2917
- event.stopPropagation();
2918
- exitHandle();
2919
- this.drawActiveG();
2920
- this.enableMaskG();
2921
- return;
2922
- }
2923
- if (event.key === 'Enter' && !event.shiftKey) {
2924
- event.preventDefault();
2925
- event.stopPropagation();
2926
- exitHandle();
2927
- this.drawActiveG();
2928
- this.enableMaskG();
2929
- return;
2930
- }
2931
- if (event.key === 'Tab') {
2932
- event.preventDefault();
2933
- event.stopPropagation();
2934
- exitHandle();
2935
- this.drawActiveG();
2936
- this.drawMaskG();
2937
- }
2938
- };
2939
- const exitHandle = () => {
2940
- this.ngZone.run(() => {
2941
- var _a;
2942
- // unsubscribe
2943
- valueChange$.unsubscribe();
2944
- composition$.unsubscribe();
2945
- mousedown$.unsubscribe();
2946
- editor.keydown = keydown; // reset keydown
2947
- // editable status
2948
- MERGING.set(this.board, false);
2949
- richtextInstance.plaitReadonly = true;
2950
- (_a = this.richtextComponentRef) === null || _a === void 0 ? void 0 : _a.changeDetectorRef.markForCheck();
2951
- this.isEditable = false;
2952
- updateMindNodeTopicSize(this.board, this.node, this.richtextG, this.isEditable);
2953
- IS_TEXT_EDITABLE.set(this.board, false);
2954
- });
2955
- };
2707
+ drawText() {
2708
+ this.textManage.draw(this.element.data.topic);
2709
+ this.g.append(this.textManage.g);
2956
2710
  }
2957
2711
  ngOnDestroy() {
2958
- var _a;
2959
2712
  super.ngOnDestroy();
2960
- (_a = this.abstractIncludedOutlineG) === null || _a === void 0 ? void 0 : _a.remove();
2961
- this.destroyRichtext();
2962
- this.emojisDrawer.destroy();
2713
+ this.textManage.destroy();
2714
+ this.nodeEmojisDrawer.destroy();
2963
2715
  this.destroy$.next();
2964
2716
  this.destroy$.complete();
2965
2717
  if (ELEMENT_TO_NODE.get(this.element) === this.node) {
@@ -2967,7 +2719,7 @@ class MindNodeComponent extends PlaitPluginElementComponent {
2967
2719
  }
2968
2720
  }
2969
2721
  }
2970
- MindNodeComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: MindNodeComponent, deps: [{ token: i0.ViewContainerRef }, { token: i0.ChangeDetectorRef }, { token: i0.Renderer2 }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
2722
+ MindNodeComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: MindNodeComponent, deps: [{ token: i0.ViewContainerRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
2971
2723
  MindNodeComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.5", type: MindNodeComponent, selector: "plait-mind-node", usesInheritance: true, ngImport: i0, template: `
2972
2724
  <plait-children
2973
2725
  *ngIf="!element.isCollapsed"
@@ -2992,7 +2744,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImpor
2992
2744
  `,
2993
2745
  changeDetection: ChangeDetectionStrategy.OnPush
2994
2746
  }]
2995
- }], ctorParameters: function () { return [{ type: i0.ViewContainerRef }, { type: i0.ChangeDetectorRef }, { type: i0.Renderer2 }, { type: i0.NgZone }]; } });
2747
+ }], ctorParameters: function () { return [{ type: i0.ViewContainerRef }, { type: i0.ChangeDetectorRef }]; } });
2996
2748
 
2997
2749
  const getLayoutOptions = (board) => {
2998
2750
  function getMainAxle(element, parent) {
@@ -3065,6 +2817,7 @@ class PlaitMindComponent extends MindNodeComponent {
3065
2817
  ngOnInit() {
3066
2818
  this.updateMindLayout();
3067
2819
  super.ngOnInit();
2820
+ this.g.classList.add('root');
3068
2821
  }
3069
2822
  beforeContextChange(value) {
3070
2823
  if (value.element !== this.element && this.initialized) {
@@ -3105,19 +2858,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImpor
3105
2858
  class MindModule {
3106
2859
  }
3107
2860
  MindModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: MindModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
3108
- MindModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.5", ngImport: i0, type: MindModule, declarations: [PlaitMindComponent, MindNodeComponent], imports: [CommonModule, RichtextModule, PlaitModule], exports: [PlaitMindComponent, MindNodeComponent] });
3109
- MindModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: MindModule, imports: [CommonModule, RichtextModule, PlaitModule] });
2861
+ MindModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.5", ngImport: i0, type: MindModule, declarations: [PlaitMindComponent, MindNodeComponent], imports: [CommonModule, TextModule, PlaitModule], exports: [PlaitMindComponent, MindNodeComponent] });
2862
+ MindModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: MindModule, imports: [CommonModule, TextModule, PlaitModule] });
3110
2863
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: MindModule, decorators: [{
3111
2864
  type: NgModule,
3112
2865
  args: [{
3113
2866
  declarations: [PlaitMindComponent, MindNodeComponent],
3114
- imports: [CommonModule, RichtextModule, PlaitModule],
2867
+ imports: [CommonModule, TextModule, PlaitModule],
3115
2868
  exports: [PlaitMindComponent, MindNodeComponent]
3116
2869
  }]
3117
2870
  }] });
3118
2871
 
3119
2872
  const DRAG_MOVE_BUFFER = 5;
3120
- const withDnd = (board) => {
2873
+ const withNodeDnd = (board) => {
3121
2874
  const { mousedown, mousemove, globalMouseup } = board;
3122
2875
  let activeElements = [];
3123
2876
  let correspondingElements = [];
@@ -3465,7 +3218,7 @@ const withAbstract = (board) => {
3465
3218
  newProperty =
3466
3219
  abstractHandlePosition === AbstractHandlePosition.start ? { start: locationIndex + 1 } : { end: locationIndex };
3467
3220
  }
3468
- abstractComponent.updateAbstractIncludedOutline(abstractHandlePosition, location);
3221
+ abstractComponent.activeDrawer.updateAbstractOutline(activeAbstractElement, abstractHandlePosition, location);
3469
3222
  }
3470
3223
  mousemove(event);
3471
3224
  };
@@ -3482,7 +3235,7 @@ const withAbstract = (board) => {
3482
3235
  }
3483
3236
  else {
3484
3237
  const abstractComponent = PlaitElement.getComponent(activeAbstractElement);
3485
- abstractComponent.updateAbstractIncludedOutline();
3238
+ abstractComponent.activeDrawer.updateAbstractOutline(activeAbstractElement);
3486
3239
  }
3487
3240
  activeAbstractElement = undefined;
3488
3241
  }
@@ -3534,22 +3287,29 @@ const withCreateMind = (board) => {
3534
3287
  const nodeG = drawRoundRectangleByElement(board, nodeRectangle, emptyMind);
3535
3288
  const topicRectangle = getTopicRectangleByElement(newBoard, nodeRectangle, emptyMind);
3536
3289
  if (!fakeCreateNodeRef) {
3537
- const { richtextComponentRef, richtextG, foreignObject } = drawTopicByElement(newBoard, topicRectangle, emptyMind);
3290
+ const textManage = new TextManage(board, PlaitBoard.getComponent(board).viewContainerRef, () => {
3291
+ return topicRectangle;
3292
+ });
3293
+ PlaitBoard.getComponent(board)
3294
+ .viewContainerRef.injector.get(NgZone)
3295
+ .run(() => {
3296
+ textManage.draw(emptyMind.data.topic);
3297
+ });
3538
3298
  fakeCreateNodeRef = {
3539
- instanceRef: richtextComponentRef,
3299
+ g: createG(),
3540
3300
  nodeG,
3541
- foreignObject,
3542
- topicG: richtextG
3301
+ textManage
3543
3302
  };
3544
- richtextComponentRef.changeDetectorRef.detectChanges();
3545
- PlaitBoard.getHost(board).append(...[fakeCreateNodeRef.nodeG, fakeCreateNodeRef.topicG]);
3303
+ fakeCreateNodeRef.g.classList.add('root');
3304
+ PlaitBoard.getHost(board).append(fakeCreateNodeRef.g);
3305
+ fakeCreateNodeRef.g.append(...[fakeCreateNodeRef.nodeG, textManage.g]);
3546
3306
  }
3547
3307
  else {
3308
+ fakeCreateNodeRef.textManage.updateRectangle(topicRectangle);
3548
3309
  fakeCreateNodeRef.nodeG.remove();
3549
3310
  fakeCreateNodeRef.nodeG = nodeG;
3550
- PlaitBoard.getHost(board).append(nodeG);
3551
- PlaitBoard.getHost(board).append(fakeCreateNodeRef.topicG);
3552
- updateForeignObject(fakeCreateNodeRef.topicG, topicRectangle.width, topicRectangle.height, topicRectangle.x, topicRectangle.y);
3311
+ fakeCreateNodeRef.g.append(nodeG);
3312
+ fakeCreateNodeRef.g.append(fakeCreateNodeRef.textManage.g);
3553
3313
  }
3554
3314
  }
3555
3315
  });
@@ -3586,9 +3346,8 @@ const withCreateMind = (board) => {
3586
3346
  };
3587
3347
  function destroy() {
3588
3348
  if (fakeCreateNodeRef) {
3589
- fakeCreateNodeRef.instanceRef.destroy();
3590
- fakeCreateNodeRef.nodeG.remove();
3591
- fakeCreateNodeRef.topicG.remove();
3349
+ fakeCreateNodeRef.textManage.destroy();
3350
+ fakeCreateNodeRef.g.remove();
3592
3351
  fakeCreateNodeRef = null;
3593
3352
  }
3594
3353
  }
@@ -3620,6 +3379,68 @@ const isExpandHotkey = (keyboardEvent) => {
3620
3379
  return isKeyHotkey('mod+/', keyboardEvent);
3621
3380
  };
3622
3381
 
3382
+ const withNodeHover = (board) => {
3383
+ const { mousemove, mouseleave } = board;
3384
+ let hoveredMindElement = null;
3385
+ board.mousemove = (event) => {
3386
+ throttleRAF(() => {
3387
+ let target = null;
3388
+ const point = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
3389
+ depthFirstRecursion(board, element => {
3390
+ if (target) {
3391
+ return;
3392
+ }
3393
+ if (!MindElement.isMindElement(board, element)) {
3394
+ return;
3395
+ }
3396
+ const isHitElement = isHitMindElement(board, point, element);
3397
+ if (isHitElement) {
3398
+ target = element;
3399
+ }
3400
+ }, node => {
3401
+ if (PlaitBoard.isBoard(node) || board.isRecursion(node)) {
3402
+ return true;
3403
+ }
3404
+ else {
3405
+ return false;
3406
+ }
3407
+ }, true);
3408
+ if (hoveredMindElement && target && hoveredMindElement === target) {
3409
+ return;
3410
+ }
3411
+ if (hoveredMindElement) {
3412
+ removeHovered(hoveredMindElement);
3413
+ }
3414
+ if (target) {
3415
+ addHovered(target);
3416
+ hoveredMindElement = target;
3417
+ }
3418
+ else {
3419
+ hoveredMindElement = null;
3420
+ }
3421
+ });
3422
+ mousemove(event);
3423
+ };
3424
+ board.mouseleave = (event) => {
3425
+ if (hoveredMindElement) {
3426
+ removeHovered(hoveredMindElement);
3427
+ hoveredMindElement = null;
3428
+ }
3429
+ mouseleave(event);
3430
+ };
3431
+ return board;
3432
+ };
3433
+ const addHovered = (element) => {
3434
+ const component = PlaitElement.getComponent(element);
3435
+ component.g.classList.add('hovered');
3436
+ };
3437
+ const removeHovered = (element) => {
3438
+ const component = PlaitElement.getComponent(element);
3439
+ if (component && component.g) {
3440
+ component.g.classList.remove('hovered');
3441
+ }
3442
+ };
3443
+
3623
3444
  const withMind = (board) => {
3624
3445
  const { drawElement, dblclick, keydown, insertFragment, setFragment, deleteFragment, isHitSelection, getRectangle, isMovable, isRecursion } = board;
3625
3446
  board.drawElement = (context) => {
@@ -3746,7 +3567,7 @@ const withMind = (board) => {
3746
3567
  if (!isVirtualKey(event)) {
3747
3568
  event.preventDefault();
3748
3569
  const selectedElement = selectedElements[0];
3749
- enterNodeEditing(selectedElement);
3570
+ editTopic(selectedElement);
3750
3571
  return;
3751
3572
  }
3752
3573
  }
@@ -3768,7 +3589,7 @@ const withMind = (board) => {
3768
3589
  .forEach(mindMap => {
3769
3590
  depthFirstRecursion(mindMap, node => {
3770
3591
  if (!PlaitBoard.hasBeenTextEditing(board) && isHitMindElement(board, point, node)) {
3771
- enterNodeEditing(node);
3592
+ editTopic(node);
3772
3593
  }
3773
3594
  }, node => {
3774
3595
  if (PlaitBoard.isBoard(node) || board.isRecursion(node)) {
@@ -3804,7 +3625,7 @@ const withMind = (board) => {
3804
3625
  }
3805
3626
  else {
3806
3627
  const text = data === null || data === void 0 ? void 0 : data.getData(`text/plain`);
3807
- const { width, height } = getSizeByText(text, PlaitBoard.getHost(board).parentElement, TOPIC_DEFAULT_MAX_WORD_COUNT);
3628
+ const { width, height } = getTextSize(board, text, TOPIC_DEFAULT_MAX_WORD_COUNT);
3808
3629
  const selectedElements = getSelectedElements(board);
3809
3630
  if (text && selectedElements.length === 1) {
3810
3631
  insertClipboardText(board, selectedElements[0], text, width, height);
@@ -3822,7 +3643,7 @@ const withMind = (board) => {
3822
3643
  MindTransforms.removeElements(board, selectedElements);
3823
3644
  deleteFragment(data);
3824
3645
  };
3825
- return withMindHotkey(withMindExtend(withCreateMind(withAbstract(withDnd(board)))));
3646
+ return withNodeHover(withMindHotkey(withMindExtend(withCreateMind(withAbstract(withNodeDnd(board))))));
3826
3647
  };
3827
3648
 
3828
3649
  class MindEmojiBaseComponent {
@@ -3876,5 +3697,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImpor
3876
3697
  * Generated bundle index. Do not edit.
3877
3698
  */
3878
3699
 
3879
- export { ABSTRACT_HANDLE_COLOR, ABSTRACT_HANDLE_LENGTH, ABSTRACT_HANDLE_MASK_WIDTH, ABSTRACT_INCLUDED_OUTLINE_OFFSET, AbstractHandlePosition, AbstractResizeState, BASE, BRANCH_WIDTH, BaseDrawer, BranchShape, DefaultAbstractNodeStyle, DefaultNodeStyle, ELEMENT_TO_NODE, EXTEND_OFFSET, EXTEND_RADIUS, GRAY_COLOR, INHERIT_ATTRIBUTE_KEYS, IS_DRAGGING, LayoutDirection, LayoutDirectionsMap, MindColorfulThemeColor, MindDarkThemeColor, MindDefaultThemeColor, MindElement, MindElementShape, MindEmojiBaseComponent, MindModule, MindNode, MindNodeComponent, MindPointerType, MindQueries, MindRetroThemeColor, MindSoftThemeColor, MindStarryThemeColor, MindThemeColor, MindThemeColors, MindTransforms, NODE_MIN_WIDTH, PRIMARY_COLOR, PlaitMind, PlaitMindComponent, QUICK_INSERT_CIRCLE_COLOR, QUICK_INSERT_CIRCLE_OFFSET, QUICK_INSERT_INNER_CROSS_COLOR, ROOT_TOPIC_FONT_SIZE, STROKE_WIDTH, TOPIC_COLOR, TOPIC_DEFAULT_MAX_WORD_COUNT, TOPIC_FONT_SIZE, TRANSPARENT, addActiveOnDragOrigin, adjustAbstractToNode, adjustNodeToRoot, adjustRootToNode, canSetAbstract, copyNewNode, correctLayoutByDirection, createDefaultMind, createEmptyMind, createMindElement, deleteElementHandleAbstract, deleteElementsHandleRightNodeCount, detectDropTarget, directionCorrector, directionDetector, divideElementByParent, drawFakeDragNode, drawFakeDropNode, enterNodeEditing, extractNodesText, findLastChild, findLocationLeftIndex, getAbstractBranchColor, getAbstractBranchWidth, getAbstractHandleRectangle, getAllowedDirection, getAvailableSubLayoutsByLayoutDirections, getBehindAbstracts, getBranchColorByMindElement, getBranchDirectionsByLayouts, getBranchShapeByMindElement, getBranchWidthByMindElement, getChildrenCount, getCorrespondingAbstract, getDefaultBranchColor, getDefaultBranchColorByIndex, getDefaultLayout, getEmojiForeignRectangle, getEmojiRectangle, getFirstLevelElement, getHitAbstractHandle, getInCorrectLayoutDirection, getLayoutDirection$1 as getLayoutDirection, getLayoutReverseDirection, getLocationScope, getMindThemeColor, getNextBranchColor, getOverallAbstracts, getPathByDropTarget, getRectangleByElement, getRectangleByNode, getRectangleByResizingLocation, getRelativeStartEndByAbstractRef, getRootLayout, getShapeByElement, getStrokeByMindElement, getTopicRectangleByElement, getTopicRectangleByNode, getValidAbstractRefs, handleTouchedAbstract, hasAfterDraw, hasPreviousOrNextOfDropPath, insertElementHandleAbstract, insertElementHandleRightNodeCount, insertMindElement, isChildElement, isChildRight, isChildUp, isCorrectLayout, isDragging, isDropStandardRight, isHitEmojis, isHitMindElement, isInRightBranchOfStandardLayout, isMixedLayout, isSetAbstract, isValidTarget, isVirtualKey, removeActiveOnDragOrigin, separateChildren, setIsDragging, withMind, withMindExtend };
3700
+ export { ABSTRACT_HANDLE_COLOR, ABSTRACT_HANDLE_LENGTH, ABSTRACT_HANDLE_MASK_WIDTH, ABSTRACT_INCLUDED_OUTLINE_OFFSET, AbstractHandlePosition, AbstractResizeState, BASE, BRANCH_WIDTH, BaseDrawer, BranchShape, DefaultAbstractNodeStyle, DefaultNodeStyle, ELEMENT_TO_NODE, EXTEND_DIAMETER, EXTEND_OFFSET, GRAY_COLOR, INHERIT_ATTRIBUTE_KEYS, IS_DRAGGING, LayoutDirection, LayoutDirectionsMap, MindColorfulThemeColor, MindDarkThemeColor, MindDefaultThemeColor, MindElement, MindElementShape, MindEmojiBaseComponent, MindModule, MindNode, MindNodeComponent, MindPointerType, MindQueries, MindRetroThemeColor, MindSoftThemeColor, MindStarryThemeColor, MindThemeColor, MindThemeColors, 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, ROOT_TOPIC_HEIGHT, STROKE_WIDTH, TOPIC_COLOR, TOPIC_DEFAULT_MAX_WORD_COUNT, TOPIC_FONT_SIZE, TRANSPARENT, addActiveOnDragOrigin, adjustAbstractToNode, adjustNodeToRoot, adjustRootToNode, canSetAbstract, copyNewNode, correctLayoutByDirection, createDefaultMind, createEmptyMind, createMindElement, deleteElementHandleAbstract, deleteElementsHandleRightNodeCount, detectDropTarget, directionCorrector, directionDetector, divideElementByParent, drawFakeDragNode, drawFakeDropNode, editTopic, extractNodesText, findLastChild, findLocationLeftIndex, getAbstractBranchColor, getAbstractBranchWidth, getAbstractHandleRectangle, getAllowedDirection, getAvailableSubLayoutsByLayoutDirections, getBehindAbstracts, getBranchColorByMindElement, getBranchDirectionsByLayouts, getBranchShapeByMindElement, getBranchWidthByMindElement, getChildrenCount, getCorrespondingAbstract, getDefaultBranchColor, getDefaultBranchColorByIndex, getDefaultLayout, getEmojiForeignRectangle, getEmojiRectangle, getFirstLevelElement, getHitAbstractHandle, getInCorrectLayoutDirection, getLayoutDirection$1 as getLayoutDirection, getLayoutReverseDirection, getLocationScope, getMindThemeColor, getNextBranchColor, getOverallAbstracts, getPathByDropTarget, getRectangleByElement, getRectangleByNode, getRectangleByResizingLocation, getRelativeStartEndByAbstractRef, getRootLayout, getShapeByElement, getStrokeByMindElement, getTopicRectangleByElement, getTopicRectangleByNode, getValidAbstractRefs, handleTouchedAbstract, hasAfterDraw, hasPreviousOrNextOfDropPath, insertElementHandleAbstract, insertElementHandleRightNodeCount, insertMindElement, isChildElement, isChildRight, isChildUp, isCorrectLayout, isDragging, isDropStandardRight, isHitEmojis, isHitMindElement, isInRightBranchOfStandardLayout, isMixedLayout, isSetAbstract, isValidTarget, isVirtualKey, removeActiveOnDragOrigin, separateChildren, setIsDragging, withMind, withMindExtend };
3880
3701
  //# sourceMappingURL=plait-mind.mjs.map