@plait/mind 0.27.0-next.3 → 0.27.0-next.5

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 (36) hide show
  1. package/base/emoji-base.component.d.ts +1 -1
  2. package/esm2022/base/emoji-base.component.mjs +5 -5
  3. package/esm2022/interfaces/element.mjs +1 -1
  4. package/esm2022/interfaces/options.mjs +1 -1
  5. package/esm2022/mind-node.component.mjs +234 -0
  6. package/esm2022/mind.component.mjs +2 -2
  7. package/esm2022/mind.module.mjs +2 -2
  8. package/esm2022/plugins/with-mind-fragment.mjs +90 -0
  9. package/esm2022/plugins/with-mind-hotkey.mjs +13 -55
  10. package/esm2022/plugins/with-mind.mjs +7 -36
  11. package/esm2022/plugins/with-node-dnd.mjs +3 -3
  12. package/esm2022/plugins/with-node-resize.mjs +2 -2
  13. package/esm2022/public-api.mjs +2 -2
  14. package/esm2022/transforms/index.mjs +2 -3
  15. package/esm2022/transforms/node.mjs +2 -18
  16. package/esm2022/utils/abstract/resize.mjs +1 -1
  17. package/esm2022/utils/dnd/common.mjs +1 -1
  18. package/esm2022/utils/draw/node-dnd.mjs +1 -1
  19. package/esm2022/utils/node/common.mjs +1 -1
  20. package/esm2022/utils/node/dynamic-width.mjs +2 -5
  21. package/esm2022/utils/node/image.mjs +1 -1
  22. package/esm2022/utils/position/topic.mjs +2 -3
  23. package/fesm2022/plait-mind.mjs +208 -234
  24. package/fesm2022/plait-mind.mjs.map +1 -1
  25. package/interfaces/options.d.ts +0 -2
  26. package/mind.component.d.ts +1 -1
  27. package/mind.module.d.ts +1 -1
  28. package/package.json +1 -1
  29. package/plugins/with-mind-fragment.d.ts +5 -0
  30. package/plugins/with-mind-hotkey.d.ts +0 -2
  31. package/public-api.d.ts +1 -1
  32. package/styles/styles.scss +0 -3
  33. package/transforms/index.d.ts +0 -1
  34. package/transforms/node.d.ts +0 -1
  35. package/esm2022/node.component.mjs +0 -251
  36. /package/{node.component.d.ts → mind-node.component.d.ts} +0 -0
@@ -1,11 +1,11 @@
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, PlaitPluginKey, getSelectedElements, idCreator, isNullOrUndefined, Transforms, clearSelectedElement, addSelectedElement, PlaitBoard, Path, PlaitNode, PlaitContextService, depthFirstRecursion, getIsRecursionFunc, drawLinearPath, drawBezierPath, createG, updateForeignObject, drawRoundRectangle, getRectangleByElements, NODE_TO_PARENT, distanceBetweenPointAndRectangle, createForeignObject, setStrokeLinecap, createText, PlaitPointerType, PlaitPluginElementComponent, NODE_TO_INDEX, PlaitModule, isMainPointer, transformPoint, toPoint, getHitElements, distanceBetweenPointAndPoint, setClipboardData, setClipboardDataByText, BOARD_TO_HOST, BoardTransforms, throttleRAF, removeSelectedElement, PlaitHistoryBoard, hotkeys, setClipboardDataByMedia, getClipboardDataByMedia, ResizeCursorClass, preventTouchMove, PRESS_AND_MOVE_BUFFER, MERGING, getDataFromClipboard } from '@plait/core';
4
+ import { DefaultThemeColor, ColorfulThemeColor, SoftThemeColor, RetroThemeColor, DarkThemeColor, StarryThemeColor, RectangleClient, PlaitElement, PlaitPluginKey, getSelectedElements, idCreator, isNullOrUndefined, Transforms, clearSelectedElement, addSelectedElement, PlaitBoard, Path, PlaitNode, PlaitContextService, depthFirstRecursion, getIsRecursionFunc, drawLinearPath, drawBezierPath, createG, updateForeignObject, drawRoundRectangle, getRectangleByElements, NODE_TO_PARENT, distanceBetweenPointAndRectangle, createForeignObject, setStrokeLinecap, createText, PlaitPointerType, PlaitPluginElementComponent, NODE_TO_INDEX, PlaitModule, isMainPointer, transformPoint, toPoint, getHitElements, distanceBetweenPointAndPoint, CoreTransforms, BOARD_TO_HOST, BoardTransforms, throttleRAF, removeSelectedElement, PlaitHistoryBoard, hotkeys, setClipboardDataByMedia, getClipboardDataByMedia, ResizeCursorClass, preventTouchMove, PRESS_AND_MOVE_BUFFER, MERGING, setClipboardData, setClipboardDataByText, getDataFromClipboard } from '@plait/core';
5
5
  import { MindLayoutType, isIndentedLayout, isHorizontalLayout, isHorizontalLogicLayout, ConnectingPosition, AbstractNode, isStandardLayout, isVerticalLogicLayout, getNonAbstractChildren, isLeftLayout, isRightLayout, isTopLayout, isBottomLayout, getCorrectStartEnd, getAbstractLayout, GlobalLayout } from '@plait/layouts';
6
6
  import { PlaitMarkEditor, MarkTypes, DEFAULT_FONT_SIZE, TEXT_DEFAULT_HEIGHT, buildText, getTextSize, TextManage, ExitOrigin, TextModule, getTextFromClipboard } from '@plait/text';
7
7
  import { fromEvent, Subject } from 'rxjs';
8
- import { RESIZE_HANDLE_DIAMETER, getRectangleResizeHandleRefs, isDrawingMode, isDndMode, setCreationMode, BoardCreationMode, isExpandHotkey, isTabHotkey, isEnterHotkey, isVirtualKey, isSpaceHotkey, MediaKeys, ResizeHandle, withResize, ActiveGenerator } from '@plait/common';
8
+ import { RESIZE_HANDLE_DIAMETER, getRectangleResizeHandleRefs, WithTextPluginKey, isDrawingMode, isDndMode, setCreationMode, BoardCreationMode, isExpandHotkey, isTabHotkey, isEnterHotkey, isVirtualKey, isDelete, isSpaceHotkey, MediaKeys, ResizeHandle, withResize, ActiveGenerator } from '@plait/common';
9
9
  import { Node as Node$1, Path as Path$1 } from 'slate';
10
10
  import { pointsOnBezierCurves } from 'points-on-curve';
11
11
  import { take, filter } from 'rxjs/operators';
@@ -386,8 +386,7 @@ const isHitEmojis = (board, element, point) => {
386
386
  function getTopicRectangleByNode(board, node) {
387
387
  let nodeRectangle = getRectangleByNode(node);
388
388
  const result = getTopicRectangleByElement(board, nodeRectangle, node.origin);
389
- // add buffer width to avoid unexpected text breaks in different scene
390
- result.width = result.width + 4;
389
+ result.width = result.width;
391
390
  return result;
392
391
  }
393
392
  function getTopicRectangleByElement(board, nodeRectangle, element) {
@@ -1078,7 +1077,7 @@ const normalizeWidthAndHeight = (board, element, width, height) => {
1078
1077
  const minWidth = NodeSpace.getNodeTopicMinWidth(board, element, element.isRoot);
1079
1078
  const newWidth = width < minWidth * board.viewport.zoom ? minWidth : width / board.viewport.zoom;
1080
1079
  const newHeight = height / board.viewport.zoom;
1081
- return { width: newWidth, height: newHeight };
1080
+ return { width: Math.ceil(newWidth), height: newHeight };
1082
1081
  };
1083
1082
  const setTopic = (board, element, topic, width, height) => {
1084
1083
  const newElement = {
@@ -1108,21 +1107,6 @@ const setTopicSize = (board, element, width, height) => {
1108
1107
  Transforms.setNode(board, newElement, path);
1109
1108
  }
1110
1109
  };
1111
- const removeElements = (board, elements) => {
1112
- const deletableElements = getFirstLevelElement(elements);
1113
- deletableElements
1114
- .map(element => {
1115
- const path = PlaitBoard.findPath(board, element);
1116
- const ref = board.pathRef(path);
1117
- return () => {
1118
- Transforms.removeNode(board, ref.current);
1119
- ref.unref();
1120
- };
1121
- })
1122
- .forEach(action => {
1123
- action();
1124
- });
1125
- };
1126
1110
  const insertNodes = (board, elements, path) => {
1127
1111
  const pathRef = board.pathRef(path);
1128
1112
  elements.forEach(element => {
@@ -1197,11 +1181,8 @@ const replaceEmoji = (board, element, oldEmoji, newEmoji) => {
1197
1181
  const getNewNodeHeight = (board, element, newNodeDynamicWidth) => {
1198
1182
  const textManage = PlaitElement.getComponent(element).textManage;
1199
1183
  const { height } = textManage.getSize();
1200
- textManage.updateWidth(newNodeDynamicWidth);
1184
+ textManage.updateRectangleWidth(newNodeDynamicWidth);
1201
1185
  const { height: newHeight } = textManage.getSize();
1202
- if (!element.manualWidth) {
1203
- textManage.updateWidth(0);
1204
- }
1205
1186
  if (height !== newHeight) {
1206
1187
  return newHeight;
1207
1188
  }
@@ -1249,7 +1230,6 @@ const MindTransforms = {
1249
1230
  insertAbstract,
1250
1231
  setAbstractsByRefs,
1251
1232
  setAbstractByStandardLayout,
1252
- removeElements,
1253
1233
  insertNodes,
1254
1234
  insertAbstractNodes,
1255
1235
  setRightNodeCountByRefs,
@@ -3050,9 +3030,6 @@ class NodeImageDrawer {
3050
3030
  }
3051
3031
  }
3052
3032
 
3053
- // 1. When the text at the end has an italic attribute, the text is partially covered
3054
- // 2. There will be some differences in the width measured by different browsers
3055
- const WIDTH_BUFFER = 4;
3056
3033
  class MindNodeComponent extends PlaitPluginElementComponent {
3057
3034
  constructor(viewContainerRef, cdr) {
3058
3035
  super(cdr);
@@ -3070,7 +3047,7 @@ class MindNodeComponent extends PlaitPluginElementComponent {
3070
3047
  this.activeDrawer = new NodeActiveDrawer(this.board);
3071
3048
  this.collapseDrawer = new CollapseDrawer(this.board);
3072
3049
  this.imageDrawer = new NodeImageDrawer(this.board, this.viewContainerRef);
3073
- const plugins = this.board.getPluginOptions(WithMindPluginKey).textPlugins;
3050
+ const plugins = this.board.getPluginOptions(WithTextPluginKey).textPlugins;
3074
3051
  this.textManage = new TextManage(this.board, this.viewContainerRef, {
3075
3052
  getRectangle: () => {
3076
3053
  const rect = getTopicRectangleByNode(this.board, this.node);
@@ -3088,7 +3065,12 @@ class MindNodeComponent extends PlaitPluginElementComponent {
3088
3065
  },
3089
3066
  textPlugins: plugins,
3090
3067
  getMaxWidth: () => {
3091
- return NodeTopicThreshold.defaultTextMaxWidth;
3068
+ if (this.element.manualWidth) {
3069
+ return NodeSpace.getNodeDynamicWidth(this.board, this.element);
3070
+ }
3071
+ else {
3072
+ return Math.max(NodeSpace.getNodeDynamicWidth(this.board, this.element), NodeTopicThreshold.defaultTextMaxWidth);
3073
+ }
3092
3074
  }
3093
3075
  });
3094
3076
  }
@@ -3204,36 +3186,17 @@ class MindNodeComponent extends PlaitPluginElementComponent {
3204
3186
  drawTopic() {
3205
3187
  this.textManage.draw(this.element.data.topic);
3206
3188
  this.g.append(this.textManage.g);
3207
- if (this.element.manualWidth) {
3208
- const width = NodeSpace.getNodeDynamicWidth(this.board, this.element);
3209
- this.textManage.updateWidth(width);
3210
- }
3211
3189
  }
3212
3190
  updateTopic() {
3213
3191
  this.textManage.updateText(this.element.data.topic);
3214
3192
  this.textManage.updateRectangle();
3215
- if (this.element.manualWidth) {
3216
- const width = NodeSpace.getNodeDynamicWidth(this.board, this.element);
3217
- this.textManage.updateWidth(width);
3218
- }
3219
3193
  }
3220
3194
  editTopic() {
3221
3195
  this.activeDrawer.draw(this.element, this.g, { selected: this.selected, isEditing: true });
3222
- // update text max-width when image width greater than topic default max width to cover node topic default max width style
3223
- const defaultMaxWidth = TOPIC_DEFAULT_MAX_WORD_COUNT * (PlaitMind.isMind(this.element) ? ROOT_TOPIC_FONT_SIZE : TOPIC_FONT_SIZE);
3224
- let hasMaxWidth = false;
3225
- if (!this.element.manualWidth && MindElement.hasImage(this.element) && this.element.data.image.width > defaultMaxWidth) {
3226
- const width = NodeSpace.getNodeDynamicWidth(this.board, this.element);
3227
- this.textManage.updateWidth(width);
3228
- hasMaxWidth = true;
3229
- }
3230
3196
  this.textManage.edit((origin) => {
3231
3197
  if (origin === ExitOrigin.default) {
3232
3198
  this.activeDrawer.draw(this.element, this.g, { selected: this.selected, isEditing: false });
3233
3199
  }
3234
- if (hasMaxWidth) {
3235
- this.textManage.updateWidth(0);
3236
- }
3237
3200
  });
3238
3201
  }
3239
3202
  ngOnDestroy() {
@@ -3453,7 +3416,7 @@ const withNodeDnd = (board) => {
3453
3416
  refs = insertElementHandleRightNodeCount(board, targetElementPathRef.current.slice(0, 1), normalElements.length, refs);
3454
3417
  }
3455
3418
  MindTransforms.setRightNodeCountByRefs(board, refs);
3456
- MindTransforms.removeElements(board, firstLevelElements);
3419
+ CoreTransforms.removeElements(board, firstLevelElements);
3457
3420
  let insertPath = targetPathRef.current;
3458
3421
  const parentPath = Path.parent(targetPathRef.current || targetPath);
3459
3422
  if (!insertPath) {
@@ -3502,108 +3465,6 @@ const withNodeDnd = (board) => {
3502
3465
  return board;
3503
3466
  };
3504
3467
 
3505
- const buildClipboardData = (board, selectedElements, startPoint) => {
3506
- let result = [];
3507
- // get overall abstract
3508
- const overallAbstracts = getOverallAbstracts(board, selectedElements);
3509
- // get valid abstract refs
3510
- const validAbstractRefs = getValidAbstractRefs(board, [...selectedElements, ...overallAbstracts]);
3511
- // keep correct order
3512
- const newSelectedElements = selectedElements.filter(value => !validAbstractRefs.find(ref => ref.abstract === value));
3513
- newSelectedElements.push(...validAbstractRefs.map(value => value.abstract));
3514
- const selectedMindNodes = newSelectedElements.map(value => MindElement.getNode(value));
3515
- newSelectedElements.forEach((element, index) => {
3516
- // handle relative location
3517
- const nodeRectangle = getRectangleByNode(selectedMindNodes[index]);
3518
- const points = [[nodeRectangle.x - startPoint[0], nodeRectangle.y - startPoint[1]]];
3519
- // handle invalid abstract
3520
- const abstractRef = validAbstractRefs.find(ref => ref.abstract === element);
3521
- if (AbstractNode.isAbstract(element) && abstractRef) {
3522
- const { start, end } = getRelativeStartEndByAbstractRef(abstractRef, newSelectedElements);
3523
- result.push({
3524
- ...element,
3525
- points,
3526
- start,
3527
- end
3528
- });
3529
- }
3530
- else {
3531
- if (AbstractNode.isAbstract(element)) {
3532
- let newElement = { ...element, points };
3533
- delete newElement.start;
3534
- delete newElement.end;
3535
- result.push(newElement);
3536
- }
3537
- else {
3538
- result.push({
3539
- ...element,
3540
- points: points
3541
- });
3542
- }
3543
- }
3544
- });
3545
- return result;
3546
- };
3547
- const setMindClipboardData = (data, elements) => {
3548
- const text = elements.reduce((string, currentNode) => {
3549
- return string + extractNodesText(currentNode);
3550
- }, '');
3551
- setClipboardData(data, elements);
3552
- setClipboardDataByText(data, text);
3553
- };
3554
- const insertClipboardData = (board, elements, targetPoint) => {
3555
- let newElement, path;
3556
- const selectedElements = getSelectedElements(board);
3557
- let newELements = [];
3558
- const hasTargetParent = selectedElements.length === 1;
3559
- const targetParent = selectedElements[0];
3560
- const targetParentPath = targetParent && PlaitBoard.findPath(board, targetParent);
3561
- const nonAbstractChildrenLength = targetParent && getNonAbstractChildren(targetParent).length;
3562
- elements.forEach((item, index) => {
3563
- newElement = copyNewNode(item);
3564
- if (hasTargetParent) {
3565
- if (item.isRoot) {
3566
- newElement = adjustRootToNode(board, newElement);
3567
- const styles = PlaitMind.isMind(targetParent) ? { fontFamily: BRANCH_FONT_FAMILY } : { fontFamily: DEFAULT_FONT_FAMILY };
3568
- const { width, height } = getTextSize(board, newElement.data.topic, TOPIC_DEFAULT_MAX_WORD_COUNT, {
3569
- ...styles,
3570
- width: newElement.manualWidth ? newElement.manualWidth : undefined
3571
- });
3572
- newElement.width = Math.max(width, getNodeDefaultFontSize());
3573
- newElement.height = height;
3574
- }
3575
- // handle abstract start and end
3576
- if (AbstractNode.isAbstract(newElement)) {
3577
- newElement.start = newElement.start + nonAbstractChildrenLength;
3578
- newElement.end = newElement.end + nonAbstractChildrenLength;
3579
- }
3580
- path = [...targetParentPath, nonAbstractChildrenLength + index];
3581
- }
3582
- else {
3583
- const point = [targetPoint[0] + item.points[0][0], targetPoint[1] + item.points[0][1]];
3584
- newElement.points = [point];
3585
- if (AbstractNode.isAbstract(item)) {
3586
- newElement = adjustAbstractToNode(newElement);
3587
- }
3588
- if (!item.isRoot) {
3589
- newElement = adjustNodeToRoot(board, newElement);
3590
- }
3591
- path = [board.children.length];
3592
- }
3593
- newELements.push(newElement);
3594
- Transforms.insertNode(board, newElement, path);
3595
- return;
3596
- });
3597
- Transforms.setSelectionWithTemporaryElements(board, newELements);
3598
- };
3599
- const insertClipboardText = (board, targetParent, text) => {
3600
- const styles = PlaitMind.isMind(targetParent) ? { fontFamily: BRANCH_FONT_FAMILY } : { fontFamily: DEFAULT_FONT_FAMILY };
3601
- const { width, height } = getTextSize(board, text, TOPIC_DEFAULT_MAX_WORD_COUNT, styles);
3602
- const newElement = createMindElement(text, Math.max(width, getFontSizeBySlateElement(text)), height, {});
3603
- Transforms.insertNode(board, newElement, findNewChildNodePath(board, targetParent));
3604
- return;
3605
- };
3606
-
3607
3468
  const withAbstract = (board) => {
3608
3469
  const newBoard = board;
3609
3470
  const { mousedown, mousemove, mouseup } = board;
@@ -3824,7 +3685,7 @@ const withCreateMind = (board) => {
3824
3685
 
3825
3686
  const withMindHotkey = (baseBoard) => {
3826
3687
  const board = baseBoard;
3827
- const { keydown, deleteFragment } = board;
3688
+ const { keydown } = board;
3828
3689
  board.keydown = (event) => {
3829
3690
  const selectedElements = getSelectedElements(board);
3830
3691
  const isSingleSelection = selectedElements.length === 1;
@@ -3864,7 +3725,11 @@ const withMindHotkey = (baseBoard) => {
3864
3725
  insertMindElement(board, targetElement, findNewSiblingNodePath(board, targetElement));
3865
3726
  return;
3866
3727
  }
3867
- if (!isVirtualKey(event) && !isSpaceHotkey(event) && isSingleSelection && MindElement.isMindElement(board, targetElement)) {
3728
+ if (!isVirtualKey(event) &&
3729
+ !isDelete(event) &&
3730
+ !isSpaceHotkey(event) &&
3731
+ isSingleSelection &&
3732
+ MindElement.isMindElement(board, targetElement)) {
3868
3733
  event.preventDefault();
3869
3734
  editTopic(targetElement);
3870
3735
  return;
@@ -3872,54 +3737,8 @@ const withMindHotkey = (baseBoard) => {
3872
3737
  }
3873
3738
  keydown(event);
3874
3739
  };
3875
- board.deleteFragment = (data) => {
3876
- const targetMindElements = getSelectedMindElements(board);
3877
- if (targetMindElements.length) {
3878
- const firstLevelElements = getFirstLevelElement(targetMindElements).reverse();
3879
- const abstractRefs = deleteElementHandleAbstract(board, firstLevelElements);
3880
- MindTransforms.setAbstractsByRefs(board, abstractRefs);
3881
- const refs = deleteElementsHandleRightNodeCount(board, targetMindElements);
3882
- MindTransforms.setRightNodeCountByRefs(board, refs);
3883
- MindTransforms.removeElements(board, targetMindElements);
3884
- const nextSelected = getNextSelectedElement(board, firstLevelElements);
3885
- if (nextSelected) {
3886
- addSelectedElement(board, nextSelected);
3887
- }
3888
- }
3889
- deleteFragment(data);
3890
- };
3891
3740
  return board;
3892
3741
  };
3893
- const getNextSelectedElement = (board, firstLevelElements) => {
3894
- let activeElement;
3895
- const firstLevelElement = firstLevelElements[0];
3896
- const firstLevelElementPath = PlaitBoard.findPath(board, firstLevelElement);
3897
- let nextSelectedPath = firstLevelElementPath;
3898
- if (Path.hasPrevious(firstLevelElementPath)) {
3899
- nextSelectedPath = Path.previous(firstLevelElementPath);
3900
- }
3901
- if (AbstractNode.isAbstract(firstLevelElement)) {
3902
- const parent = MindElement.getParent(firstLevelElement);
3903
- if (!firstLevelElements.includes(parent.children[firstLevelElement.start])) {
3904
- activeElement = parent.children[firstLevelElement.start];
3905
- }
3906
- }
3907
- try {
3908
- if (!activeElement) {
3909
- activeElement = PlaitNode.get(board, nextSelectedPath);
3910
- }
3911
- }
3912
- catch (error) { }
3913
- const firstElement = firstLevelElements[0];
3914
- const firstElementParent = MindElement.findParent(firstElement);
3915
- const hasSameParent = firstLevelElements.every(element => {
3916
- return MindElement.findParent(element) === firstElementParent;
3917
- });
3918
- if (firstElementParent && hasSameParent && !activeElement) {
3919
- activeElement = firstElementParent;
3920
- }
3921
- return activeElement;
3922
- };
3923
3742
 
3924
3743
  const mouseMoveHandle = (board, event, nodeHoveredExtendRef) => {
3925
3744
  let target = null;
@@ -4131,7 +3950,7 @@ const withNodeResize = (board) => {
4131
3950
  }
4132
3951
  const newTarget = PlaitNode.get(board, targetElementRef.path);
4133
3952
  if (newTarget && NodeSpace.getNodeTopicMinWidth(board, newTarget) !== resizedWidth) {
4134
- targetElementRef.textManage.updateWidth(resizedWidth);
3953
+ targetElementRef.textManage.updateRectangleWidth(resizedWidth);
4135
3954
  const { height } = targetElementRef.textManage.getSize();
4136
3955
  MindTransforms.setNodeManualWidth(board, newTarget, resizedWidth * zoom, height);
4137
3956
  }
@@ -4245,9 +4064,191 @@ const withNodeImageResize = (board) => {
4245
4064
  return board;
4246
4065
  };
4247
4066
 
4067
+ const buildClipboardData = (board, selectedElements, startPoint) => {
4068
+ let result = [];
4069
+ // get overall abstract
4070
+ const overallAbstracts = getOverallAbstracts(board, selectedElements);
4071
+ // get valid abstract refs
4072
+ const validAbstractRefs = getValidAbstractRefs(board, [...selectedElements, ...overallAbstracts]);
4073
+ // keep correct order
4074
+ const newSelectedElements = selectedElements.filter(value => !validAbstractRefs.find(ref => ref.abstract === value));
4075
+ newSelectedElements.push(...validAbstractRefs.map(value => value.abstract));
4076
+ const selectedMindNodes = newSelectedElements.map(value => MindElement.getNode(value));
4077
+ newSelectedElements.forEach((element, index) => {
4078
+ // handle relative location
4079
+ const nodeRectangle = getRectangleByNode(selectedMindNodes[index]);
4080
+ const points = [[nodeRectangle.x - startPoint[0], nodeRectangle.y - startPoint[1]]];
4081
+ // handle invalid abstract
4082
+ const abstractRef = validAbstractRefs.find(ref => ref.abstract === element);
4083
+ if (AbstractNode.isAbstract(element) && abstractRef) {
4084
+ const { start, end } = getRelativeStartEndByAbstractRef(abstractRef, newSelectedElements);
4085
+ result.push({
4086
+ ...element,
4087
+ points,
4088
+ start,
4089
+ end
4090
+ });
4091
+ }
4092
+ else {
4093
+ if (AbstractNode.isAbstract(element)) {
4094
+ let newElement = { ...element, points };
4095
+ delete newElement.start;
4096
+ delete newElement.end;
4097
+ result.push(newElement);
4098
+ }
4099
+ else {
4100
+ result.push({
4101
+ ...element,
4102
+ points: points
4103
+ });
4104
+ }
4105
+ }
4106
+ });
4107
+ return result;
4108
+ };
4109
+ const setMindClipboardData = (data, elements) => {
4110
+ const text = elements.reduce((string, currentNode) => {
4111
+ return string + extractNodesText(currentNode);
4112
+ }, '');
4113
+ setClipboardData(data, elements);
4114
+ setClipboardDataByText(data, text);
4115
+ };
4116
+ const insertClipboardData = (board, elements, targetPoint) => {
4117
+ let newElement, path;
4118
+ const selectedElements = getSelectedElements(board);
4119
+ let newELements = [];
4120
+ const hasTargetParent = selectedElements.length === 1;
4121
+ const targetParent = selectedElements[0];
4122
+ const targetParentPath = targetParent && PlaitBoard.findPath(board, targetParent);
4123
+ const nonAbstractChildrenLength = targetParent && getNonAbstractChildren(targetParent).length;
4124
+ elements.forEach((item, index) => {
4125
+ newElement = copyNewNode(item);
4126
+ if (hasTargetParent) {
4127
+ if (item.isRoot) {
4128
+ newElement = adjustRootToNode(board, newElement);
4129
+ const styles = PlaitMind.isMind(targetParent) ? { fontFamily: BRANCH_FONT_FAMILY } : { fontFamily: DEFAULT_FONT_FAMILY };
4130
+ const { width, height } = getTextSize(board, newElement.data.topic, TOPIC_DEFAULT_MAX_WORD_COUNT, {
4131
+ ...styles,
4132
+ width: newElement.manualWidth ? newElement.manualWidth : undefined
4133
+ });
4134
+ newElement.width = Math.max(width, getNodeDefaultFontSize());
4135
+ newElement.height = height;
4136
+ }
4137
+ // handle abstract start and end
4138
+ if (AbstractNode.isAbstract(newElement)) {
4139
+ newElement.start = newElement.start + nonAbstractChildrenLength;
4140
+ newElement.end = newElement.end + nonAbstractChildrenLength;
4141
+ }
4142
+ path = [...targetParentPath, nonAbstractChildrenLength + index];
4143
+ }
4144
+ else {
4145
+ const point = [targetPoint[0] + item.points[0][0], targetPoint[1] + item.points[0][1]];
4146
+ newElement.points = [point];
4147
+ if (AbstractNode.isAbstract(item)) {
4148
+ newElement = adjustAbstractToNode(newElement);
4149
+ }
4150
+ if (!item.isRoot) {
4151
+ newElement = adjustNodeToRoot(board, newElement);
4152
+ }
4153
+ path = [board.children.length];
4154
+ }
4155
+ newELements.push(newElement);
4156
+ Transforms.insertNode(board, newElement, path);
4157
+ return;
4158
+ });
4159
+ Transforms.setSelectionWithTemporaryElements(board, newELements);
4160
+ };
4161
+ const insertClipboardText = (board, targetParent, text) => {
4162
+ const styles = PlaitMind.isMind(targetParent) ? { fontFamily: BRANCH_FONT_FAMILY } : { fontFamily: DEFAULT_FONT_FAMILY };
4163
+ const { width, height } = getTextSize(board, text, TOPIC_DEFAULT_MAX_WORD_COUNT, styles);
4164
+ const newElement = createMindElement(text, Math.max(width, getFontSizeBySlateElement(text)), height, {});
4165
+ Transforms.insertNode(board, newElement, findNewChildNodePath(board, targetParent));
4166
+ return;
4167
+ };
4168
+
4169
+ const withMindFragment = (baseBoard) => {
4170
+ const board = baseBoard;
4171
+ const { getDeletedFragment, insertFragment, setFragment } = board;
4172
+ board.getDeletedFragment = (data) => {
4173
+ const targetMindElements = getSelectedMindElements(board);
4174
+ if (targetMindElements.length) {
4175
+ const firstLevelElements = getFirstLevelElement(targetMindElements).reverse();
4176
+ const abstractRefs = deleteElementHandleAbstract(board, firstLevelElements);
4177
+ MindTransforms.setAbstractsByRefs(board, abstractRefs);
4178
+ const refs = deleteElementsHandleRightNodeCount(board, targetMindElements);
4179
+ MindTransforms.setRightNodeCountByRefs(board, refs);
4180
+ const deletableElements = getFirstLevelElement(targetMindElements);
4181
+ data.push(...deletableElements);
4182
+ const nextSelected = getNextSelectedElement(board, firstLevelElements);
4183
+ if (nextSelected) {
4184
+ addSelectedElement(board, nextSelected);
4185
+ }
4186
+ }
4187
+ return getDeletedFragment(data);
4188
+ };
4189
+ board.setFragment = (data, rectangle) => {
4190
+ const targetMindElements = getSelectedMindElements(board);
4191
+ const firstLevelElements = getFirstLevelElement(targetMindElements);
4192
+ if (firstLevelElements.length) {
4193
+ const elements = buildClipboardData(board, firstLevelElements, rectangle ? [rectangle.x, rectangle.y] : [0, 0]);
4194
+ setMindClipboardData(data, elements);
4195
+ }
4196
+ setFragment(data, rectangle);
4197
+ };
4198
+ board.insertFragment = (data, targetPoint) => {
4199
+ const elements = getDataFromClipboard(data);
4200
+ const mindElements = elements.filter(value => MindElement.isMindElement(board, value));
4201
+ if (elements.length > 0 && mindElements.length > 0) {
4202
+ insertClipboardData(board, mindElements, targetPoint);
4203
+ }
4204
+ else if (elements.length === 0) {
4205
+ const mindElements = getSelectedMindElements(board);
4206
+ if (mindElements.length === 1) {
4207
+ const text = getTextFromClipboard(data);
4208
+ if (text) {
4209
+ insertClipboardText(board, mindElements[0], buildText(text));
4210
+ return;
4211
+ }
4212
+ }
4213
+ }
4214
+ insertFragment(data, targetPoint);
4215
+ };
4216
+ return board;
4217
+ };
4218
+ const getNextSelectedElement = (board, firstLevelElements) => {
4219
+ let activeElement;
4220
+ const firstLevelElement = firstLevelElements[0];
4221
+ const firstLevelElementPath = PlaitBoard.findPath(board, firstLevelElement);
4222
+ let nextSelectedPath = firstLevelElementPath;
4223
+ if (Path.hasPrevious(firstLevelElementPath)) {
4224
+ nextSelectedPath = Path.previous(firstLevelElementPath);
4225
+ }
4226
+ if (AbstractNode.isAbstract(firstLevelElement)) {
4227
+ const parent = MindElement.getParent(firstLevelElement);
4228
+ if (!firstLevelElements.includes(parent.children[firstLevelElement.start])) {
4229
+ activeElement = parent.children[firstLevelElement.start];
4230
+ }
4231
+ }
4232
+ try {
4233
+ if (!activeElement) {
4234
+ activeElement = PlaitNode.get(board, nextSelectedPath);
4235
+ }
4236
+ }
4237
+ catch (error) { }
4238
+ const firstElement = firstLevelElements[0];
4239
+ const firstElementParent = MindElement.findParent(firstElement);
4240
+ const hasSameParent = firstLevelElements.every(element => {
4241
+ return MindElement.findParent(element) === firstElementParent;
4242
+ });
4243
+ if (firstElementParent && hasSameParent && !activeElement) {
4244
+ activeElement = firstElementParent;
4245
+ }
4246
+ return activeElement;
4247
+ };
4248
+
4248
4249
  const withMind = (baseBoard) => {
4249
4250
  const board = baseBoard;
4250
- const { drawElement, dblclick, insertFragment, setFragment, isHitSelection, getRectangle, isMovable, isRecursion } = board;
4251
+ const { drawElement, dblclick, isHitSelection, getRectangle, isMovable, isRecursion } = board;
4251
4252
  board.drawElement = (context) => {
4252
4253
  if (PlaitMind.isMind(context.element)) {
4253
4254
  return PlaitMindComponent;
@@ -4311,41 +4312,14 @@ const withMind = (baseBoard) => {
4311
4312
  }
4312
4313
  dblclick(event);
4313
4314
  };
4314
- board.setFragment = (data, rectangle) => {
4315
- const targetMindElements = getSelectedMindElements(board);
4316
- const firstLevelElements = getFirstLevelElement(targetMindElements);
4317
- if (firstLevelElements.length) {
4318
- const elements = buildClipboardData(board, firstLevelElements, rectangle ? [rectangle.x, rectangle.y] : [0, 0]);
4319
- setMindClipboardData(data, elements);
4320
- }
4321
- setFragment(data, rectangle);
4322
- };
4323
- board.insertFragment = (data, targetPoint) => {
4324
- const elements = getDataFromClipboard(data);
4325
- const mindElements = elements.filter(value => MindElement.isMindElement(board, value));
4326
- if (elements.length > 0 && mindElements.length > 0) {
4327
- insertClipboardData(board, mindElements, targetPoint);
4328
- }
4329
- else if (elements.length === 0) {
4330
- const mindElements = getSelectedMindElements(board);
4331
- if (mindElements.length === 1) {
4332
- const text = getTextFromClipboard(data);
4333
- if (text) {
4334
- insertClipboardText(board, mindElements[0], buildText(text));
4335
- return;
4336
- }
4337
- }
4338
- }
4339
- insertFragment(data, targetPoint);
4340
- };
4341
- return withNodeResize(withNodeImageResize(withNodeImage(withNodeHoverDetect(withMindHotkey(withMindExtend(withCreateMind(withAbstract(withNodeDnd(board)))))))));
4315
+ return withNodeResize(withNodeImageResize(withNodeImage(withNodeHoverDetect(withMindFragment(withMindHotkey(withMindExtend(withCreateMind(withAbstract(withNodeDnd(board))))))))));
4342
4316
  };
4343
4317
 
4344
4318
  class MindEmojiBaseComponent {
4345
4319
  get nativeElement() {
4346
4320
  return this.elementRef.nativeElement;
4347
4321
  }
4348
- handleClick() {
4322
+ handlePointerDown() {
4349
4323
  const currentOptions = this.board.getPluginOptions(PlaitPluginKey.withSelection);
4350
4324
  this.board.setPluginOptions(PlaitPluginKey.withSelection, {
4351
4325
  isDisabledSelect: true
@@ -4362,7 +4336,7 @@ class MindEmojiBaseComponent {
4362
4336
  this.elementRef.nativeElement.style.fontSize = `${this.fontSize}px`;
4363
4337
  }
4364
4338
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.3", ngImport: i0, type: MindEmojiBaseComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); }
4365
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.3", type: MindEmojiBaseComponent, inputs: { fontSize: "fontSize", emojiItem: "emojiItem", board: "board", element: "element" }, host: { listeners: { "mousedown": "handleClick()" }, classAttribute: "mind-node-emoji" }, ngImport: i0 }); }
4339
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.3", type: MindEmojiBaseComponent, inputs: { fontSize: "fontSize", emojiItem: "emojiItem", board: "board", element: "element" }, host: { listeners: { "pointerdown": "handlePointerDown()" }, classAttribute: "mind-node-emoji" }, ngImport: i0 }); }
4366
4340
  }
4367
4341
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.3", ngImport: i0, type: MindEmojiBaseComponent, decorators: [{
4368
4342
  type: Directive,
@@ -4379,9 +4353,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.3", ngImpor
4379
4353
  type: Input
4380
4354
  }], element: [{
4381
4355
  type: Input
4382
- }], handleClick: [{
4356
+ }], handlePointerDown: [{
4383
4357
  type: HostListener,
4384
- args: ['mousedown']
4358
+ args: ['pointerdown']
4385
4359
  }] } });
4386
4360
 
4387
4361
  class MindImageBaseComponent {