@plait/mind 0.14.0 → 0.16.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 (33) hide show
  1. package/constants/default.d.ts +1 -0
  2. package/constants/node-topic-style.d.ts +2 -0
  3. package/esm2020/constants/default.mjs +2 -1
  4. package/esm2020/constants/node-topic-style.mjs +3 -1
  5. package/esm2020/interfaces/options.mjs +1 -1
  6. package/esm2020/node.component.mjs +8 -5
  7. package/esm2020/plugins/with-abstract-resize.board.mjs +1 -1
  8. package/esm2020/plugins/with-mind-create.mjs +3 -3
  9. package/esm2020/plugins/with-mind-extend.mjs +3 -4
  10. package/esm2020/plugins/with-mind-hotkey.mjs +42 -32
  11. package/esm2020/plugins/with-mind.board.mjs +1 -1
  12. package/esm2020/plugins/with-mind.mjs +7 -9
  13. package/esm2020/plugins/with-node-dnd.mjs +13 -6
  14. package/esm2020/transforms/abstract-node.mjs +1 -3
  15. package/esm2020/utils/abstract/common.mjs +5 -1
  16. package/esm2020/utils/clipboard.mjs +14 -5
  17. package/esm2020/utils/draw/node-link/indented-link.mjs +4 -15
  18. package/esm2020/utils/node/adjust-node.mjs +3 -7
  19. package/esm2020/utils/node-style/branch.mjs +6 -1
  20. package/esm2020/utils/node-style/shape.mjs +8 -1
  21. package/esm2020/utils/space/emoji.mjs +3 -2
  22. package/esm2020/utils/space/node-space.mjs +3 -2
  23. package/fesm2015/plait-mind.mjs +259 -239
  24. package/fesm2015/plait-mind.mjs.map +1 -1
  25. package/fesm2020/plait-mind.mjs +259 -239
  26. package/fesm2020/plait-mind.mjs.map +1 -1
  27. package/interfaces/options.d.ts +2 -1
  28. package/package.json +1 -1
  29. package/plugins/with-abstract-resize.board.d.ts +2 -2
  30. package/plugins/with-mind-hotkey.d.ts +2 -0
  31. package/plugins/with-mind.board.d.ts +0 -2
  32. package/utils/abstract/common.d.ts +1 -0
  33. package/utils/clipboard.d.ts +1 -1
@@ -1,9 +1,9 @@
1
1
  import * as i0 from '@angular/core';
2
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, 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, getHitElements, distanceBetweenPointAndPoint, CLIP_BOARD_FORMAT_KEY, isMainPointer, BOARD_TO_HOST, PlaitPluginKey, throttleRAF, BoardTransforms, removeSelectedElement, PlaitHistoryBoard, hotkeys } from '@plait/core';
5
- import { MindLayoutType, isIndentedLayout, getNonAbstractChildren, isStandardLayout, AbstractNode, isLeftLayout, isRightLayout, isVerticalLogicLayout, isHorizontalLogicLayout, isTopLayout, isBottomLayout, isHorizontalLayout, getCorrectStartEnd, getAbstractLayout, ConnectingPosition, GlobalLayout } from '@plait/layouts';
6
- import { TEXT_DEFAULT_HEIGHT, buildText, getTextSize, TextManage, TextModule, getTextFromClipboard } from '@plait/text';
4
+ import { DefaultThemeColor, ColorfulThemeColor, SoftThemeColor, RetroThemeColor, DarkThemeColor, StarryThemeColor, RectangleClient, PlaitElement, idCreator, isNullOrUndefined, Transforms, clearSelectedElement, addSelectedElement, PlaitNode, Path, PlaitBoard, depthFirstRecursion, drawLinearPath, drawBezierPath, createG, updateForeignObject, drawRoundRectangle, getRectangleByElements, getSelectedElements, NODE_TO_PARENT, distanceBetweenPointAndRectangle, createForeignObject, drawAbstractRoundRectangle, createText, PlaitPointerType, PlaitPluginElementComponent, NODE_TO_INDEX, PlaitModule, transformPoint, toPoint, getHitElements, distanceBetweenPointAndPoint, CLIP_BOARD_FORMAT_KEY, isMainPointer, BOARD_TO_HOST, PlaitPluginKey, throttleRAF, BoardTransforms, removeSelectedElement, PlaitHistoryBoard, hotkeys } from '@plait/core';
5
+ import { MindLayoutType, isIndentedLayout, AbstractNode, getNonAbstractChildren, isStandardLayout, isLeftLayout, isRightLayout, isVerticalLogicLayout, isHorizontalLogicLayout, isTopLayout, isBottomLayout, isHorizontalLayout, getCorrectStartEnd, getAbstractLayout, ConnectingPosition, GlobalLayout } from '@plait/layouts';
6
+ import { TEXT_DEFAULT_HEIGHT, buildText, getTextSize, TextManage, ExitOrigin, TextModule, getTextFromClipboard } from '@plait/text';
7
7
  import { fromEvent, Subject } from 'rxjs';
8
8
  import { Node, Path as Path$1 } from 'slate';
9
9
  import { isKeyHotkey } from 'is-hotkey';
@@ -179,6 +179,7 @@ const MindThemeColor = {
179
179
  }
180
180
  };
181
181
 
182
+ const WithMindPluginKey = 'plait-mind-plugin-key';
182
183
  const BASE = 4;
183
184
  const PRIMARY_COLOR = '#6698FF';
184
185
  const TRANSPARENT = 'transparent';
@@ -192,7 +193,7 @@ const QUICK_INSERT_CIRCLE_COLOR = '#6698FF';
192
193
  const QUICK_INSERT_INNER_CROSS_COLOR = 'white';
193
194
 
194
195
  function getEmojisWidthHeight(board, element) {
195
- const options = board.getMindOptions();
196
+ const options = board.getPluginOptions(WithMindPluginKey);
196
197
  const count = element.data.emojis.length;
197
198
  const fontSize = getEmojiFontSize(element);
198
199
  return {
@@ -272,7 +273,7 @@ const NodeSpace = {
272
273
  return nodeAndText;
273
274
  },
274
275
  getEmojiLeftSpace(board, element) {
275
- const options = board.getMindOptions();
276
+ const options = board.getPluginOptions(WithMindPluginKey);
276
277
  const nodeAndText = getHorizontalSpaceBetweenNodeAndText(board, element);
277
278
  return nodeAndText - options.emojiPadding;
278
279
  },
@@ -335,6 +336,8 @@ const TOPIC_FONT_SIZE = 14;
335
336
  const ROOT_TOPIC_FONT_SIZE = 18;
336
337
  const ROOT_TOPIC_HEIGHT = 25;
337
338
  const TOPIC_DEFAULT_MAX_WORD_COUNT = 34;
339
+ const DEFAULT_FONT_FAMILY = 'PingFangSC-Regular, "PingFang SC"';
340
+ const BRANCH_FONT_FAMILY = 'PingFangSC-Medium, "PingFang SC"';
338
341
 
339
342
  const createEmptyMind = (point) => {
340
343
  const element = createMindElement('思维导图', 72, ROOT_TOPIC_HEIGHT, { layout: MindLayoutType.right });
@@ -585,10 +588,6 @@ const adjustRootToNode = (board, node) => {
585
588
  delete newNode.isRoot;
586
589
  delete newNode.rightNodeCount;
587
590
  delete newNode.type;
588
- const text = Node.string(node.data.topic.children[0]) || ' ';
589
- const { width, height } = getTextSize(board, text, TOPIC_DEFAULT_MAX_WORD_COUNT);
590
- newNode.width = Math.max(width, NODE_MIN_WIDTH);
591
- newNode.height = height;
592
591
  if (newNode.layout === MindLayoutType.standard) {
593
592
  delete newNode.layout;
594
593
  }
@@ -612,7 +611,7 @@ const adjustNodeToRoot = (board, node) => {
612
611
  delete newElement?.isCollapsed;
613
612
  const { width, height } = getTextSize(board, newElement.data.topic, TOPIC_DEFAULT_MAX_WORD_COUNT, {
614
613
  fontSize: ROOT_TOPIC_FONT_SIZE,
615
- fontFamily: 'PingFangSC-Medium, "PingFang SC"'
614
+ fontFamily: BRANCH_FONT_FAMILY
616
615
  });
617
616
  newElement.width = Math.max(width, NODE_MIN_WIDTH);
618
617
  newElement.height = height;
@@ -640,10 +639,180 @@ const getAvailableProperty = (board, element, propertyKey) => {
640
639
  return element[propertyKey];
641
640
  };
642
641
 
642
+ const separateChildren = (parentElement) => {
643
+ const rightNodeCount = parentElement.rightNodeCount;
644
+ const children = parentElement.children;
645
+ let rightChildren = [], leftChildren = [];
646
+ for (let i = 0; i < children.length; i++) {
647
+ const child = children[i];
648
+ if (AbstractNode.isAbstract(child) && child.end < rightNodeCount) {
649
+ rightChildren.push(child);
650
+ continue;
651
+ }
652
+ if (AbstractNode.isAbstract(child) && child.start >= rightNodeCount) {
653
+ leftChildren.push(child);
654
+ continue;
655
+ }
656
+ if (i < rightNodeCount) {
657
+ rightChildren.push(child);
658
+ }
659
+ else {
660
+ leftChildren.push(child);
661
+ }
662
+ }
663
+ return { leftChildren, rightChildren };
664
+ };
665
+ const isSetAbstract = (element) => {
666
+ return !!getCorrespondingAbstract(element);
667
+ };
668
+ const canSetAbstract = (element) => {
669
+ return !PlaitElement.isRootElement(element) && !AbstractNode.isAbstract(element) && !isSetAbstract(element);
670
+ };
671
+ const getCorrespondingAbstract = (element) => {
672
+ const parent = MindElement.findParent(element);
673
+ if (!parent)
674
+ return undefined;
675
+ const elementIndex = parent.children.indexOf(element);
676
+ return parent.children.find(child => {
677
+ return AbstractNode.isAbstract(child) && elementIndex >= child.start && elementIndex <= child.end;
678
+ });
679
+ };
680
+ const getBehindAbstracts = (element) => {
681
+ const parent = MindElement.findParent(element);
682
+ if (!parent)
683
+ return [];
684
+ const index = parent.children.indexOf(element);
685
+ return parent.children.filter(child => AbstractNode.isAbstract(child) && child.start > index);
686
+ };
687
+ /**
688
+ * return corresponding abstract that is not child of elements
689
+ */
690
+ const getOverallAbstracts = (board, elements) => {
691
+ const overallAbstracts = [];
692
+ elements
693
+ .filter(value => !AbstractNode.isAbstract(value) && !PlaitMind.isMind(value))
694
+ .forEach(value => {
695
+ const abstract = getCorrespondingAbstract(value);
696
+ if (abstract && elements.indexOf(abstract) === -1 && overallAbstracts.indexOf(abstract) === -1) {
697
+ const { start, end } = abstract;
698
+ const parent = MindElement.getParent(value);
699
+ const isOverall = parent.children.slice(start, end + 1).every(includedElement => elements.indexOf(includedElement) > -1);
700
+ if (isOverall) {
701
+ overallAbstracts.push(abstract);
702
+ }
703
+ }
704
+ });
705
+ return overallAbstracts;
706
+ };
707
+ /**
708
+ * abstract node is valid when elements contains at least one element it is referenced with
709
+ */
710
+ const getValidAbstractRefs = (board, elements) => {
711
+ const validAbstractRefs = [];
712
+ elements
713
+ .filter(value => !AbstractNode.isAbstract(value) && !PlaitMind.isMind(value))
714
+ .forEach(value => {
715
+ const abstract = getCorrespondingAbstract(value);
716
+ if (abstract && elements.indexOf(abstract) > 0) {
717
+ const index = validAbstractRefs.findIndex(value => value.abstract === abstract);
718
+ if (index === -1) {
719
+ validAbstractRefs.push({
720
+ abstract: abstract,
721
+ references: [value]
722
+ });
723
+ }
724
+ else {
725
+ validAbstractRefs[index].references.push(value);
726
+ }
727
+ }
728
+ });
729
+ return validAbstractRefs;
730
+ };
731
+ function getRelativeStartEndByAbstractRef(abstractRef, elements) {
732
+ const start = elements.indexOf(abstractRef.references[0]);
733
+ const end = elements.indexOf(abstractRef.references[abstractRef.references.length - 1]);
734
+ return { start, end };
735
+ }
736
+ const insertElementHandleAbstract = (board, path, step = 1,
737
+ //由此区分拖拽和新增到概要概括最后一个节点
738
+ isExtendPreviousNode = true, effectedAbstracts = new Map()) => {
739
+ const parent = PlaitNode.parent(board, path);
740
+ const hasPreviousNode = path[path.length - 1] !== 0;
741
+ let behindAbstracts;
742
+ if (!hasPreviousNode) {
743
+ behindAbstracts = parent.children.filter(child => AbstractNode.isAbstract(child));
744
+ }
745
+ else {
746
+ const selectedElement = PlaitNode.get(board, Path.previous(path));
747
+ behindAbstracts = getBehindAbstracts(selectedElement);
748
+ }
749
+ if (behindAbstracts.length) {
750
+ behindAbstracts.forEach(abstract => {
751
+ let newProperties = effectedAbstracts.get(abstract);
752
+ if (!newProperties) {
753
+ newProperties = { start: 0, end: 0 };
754
+ effectedAbstracts.set(abstract, newProperties);
755
+ }
756
+ newProperties.start = newProperties.start + step;
757
+ newProperties.end = newProperties.end + step;
758
+ });
759
+ }
760
+ if (!hasPreviousNode) {
761
+ return effectedAbstracts;
762
+ }
763
+ const selectedElement = PlaitNode.get(board, Path.previous(path));
764
+ const correspondingAbstract = getCorrespondingAbstract(selectedElement);
765
+ const isDragToLast = !isExtendPreviousNode && correspondingAbstract && correspondingAbstract.end === path[path.length - 1] - 1;
766
+ if (correspondingAbstract && !isDragToLast) {
767
+ let newProperties = effectedAbstracts.get(correspondingAbstract);
768
+ if (!newProperties) {
769
+ newProperties = { start: 0, end: 0 };
770
+ effectedAbstracts.set(correspondingAbstract, newProperties);
771
+ }
772
+ newProperties.end = newProperties.end + step;
773
+ }
774
+ return effectedAbstracts;
775
+ };
776
+ const deleteElementHandleAbstract = (board, deletableElements, effectedAbstracts = new Map()) => {
777
+ deletableElements.forEach(node => {
778
+ if (!PlaitMind.isMind(node)) {
779
+ const behindAbstracts = getBehindAbstracts(node).filter(abstract => !deletableElements.includes(abstract));
780
+ if (behindAbstracts.length) {
781
+ behindAbstracts.forEach(abstract => {
782
+ let newProperties = effectedAbstracts.get(abstract);
783
+ if (!newProperties) {
784
+ newProperties = { start: 0, end: 0 };
785
+ effectedAbstracts.set(abstract, newProperties);
786
+ }
787
+ newProperties.start = newProperties.start - 1;
788
+ newProperties.end = newProperties.end - 1;
789
+ });
790
+ }
791
+ const correspondingAbstract = getCorrespondingAbstract(node);
792
+ if (correspondingAbstract && !deletableElements.includes(correspondingAbstract)) {
793
+ let newProperties = effectedAbstracts.get(correspondingAbstract);
794
+ if (!newProperties) {
795
+ newProperties = { start: 0, end: 0 };
796
+ effectedAbstracts.set(correspondingAbstract, newProperties);
797
+ }
798
+ newProperties.end = newProperties.end - 1;
799
+ }
800
+ }
801
+ });
802
+ return effectedAbstracts;
803
+ };
804
+ const isChildOfAbstract = (board, element) => {
805
+ const ancestors = MindElement.getAncestors(board, element);
806
+ return !!ancestors.find((value) => AbstractNode.isAbstract(value));
807
+ };
808
+
643
809
  /**
644
810
  * Processing of branch color, width, style, etc. of the mind node
645
811
  */
646
812
  const getBranchColorByMindElement = (board, element) => {
813
+ if (AbstractNode.isAbstract(element) || isChildOfAbstract(board, element)) {
814
+ return getAbstractBranchColor(board, element);
815
+ }
647
816
  const branchColor = getAvailableProperty(board, element, 'branchColor');
648
817
  return branchColor || getDefaultBranchColor(board, element);
649
818
  };
@@ -697,6 +866,10 @@ const getStrokeByMindElement = (board, element) => {
697
866
  const defaultRootStroke = getMindThemeColor(board).rootFill;
698
867
  return element.strokeColor || defaultRootStroke;
699
868
  }
869
+ if (AbstractNode.isAbstract(element) || isChildOfAbstract(board, element)) {
870
+ return element.strokeColor || DefaultAbstractNodeStyle.strokeColor;
871
+ ;
872
+ }
700
873
  return getAvailableProperty(board, element, 'strokeColor') || getDefaultBranchColor(board, element);
701
874
  };
702
875
  const getShapeByElement = (board, element) => {
@@ -1106,15 +1279,6 @@ function drawIndentedLink(board, node, child, defaultStroke = null, needDrawUnde
1106
1279
  endY = isUnderlineShape ? endNode.y + endNode.height - endNode.vGap : endNode.y + endNode.height / 2;
1107
1280
  //根据位置,设置正负参数
1108
1281
  let plusMinus = isChildUp(node, child) ? (node.left ? [-1, -1] : [1, -1]) : node.left ? [-1, 1] : [1, 1];
1109
- const layout = MindQueries.getCorrectLayoutByElement(board, node.origin);
1110
- if (beginNode.origin.isRoot) {
1111
- if (layout === MindLayoutType.leftBottomIndented || layout === MindLayoutType.rightBottomIndented) {
1112
- beginY += branchWidth;
1113
- }
1114
- if (layout === MindLayoutType.leftTopIndented || layout === MindLayoutType.rightTopIndented) {
1115
- beginY -= branchWidth;
1116
- }
1117
- }
1118
1282
  let curve = [
1119
1283
  [beginX, beginY],
1120
1284
  [beginX, beginY],
@@ -1136,8 +1300,8 @@ function drawIndentedLink(board, node, child, defaultStroke = null, needDrawUnde
1136
1300
  ];
1137
1301
  return drawLinearPath(polylinePoints, { stroke: branchColor, strokeWidth: branchWidth });
1138
1302
  }
1139
- const points = pointsOnBezierCurves(curve);
1140
- return PlaitBoard.getRoughSVG(board).curve(points, { stroke: branchColor, strokeWidth: branchWidth });
1303
+ const points = pointsOnBezierCurves(curve, 0.001);
1304
+ return drawBezierPath(points, { stroke: branchColor, strokeWidth: branchWidth });
1141
1305
  }
1142
1306
 
1143
1307
  function drawLogicLink(board, parent, node, isHorizontal, defaultStroke = null, defaultStrokeWidth) {
@@ -1345,169 +1509,6 @@ const drawFakeDropNode = (board, dropTarget, path) => {
1345
1509
  return fakeDropNodeG;
1346
1510
  };
1347
1511
 
1348
- const separateChildren = (parentElement) => {
1349
- const rightNodeCount = parentElement.rightNodeCount;
1350
- const children = parentElement.children;
1351
- let rightChildren = [], leftChildren = [];
1352
- for (let i = 0; i < children.length; i++) {
1353
- const child = children[i];
1354
- if (AbstractNode.isAbstract(child) && child.end < rightNodeCount) {
1355
- rightChildren.push(child);
1356
- continue;
1357
- }
1358
- if (AbstractNode.isAbstract(child) && child.start >= rightNodeCount) {
1359
- leftChildren.push(child);
1360
- continue;
1361
- }
1362
- if (i < rightNodeCount) {
1363
- rightChildren.push(child);
1364
- }
1365
- else {
1366
- leftChildren.push(child);
1367
- }
1368
- }
1369
- return { leftChildren, rightChildren };
1370
- };
1371
- const isSetAbstract = (element) => {
1372
- return !!getCorrespondingAbstract(element);
1373
- };
1374
- const canSetAbstract = (element) => {
1375
- return !PlaitElement.isRootElement(element) && !AbstractNode.isAbstract(element) && !isSetAbstract(element);
1376
- };
1377
- const getCorrespondingAbstract = (element) => {
1378
- const parent = MindElement.findParent(element);
1379
- if (!parent)
1380
- return undefined;
1381
- const elementIndex = parent.children.indexOf(element);
1382
- return parent.children.find(child => {
1383
- return AbstractNode.isAbstract(child) && elementIndex >= child.start && elementIndex <= child.end;
1384
- });
1385
- };
1386
- const getBehindAbstracts = (element) => {
1387
- const parent = MindElement.findParent(element);
1388
- if (!parent)
1389
- return [];
1390
- const index = parent.children.indexOf(element);
1391
- return parent.children.filter(child => AbstractNode.isAbstract(child) && child.start > index);
1392
- };
1393
- /**
1394
- * return corresponding abstract that is not child of elements
1395
- */
1396
- const getOverallAbstracts = (board, elements) => {
1397
- const overallAbstracts = [];
1398
- elements
1399
- .filter(value => !AbstractNode.isAbstract(value) && !PlaitMind.isMind(value))
1400
- .forEach(value => {
1401
- const abstract = getCorrespondingAbstract(value);
1402
- if (abstract && elements.indexOf(abstract) === -1 && overallAbstracts.indexOf(abstract) === -1) {
1403
- const { start, end } = abstract;
1404
- const parent = MindElement.getParent(value);
1405
- const isOverall = parent.children.slice(start, end + 1).every(includedElement => elements.indexOf(includedElement) > -1);
1406
- if (isOverall) {
1407
- overallAbstracts.push(abstract);
1408
- }
1409
- }
1410
- });
1411
- return overallAbstracts;
1412
- };
1413
- /**
1414
- * abstract node is valid when elements contains at least one element it is referenced with
1415
- */
1416
- const getValidAbstractRefs = (board, elements) => {
1417
- const validAbstractRefs = [];
1418
- elements
1419
- .filter(value => !AbstractNode.isAbstract(value) && !PlaitMind.isMind(value))
1420
- .forEach(value => {
1421
- const abstract = getCorrespondingAbstract(value);
1422
- if (abstract && elements.indexOf(abstract) > 0) {
1423
- const index = validAbstractRefs.findIndex(value => value.abstract === abstract);
1424
- if (index === -1) {
1425
- validAbstractRefs.push({
1426
- abstract: abstract,
1427
- references: [value]
1428
- });
1429
- }
1430
- else {
1431
- validAbstractRefs[index].references.push(value);
1432
- }
1433
- }
1434
- });
1435
- return validAbstractRefs;
1436
- };
1437
- function getRelativeStartEndByAbstractRef(abstractRef, elements) {
1438
- const start = elements.indexOf(abstractRef.references[0]);
1439
- const end = elements.indexOf(abstractRef.references[abstractRef.references.length - 1]);
1440
- return { start, end };
1441
- }
1442
- const insertElementHandleAbstract = (board, path, step = 1,
1443
- //由此区分拖拽和新增到概要概括最后一个节点
1444
- isExtendPreviousNode = true, effectedAbstracts = new Map()) => {
1445
- const parent = PlaitNode.parent(board, path);
1446
- const hasPreviousNode = path[path.length - 1] !== 0;
1447
- let behindAbstracts;
1448
- if (!hasPreviousNode) {
1449
- behindAbstracts = parent.children.filter(child => AbstractNode.isAbstract(child));
1450
- }
1451
- else {
1452
- const selectedElement = PlaitNode.get(board, Path.previous(path));
1453
- behindAbstracts = getBehindAbstracts(selectedElement);
1454
- }
1455
- if (behindAbstracts.length) {
1456
- behindAbstracts.forEach(abstract => {
1457
- let newProperties = effectedAbstracts.get(abstract);
1458
- if (!newProperties) {
1459
- newProperties = { start: 0, end: 0 };
1460
- effectedAbstracts.set(abstract, newProperties);
1461
- }
1462
- newProperties.start = newProperties.start + step;
1463
- newProperties.end = newProperties.end + step;
1464
- });
1465
- }
1466
- if (!hasPreviousNode) {
1467
- return effectedAbstracts;
1468
- }
1469
- const selectedElement = PlaitNode.get(board, Path.previous(path));
1470
- const correspondingAbstract = getCorrespondingAbstract(selectedElement);
1471
- const isDragToLast = !isExtendPreviousNode && correspondingAbstract && correspondingAbstract.end === path[path.length - 1] - 1;
1472
- if (correspondingAbstract && !isDragToLast) {
1473
- let newProperties = effectedAbstracts.get(correspondingAbstract);
1474
- if (!newProperties) {
1475
- newProperties = { start: 0, end: 0 };
1476
- effectedAbstracts.set(correspondingAbstract, newProperties);
1477
- }
1478
- newProperties.end = newProperties.end + step;
1479
- }
1480
- return effectedAbstracts;
1481
- };
1482
- const deleteElementHandleAbstract = (board, deletableElements, effectedAbstracts = new Map()) => {
1483
- deletableElements.forEach(node => {
1484
- if (!PlaitMind.isMind(node)) {
1485
- const behindAbstracts = getBehindAbstracts(node).filter(abstract => !deletableElements.includes(abstract));
1486
- if (behindAbstracts.length) {
1487
- behindAbstracts.forEach(abstract => {
1488
- let newProperties = effectedAbstracts.get(abstract);
1489
- if (!newProperties) {
1490
- newProperties = { start: 0, end: 0 };
1491
- effectedAbstracts.set(abstract, newProperties);
1492
- }
1493
- newProperties.start = newProperties.start - 1;
1494
- newProperties.end = newProperties.end - 1;
1495
- });
1496
- }
1497
- const correspondingAbstract = getCorrespondingAbstract(node);
1498
- if (correspondingAbstract && !deletableElements.includes(correspondingAbstract)) {
1499
- let newProperties = effectedAbstracts.get(correspondingAbstract);
1500
- if (!newProperties) {
1501
- newProperties = { start: 0, end: 0 };
1502
- effectedAbstracts.set(correspondingAbstract, newProperties);
1503
- }
1504
- newProperties.end = newProperties.end - 1;
1505
- }
1506
- }
1507
- });
1508
- return effectedAbstracts;
1509
- };
1510
-
1511
1512
  var AbstractHandlePosition;
1512
1513
  (function (AbstractHandlePosition) {
1513
1514
  AbstractHandlePosition["start"] = "start";
@@ -2166,9 +2167,7 @@ const setAbstractByElements = (board, groupParent, group) => {
2166
2167
  };
2167
2168
  const insertAbstractNode = (board, path, start, end) => {
2168
2169
  const mindElement = createMindElement('概要', 28, 20, {
2169
- strokeColor: DefaultAbstractNodeStyle.strokeColor,
2170
2170
  strokeWidth: DefaultAbstractNodeStyle.branchWidth,
2171
- branchColor: DefaultAbstractNodeStyle.branchColor,
2172
2171
  branchWidth: DefaultAbstractNodeStyle.branchWidth
2173
2172
  });
2174
2173
  mindElement.start = start;
@@ -2656,7 +2655,7 @@ class MindNodeComponent extends PlaitPluginElementComponent {
2656
2655
  this.nodeInsertDrawer = new NodeInsertDrawer(this.board);
2657
2656
  this.activeDrawer = new NodeActiveDrawer(this.board);
2658
2657
  this.collapseDrawer = new CollapseDrawer(this.board);
2659
- const plugins = this.board.getMindOptions().textPlugins;
2658
+ const plugins = this.board.getPluginOptions(WithMindPluginKey).textPlugins;
2660
2659
  this.textManage = new TextManage(this.board, this.viewContainerRef, () => {
2661
2660
  const rect = getTopicRectangleByNode(this.board, this.node);
2662
2661
  return rect;
@@ -2692,8 +2691,10 @@ class MindNodeComponent extends PlaitPluginElementComponent {
2692
2691
  }
2693
2692
  editTopic() {
2694
2693
  this.activeDrawer.draw(this.element, this.g, { selected: this.selected, isEditing: true });
2695
- this.textManage.edit(() => {
2696
- this.activeDrawer.draw(this.element, this.g, { selected: this.selected, isEditing: false });
2694
+ this.textManage.edit((origin) => {
2695
+ if (origin === ExitOrigin.default) {
2696
+ this.activeDrawer.draw(this.element, this.g, { selected: this.selected, isEditing: false });
2697
+ }
2697
2698
  });
2698
2699
  }
2699
2700
  onContextChanged(value, previous) {
@@ -2982,12 +2983,11 @@ const withNodeDnd = (board) => {
2982
2983
  !AbstractNode.isAbstract(targetElement)) {
2983
2984
  const targetElements = selectedElements.filter(element => MindElement.isMindElement(board, element) && !element.isRoot && !AbstractNode.isAbstract(element));
2984
2985
  const isMultiple = selectedElements.length > 0 && selectedElements.includes(targetElement);
2985
- const isSingle = !isMultiple && selectedElements.length === 0;
2986
2986
  if (isMultiple) {
2987
2987
  activeElements = targetElements;
2988
2988
  startPoint = point;
2989
2989
  }
2990
- else if (isSingle) {
2990
+ else {
2991
2991
  activeElements = [targetElement];
2992
2992
  startPoint = point;
2993
2993
  }
@@ -3041,6 +3041,7 @@ const withNodeDnd = (board) => {
3041
3041
  }
3042
3042
  if (dropTarget) {
3043
3043
  const targetPathRef = board.pathRef(targetPath);
3044
+ const targetPreviousPathRef = Path.hasPrevious(targetPath) && board.pathRef(Path.previous(targetPath));
3044
3045
  const targetElementPathRef = board.pathRef(PlaitBoard.findPath(board, dropTarget.target));
3045
3046
  let abstractRefs = getValidAbstractRefs(board, firstLevelElements);
3046
3047
  const normalElements = firstLevelElements
@@ -3078,9 +3079,16 @@ const withNodeDnd = (board) => {
3078
3079
  let insertPath = targetPathRef.current;
3079
3080
  const parentPath = Path.parent(targetPathRef.current || targetPath);
3080
3081
  if (!insertPath) {
3081
- const parent = PlaitNode.get(board, parentPath);
3082
- const children = getNonAbstractChildren(parent);
3083
- insertPath = [...parentPath, children.length || 0];
3082
+ //当插入位置和选中节点位置相同时,使用记录的 previousPath
3083
+ const previousPath = targetPreviousPathRef && targetPreviousPathRef.unref();
3084
+ if (previousPath) {
3085
+ insertPath = Path.next(previousPath);
3086
+ }
3087
+ else {
3088
+ const parent = PlaitNode.get(board, parentPath);
3089
+ const children = getNonAbstractChildren(parent);
3090
+ insertPath = [...parentPath, children.length || 0];
3091
+ }
3084
3092
  }
3085
3093
  MindTransforms.insertNodes(board, normalElements, insertPath);
3086
3094
  if (abstractRefs.length) {
@@ -3190,6 +3198,10 @@ const insertClipboardData = (board, elements, targetPoint) => {
3190
3198
  if (hasTargetParent) {
3191
3199
  if (item.isRoot) {
3192
3200
  newElement = adjustRootToNode(board, newElement);
3201
+ const styles = PlaitMind.isMind(targetParent) ? { fontFamily: BRANCH_FONT_FAMILY } : { fontFamily: DEFAULT_FONT_FAMILY };
3202
+ const { width, height } = getTextSize(board, newElement.data.topic, TOPIC_DEFAULT_MAX_WORD_COUNT, styles);
3203
+ newElement.width = Math.max(width, NODE_MIN_WIDTH);
3204
+ newElement.height = height;
3193
3205
  }
3194
3206
  // handle abstract start and end
3195
3207
  if (AbstractNode.isAbstract(newElement)) {
@@ -3215,10 +3227,11 @@ const insertClipboardData = (board, elements, targetPoint) => {
3215
3227
  });
3216
3228
  Transforms.setSelectionWithTemporaryElements(board, newELements);
3217
3229
  };
3218
- const insertClipboardText = (board, parentElement, text, width, height) => {
3230
+ const insertClipboardText = (board, targetParent, text) => {
3231
+ const styles = PlaitMind.isMind(targetParent) ? { fontFamily: BRANCH_FONT_FAMILY } : { fontFamily: DEFAULT_FONT_FAMILY };
3232
+ const { width, height } = getTextSize(board, text, TOPIC_DEFAULT_MAX_WORD_COUNT, styles);
3219
3233
  const newElement = createMindElement(text, width, height, {});
3220
- const path = PlaitBoard.findPath(board, parentElement).concat((parentElement.children || []).length);
3221
- Transforms.insertNode(board, newElement, path);
3234
+ Transforms.insertNode(board, newElement, findNewChildNodePath(board, targetParent));
3222
3235
  return;
3223
3236
  };
3224
3237
 
@@ -3331,9 +3344,7 @@ const withMindExtend = (board) => {
3331
3344
  newBoard.drawEmoji = (emoji, element) => {
3332
3345
  throw new Error('Not implement drawEmoji method error.');
3333
3346
  };
3334
- newBoard.getMindOptions = () => {
3335
- return { spaceBetweenEmojis: 4, emojiPadding: 0 };
3336
- };
3347
+ board.setPluginOptions(WithMindPluginKey, { spaceBetweenEmojis: 4, emojiPadding: 0 });
3337
3348
  return newBoard;
3338
3349
  };
3339
3350
 
@@ -3361,7 +3372,7 @@ const withCreateMind = (board) => {
3361
3372
  }
3362
3373
  if (PlaitBoard.isPointer(board, MindPointerType.mind)) {
3363
3374
  throttleRAF(() => {
3364
- const movingPoint = PlaitBoard.getMovingPoint(board);
3375
+ const movingPoint = PlaitBoard.getMovingPointInBoard(board);
3365
3376
  if (movingPoint) {
3366
3377
  const targetPoint = transformPoint(board, toPoint(movingPoint[0], movingPoint[1], PlaitBoard.getHost(board)));
3367
3378
  const emptyMind = createEmptyMind(targetPoint);
@@ -3403,7 +3414,7 @@ const withCreateMind = (board) => {
3403
3414
  mousemove(event);
3404
3415
  };
3405
3416
  newBoard.mouseup = (event) => {
3406
- const movingPoint = PlaitBoard.getMovingPoint(board);
3417
+ const movingPoint = PlaitBoard.getMovingPointInBoard(board);
3407
3418
  if (movingPoint && fakeCreateNodeRef && PlaitBoard.isPointer(board, MindPointerType.mind)) {
3408
3419
  const targetPoint = transformPoint(board, toPoint(movingPoint[0], movingPoint[1], PlaitBoard.getHost(board)));
3409
3420
  const emptyMind = createEmptyMind(targetPoint);
@@ -3482,38 +3493,18 @@ const withMindHotkey = (board) => {
3482
3493
  event.preventDefault();
3483
3494
  const targetMindElements = selectedElements.filter(el => MindElement.isMindElement(board, el));
3484
3495
  const firstLevelElements = getFirstLevelElement(targetMindElements);
3485
- const deletableElements = firstLevelElements.reverse();
3486
- const abstractRefs = deleteElementHandleAbstract(board, deletableElements);
3487
- MindTransforms.setAbstractsByRefs(board, abstractRefs);
3488
- const refs = deleteElementsHandleRightNodeCount(board, targetMindElements);
3489
- MindTransforms.setRightNodeCountByRefs(board, refs);
3490
- MindTransforms.removeElements(board, targetMindElements);
3491
- let activeElement;
3492
- if (AbstractNode.isAbstract(firstLevelElements[0])) {
3493
- const parent = MindElement.getParent(firstLevelElements[0]);
3494
- activeElement = parent.children[firstLevelElements[0].start];
3495
- }
3496
- const firstElement = firstLevelElements[0];
3497
- const firstElementParent = MindElement.findParent(firstElement);
3498
- const hasSameParent = firstLevelElements.every(element => {
3499
- return MindElement.findParent(element) === firstElementParent;
3500
- });
3501
- if (firstElementParent && hasSameParent && !activeElement) {
3502
- const firstElementIndex = firstElementParent.children.indexOf(firstElement);
3503
- const childrenCount = firstElementParent.children.length;
3504
- // active parent element
3505
- if (childrenCount === firstLevelElements.length) {
3506
- activeElement = firstElementParent;
3507
- }
3508
- else {
3509
- if (firstElementIndex > 0) {
3510
- activeElement = firstElementParent.children[firstElementIndex - 1];
3511
- }
3496
+ if (firstLevelElements.length > 0) {
3497
+ const deletableElements = [...firstLevelElements].reverse();
3498
+ const abstractRefs = deleteElementHandleAbstract(board, deletableElements);
3499
+ MindTransforms.setAbstractsByRefs(board, abstractRefs);
3500
+ const refs = deleteElementsHandleRightNodeCount(board, targetMindElements);
3501
+ MindTransforms.setRightNodeCountByRefs(board, refs);
3502
+ MindTransforms.removeElements(board, targetMindElements);
3503
+ const nextSelected = getNextSelectedElement(board, firstLevelElements);
3504
+ if (nextSelected) {
3505
+ addSelectedElement(board, nextSelected);
3512
3506
  }
3513
3507
  }
3514
- if (activeElement) {
3515
- addSelectedElement(board, activeElement);
3516
- }
3517
3508
  return;
3518
3509
  }
3519
3510
  if (!isVirtualKey(event) && !isSpaceHotkey(event) && isSingleSelection) {
@@ -3526,6 +3517,36 @@ const withMindHotkey = (board) => {
3526
3517
  };
3527
3518
  return board;
3528
3519
  };
3520
+ const getNextSelectedElement = (board, firstLevelElements) => {
3521
+ let activeElement;
3522
+ const firstLevelElement = firstLevelElements[0];
3523
+ const firstLevelElementPath = PlaitBoard.findPath(board, firstLevelElement);
3524
+ let nextSelectedPath = firstLevelElementPath;
3525
+ if (Path.hasPrevious(firstLevelElementPath)) {
3526
+ nextSelectedPath = Path.previous(firstLevelElementPath);
3527
+ }
3528
+ if (AbstractNode.isAbstract(firstLevelElement)) {
3529
+ const parent = MindElement.getParent(firstLevelElement);
3530
+ if (!firstLevelElements.includes(parent.children[firstLevelElement.start])) {
3531
+ activeElement = parent.children[firstLevelElement.start];
3532
+ }
3533
+ }
3534
+ try {
3535
+ if (!activeElement) {
3536
+ activeElement = PlaitNode.get(board, nextSelectedPath);
3537
+ }
3538
+ }
3539
+ catch (error) { }
3540
+ const firstElement = firstLevelElements[0];
3541
+ const firstElementParent = MindElement.findParent(firstElement);
3542
+ const hasSameParent = firstLevelElements.every(element => {
3543
+ return MindElement.findParent(element) === firstElementParent;
3544
+ });
3545
+ if (firstElementParent && hasSameParent && !activeElement) {
3546
+ activeElement = firstElementParent;
3547
+ }
3548
+ return activeElement;
3549
+ };
3529
3550
  const isExpandHotkey = (event) => {
3530
3551
  return isKeyHotkey('mod+/', event);
3531
3552
  };
@@ -3698,13 +3719,12 @@ const withMind = (board) => {
3698
3719
  insertClipboardData(board, elements, targetPoint || [0, 0]);
3699
3720
  }
3700
3721
  else {
3701
- const text = getTextFromClipboard(data);
3702
- const { width, height } = getTextSize(board, text, TOPIC_DEFAULT_MAX_WORD_COUNT, {
3703
- fontFamily: 'PingFangSC-Regular, "PingFang SC"'
3704
- });
3705
3722
  const selectedElements = getSelectedElements(board);
3706
- if (text && selectedElements.length === 1) {
3707
- insertClipboardText(board, selectedElements[0], buildText(text), width, height);
3723
+ if (selectedElements.length === 1) {
3724
+ const text = getTextFromClipboard(data);
3725
+ if (text) {
3726
+ insertClipboardText(board, selectedElements[0], buildText(text));
3727
+ }
3708
3728
  }
3709
3729
  }
3710
3730
  insertFragment(data, targetPoint);
@@ -3773,5 +3793,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImpor
3773
3793
  * Generated bundle index. Do not edit.
3774
3794
  */
3775
3795
 
3776
- 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 };
3796
+ export { ABSTRACT_HANDLE_COLOR, ABSTRACT_HANDLE_LENGTH, ABSTRACT_HANDLE_MASK_WIDTH, ABSTRACT_INCLUDED_OUTLINE_OFFSET, AbstractHandlePosition, AbstractResizeState, BASE, BRANCH_FONT_FAMILY, BRANCH_WIDTH, BaseDrawer, BranchShape, DEFAULT_FONT_FAMILY, 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, WithMindPluginKey, 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, isChildOfAbstract, isChildRight, isChildUp, isCorrectLayout, isDragging, isDropStandardRight, isHitEmojis, isHitMindElement, isInRightBranchOfStandardLayout, isMixedLayout, isSetAbstract, isValidTarget, isVirtualKey, removeActiveOnDragOrigin, separateChildren, setIsDragging, withMind, withMindExtend };
3777
3797
  //# sourceMappingURL=plait-mind.mjs.map