@plait/mind 0.12.1 → 0.13.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.
@@ -1,7 +1,7 @@
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, 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, getHitElements, 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
6
  import { getTextSize, TEXT_DEFAULT_HEIGHT, TextManage, TextModule } from '@plait/text';
7
7
  import { fromEvent, Subject } from 'rxjs';
@@ -310,7 +310,10 @@ const isHitEmojis = (board, element, point) => {
310
310
 
311
311
  function getTopicRectangleByNode(board, node) {
312
312
  let nodeRectangle = getRectangleByNode(node);
313
- return getTopicRectangleByElement(board, nodeRectangle, node.origin);
313
+ const result = getTopicRectangleByElement(board, nodeRectangle, node.origin);
314
+ // add buffer width to avoid unexpected text breaks in different scene
315
+ result.width = result.width + 4;
316
+ return result;
314
317
  }
315
318
  function getTopicRectangleByElement(board, nodeRectangle, element) {
316
319
  const x = nodeRectangle.x + NodeSpace.getTextLeftSpace(board, element);
@@ -324,7 +327,7 @@ const NODE_MIN_WIDTH = 18;
324
327
 
325
328
  function editTopic(element) {
326
329
  const component = PlaitElement.getComponent(element);
327
- component.editTopic();
330
+ component?.editTopic();
328
331
  }
329
332
 
330
333
  const TOPIC_COLOR = '#333';
@@ -476,7 +479,6 @@ const extractNodesText = (node) => {
476
479
  }
477
480
  return str;
478
481
  };
479
- // layoutLevel 用来表示插入兄弟节点还是子节点
480
482
  const insertMindElement = (board, inheritNode, path) => {
481
483
  const newNode = {};
482
484
  if (!inheritNode.isRoot) {
@@ -2647,7 +2649,6 @@ class MindNodeComponent extends PlaitPluginElementComponent {
2647
2649
  const plugins = this.board.getMindOptions().textPlugins;
2648
2650
  this.textManage = new TextManage(this.board, this.viewContainerRef, () => {
2649
2651
  const rect = getTopicRectangleByNode(this.board, this.node);
2650
- rect.width = rect.width + WIDTH_BUFFER;
2651
2652
  return rect;
2652
2653
  }, (point) => {
2653
2654
  return isHitMindElement(this.board, point, this.element);
@@ -2959,33 +2960,29 @@ const withNodeDnd = (board) => {
2959
2960
  mousedown(event);
2960
2961
  return;
2961
2962
  }
2962
- // 确认是否 hit 节点
2963
2963
  const point = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
2964
2964
  const selectedElements = getSelectedElements(board);
2965
- depthFirstRecursion(board, element => {
2966
- if (activeElements.length || !MindElement.isMindElement(board, element)) {
2967
- return;
2968
- }
2969
- const isHitElement = isHitMindElement(board, point, element) && !element.isRoot && !AbstractNode.isAbstract(element);
2970
- const isAllMindElement = selectedElements.every(element => MindElement.isMindElement(board, element));
2971
- const isMultiple = isHitElement && selectedElements.length > 1 && selectedElements.includes(element) && isAllMindElement;
2972
- const isSingle = isHitElement && !(selectedElements.length > 1 && selectedElements.includes(element));
2973
- if (isSingle) {
2974
- activeElements = [element];
2965
+ const hitTarget = getHitElements(board, { ranges: [{ anchor: point, focus: point }] }, (element) => {
2966
+ return MindElement.isMindElement(board, element);
2967
+ });
2968
+ const targetElement = hitTarget && hitTarget.length === 1 ? hitTarget[0] : null;
2969
+ if (targetElement &&
2970
+ MindElement.isMindElement(board, targetElement) &&
2971
+ !targetElement.isRoot &&
2972
+ !AbstractNode.isAbstract(targetElement)) {
2973
+ const targetElements = selectedElements.filter(element => MindElement.isMindElement(board, element) && !element.isRoot && !AbstractNode.isAbstract(element));
2974
+ const isMultiple = selectedElements.length > 0 && selectedElements.includes(targetElement);
2975
+ const isSingle = !isMultiple && selectedElements.length === 0;
2976
+ if (isMultiple) {
2977
+ activeElements = targetElements;
2975
2978
  startPoint = point;
2976
2979
  }
2977
- else if (isMultiple) {
2978
- activeElements = selectedElements;
2980
+ else if (isSingle) {
2981
+ activeElements = [targetElement];
2979
2982
  startPoint = point;
2980
2983
  }
2981
- }, node => {
2982
- if (PlaitBoard.isBoard(node) || board.isRecursion(node)) {
2983
- return true;
2984
- }
2985
- else {
2986
- return false;
2987
- }
2988
- });
2984
+ event.preventDefault();
2985
+ }
2989
2986
  if (activeElements.length) {
2990
2987
  correspondingElements = getOverallAbstracts(board, activeElements);
2991
2988
  event.preventDefault();
@@ -3236,12 +3233,12 @@ const withAbstract = (board) => {
3236
3233
  const point = transformPoint(board, toPoint(event.x, event.y, host));
3237
3234
  activeAbstractElement = activeAbstractElements.find(element => {
3238
3235
  abstractHandlePosition = getHitAbstractHandle(board, element, point);
3239
- if (newBoard?.onAbstractResize) {
3240
- newBoard.onAbstractResize(AbstractResizeState.start);
3241
- }
3242
3236
  return abstractHandlePosition;
3243
3237
  });
3244
3238
  if (activeAbstractElement) {
3239
+ if (newBoard?.onAbstractResize) {
3240
+ newBoard.onAbstractResize(AbstractResizeState.start);
3241
+ }
3245
3242
  startPoint = point;
3246
3243
  return;
3247
3244
  }
@@ -3434,27 +3431,104 @@ const withCreateMind = (board) => {
3434
3431
 
3435
3432
  const withMindHotkey = (board) => {
3436
3433
  const { keydown } = board;
3437
- board.keydown = (keyboardEvent) => {
3438
- if (!PlaitBoard.getMovingPoint(board)) {
3439
- return;
3434
+ board.keydown = (event) => {
3435
+ const selectedElements = getSelectedElements(board);
3436
+ const isSingleSelection = selectedElements.length === 1;
3437
+ const isSingleMindElement = selectedElements.length === 1 && MindElement.isMindElement(board, selectedElements[0]);
3438
+ const targetElement = selectedElements[0];
3439
+ if (isExpandHotkey(event) && isSingleMindElement && !PlaitMind.isMind(targetElement)) {
3440
+ if (targetElement.children && targetElement.children.length > 0) {
3441
+ Transforms.setNode(board, { isCollapsed: targetElement.isCollapsed ? false : true }, PlaitBoard.findPath(board, targetElement));
3442
+ return;
3443
+ }
3440
3444
  }
3441
- if (isExpandHotkey(keyboardEvent)) {
3442
- const selectedMindElements = getSelectedElements(board).filter(element => MindElement.isMindElement(board, element));
3443
- if (selectedMindElements.length === 1 &&
3444
- !PlaitMind.isMind(selectedMindElements[0]) &&
3445
- selectedMindElements[0].children &&
3446
- selectedMindElements[0].children.length > 0) {
3447
- const element = selectedMindElements[0];
3448
- Transforms.setNode(board, { isCollapsed: element.isCollapsed ? false : true }, PlaitBoard.findPath(board, element));
3445
+ if (!PlaitBoard.isReadonly(board)) {
3446
+ if (isTabHotkey(event) && isSingleMindElement) {
3447
+ event.preventDefault();
3448
+ removeSelectedElement(board, targetElement);
3449
+ const targetElementPath = PlaitBoard.findPath(board, targetElement);
3450
+ if (targetElement.isCollapsed) {
3451
+ const newElement = { isCollapsed: false };
3452
+ PlaitHistoryBoard.withoutSaving(board, () => {
3453
+ Transforms.setNode(board, newElement, targetElementPath);
3454
+ });
3455
+ }
3456
+ insertMindElement(board, targetElement, findNewChildNodePath(board, targetElement));
3457
+ return;
3458
+ }
3459
+ if (isEnterHotkey(event) &&
3460
+ isSingleMindElement &&
3461
+ !PlaitMind.isMind(targetElement) &&
3462
+ !AbstractNode.isAbstract(targetElement)) {
3463
+ const targetElementPath = PlaitBoard.findPath(board, targetElement);
3464
+ if (isInRightBranchOfStandardLayout(targetElement)) {
3465
+ const refs = insertElementHandleRightNodeCount(board, targetElementPath.slice(0, 1), 1);
3466
+ MindTransforms.setRightNodeCountByRefs(board, refs);
3467
+ }
3468
+ const abstractRefs = insertElementHandleAbstract(board, Path.next(targetElementPath));
3469
+ MindTransforms.setAbstractsByRefs(board, abstractRefs);
3470
+ insertMindElement(board, targetElement, findNewSiblingNodePath(board, targetElement));
3471
+ return;
3472
+ }
3473
+ if (selectedElements.length > 0 && (hotkeys.isDeleteBackward(event) || hotkeys.isDeleteForward(event))) {
3474
+ event.preventDefault();
3475
+ const targetMindElements = selectedElements.filter(el => MindElement.isMindElement(board, el));
3476
+ const firstLevelElements = getFirstLevelElement(targetMindElements);
3477
+ const deletableElements = firstLevelElements.reverse();
3478
+ const abstractRefs = deleteElementHandleAbstract(board, deletableElements);
3479
+ MindTransforms.setAbstractsByRefs(board, abstractRefs);
3480
+ const refs = deleteElementsHandleRightNodeCount(board, targetMindElements);
3481
+ MindTransforms.setRightNodeCountByRefs(board, refs);
3482
+ MindTransforms.removeElements(board, targetMindElements);
3483
+ let activeElement;
3484
+ if (AbstractNode.isAbstract(firstLevelElements[0])) {
3485
+ const parent = MindElement.getParent(firstLevelElements[0]);
3486
+ activeElement = parent.children[firstLevelElements[0].start];
3487
+ }
3488
+ const firstElement = firstLevelElements[0];
3489
+ const firstElementParent = MindElement.findParent(firstElement);
3490
+ const hasSameParent = firstLevelElements.every(element => {
3491
+ return MindElement.findParent(element) === firstElementParent;
3492
+ });
3493
+ if (firstElementParent && hasSameParent && !activeElement) {
3494
+ const firstElementIndex = firstElementParent.children.indexOf(firstElement);
3495
+ const childrenCount = firstElementParent.children.length;
3496
+ // active parent element
3497
+ if (childrenCount === firstLevelElements.length) {
3498
+ activeElement = firstElementParent;
3499
+ }
3500
+ else {
3501
+ if (firstElementIndex > 0) {
3502
+ activeElement = firstElementParent.children[firstElementIndex - 1];
3503
+ }
3504
+ }
3505
+ }
3506
+ if (activeElement) {
3507
+ addSelectedElement(board, activeElement);
3508
+ }
3509
+ return;
3510
+ }
3511
+ if (!isVirtualKey(event) && !isSpaceHotkey(event) && isSingleSelection) {
3512
+ event.preventDefault();
3513
+ editTopic(targetElement);
3449
3514
  return;
3450
3515
  }
3451
3516
  }
3452
- keydown(keyboardEvent);
3517
+ keydown(event);
3453
3518
  };
3454
3519
  return board;
3455
3520
  };
3456
- const isExpandHotkey = (keyboardEvent) => {
3457
- return isKeyHotkey('mod+/', keyboardEvent);
3521
+ const isExpandHotkey = (event) => {
3522
+ return isKeyHotkey('mod+/', event);
3523
+ };
3524
+ const isTabHotkey = (event) => {
3525
+ return event.key === 'Tab';
3526
+ };
3527
+ const isEnterHotkey = (event) => {
3528
+ return event.key === 'Enter';
3529
+ };
3530
+ const isSpaceHotkey = (event) => {
3531
+ return event.code === 'Space';
3458
3532
  };
3459
3533
 
3460
3534
  const withNodeHover = (board) => {
@@ -3570,92 +3644,6 @@ const withMind = (board) => {
3570
3644
  }
3571
3645
  return isMovable(element);
3572
3646
  };
3573
- board.keydown = (event) => {
3574
- if (PlaitBoard.isReadonly(board)) {
3575
- keydown(event);
3576
- return;
3577
- }
3578
- const selectedElements = getSelectedElements(board);
3579
- if (selectedElements.length) {
3580
- if (selectedElements.length === 1 &&
3581
- (event.key === 'Tab' ||
3582
- (event.key === 'Enter' && !selectedElements[0].isRoot && !AbstractNode.isAbstract(selectedElements[0])))) {
3583
- event.preventDefault();
3584
- const selectedElement = selectedElements[0];
3585
- removeSelectedElement(board, selectedElement);
3586
- const selectedElementPath = PlaitBoard.findPath(board, selectedElement);
3587
- if (event.key === 'Tab') {
3588
- if (selectedElement.isCollapsed) {
3589
- const newElement = { isCollapsed: false };
3590
- PlaitHistoryBoard.withoutSaving(board, () => {
3591
- Transforms.setNode(board, newElement, selectedElementPath);
3592
- });
3593
- }
3594
- insertMindElement(board, selectedElement, findNewChildNodePath(board, selectedElement));
3595
- }
3596
- else {
3597
- if (isInRightBranchOfStandardLayout(selectedElement)) {
3598
- const refs = insertElementHandleRightNodeCount(board, selectedElementPath.slice(0, 1), 1);
3599
- MindTransforms.setRightNodeCountByRefs(board, refs);
3600
- }
3601
- const abstractRefs = insertElementHandleAbstract(board, Path.next(selectedElementPath));
3602
- MindTransforms.setAbstractsByRefs(board, abstractRefs);
3603
- insertMindElement(board, selectedElement, findNewSiblingNodePath(board, selectedElement));
3604
- }
3605
- return;
3606
- }
3607
- if (hotkeys.isDeleteBackward(event) || hotkeys.isDeleteForward(event)) {
3608
- event.preventDefault();
3609
- const deletableElements = getFirstLevelElement(selectedElements).reverse();
3610
- const abstractRefs = deleteElementHandleAbstract(board, deletableElements);
3611
- MindTransforms.setAbstractsByRefs(board, abstractRefs);
3612
- const refs = deleteElementsHandleRightNodeCount(board, selectedElements);
3613
- MindTransforms.setRightNodeCountByRefs(board, refs);
3614
- MindTransforms.removeElements(board, selectedElements);
3615
- let activeElement;
3616
- const firstLevelElements = getFirstLevelElement(selectedElements);
3617
- if (AbstractNode.isAbstract(firstLevelElements[0])) {
3618
- const parent = MindElement.getParent(firstLevelElements[0]);
3619
- activeElement = parent.children[firstLevelElements[0].start];
3620
- }
3621
- const firstElement = firstLevelElements[0];
3622
- const firstElementParent = MindElement.findParent(firstElement);
3623
- const hasSameParent = firstLevelElements.every(element => {
3624
- return MindElement.findParent(element) === firstElementParent;
3625
- });
3626
- if (firstElementParent && hasSameParent && !activeElement) {
3627
- const firstElementIndex = firstElementParent.children.indexOf(firstElement);
3628
- const childrenCount = firstElementParent.children.length;
3629
- // active parent element
3630
- if (childrenCount === firstLevelElements.length) {
3631
- activeElement = firstElementParent;
3632
- }
3633
- else {
3634
- if (firstElementIndex > 0) {
3635
- activeElement = firstElementParent.children[firstElementIndex - 1];
3636
- }
3637
- }
3638
- }
3639
- if (activeElement) {
3640
- addSelectedElement(board, activeElement);
3641
- }
3642
- return;
3643
- }
3644
- // auto enter edit status
3645
- if (!isVirtualKey(event)) {
3646
- event.preventDefault();
3647
- const selectedElement = selectedElements[0];
3648
- editTopic(selectedElement);
3649
- return;
3650
- }
3651
- }
3652
- if (board.selection && event.code === 'Space') {
3653
- if (selectedElements?.length) {
3654
- return;
3655
- }
3656
- }
3657
- keydown(event);
3658
- };
3659
3647
  board.dblclick = (event) => {
3660
3648
  if (PlaitBoard.isReadonly(board)) {
3661
3649
  dblclick(event);