@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;
@@ -215,36 +179,17 @@ const MindThemeColor = {
215
179
  }
216
180
  };
217
181
 
218
- function getRectangleByNode(node) {
219
- const x = node.x + node.hGap;
220
- let y = node.y + node.vGap;
221
- const width = node.width - node.hGap * 2;
222
- const height = node.height - node.vGap * 2;
223
- return {
224
- x,
225
- y,
226
- width,
227
- height
228
- };
229
- }
230
- function getRectangleByElement(board, originPoint, element) {
231
- const nodeRectangle = {
232
- x: originPoint[0],
233
- y: originPoint[1],
234
- width: NodeSpace.getNodeWidth(board, element),
235
- height: NodeSpace.getNodeHeight(board, element)
236
- };
237
- return nodeRectangle;
238
- }
239
- function isHitMindElement(board, point, element) {
240
- const node = MindElement.getNode(element);
241
- if (node && distanceBetweenPointAndRectangle(point[0], point[1], getRectangleByNode(node)) === 0) {
242
- return true;
243
- }
244
- else {
245
- return false;
246
- }
247
- }
182
+ const BASE = 4;
183
+ const PRIMARY_COLOR = '#6698FF';
184
+ const TRANSPARENT = 'transparent';
185
+ const GRAY_COLOR = '#AAAAAA';
186
+ const STROKE_WIDTH = 3;
187
+ const BRANCH_WIDTH = 3;
188
+ const EXTEND_OFFSET = 8;
189
+ const EXTEND_DIAMETER = 16;
190
+ const QUICK_INSERT_CIRCLE_OFFSET = 9;
191
+ const QUICK_INSERT_CIRCLE_COLOR = '#6698FF';
192
+ const QUICK_INSERT_INNER_CROSS_COLOR = 'white';
248
193
 
249
194
  function getEmojisWidthHeight(board, element) {
250
195
  const options = board.getMindOptions();
@@ -264,6 +209,79 @@ function getEmojiFontSize(element) {
264
209
  }
265
210
  }
266
211
 
212
+ const NodeDefaultSpace = {
213
+ horizontal: {
214
+ nodeAndText: BASE * 3,
215
+ emojiAndText: BASE * 1.5
216
+ },
217
+ vertical: {
218
+ nodeAndText: BASE * 1.5
219
+ }
220
+ };
221
+ const RootDefaultSpace = {
222
+ horizontal: {
223
+ nodeAndText: BASE * 4,
224
+ emojiAndText: BASE * 2
225
+ },
226
+ vertical: {
227
+ nodeAndText: BASE * 2
228
+ }
229
+ };
230
+ const getHorizontalSpaceBetweenNodeAndText = (board, element) => {
231
+ const isMind = PlaitMind.isMind(element);
232
+ const nodeAndText = isMind ? RootDefaultSpace.horizontal.nodeAndText : NodeDefaultSpace.horizontal.nodeAndText;
233
+ return nodeAndText;
234
+ };
235
+ const getVerticalSpaceBetweenNodeAndText = (element) => {
236
+ const isMind = PlaitMind.isMind(element);
237
+ const nodeAndText = isMind ? RootDefaultSpace.vertical.nodeAndText : NodeDefaultSpace.vertical.nodeAndText;
238
+ return nodeAndText;
239
+ };
240
+ const getSpaceEmojiAndText = (element) => {
241
+ const isMind = PlaitMind.isMind(element);
242
+ const emojiAndText = isMind ? RootDefaultSpace.horizontal.emojiAndText : NodeDefaultSpace.horizontal.emojiAndText;
243
+ return emojiAndText;
244
+ };
245
+ const NodeSpace = {
246
+ getNodeWidth(board, element) {
247
+ const nodeAndText = getHorizontalSpaceBetweenNodeAndText(board, element);
248
+ if (MindElement.hasEmojis(element)) {
249
+ return (NodeSpace.getEmojiLeftSpace(board, element) +
250
+ getEmojisWidthHeight(board, element).width +
251
+ getSpaceEmojiAndText(element) +
252
+ element.width +
253
+ nodeAndText);
254
+ }
255
+ return nodeAndText + element.width + nodeAndText;
256
+ },
257
+ getNodeHeight(board, element) {
258
+ const nodeAndText = getVerticalSpaceBetweenNodeAndText(element);
259
+ return nodeAndText + element.height + nodeAndText;
260
+ },
261
+ getTextLeftSpace(board, element) {
262
+ const nodeAndText = getHorizontalSpaceBetweenNodeAndText(board, element);
263
+ if (MindElement.hasEmojis(element)) {
264
+ return NodeSpace.getEmojiLeftSpace(board, element) + getEmojisWidthHeight(board, element).width + getSpaceEmojiAndText(element);
265
+ }
266
+ else {
267
+ return nodeAndText;
268
+ }
269
+ },
270
+ getTextTopSpace(element) {
271
+ const nodeAndText = getVerticalSpaceBetweenNodeAndText(element);
272
+ return nodeAndText;
273
+ },
274
+ getEmojiLeftSpace(board, element) {
275
+ const options = board.getMindOptions();
276
+ const nodeAndText = getHorizontalSpaceBetweenNodeAndText(board, element);
277
+ return nodeAndText - options.emojiPadding;
278
+ },
279
+ getEmojiTopSpace(element) {
280
+ const nodeAndText = getVerticalSpaceBetweenNodeAndText(element);
281
+ return nodeAndText;
282
+ }
283
+ };
284
+
267
285
  function getEmojiRectangle(board, element) {
268
286
  let { x, y } = getRectangleByNode(MindElement.getNode(element));
269
287
  x = x + NodeSpace.getEmojiLeftSpace(board, element);
@@ -290,18 +308,38 @@ const isHitEmojis = (board, element, point) => {
290
308
  return RectangleClient.isHit(RectangleClient.toRectangleClient([point, point]), getEmojiRectangle(board, element));
291
309
  };
292
310
 
293
- function enterNodeEditing(element) {
311
+ function getTopicRectangleByNode(board, node) {
312
+ let nodeRectangle = getRectangleByNode(node);
313
+ return getTopicRectangleByElement(board, nodeRectangle, node.origin);
314
+ }
315
+ function getTopicRectangleByElement(board, nodeRectangle, element) {
316
+ const x = nodeRectangle.x + NodeSpace.getTextLeftSpace(board, element);
317
+ const y = nodeRectangle.y + NodeSpace.getTextTopSpace(element);
318
+ const width = Math.ceil(element.width);
319
+ const height = Math.ceil(element.height);
320
+ return { height, width, x, y };
321
+ }
322
+
323
+ const NODE_MIN_WIDTH = 18;
324
+
325
+ function editTopic(element) {
294
326
  const component = PlaitElement.getComponent(element);
295
- component.startEditText(false, false);
327
+ component.editTopic();
296
328
  }
297
329
 
330
+ const TOPIC_COLOR = '#333';
331
+ const TOPIC_FONT_SIZE = 14;
332
+ const ROOT_TOPIC_FONT_SIZE = 18;
333
+ const ROOT_TOPIC_HEIGHT = 25;
334
+ const TOPIC_DEFAULT_MAX_WORD_COUNT = 34;
335
+
298
336
  const adjustRootToNode = (board, node) => {
299
337
  const newNode = { ...node };
300
338
  delete newNode.isRoot;
301
339
  delete newNode.rightNodeCount;
302
340
  delete newNode.type;
303
341
  const text = Node.string(node.data.topic.children[0]) || ' ';
304
- const { width, height } = getSizeByText(text, PlaitBoard.getViewportContainer(board), TOPIC_DEFAULT_MAX_WORD_COUNT);
342
+ const { width, height } = getTextSize(board, text, TOPIC_DEFAULT_MAX_WORD_COUNT);
305
343
  newNode.width = Math.max(width, NODE_MIN_WIDTH);
306
344
  newNode.height = height;
307
345
  if (newNode.layout === MindLayoutType.standard) {
@@ -326,7 +364,7 @@ const adjustNodeToRoot = (board, node) => {
326
364
  delete newElement?.fill;
327
365
  delete newElement?.shape;
328
366
  delete newElement?.strokeWidth;
329
- const { width, height } = getSizeByText(text, PlaitBoard.getViewportContainer(board), TOPIC_DEFAULT_MAX_WORD_COUNT, ROOT_TOPIC_FONT_SIZE);
367
+ const { width, height } = getTextSize(board, text, TOPIC_DEFAULT_MAX_WORD_COUNT, ROOT_TOPIC_FONT_SIZE);
330
368
  newElement.width = Math.max(width, NODE_MIN_WIDTH);
331
369
  newElement.height = height;
332
370
  return {
@@ -345,7 +383,7 @@ const createEmptyMind = (board, point) => {
345
383
  return rootElement;
346
384
  };
347
385
  const createDefaultMind = (point, rightNodeCount, layout) => {
348
- const root = createMindElement('思维导图', 72, ROOT_DEFAULT_HEIGHT, { layout });
386
+ const root = createMindElement('思维导图', 72, ROOT_TOPIC_HEIGHT, { layout });
349
387
  root.rightNodeCount = rightNodeCount;
350
388
  root.isRoot = true;
351
389
  root.type = 'mindmap';
@@ -452,7 +490,7 @@ const insertMindElement = (board, inheritNode, path) => {
452
490
  clearSelectedElement(board);
453
491
  addSelectedElement(board, newElement);
454
492
  setTimeout(() => {
455
- enterNodeEditing(newElement);
493
+ editTopic(newElement);
456
494
  });
457
495
  };
458
496
  const findLastChild = (child) => {
@@ -582,6 +620,18 @@ const getRootLayout = (root) => {
582
620
  return root.layout || getDefaultLayout();
583
621
  };
584
622
 
623
+ const DefaultAbstractNodeStyle = {
624
+ strokeColor: GRAY_COLOR,
625
+ strokeWidth: 2,
626
+ branchColor: GRAY_COLOR,
627
+ branchWidth: 2
628
+ };
629
+ const DefaultNodeStyle = {
630
+ strokeWidth: 3,
631
+ branchWidth: 3,
632
+ fill: 'none'
633
+ };
634
+
585
635
  const getAvailableProperty = (board, element, propertyKey) => {
586
636
  return element[propertyKey];
587
637
  };
@@ -684,6 +734,12 @@ const isDragging = (board) => {
684
734
  };
685
735
  const setIsDragging = (board, state) => {
686
736
  IS_DRAGGING.set(board, state);
737
+ if (state) {
738
+ PlaitBoard.getBoardContainer(board).classList.add('mind-node-dragging');
739
+ }
740
+ else {
741
+ PlaitBoard.getBoardContainer(board).classList.remove('mind-node-dragging');
742
+ }
687
743
  };
688
744
  const hasPreviousOrNextOfDropPath = (parent, dropTarget, dropPath) => {
689
745
  let children = getNonAbstractChildren(parent);
@@ -897,23 +953,10 @@ const getPathByDropTarget = (board, dropTarget) => {
897
953
  return targetPath;
898
954
  };
899
955
 
900
- function drawRoundRectangleByNode(board, node) {
901
- const rectangle = getRectangleByNode(node);
902
- return drawRoundRectangleByElement(board, rectangle, node.origin);
903
- }
904
- function drawRoundRectangleByElement(board, nodeRectangle, element) {
905
- const defaultRootFill = getMindThemeColor(board).rootFill;
906
- const fill = element.fill ? element.fill : element.isRoot ? defaultRootFill : DefaultNodeStyle.fill;
907
- const stroke = getStrokeByMindElement(board, element);
908
- const strokeWidth = element.strokeWidth ? element.strokeWidth : DefaultNodeStyle.strokeWidth;
909
- const nodeG = drawRoundRectangle(PlaitBoard.getRoughSVG(board), nodeRectangle.x, nodeRectangle.y, nodeRectangle.x + nodeRectangle.width, nodeRectangle.y + nodeRectangle.height, {
910
- stroke,
911
- strokeWidth,
912
- fill,
913
- fillStyle: 'solid'
914
- });
915
- return nodeG;
916
- }
956
+ const ABSTRACT_HANDLE_COLOR = '#6698FF80'; //primary color 50% opacity
957
+ const ABSTRACT_INCLUDED_OUTLINE_OFFSET = 3.5;
958
+ const ABSTRACT_HANDLE_LENGTH = 10;
959
+ const ABSTRACT_HANDLE_MASK_WIDTH = 8;
917
960
 
918
961
  var HorizontalPlacement;
919
962
  (function (HorizontalPlacement) {
@@ -1171,13 +1214,13 @@ const drawFakeDragNode = (board, element, offsetX, offsetY) => {
1171
1214
  };
1172
1215
  const textRectangle = getTopicRectangleByNode(board, activeComponent.node);
1173
1216
  const fakeNodeG = drawRoundRectangleByNode(board, fakeDraggingNode);
1174
- const richtextG = activeComponent.richtextG?.cloneNode(true);
1217
+ const richtextG = activeComponent.textManage.g.cloneNode(true);
1175
1218
  updateForeignObject(richtextG, textRectangle.width, textRectangle.height, textRectangle.x + offsetX, textRectangle.y + offsetY);
1176
1219
  dragFakeNodeG?.append(fakeNodeG);
1177
1220
  dragFakeNodeG?.append(richtextG);
1178
1221
  // draw emojis
1179
1222
  if (MindElement.hasEmojis(element)) {
1180
- const fakeEmojisG = activeComponent.emojisDrawer.g.cloneNode(true);
1223
+ const fakeEmojisG = activeComponent.nodeEmojisDrawer.g.cloneNode(true);
1181
1224
  const foreignRectangle = getEmojiForeignRectangle(board, element);
1182
1225
  updateForeignObject(fakeEmojisG, foreignRectangle.width, foreignRectangle.height, foreignRectangle.x + offsetX, foreignRectangle.y + offsetY);
1183
1226
  dragFakeNodeG?.append(fakeEmojisG);
@@ -1637,9 +1680,7 @@ function findLocationLeftIndex(board, parentChildren, location, isHorizontal) {
1637
1680
  }
1638
1681
  function handleTouchedAbstract(board, touchedAbstract, endPoint) {
1639
1682
  let touchedHandle;
1640
- const abstract = getSelectedElements(board)
1641
- .filter(element => AbstractNode.isAbstract(element))
1642
- .find(element => {
1683
+ const abstract = getSelectedElements(board).filter(element => AbstractNode.isAbstract(element)).find(element => {
1643
1684
  touchedHandle = getHitAbstractHandle(board, element, endPoint);
1644
1685
  return touchedHandle;
1645
1686
  });
@@ -1648,13 +1689,13 @@ function handleTouchedAbstract(board, touchedAbstract, endPoint) {
1648
1689
  }
1649
1690
  if (touchedAbstract) {
1650
1691
  const component = PlaitElement.getComponent(touchedAbstract);
1651
- component.updateAbstractIncludedOutline();
1692
+ component.activeDrawer.updateAbstractOutline(touchedAbstract);
1652
1693
  touchedAbstract = undefined;
1653
1694
  }
1654
1695
  if (abstract) {
1655
1696
  touchedAbstract = abstract;
1656
1697
  const component = PlaitElement.getComponent(touchedAbstract);
1657
- component.updateAbstractIncludedOutline(touchedHandle);
1698
+ component.activeDrawer.updateAbstractOutline(touchedAbstract, touchedHandle);
1658
1699
  }
1659
1700
  return touchedAbstract;
1660
1701
  }
@@ -1879,6 +1920,9 @@ const MindElement = {
1879
1920
  },
1880
1921
  getEmojis(element) {
1881
1922
  return element.data.emojis;
1923
+ },
1924
+ getEditor(element) {
1925
+ return PlaitElement.getComponent(element).textManage.componentRef.instance.editor;
1882
1926
  }
1883
1927
  };
1884
1928
  var MindElementShape;
@@ -1892,118 +1936,53 @@ var BranchShape;
1892
1936
  BranchShape["polyline"] = "polyline";
1893
1937
  })(BranchShape || (BranchShape = {}));
1894
1938
 
1895
- const NodeDefaultSpace = {
1896
- horizontal: {
1897
- nodeAndText: BASE * 3,
1898
- emojiAndText: BASE * 1.5
1899
- },
1900
- vertical: {
1901
- nodeAndText: BASE * 1.5
1939
+ function getRectangleByNode(node) {
1940
+ const x = node.x + node.hGap;
1941
+ let y = node.y + node.vGap;
1942
+ const width = node.width - node.hGap * 2;
1943
+ const height = node.height - node.vGap * 2;
1944
+ return {
1945
+ x,
1946
+ y,
1947
+ width,
1948
+ height
1949
+ };
1950
+ }
1951
+ function getRectangleByElement(board, originPoint, element) {
1952
+ const nodeRectangle = {
1953
+ x: originPoint[0],
1954
+ y: originPoint[1],
1955
+ width: NodeSpace.getNodeWidth(board, element),
1956
+ height: NodeSpace.getNodeHeight(board, element)
1957
+ };
1958
+ return nodeRectangle;
1959
+ }
1960
+ function isHitMindElement(board, point, element) {
1961
+ const node = MindElement.getNode(element);
1962
+ if (node && distanceBetweenPointAndRectangle(point[0], point[1], getRectangleByNode(node)) === 0) {
1963
+ return true;
1902
1964
  }
1903
- };
1904
- const RootDefaultSpace = {
1905
- horizontal: {
1906
- nodeAndText: BASE * 4,
1907
- emojiAndText: BASE * 2
1908
- },
1909
- vertical: {
1910
- nodeAndText: BASE * 2
1965
+ else {
1966
+ return false;
1911
1967
  }
1912
- };
1913
- const getHorizontalSpaceBetweenNodeAndText = (board, element) => {
1914
- const isMind = PlaitMind.isMind(element);
1915
- const nodeAndText = isMind ? RootDefaultSpace.horizontal.nodeAndText : NodeDefaultSpace.horizontal.nodeAndText;
1916
- return nodeAndText;
1917
- };
1918
- const getVerticalSpaceBetweenNodeAndText = (element) => {
1919
- const isMind = PlaitMind.isMind(element);
1920
- const nodeAndText = isMind ? RootDefaultSpace.vertical.nodeAndText : NodeDefaultSpace.vertical.nodeAndText;
1921
- return nodeAndText;
1922
- };
1923
- const getSpaceEmojiAndText = (element) => {
1924
- const isMind = PlaitMind.isMind(element);
1925
- const emojiAndText = isMind ? RootDefaultSpace.horizontal.emojiAndText : NodeDefaultSpace.horizontal.emojiAndText;
1926
- return emojiAndText;
1927
- };
1928
- const NodeSpace = {
1929
- getNodeWidth(board, element) {
1930
- const nodeAndText = getHorizontalSpaceBetweenNodeAndText(board, element);
1931
- if (MindElement.hasEmojis(element)) {
1932
- return (NodeSpace.getEmojiLeftSpace(board, element) +
1933
- getEmojisWidthHeight(board, element).width +
1934
- getSpaceEmojiAndText(element) +
1935
- element.width +
1936
- nodeAndText);
1937
- }
1938
- return nodeAndText + element.width + nodeAndText;
1939
- },
1940
- getNodeHeight(board, element) {
1941
- const nodeAndText = getVerticalSpaceBetweenNodeAndText(element);
1942
- return nodeAndText + element.height + nodeAndText;
1943
- },
1944
- getTextLeftSpace(board, element) {
1945
- const nodeAndText = getHorizontalSpaceBetweenNodeAndText(board, element);
1946
- if (MindElement.hasEmojis(element)) {
1947
- return NodeSpace.getEmojiLeftSpace(board, element) + getEmojisWidthHeight(board, element).width + getSpaceEmojiAndText(element);
1948
- }
1949
- else {
1950
- return nodeAndText;
1951
- }
1952
- },
1953
- getTextTopSpace(element) {
1954
- const nodeAndText = getVerticalSpaceBetweenNodeAndText(element);
1955
- return nodeAndText;
1956
- },
1957
- getEmojiLeftSpace(board, element) {
1958
- const options = board.getMindOptions();
1959
- const nodeAndText = getHorizontalSpaceBetweenNodeAndText(board, element);
1960
- return nodeAndText - options.emojiPadding;
1961
- },
1962
- getEmojiTopSpace(element) {
1963
- const nodeAndText = getVerticalSpaceBetweenNodeAndText(element);
1964
- return nodeAndText;
1965
- }
1966
- };
1967
-
1968
- function getTopicRectangleByNode(board, node) {
1969
- let nodeRectangle = getRectangleByNode(node);
1970
- return getTopicRectangleByElement(board, nodeRectangle, node.origin);
1971
- }
1972
- function getTopicRectangleByElement(board, nodeRectangle, element) {
1973
- const x = nodeRectangle.x + NodeSpace.getTextLeftSpace(board, element);
1974
- const y = nodeRectangle.y + NodeSpace.getTextTopSpace(element);
1975
- const width = Math.ceil(element.width);
1976
- const height = Math.ceil(element.height);
1977
- return { height, width, x, y };
1978
1968
  }
1979
1969
 
1980
- function drawTopicByNode(board, node, viewContainerRef) {
1981
- const rectangle = getTopicRectangleByNode(board, node);
1982
- return drawTopicByElement(board, rectangle, node.origin, viewContainerRef);
1983
- }
1984
- function drawTopicByElement(board, rectangle, element, viewContainerRef) {
1985
- const containerRef = viewContainerRef || PlaitBoard.getComponent(board).viewContainerRef;
1986
- const classList = [];
1987
- if (element.isRoot) {
1988
- classList.push('root-node');
1989
- classList.push('font-size-18');
1990
- }
1991
- else {
1992
- classList.push('child-node');
1993
- }
1994
- // COMPAT: last character can not show in safari browser
1995
- return drawRichtext(rectangle.x, rectangle.y, rectangle.width, rectangle.height, element.data.topic, containerRef, classList);
1970
+ function drawRoundRectangleByNode(board, node) {
1971
+ const rectangle = getRectangleByNode(node);
1972
+ return drawRoundRectangleByElement(board, rectangle, node.origin);
1996
1973
  }
1997
- function updateMindNodeTopicSize(board, node, g, isEditable) {
1998
- const { x, y, width, height } = getTopicRectangleByNode(board, node);
1999
- if (isEditable) {
2000
- // add 999, avoid changing lines when paste more text
2001
- updateForeignObject(g, width + 999, height + 999, x, y);
2002
- }
2003
- else {
2004
- // COMPAT: last character can not show in safari browser
2005
- updateForeignObject(g, width, height, x, y);
2006
- }
1974
+ function drawRoundRectangleByElement(board, nodeRectangle, element) {
1975
+ const defaultRootFill = getMindThemeColor(board).rootFill;
1976
+ const fill = element.fill ? element.fill : element.isRoot ? defaultRootFill : DefaultNodeStyle.fill;
1977
+ const stroke = getStrokeByMindElement(board, element);
1978
+ const strokeWidth = element.strokeWidth ? element.strokeWidth : DefaultNodeStyle.strokeWidth;
1979
+ const nodeG = drawRoundRectangle(PlaitBoard.getRoughSVG(board), nodeRectangle.x, nodeRectangle.y, nodeRectangle.x + nodeRectangle.width, nodeRectangle.y + nodeRectangle.height, {
1980
+ stroke,
1981
+ strokeWidth,
1982
+ fill,
1983
+ fillStyle: 'solid'
1984
+ });
1985
+ return nodeG;
2007
1986
  }
2008
1987
 
2009
1988
  function drawAbstractLink(board, node, isHorizontal) {
@@ -2084,7 +2063,7 @@ class EmojiDrawer {
2084
2063
  }
2085
2064
  }
2086
2065
  }
2087
- class EmojisDrawer {
2066
+ class NodeEmojisDrawer {
2088
2067
  constructor(board, viewContainerRef) {
2089
2068
  this.board = board;
2090
2069
  this.viewContainerRef = viewContainerRef;
@@ -2210,11 +2189,15 @@ const correctLogicLayoutNode = (board, layout, path) => {
2210
2189
  }
2211
2190
  };
2212
2191
 
2192
+ const normalizeWidthAndHeight = (board, width, height) => {
2193
+ const newWidth = width < NODE_MIN_WIDTH * board.viewport.zoom ? NODE_MIN_WIDTH : width / board.viewport.zoom;
2194
+ const newHeight = height / board.viewport.zoom;
2195
+ return { width: newWidth, height: newHeight };
2196
+ };
2213
2197
  const setTopic = (board, element, topic, width, height) => {
2214
2198
  const newElement = {
2215
2199
  data: { topic },
2216
- width: width < NODE_MIN_WIDTH * board.viewport.zoom ? NODE_MIN_WIDTH : width / board.viewport.zoom,
2217
- height: height / board.viewport.zoom
2200
+ ...normalizeWidthAndHeight(board, width, height)
2218
2201
  };
2219
2202
  if (MindElement.hasEmojis(element)) {
2220
2203
  newElement.data.emojis = element.data.emojis;
@@ -2224,11 +2207,10 @@ const setTopic = (board, element, topic, width, height) => {
2224
2207
  };
2225
2208
  const setTopicSize = (board, element, width, height) => {
2226
2209
  const newElement = {
2227
- width: width < NODE_MIN_WIDTH * board.viewport.zoom ? NODE_MIN_WIDTH : width / board.viewport.zoom,
2228
- height: height / board.viewport.zoom
2210
+ ...normalizeWidthAndHeight(board, width, height)
2229
2211
  };
2230
- const path = PlaitBoard.findPath(board, element);
2231
- if (newElement.width !== element.width || newElement.height !== element.height) {
2212
+ if (element.width !== newElement.width || element.height !== newElement.height) {
2213
+ const path = PlaitBoard.findPath(board, element);
2232
2214
  Transforms.setNode(board, newElement, path);
2233
2215
  }
2234
2216
  };
@@ -2327,75 +2309,22 @@ const MindTransforms = {
2327
2309
  setRightNodeCountByRefs
2328
2310
  };
2329
2311
 
2330
- function drawAbstractIncludedOutline(board, roughSVG, element, activeHandlePosition, resizingLocation) {
2331
- const abstractIncludedG = createG();
2332
- const parentElement = MindElement.getParent(element);
2333
- const nodeLayout = MindQueries.getCorrectLayoutByElement(board, element);
2334
- const isHorizontal = isHorizontalLayout(nodeLayout);
2335
- const includedElements = parentElement.children.slice(element.start, element.end + 1);
2336
- let abstractRectangle = getRectangleByElements(board, includedElements, true);
2337
- abstractRectangle = RectangleClient.getOutlineRectangle(abstractRectangle, -ABSTRACT_INCLUDED_OUTLINE_OFFSET);
2338
- if (resizingLocation) {
2339
- abstractRectangle = getRectangleByResizingLocation(abstractRectangle, resizingLocation, activeHandlePosition, isHorizontal);
2340
- }
2341
- const rectangle = drawAbstractRoundRectangle(roughSVG, abstractRectangle.x, abstractRectangle.y, abstractRectangle.x + abstractRectangle.width, abstractRectangle.y + abstractRectangle.height, isHorizontal, {
2342
- stroke: PRIMARY_COLOR,
2343
- strokeWidth: 1,
2344
- fillStyle: 'solid'
2345
- });
2346
- const startPlacement = [HorizontalPlacement.center, VerticalPlacement.top];
2347
- const endPlacement = [HorizontalPlacement.center, VerticalPlacement.bottom];
2348
- const linkDirection = getLayoutDirection(MindElement.getNode(element), isHorizontal);
2349
- transformPlacement(startPlacement, linkDirection);
2350
- transformPlacement(endPlacement, linkDirection);
2351
- let startCenterPoint = getPointByPlacement(abstractRectangle, startPlacement);
2352
- let endCenterPoint = getPointByPlacement(abstractRectangle, endPlacement);
2353
- const startPoint1 = moveXOfPoint(startCenterPoint, -ABSTRACT_HANDLE_LENGTH / 2, linkDirection);
2354
- const startPoint2 = moveXOfPoint(startCenterPoint, ABSTRACT_HANDLE_LENGTH / 2, linkDirection);
2355
- const endPoint1 = moveXOfPoint(endCenterPoint, -ABSTRACT_HANDLE_LENGTH / 2, linkDirection);
2356
- const endPoint2 = moveXOfPoint(endCenterPoint, ABSTRACT_HANDLE_LENGTH / 2, linkDirection);
2357
- const startHandle = roughSVG.line(startPoint1[0], startPoint1[1], startPoint2[0], startPoint2[1], getHandleOption(activeHandlePosition === AbstractHandlePosition.start));
2358
- const endHandle = roughSVG.line(endPoint1[0], endPoint1[1], endPoint2[0], endPoint2[1], getHandleOption(activeHandlePosition === AbstractHandlePosition.end));
2359
- changeBoardClass(board, activeHandlePosition, isHorizontal);
2360
- startHandle.setAttribute('stroke-linecap', 'round');
2361
- endHandle.setAttribute('stroke-linecap', 'round');
2362
- abstractIncludedG.append(startHandle);
2363
- abstractIncludedG.append(endHandle);
2364
- abstractIncludedG.append(rectangle);
2365
- return abstractIncludedG;
2366
- }
2367
- function getHandleOption(isHover) {
2368
- return isHover
2369
- ? {
2370
- stroke: PRIMARY_COLOR,
2371
- strokeWidth: 4,
2372
- fillStyle: 'solid'
2373
- }
2374
- : {
2375
- stroke: ABSTRACT_HANDLE_COLOR,
2376
- strokeWidth: 3,
2377
- fillStyle: 'solid'
2378
- };
2379
- }
2380
- function changeBoardClass(board, activeHandlePosition, isHorizontal) {
2381
- if (activeHandlePosition) {
2382
- if (isHorizontal) {
2383
- PlaitBoard.getBoardNativeElement(board).classList.add('abstract-resizing-horizontal');
2384
- }
2385
- else {
2386
- PlaitBoard.getBoardNativeElement(board).classList.add('abstract-resizing-vertical');
2387
- }
2388
- }
2389
- else {
2390
- PlaitBoard.getBoardNativeElement(board).classList.remove('abstract-resizing-horizontal');
2391
- PlaitBoard.getBoardNativeElement(board).classList.remove('abstract-resizing-vertical');
2392
- }
2393
- }
2394
-
2395
2312
  class BaseDrawer {
2396
2313
  constructor(board) {
2397
2314
  this.board = board;
2398
2315
  }
2316
+ draw(element, parentG, data) {
2317
+ this.destroy();
2318
+ if (this.canDraw && this.canDraw(element, data)) {
2319
+ const g = this.baseDraw(element, data);
2320
+ if (g) {
2321
+ parentG.append(g);
2322
+ }
2323
+ if (hasAfterDraw(this)) {
2324
+ this.afterDraw(element);
2325
+ }
2326
+ }
2327
+ }
2399
2328
  destroy() {
2400
2329
  if (this.g) {
2401
2330
  this.g.remove();
@@ -2418,14 +2347,14 @@ function findNewSiblingNodePath(board, element) {
2418
2347
  return Path$1.next(path);
2419
2348
  }
2420
2349
 
2421
- class QuickInsertDrawer extends BaseDrawer {
2350
+ class NodeInsertDrawer extends BaseDrawer {
2422
2351
  canDraw(element) {
2423
2352
  if (PlaitBoard.isReadonly(this.board) || element?.isCollapsed) {
2424
2353
  return false;
2425
2354
  }
2426
2355
  return true;
2427
2356
  }
2428
- draw(element) {
2357
+ baseDraw(element) {
2429
2358
  const quickInsertG = createG();
2430
2359
  this.g = quickInsertG;
2431
2360
  quickInsertG.classList.add('quick-insert');
@@ -2451,7 +2380,7 @@ class QuickInsertDrawer extends BaseDrawer {
2451
2380
  }
2452
2381
  let beginPoint = getPointByPlacement(nodeClient, placement);
2453
2382
  if (element.children.length > 0 && !element.isRoot) {
2454
- beginPoint = moveXOfPoint(beginPoint, EXTEND_RADIUS + 8, linkDirection);
2383
+ beginPoint = moveXOfPoint(beginPoint, EXTEND_DIAMETER + 8, linkDirection);
2455
2384
  distance = 5;
2456
2385
  }
2457
2386
  const endPoint = moveXOfPoint(beginPoint, distance, linkDirection);
@@ -2460,7 +2389,7 @@ class QuickInsertDrawer extends BaseDrawer {
2460
2389
  stroke: branchColor,
2461
2390
  strokeWidth: branchWidth
2462
2391
  });
2463
- const circle = PlaitBoard.getRoughSVG(this.board).circle(circleCenter[0], circleCenter[1], EXTEND_RADIUS, {
2392
+ const circle = PlaitBoard.getRoughSVG(this.board).circle(circleCenter[0], circleCenter[1], EXTEND_DIAMETER, {
2464
2393
  fill: QUICK_INSERT_CIRCLE_COLOR,
2465
2394
  stroke: QUICK_INSERT_CIRCLE_COLOR,
2466
2395
  fillStyle: 'solid'
@@ -2501,70 +2430,271 @@ class QuickInsertDrawer extends BaseDrawer {
2501
2430
  }
2502
2431
  }
2503
2432
 
2504
- class MindNodeComponent extends PlaitPluginElementComponent {
2505
- get handActive() {
2506
- return this.board.pointer === PlaitPointerType.hand;
2433
+ function drawAbstractIncludedOutline(board, roughSVG, element, activeHandlePosition, resizingLocation) {
2434
+ const abstractIncludedG = createG();
2435
+ const parentElement = MindElement.getParent(element);
2436
+ const nodeLayout = MindQueries.getCorrectLayoutByElement(board, element);
2437
+ const isHorizontal = isHorizontalLayout(nodeLayout);
2438
+ const includedElements = parentElement.children.slice(element.start, element.end + 1);
2439
+ let abstractRectangle = getRectangleByElements(board, includedElements, true);
2440
+ abstractRectangle = RectangleClient.getOutlineRectangle(abstractRectangle, -ABSTRACT_INCLUDED_OUTLINE_OFFSET);
2441
+ if (resizingLocation) {
2442
+ abstractRectangle = getRectangleByResizingLocation(abstractRectangle, resizingLocation, activeHandlePosition, isHorizontal);
2443
+ }
2444
+ const rectangle = drawAbstractRoundRectangle(roughSVG, abstractRectangle.x, abstractRectangle.y, abstractRectangle.x + abstractRectangle.width, abstractRectangle.y + abstractRectangle.height, isHorizontal, {
2445
+ stroke: PRIMARY_COLOR,
2446
+ strokeWidth: 1,
2447
+ fillStyle: 'solid'
2448
+ });
2449
+ const startPlacement = [HorizontalPlacement.center, VerticalPlacement.top];
2450
+ const endPlacement = [HorizontalPlacement.center, VerticalPlacement.bottom];
2451
+ const linkDirection = getLayoutDirection(MindElement.getNode(element), isHorizontal);
2452
+ transformPlacement(startPlacement, linkDirection);
2453
+ transformPlacement(endPlacement, linkDirection);
2454
+ let startCenterPoint = getPointByPlacement(abstractRectangle, startPlacement);
2455
+ let endCenterPoint = getPointByPlacement(abstractRectangle, endPlacement);
2456
+ const startPoint1 = moveXOfPoint(startCenterPoint, -ABSTRACT_HANDLE_LENGTH / 2, linkDirection);
2457
+ const startPoint2 = moveXOfPoint(startCenterPoint, ABSTRACT_HANDLE_LENGTH / 2, linkDirection);
2458
+ const endPoint1 = moveXOfPoint(endCenterPoint, -ABSTRACT_HANDLE_LENGTH / 2, linkDirection);
2459
+ const endPoint2 = moveXOfPoint(endCenterPoint, ABSTRACT_HANDLE_LENGTH / 2, linkDirection);
2460
+ const startHandle = roughSVG.line(startPoint1[0], startPoint1[1], startPoint2[0], startPoint2[1], getHandleOption(activeHandlePosition === AbstractHandlePosition.start));
2461
+ const endHandle = roughSVG.line(endPoint1[0], endPoint1[1], endPoint2[0], endPoint2[1], getHandleOption(activeHandlePosition === AbstractHandlePosition.end));
2462
+ handleBoardClass(board, activeHandlePosition, isHorizontal);
2463
+ startHandle.setAttribute('stroke-linecap', 'round');
2464
+ endHandle.setAttribute('stroke-linecap', 'round');
2465
+ abstractIncludedG.append(startHandle);
2466
+ abstractIncludedG.append(endHandle);
2467
+ abstractIncludedG.append(rectangle);
2468
+ return abstractIncludedG;
2469
+ }
2470
+ function getHandleOption(isHover) {
2471
+ return isHover
2472
+ ? {
2473
+ stroke: PRIMARY_COLOR,
2474
+ strokeWidth: 4,
2475
+ fillStyle: 'solid'
2476
+ }
2477
+ : {
2478
+ stroke: ABSTRACT_HANDLE_COLOR,
2479
+ strokeWidth: 3,
2480
+ fillStyle: 'solid'
2481
+ };
2482
+ }
2483
+ function handleBoardClass(board, activeHandlePosition, isHorizontal) {
2484
+ if (activeHandlePosition) {
2485
+ if (isHorizontal) {
2486
+ PlaitBoard.getBoardContainer(board).classList.add('abstract-resizing-horizontal');
2487
+ }
2488
+ else {
2489
+ PlaitBoard.getBoardContainer(board).classList.add('abstract-resizing-vertical');
2490
+ }
2491
+ }
2492
+ else {
2493
+ PlaitBoard.getBoardContainer(board).classList.remove('abstract-resizing-horizontal');
2494
+ PlaitBoard.getBoardContainer(board).classList.remove('abstract-resizing-vertical');
2495
+ }
2496
+ }
2497
+
2498
+ class NodeActiveDrawer extends BaseDrawer {
2499
+ canDraw(element, data) {
2500
+ if (data.selected) {
2501
+ return true;
2502
+ }
2503
+ else {
2504
+ return false;
2505
+ }
2506
+ }
2507
+ baseDraw(element, data) {
2508
+ const activeG = createG();
2509
+ this.g = activeG;
2510
+ if (AbstractNode.isAbstract(element)) {
2511
+ this.abstractOutlineG = drawAbstractIncludedOutline(this.board, PlaitBoard.getRoughSVG(this.board), element);
2512
+ activeG.append(this.abstractOutlineG);
2513
+ }
2514
+ const node = MindElement.getNode(element);
2515
+ let { x, y, width, height } = getRectangleByNode(node);
2516
+ const strokeG = drawRoundRectangle(PlaitBoard.getRoughSVG(this.board), x - 2, y - 2, x + width + 2, y + height + 2, { stroke: PRIMARY_COLOR, strokeWidth: 2, fill: '' }, true);
2517
+ this.g.appendChild(strokeG);
2518
+ if (!data.isEditing) {
2519
+ 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);
2520
+ fillG.style.opacity = '0.15';
2521
+ this.g.appendChild(fillG);
2522
+ }
2523
+ return activeG;
2524
+ }
2525
+ updateAbstractOutline(element, activeHandlePosition, resizingLocation) {
2526
+ if (this.abstractOutlineG) {
2527
+ this.abstractOutlineG.remove();
2528
+ }
2529
+ this.abstractOutlineG = drawAbstractIncludedOutline(this.board, PlaitBoard.getRoughSVG(this.board), element, activeHandlePosition, resizingLocation);
2530
+ this.g.append(this.abstractOutlineG);
2531
+ }
2532
+ }
2533
+
2534
+ class CollapseDrawer extends BaseDrawer {
2535
+ canDraw(element) {
2536
+ if (element.children.length && !PlaitMind.isMind(element)) {
2537
+ return true;
2538
+ }
2539
+ return false;
2507
2540
  }
2508
- constructor(viewContainerRef, cdr, render2, ngZone) {
2541
+ baseDraw(element) {
2542
+ const collapseG = createG();
2543
+ this.g = collapseG;
2544
+ collapseG.classList.add('collapse-container');
2545
+ const node = MindElement.getNode(element);
2546
+ const stroke = getBranchColorByMindElement(this.board, element);
2547
+ const branchWidth = getBranchWidthByMindElement(this.board, element);
2548
+ const layout = MindQueries.getLayoutByElement(element);
2549
+ const isUnderlineShape = getShapeByElement(this.board, element) === MindElementShape.underline;
2550
+ const isHorizontal = isHorizontalLayout(layout);
2551
+ const nodeClient = getRectangleByNode(node);
2552
+ let linkDirection = getLayoutDirection(node, isHorizontal);
2553
+ if (isIndentedLayout(layout)) {
2554
+ linkDirection = isTopLayout(layout) ? LayoutDirection.top : LayoutDirection.bottom;
2555
+ }
2556
+ let placement = [HorizontalPlacement.right, VerticalPlacement.middle];
2557
+ transformPlacement(placement, linkDirection);
2558
+ // underline shape and horizontal
2559
+ if (isHorizontal && isUnderlineShape && !element.isRoot) {
2560
+ placement[1] = VerticalPlacement.bottom;
2561
+ }
2562
+ let startPoint = getPointByPlacement(nodeClient, placement);
2563
+ const endPoint = moveXOfPoint(startPoint, EXTEND_OFFSET, linkDirection);
2564
+ const circleCenter = moveXOfPoint(endPoint, EXTEND_DIAMETER / 2, linkDirection);
2565
+ const arrowPoints = this.getArrowPoints(circleCenter, linkDirection);
2566
+ const arrowLine = drawLinearPath(arrowPoints, {
2567
+ stroke,
2568
+ strokeWidth: 2
2569
+ });
2570
+ const extendLine = PlaitBoard.getRoughSVG(this.board).line(startPoint[0], startPoint[1], endPoint[0], endPoint[1], {
2571
+ strokeWidth: branchWidth,
2572
+ stroke
2573
+ });
2574
+ const badge = PlaitBoard.getRoughSVG(this.board).circle(circleCenter[0], circleCenter[1], EXTEND_DIAMETER, {
2575
+ fill: stroke,
2576
+ stroke,
2577
+ fillStyle: 'solid'
2578
+ });
2579
+ const hideCircleG = PlaitBoard.getRoughSVG(this.board).circle(circleCenter[0], circleCenter[1], EXTEND_DIAMETER, {
2580
+ fill: '#fff',
2581
+ stroke,
2582
+ strokeWidth: branchWidth > 3 ? 3 : branchWidth,
2583
+ fillStyle: 'solid'
2584
+ });
2585
+ if (element.isCollapsed) {
2586
+ let numberOffset = 0;
2587
+ if (getChildrenCount(element) >= 10)
2588
+ numberOffset = -2;
2589
+ if (getChildrenCount(element) === 1)
2590
+ numberOffset = 1;
2591
+ const badgeText = createText(circleCenter[0] - 4 + numberOffset, circleCenter[1] + 4, stroke, `${getChildrenCount(element)}`);
2592
+ badge.setAttribute('style', 'opacity: 0.15');
2593
+ badgeText.setAttribute('style', 'font-size: 12px');
2594
+ collapseG.appendChild(badge);
2595
+ collapseG.appendChild(badgeText);
2596
+ collapseG.appendChild(extendLine);
2597
+ }
2598
+ else {
2599
+ collapseG.appendChild(hideCircleG);
2600
+ collapseG.appendChild(arrowLine);
2601
+ }
2602
+ collapseG.appendChild(extendLine);
2603
+ return collapseG;
2604
+ }
2605
+ afterDraw(element) {
2606
+ if (!this.g) {
2607
+ throw new Error(`can not find quick insert g`);
2608
+ }
2609
+ fromEvent(this.g, 'mouseup')
2610
+ .pipe(filter(() => !PlaitBoard.isPointer(this.board, PlaitPointerType.hand) || !!PlaitBoard.isReadonly(this.board)), take(1))
2611
+ .subscribe(() => {
2612
+ const isCollapsed = !element.isCollapsed;
2613
+ const newElement = { isCollapsed };
2614
+ const path = PlaitBoard.findPath(this.board, element);
2615
+ Transforms.setNode(this.board, newElement, path);
2616
+ });
2617
+ }
2618
+ getArrowPoints(circleCenter, linkDirection) {
2619
+ let arrowTopPoint = moveXOfPoint(circleCenter, 2, linkDirection);
2620
+ arrowTopPoint = moveYOfPoint(arrowTopPoint, 4, linkDirection);
2621
+ const arrowMiddlePoint = moveXOfPoint(circleCenter, -2, linkDirection);
2622
+ let arrowBottomPoint = moveXOfPoint(circleCenter, 2, linkDirection);
2623
+ arrowBottomPoint = moveYOfPoint(arrowBottomPoint, -4, linkDirection);
2624
+ return [arrowTopPoint, arrowMiddlePoint, arrowBottomPoint];
2625
+ }
2626
+ }
2627
+
2628
+ class MindNodeComponent extends PlaitPluginElementComponent {
2629
+ constructor(viewContainerRef, cdr) {
2509
2630
  super(cdr);
2510
2631
  this.viewContainerRef = viewContainerRef;
2511
2632
  this.cdr = cdr;
2512
- this.render2 = render2;
2513
- this.ngZone = ngZone;
2514
- this.isEditable = false;
2515
- this.activeG = [];
2516
2633
  this.shapeG = null;
2517
2634
  this.destroy$ = new Subject();
2518
2635
  this.trackBy = (index, node) => {
2519
2636
  return node.origin.id;
2520
2637
  };
2521
2638
  }
2639
+ initializeDrawer() {
2640
+ this.nodeEmojisDrawer = new NodeEmojisDrawer(this.board, this.viewContainerRef);
2641
+ this.nodeInsertDrawer = new NodeInsertDrawer(this.board);
2642
+ this.activeDrawer = new NodeActiveDrawer(this.board);
2643
+ this.collapseDrawer = new CollapseDrawer(this.board);
2644
+ this.textManage = new TextManage(this.board, this.viewContainerRef, () => {
2645
+ return getTopicRectangleByNode(this.board, this.node);
2646
+ }, (point) => {
2647
+ return isHitMindElement(this.board, point, this.element);
2648
+ }, (textManageRef) => {
2649
+ const width = textManageRef.width;
2650
+ const height = textManageRef.height;
2651
+ if (textManageRef.newValue) {
2652
+ MindTransforms.setTopic(this.board, this.element, textManageRef.newValue, width, height);
2653
+ }
2654
+ else {
2655
+ MindTransforms.setTopicSize(this.board, this.element, width, height);
2656
+ }
2657
+ });
2658
+ }
2522
2659
  ngOnInit() {
2523
- this.emojisDrawer = new EmojisDrawer(this.board, this.viewContainerRef);
2524
- this.quickInsertDrawer = new QuickInsertDrawer(this.board);
2525
2660
  super.ngOnInit();
2661
+ this.initializeDrawer();
2526
2662
  this.node = MindElement.getNode(this.element);
2527
2663
  this.index = NODE_TO_INDEX.get(this.element) || 0;
2528
2664
  this.roughSVG = PlaitBoard.getRoughSVG(this.board);
2529
2665
  this.parentG = PlaitElement.getComponent(MindElement.getRoot(this.board, this.element)).rootG;
2530
2666
  this.drawShape();
2531
2667
  this.drawLink();
2532
- this.drawRichtext();
2533
- this.drawActiveG();
2534
- this.updateActiveClass();
2535
- this.drawMaskG();
2668
+ this.drawText();
2669
+ this.activeDrawer.draw(this.element, this.g, { selected: this.selected, isEditing: this.textManage.isEditing });
2536
2670
  this.drawEmojis();
2537
2671
  this.drawExtend();
2538
- this.drawQuickInsert();
2672
+ }
2673
+ editTopic() {
2674
+ this.activeDrawer.draw(this.element, this.g, { selected: this.selected, isEditing: true });
2675
+ this.textManage.edit(() => {
2676
+ this.activeDrawer.draw(this.element, this.g, { selected: this.selected, isEditing: false });
2677
+ });
2539
2678
  }
2540
2679
  onContextChanged(value, previous) {
2541
2680
  const newNode = MindElement.getNode(value.element);
2542
- // resolve move node richtext lose issue
2543
- if (this.node !== newNode) {
2544
- if (this.foreignObject && this.foreignObject.children.length <= 0) {
2545
- this.foreignObject?.appendChild(this.richtextComponentRef?.instance.editable);
2546
- }
2547
- }
2548
2681
  const isEqualNode = RectangleClient.isEqual(this.node, newNode);
2549
2682
  this.node = newNode;
2550
2683
  const isChangeTheme = this.board.operations.find(op => op.type === 'set_theme');
2551
2684
  if (!isEqualNode || value.element !== previous.element || isChangeTheme) {
2552
- this.drawActiveG();
2553
- this.updateActiveClass();
2685
+ this.activeDrawer.draw(this.element, this.g, { selected: this.selected, isEditing: this.textManage.isEditing });
2554
2686
  this.drawShape();
2555
2687
  this.drawLink();
2556
- this.updateRichtext();
2557
- this.drawMaskG();
2558
- this.drawExtend();
2559
- this.drawQuickInsert();
2560
2688
  this.drawEmojis();
2689
+ this.drawExtend();
2690
+ this.textManage.updateText(this.element.data.topic);
2691
+ this.textManage.updateRectangle();
2561
2692
  }
2562
2693
  else {
2563
2694
  const hasSameSelected = value.selected === previous.selected;
2564
2695
  const hasSameParent = value.parent === previous.parent;
2565
2696
  if (!hasSameSelected) {
2566
- this.drawActiveG();
2567
- this.updateActiveClass();
2697
+ this.activeDrawer.draw(this.element, this.g, { selected: this.selected, isEditing: this.textManage.isEditing });
2568
2698
  }
2569
2699
  if (!hasSameParent) {
2570
2700
  this.drawLink();
@@ -2572,21 +2702,11 @@ class MindNodeComponent extends PlaitPluginElementComponent {
2572
2702
  }
2573
2703
  }
2574
2704
  drawEmojis() {
2575
- const g = this.emojisDrawer.drawEmojis(this.element);
2705
+ const g = this.nodeEmojisDrawer.drawEmojis(this.element);
2576
2706
  if (g) {
2577
2707
  this.g.append(g);
2578
2708
  }
2579
2709
  }
2580
- drawQuickInsert() {
2581
- this.quickInsertDrawer.destroy();
2582
- if (this.quickInsertDrawer.canDraw(this.element)) {
2583
- const g = this.quickInsertDrawer.draw(this.element);
2584
- if (hasAfterDraw(this.quickInsertDrawer)) {
2585
- this.quickInsertDrawer.afterDraw(this.element);
2586
- }
2587
- this.extendG?.appendChild(g);
2588
- }
2589
- }
2590
2710
  drawShape() {
2591
2711
  this.destroyShape();
2592
2712
  const shape = getShapeByElement(this.board, this.node.origin);
@@ -2628,389 +2748,33 @@ class MindNodeComponent extends PlaitPluginElementComponent {
2628
2748
  this.linkG.remove();
2629
2749
  }
2630
2750
  }
2631
- drawMaskG() {
2632
- this.destroyMaskG();
2633
- const lineWidthOffset = 2;
2634
- const extendOffset = 15;
2635
- const nodeLayout = MindQueries.getLayoutByElement(this.node.origin);
2636
- const isTop = isTopLayout(nodeLayout);
2637
- const isRight = isRightLayout(nodeLayout);
2638
- const isBottom = isBottomLayout(nodeLayout);
2639
- const isLeft = isLeftLayout(nodeLayout);
2640
- const { x, y, width, height } = getRectangleByNode(this.node);
2641
- let drawX = x;
2642
- let drawY = y;
2643
- let drawWidth = x + width;
2644
- let drawHeight = y + height;
2645
- switch (true) {
2646
- case isTop:
2647
- drawX = x - lineWidthOffset;
2648
- drawY = y - extendOffset;
2649
- drawWidth = x + width + lineWidthOffset;
2650
- drawHeight = y + height + lineWidthOffset;
2651
- break;
2652
- case isBottom:
2653
- drawX = x - lineWidthOffset;
2654
- drawY = y - lineWidthOffset;
2655
- drawWidth = x + width + lineWidthOffset;
2656
- drawHeight = y + height + extendOffset;
2657
- break;
2658
- case isLeft:
2659
- drawX = x - extendOffset;
2660
- drawY = y - lineWidthOffset;
2661
- drawWidth = x + width + lineWidthOffset;
2662
- drawHeight = y + height + lineWidthOffset;
2663
- break;
2664
- case isRight:
2665
- drawX = x - lineWidthOffset;
2666
- drawY = y - lineWidthOffset;
2667
- drawWidth = x + width + extendOffset;
2668
- drawHeight = y + height + lineWidthOffset;
2669
- break;
2670
- }
2671
- this.maskG = drawRoundRectangle(this.roughSVG, drawX, drawY, drawWidth, drawHeight, { stroke: 'none', fill: 'rgba(255,255,255,0)', fillStyle: 'solid' }, true);
2672
- this.maskG.classList.add('mask');
2673
- this.maskG.setAttribute('visibility', 'visible');
2674
- this.g.append(this.maskG);
2675
- if (this.isEditable) {
2676
- this.disabledMaskG();
2677
- }
2678
- fromEvent(this.maskG, 'mouseenter')
2679
- .pipe(takeUntil(this.destroy$), filter(() => {
2680
- return PlaitBoard.isFocus(this.board) && !this.element.isCollapsed && !this.handActive;
2681
- }))
2682
- .subscribe(() => {
2683
- this.g.classList.add('hovered');
2684
- });
2685
- fromEvent(this.maskG, 'mouseleave')
2686
- .pipe(takeUntil(this.destroy$), filter(() => {
2687
- return PlaitBoard.isFocus(this.board) && !this.element.isCollapsed;
2688
- }))
2689
- .subscribe(() => {
2690
- this.g.classList.remove('hovered');
2691
- });
2692
- }
2693
- destroyMaskG() {
2694
- if (this.maskG) {
2695
- this.maskG.remove();
2696
- this.g.classList.remove('hovered');
2697
- }
2698
- }
2699
- enableMaskG() {
2700
- if (this.maskG) {
2701
- this.maskG.setAttribute('visibility', 'visible');
2702
- }
2703
- }
2704
- disabledMaskG() {
2705
- if (this.maskG) {
2706
- this.maskG.setAttribute('visibility', 'hidden');
2707
- }
2708
- }
2709
- drawActiveG() {
2710
- this.destroyActiveG();
2711
- this.abstractIncludedOutlineG?.remove();
2712
- if (this.selected) {
2713
- if (AbstractNode.isAbstract(this.element)) {
2714
- this.updateAbstractIncludedOutline();
2715
- }
2716
- let { x, y, width, height } = getRectangleByNode(this.node);
2717
- const selectedStrokeG = drawRoundRectangle(this.roughSVG, x - 2, y - 2, x + width + 2, y + height + 2, { stroke: PRIMARY_COLOR, strokeWidth: 2, fill: '' }, true);
2718
- // 影响 mask 移入移出事件
2719
- selectedStrokeG.style.pointerEvents = 'none';
2720
- this.g.appendChild(selectedStrokeG);
2721
- this.activeG.push(selectedStrokeG);
2722
- if (this.richtextComponentRef?.instance.plaitReadonly === true) {
2723
- const selectedBackgroundG = drawRoundRectangle(this.roughSVG, x - 2, y - 2, x + width + 2, y + height + 2, { stroke: PRIMARY_COLOR, fill: PRIMARY_COLOR, fillStyle: 'solid' }, true);
2724
- selectedBackgroundG.style.opacity = '0.15';
2725
- // 影响双击事件
2726
- selectedBackgroundG.style.pointerEvents = 'none';
2727
- this.g.appendChild(selectedBackgroundG);
2728
- this.activeG.push(selectedBackgroundG, selectedStrokeG);
2729
- }
2730
- }
2731
- }
2732
- destroyActiveG() {
2733
- this.activeG.forEach(g => g.remove());
2734
- this.activeG = [];
2735
- }
2736
- updateActiveClass() {
2737
- if (!this.g) {
2738
- return;
2739
- }
2740
- if (this.selected) {
2741
- this.render2.addClass(this.g, 'active');
2742
- }
2743
- else {
2744
- this.render2.removeClass(this.g, 'active');
2745
- }
2746
- }
2747
- drawRichtext() {
2748
- const { richtextG, richtextComponentRef, foreignObject } = drawTopicByNode(this.board, this.node, this.viewContainerRef);
2749
- this.richtextComponentRef = richtextComponentRef;
2750
- this.richtextG = richtextG;
2751
- this.foreignObject = foreignObject;
2752
- this.render2.addClass(richtextG, 'richtext');
2753
- this.g.append(richtextG);
2754
- }
2755
2751
  drawExtend() {
2756
2752
  this.destroyExtend();
2757
- // create extend
2758
2753
  this.extendG = createG();
2759
- const collapseG = createG();
2760
2754
  this.extendG.classList.add('extend');
2761
- collapseG.classList.add('collapse-container');
2762
2755
  this.g.append(this.extendG);
2763
- this.extendG.append(collapseG);
2764
- if (this.node.origin.isRoot) {
2765
- return;
2766
- }
2767
- // interactive
2768
- fromEvent(collapseG, 'mouseup')
2769
- .pipe(filter(() => !this.handActive || !!PlaitBoard.isReadonly(this.board)), take(1))
2770
- .subscribe(() => {
2771
- const isCollapsed = !this.node.origin.isCollapsed;
2772
- const newElement = { isCollapsed };
2773
- const path = PlaitBoard.findPath(this.board, this.element);
2774
- Transforms.setNode(this.board, newElement, path);
2775
- });
2776
- const { x, y, width, height } = getRectangleByNode(this.node);
2777
- const stroke = getBranchColorByMindElement(this.board, this.element);
2778
- const branchWidth = getBranchWidthByMindElement(this.board, this.element);
2779
- const extendY = y + height / 2;
2780
- const nodeLayout = MindQueries.getCorrectLayoutByElement(this.board, this.element);
2781
- let extendLineXY = [
2782
- [x + width, extendY],
2783
- [x + width + EXTEND_OFFSET, extendY]
2784
- ];
2785
- let arrowYOffset = [-4, 1, -0.6, 4];
2786
- let arrowXOffset = [10, 5.5, 5.5, 10];
2787
- let extendLineXOffset = [0, 0];
2788
- let extendLineYOffset = [0, 0];
2789
- let circleOffset = [EXTEND_RADIUS / 2, 0];
2790
- if (isHorizontalLayout(nodeLayout) && !isIndentedLayout(nodeLayout)) {
2791
- extendLineYOffset =
2792
- getShapeByElement(this.board, this.node.origin) === MindElementShape.roundRectangle
2793
- ? [0, 0]
2794
- : [height / 2, height / 2];
2795
- if (isLeftLayout(nodeLayout)) {
2796
- //左
2797
- extendLineXOffset = [-width, -width - EXTEND_OFFSET * 2];
2798
- circleOffset = [-EXTEND_RADIUS / 2, 0];
2799
- arrowXOffset = [-10, -5.5, -5.5, -10];
2800
- }
2801
- }
2802
- else {
2803
- arrowXOffset = [-4, 0.6, -1, 4];
2804
- if (isTopLayout(nodeLayout)) {
2805
- //上
2806
- extendLineXOffset = [-width / 2, -width / 2 - EXTEND_OFFSET];
2807
- extendLineYOffset = [-height / 2, -height / 2 - EXTEND_OFFSET];
2808
- arrowYOffset = [-10, -5.5, -5.5, -10];
2809
- circleOffset = [0, -EXTEND_RADIUS / 2];
2810
- }
2811
- else {
2812
- //下
2813
- extendLineXOffset = [-width / 2, -width / 2 - EXTEND_OFFSET];
2814
- extendLineYOffset = [height / 2, height / 2 + EXTEND_OFFSET];
2815
- arrowYOffset = [10, 5.5, 5.5, 10];
2816
- circleOffset = [0, EXTEND_RADIUS / 2];
2817
- }
2818
- }
2819
- extendLineXY = [
2820
- [extendLineXY[0][0] + extendLineXOffset[0], extendLineXY[0][1] + extendLineYOffset[0]],
2821
- [extendLineXY[1][0] + extendLineXOffset[1], extendLineXY[1][1] + extendLineYOffset[1]]
2822
- ];
2823
- const extendLine = this.roughSVG.line(extendLineXY[0][0], extendLineXY[0][1], extendLineXY[1][0], extendLineXY[1][1], {
2824
- strokeWidth: branchWidth,
2825
- stroke
2826
- });
2827
- //绘制箭头
2828
- 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], {
2829
- stroke,
2830
- strokeWidth: 2
2831
- });
2832
- 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], {
2833
- stroke,
2834
- strokeWidth: 2
2835
- });
2836
- if (this.node.origin.isCollapsed) {
2837
- const badge = this.roughSVG.circle(extendLineXY[1][0] + circleOffset[0], extendLineXY[1][1] + circleOffset[1], EXTEND_RADIUS, {
2838
- fill: stroke,
2839
- stroke,
2840
- fillStyle: 'solid'
2841
- });
2842
- let numberOffset = 0;
2843
- if (getChildrenCount(this.node.origin) >= 10)
2844
- numberOffset = -2;
2845
- if (getChildrenCount(this.node.origin) === 1)
2846
- numberOffset = 1;
2847
- const badgeText = createText(extendLineXY[1][0] + circleOffset[0] - 4 + numberOffset, extendLineXY[1][1] + circleOffset[1] + 4, stroke, `${getChildrenCount(this.node.origin)}`);
2756
+ if (this.element.isCollapsed) {
2848
2757
  this.g.classList.add('collapsed');
2849
- badge.setAttribute('style', 'opacity: 0.15');
2850
- badgeText.setAttribute('style', 'font-size: 12px');
2851
- collapseG.appendChild(badge);
2852
- collapseG.appendChild(badgeText);
2853
- collapseG.appendChild(extendLine);
2854
2758
  }
2855
2759
  else {
2856
2760
  this.g.classList.remove('collapsed');
2857
- if (this.node.origin.children.length > 0) {
2858
- const hideCircleG = this.roughSVG.circle(extendLineXY[1][0] + circleOffset[0], extendLineXY[1][1] + circleOffset[1], EXTEND_RADIUS - 1, {
2859
- fill: '#fff',
2860
- stroke,
2861
- strokeWidth: branchWidth > 3 ? 3 : branchWidth,
2862
- fillStyle: 'solid'
2863
- });
2864
- collapseG.appendChild(hideCircleG);
2865
- collapseG.appendChild(hideArrowTopLine);
2866
- collapseG.appendChild(hideArrowBottomLine);
2867
- }
2868
2761
  }
2762
+ this.nodeInsertDrawer.draw(this.element, this.extendG);
2763
+ this.collapseDrawer.draw(this.element, this.extendG);
2869
2764
  }
2870
2765
  destroyExtend() {
2871
2766
  if (this.extendG) {
2872
2767
  this.extendG.remove();
2873
2768
  }
2874
2769
  }
2875
- destroyRichtext() {
2876
- if (this.richtextG) {
2877
- this.richtextG.remove();
2878
- }
2879
- if (this.richtextComponentRef) {
2880
- this.richtextComponentRef.destroy();
2881
- }
2882
- }
2883
- updateAbstractIncludedOutline(activeHandlePosition, resizingLocation) {
2884
- this.abstractIncludedOutlineG?.remove();
2885
- this.abstractIncludedOutlineG = drawAbstractIncludedOutline(this.board, this.roughSVG, this.element, activeHandlePosition, resizingLocation);
2886
- PlaitBoard.getHost(this.board).append(this.abstractIncludedOutlineG);
2887
- }
2888
- updateRichtext() {
2889
- updateRichText(this.node.origin.data.topic, this.richtextComponentRef);
2890
- updateMindNodeTopicSize(this.board, this.node, this.richtextG, this.isEditable);
2891
- }
2892
- startEditText(isEnd, isClear) {
2893
- if (!this.richtextComponentRef) {
2894
- throw new Error('undefined richtextComponentRef');
2895
- }
2896
- const richtextInstance = this.richtextComponentRef.instance;
2897
- this.isEditable = true;
2898
- IS_TEXT_EDITABLE.set(this.board, true);
2899
- this.disabledMaskG();
2900
- updateMindNodeTopicSize(this.board, this.node, this.richtextG, this.isEditable);
2901
- if (richtextInstance.plaitReadonly) {
2902
- richtextInstance.plaitReadonly = false;
2903
- this.richtextComponentRef.changeDetectorRef.detectChanges();
2904
- this.drawActiveG();
2905
- const location = isEnd ? Editor.end(richtextInstance.editor, [0]) : [0];
2906
- setFullSelectionAndFocus(richtextInstance.editor, location);
2907
- if (isClear) {
2908
- Editor.deleteBackward(richtextInstance.editor);
2909
- }
2910
- // handle invalid width and height (old data)
2911
- let { width, height } = getRichtextContentSize(richtextInstance.editable);
2912
- if (width !== this.element.width || height !== this.element.height) {
2913
- MindTransforms.setTopicSize(this.board, this.element, width, height);
2914
- }
2915
- }
2916
- let richtext = richtextInstance.plaitValue;
2917
- // use debounceTime to wait DOM render complete
2918
- const valueChange$ = richtextInstance.plaitChange
2919
- .pipe(debounceTime(0), filter(event => {
2920
- // 过滤掉 operations 中全是 set_selection 的操作
2921
- return !event.operations.every(op => Operation.isSelectionOperation(op));
2922
- }))
2923
- .subscribe(event => {
2924
- if (richtext === event.value) {
2925
- return;
2926
- }
2927
- this.updateRichtext();
2928
- // 更新富文本、更新宽高
2929
- let { width, height } = getRichtextContentSize(richtextInstance.editable);
2930
- MindTransforms.setTopic(this.board, this.element, event.value, width, height);
2931
- MERGING.set(this.board, true);
2932
- });
2933
- const composition$ = richtextInstance.plaitComposition.pipe(debounceTime(0)).subscribe(event => {
2934
- let { width, height } = getRichtextContentSize(richtextInstance.editable);
2935
- if (width < NODE_MIN_WIDTH) {
2936
- width = NODE_MIN_WIDTH;
2937
- }
2938
- if (event.isComposing && (width !== this.node.origin.width || height !== this.node.origin.height)) {
2939
- const newElement = {
2940
- width: width / this.board.viewport.zoom,
2941
- height: height / this.board.viewport.zoom
2942
- };
2943
- const path = PlaitBoard.findPath(this.board, this.element);
2944
- Transforms.setNode(this.board, newElement, path);
2945
- MERGING.set(this.board, true);
2946
- }
2947
- });
2948
- const mousedown$ = fromEvent(document, 'mousedown').subscribe((event) => {
2949
- const point = transformPoint(this.board, toPoint(event.x, event.y, PlaitBoard.getHost(this.board)));
2950
- const clickInNode = isHitMindElement(this.board, point, this.element);
2951
- if (clickInNode && !hasEditableTarget(richtextInstance.editor, event.target)) {
2952
- event.preventDefault();
2953
- }
2954
- else if (!clickInNode) {
2955
- // handle composition input state, like: Chinese IME Composition Input
2956
- timer(0).subscribe(() => {
2957
- exitHandle();
2958
- this.enableMaskG();
2959
- });
2960
- }
2961
- });
2962
- const editor = richtextInstance.editor;
2963
- const { keydown } = editor;
2964
- editor.keydown = (event) => {
2965
- if (event.isComposing) {
2966
- return;
2967
- }
2968
- if (event.key === 'Escape') {
2969
- event.preventDefault();
2970
- event.stopPropagation();
2971
- exitHandle();
2972
- this.drawActiveG();
2973
- this.enableMaskG();
2974
- return;
2975
- }
2976
- if (event.key === 'Enter' && !event.shiftKey) {
2977
- event.preventDefault();
2978
- event.stopPropagation();
2979
- exitHandle();
2980
- this.drawActiveG();
2981
- this.enableMaskG();
2982
- return;
2983
- }
2984
- if (event.key === 'Tab') {
2985
- event.preventDefault();
2986
- event.stopPropagation();
2987
- exitHandle();
2988
- this.drawActiveG();
2989
- this.drawMaskG();
2990
- }
2991
- };
2992
- const exitHandle = () => {
2993
- this.ngZone.run(() => {
2994
- // unsubscribe
2995
- valueChange$.unsubscribe();
2996
- composition$.unsubscribe();
2997
- mousedown$.unsubscribe();
2998
- editor.keydown = keydown; // reset keydown
2999
- // editable status
3000
- MERGING.set(this.board, false);
3001
- richtextInstance.plaitReadonly = true;
3002
- this.richtextComponentRef?.changeDetectorRef.markForCheck();
3003
- this.isEditable = false;
3004
- updateMindNodeTopicSize(this.board, this.node, this.richtextG, this.isEditable);
3005
- IS_TEXT_EDITABLE.set(this.board, false);
3006
- });
3007
- };
2770
+ drawText() {
2771
+ this.textManage.draw(this.element.data.topic);
2772
+ this.g.append(this.textManage.g);
3008
2773
  }
3009
2774
  ngOnDestroy() {
3010
2775
  super.ngOnDestroy();
3011
- this.abstractIncludedOutlineG?.remove();
3012
- this.destroyRichtext();
3013
- this.emojisDrawer.destroy();
2776
+ this.textManage.destroy();
2777
+ this.nodeEmojisDrawer.destroy();
3014
2778
  this.destroy$.next();
3015
2779
  this.destroy$.complete();
3016
2780
  if (ELEMENT_TO_NODE.get(this.element) === this.node) {
@@ -3018,7 +2782,7 @@ class MindNodeComponent extends PlaitPluginElementComponent {
3018
2782
  }
3019
2783
  }
3020
2784
  }
3021
- 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 });
2785
+ 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 });
3022
2786
  MindNodeComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.5", type: MindNodeComponent, selector: "plait-mind-node", usesInheritance: true, ngImport: i0, template: `
3023
2787
  <plait-children
3024
2788
  *ngIf="!element.isCollapsed"
@@ -3043,7 +2807,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImpor
3043
2807
  `,
3044
2808
  changeDetection: ChangeDetectionStrategy.OnPush
3045
2809
  }]
3046
- }], ctorParameters: function () { return [{ type: i0.ViewContainerRef }, { type: i0.ChangeDetectorRef }, { type: i0.Renderer2 }, { type: i0.NgZone }]; } });
2810
+ }], ctorParameters: function () { return [{ type: i0.ViewContainerRef }, { type: i0.ChangeDetectorRef }]; } });
3047
2811
 
3048
2812
  const getLayoutOptions = (board) => {
3049
2813
  function getMainAxle(element, parent) {
@@ -3116,6 +2880,7 @@ class PlaitMindComponent extends MindNodeComponent {
3116
2880
  ngOnInit() {
3117
2881
  this.updateMindLayout();
3118
2882
  super.ngOnInit();
2883
+ this.g.classList.add('root');
3119
2884
  }
3120
2885
  beforeContextChange(value) {
3121
2886
  if (value.element !== this.element && this.initialized) {
@@ -3156,19 +2921,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImpor
3156
2921
  class MindModule {
3157
2922
  }
3158
2923
  MindModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: MindModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
3159
- 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] });
3160
- MindModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: MindModule, imports: [CommonModule, RichtextModule, PlaitModule] });
2924
+ 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] });
2925
+ MindModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: MindModule, imports: [CommonModule, TextModule, PlaitModule] });
3161
2926
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: MindModule, decorators: [{
3162
2927
  type: NgModule,
3163
2928
  args: [{
3164
2929
  declarations: [PlaitMindComponent, MindNodeComponent],
3165
- imports: [CommonModule, RichtextModule, PlaitModule],
2930
+ imports: [CommonModule, TextModule, PlaitModule],
3166
2931
  exports: [PlaitMindComponent, MindNodeComponent]
3167
2932
  }]
3168
2933
  }] });
3169
2934
 
3170
2935
  const DRAG_MOVE_BUFFER = 5;
3171
- const withDnd = (board) => {
2936
+ const withNodeDnd = (board) => {
3172
2937
  const { mousedown, mousemove, globalMouseup } = board;
3173
2938
  let activeElements = [];
3174
2939
  let correspondingElements = [];
@@ -3522,7 +3287,7 @@ const withAbstract = (board) => {
3522
3287
  newProperty =
3523
3288
  abstractHandlePosition === AbstractHandlePosition.start ? { start: locationIndex + 1 } : { end: locationIndex };
3524
3289
  }
3525
- abstractComponent.updateAbstractIncludedOutline(abstractHandlePosition, location);
3290
+ abstractComponent.activeDrawer.updateAbstractOutline(activeAbstractElement, abstractHandlePosition, location);
3526
3291
  }
3527
3292
  mousemove(event);
3528
3293
  };
@@ -3539,7 +3304,7 @@ const withAbstract = (board) => {
3539
3304
  }
3540
3305
  else {
3541
3306
  const abstractComponent = PlaitElement.getComponent(activeAbstractElement);
3542
- abstractComponent.updateAbstractIncludedOutline();
3307
+ abstractComponent.activeDrawer.updateAbstractOutline(activeAbstractElement);
3543
3308
  }
3544
3309
  activeAbstractElement = undefined;
3545
3310
  }
@@ -3591,22 +3356,29 @@ const withCreateMind = (board) => {
3591
3356
  const nodeG = drawRoundRectangleByElement(board, nodeRectangle, emptyMind);
3592
3357
  const topicRectangle = getTopicRectangleByElement(newBoard, nodeRectangle, emptyMind);
3593
3358
  if (!fakeCreateNodeRef) {
3594
- const { richtextComponentRef, richtextG, foreignObject } = drawTopicByElement(newBoard, topicRectangle, emptyMind);
3359
+ const textManage = new TextManage(board, PlaitBoard.getComponent(board).viewContainerRef, () => {
3360
+ return topicRectangle;
3361
+ });
3362
+ PlaitBoard.getComponent(board)
3363
+ .viewContainerRef.injector.get(NgZone)
3364
+ .run(() => {
3365
+ textManage.draw(emptyMind.data.topic);
3366
+ });
3595
3367
  fakeCreateNodeRef = {
3596
- instanceRef: richtextComponentRef,
3368
+ g: createG(),
3597
3369
  nodeG,
3598
- foreignObject,
3599
- topicG: richtextG
3370
+ textManage
3600
3371
  };
3601
- richtextComponentRef.changeDetectorRef.detectChanges();
3602
- PlaitBoard.getHost(board).append(...[fakeCreateNodeRef.nodeG, fakeCreateNodeRef.topicG]);
3372
+ fakeCreateNodeRef.g.classList.add('root');
3373
+ PlaitBoard.getHost(board).append(fakeCreateNodeRef.g);
3374
+ fakeCreateNodeRef.g.append(...[fakeCreateNodeRef.nodeG, textManage.g]);
3603
3375
  }
3604
3376
  else {
3377
+ fakeCreateNodeRef.textManage.updateRectangle(topicRectangle);
3605
3378
  fakeCreateNodeRef.nodeG.remove();
3606
3379
  fakeCreateNodeRef.nodeG = nodeG;
3607
- PlaitBoard.getHost(board).append(nodeG);
3608
- PlaitBoard.getHost(board).append(fakeCreateNodeRef.topicG);
3609
- updateForeignObject(fakeCreateNodeRef.topicG, topicRectangle.width, topicRectangle.height, topicRectangle.x, topicRectangle.y);
3380
+ fakeCreateNodeRef.g.append(nodeG);
3381
+ fakeCreateNodeRef.g.append(fakeCreateNodeRef.textManage.g);
3610
3382
  }
3611
3383
  }
3612
3384
  });
@@ -3643,9 +3415,8 @@ const withCreateMind = (board) => {
3643
3415
  };
3644
3416
  function destroy() {
3645
3417
  if (fakeCreateNodeRef) {
3646
- fakeCreateNodeRef.instanceRef.destroy();
3647
- fakeCreateNodeRef.nodeG.remove();
3648
- fakeCreateNodeRef.topicG.remove();
3418
+ fakeCreateNodeRef.textManage.destroy();
3419
+ fakeCreateNodeRef.g.remove();
3649
3420
  fakeCreateNodeRef = null;
3650
3421
  }
3651
3422
  }
@@ -3677,6 +3448,68 @@ const isExpandHotkey = (keyboardEvent) => {
3677
3448
  return isKeyHotkey('mod+/', keyboardEvent);
3678
3449
  };
3679
3450
 
3451
+ const withNodeHover = (board) => {
3452
+ const { mousemove, mouseleave } = board;
3453
+ let hoveredMindElement = null;
3454
+ board.mousemove = (event) => {
3455
+ throttleRAF(() => {
3456
+ let target = null;
3457
+ const point = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
3458
+ depthFirstRecursion(board, element => {
3459
+ if (target) {
3460
+ return;
3461
+ }
3462
+ if (!MindElement.isMindElement(board, element)) {
3463
+ return;
3464
+ }
3465
+ const isHitElement = isHitMindElement(board, point, element);
3466
+ if (isHitElement) {
3467
+ target = element;
3468
+ }
3469
+ }, node => {
3470
+ if (PlaitBoard.isBoard(node) || board.isRecursion(node)) {
3471
+ return true;
3472
+ }
3473
+ else {
3474
+ return false;
3475
+ }
3476
+ }, true);
3477
+ if (hoveredMindElement && target && hoveredMindElement === target) {
3478
+ return;
3479
+ }
3480
+ if (hoveredMindElement) {
3481
+ removeHovered(hoveredMindElement);
3482
+ }
3483
+ if (target) {
3484
+ addHovered(target);
3485
+ hoveredMindElement = target;
3486
+ }
3487
+ else {
3488
+ hoveredMindElement = null;
3489
+ }
3490
+ });
3491
+ mousemove(event);
3492
+ };
3493
+ board.mouseleave = (event) => {
3494
+ if (hoveredMindElement) {
3495
+ removeHovered(hoveredMindElement);
3496
+ hoveredMindElement = null;
3497
+ }
3498
+ mouseleave(event);
3499
+ };
3500
+ return board;
3501
+ };
3502
+ const addHovered = (element) => {
3503
+ const component = PlaitElement.getComponent(element);
3504
+ component.g.classList.add('hovered');
3505
+ };
3506
+ const removeHovered = (element) => {
3507
+ const component = PlaitElement.getComponent(element);
3508
+ if (component && component.g) {
3509
+ component.g.classList.remove('hovered');
3510
+ }
3511
+ };
3512
+
3680
3513
  const withMind = (board) => {
3681
3514
  const { drawElement, dblclick, keydown, insertFragment, setFragment, deleteFragment, isHitSelection, getRectangle, isMovable, isRecursion } = board;
3682
3515
  board.drawElement = (context) => {
@@ -3803,7 +3636,7 @@ const withMind = (board) => {
3803
3636
  if (!isVirtualKey(event)) {
3804
3637
  event.preventDefault();
3805
3638
  const selectedElement = selectedElements[0];
3806
- enterNodeEditing(selectedElement);
3639
+ editTopic(selectedElement);
3807
3640
  return;
3808
3641
  }
3809
3642
  }
@@ -3825,7 +3658,7 @@ const withMind = (board) => {
3825
3658
  .forEach(mindMap => {
3826
3659
  depthFirstRecursion(mindMap, node => {
3827
3660
  if (!PlaitBoard.hasBeenTextEditing(board) && isHitMindElement(board, point, node)) {
3828
- enterNodeEditing(node);
3661
+ editTopic(node);
3829
3662
  }
3830
3663
  }, node => {
3831
3664
  if (PlaitBoard.isBoard(node) || board.isRecursion(node)) {
@@ -3861,7 +3694,7 @@ const withMind = (board) => {
3861
3694
  }
3862
3695
  else {
3863
3696
  const text = data?.getData(`text/plain`);
3864
- const { width, height } = getSizeByText(text, PlaitBoard.getHost(board).parentElement, TOPIC_DEFAULT_MAX_WORD_COUNT);
3697
+ const { width, height } = getTextSize(board, text, TOPIC_DEFAULT_MAX_WORD_COUNT);
3865
3698
  const selectedElements = getSelectedElements(board);
3866
3699
  if (text && selectedElements.length === 1) {
3867
3700
  insertClipboardText(board, selectedElements[0], text, width, height);
@@ -3879,7 +3712,7 @@ const withMind = (board) => {
3879
3712
  MindTransforms.removeElements(board, selectedElements);
3880
3713
  deleteFragment(data);
3881
3714
  };
3882
- return withMindHotkey(withMindExtend(withCreateMind(withAbstract(withDnd(board)))));
3715
+ return withNodeHover(withMindHotkey(withMindExtend(withCreateMind(withAbstract(withNodeDnd(board))))));
3883
3716
  };
3884
3717
 
3885
3718
  class MindEmojiBaseComponent {
@@ -3933,5 +3766,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImpor
3933
3766
  * Generated bundle index. Do not edit.
3934
3767
  */
3935
3768
 
3936
- 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 };
3769
+ 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 };
3937
3770
  //# sourceMappingURL=plait-mind.mjs.map