@plait/mind 0.25.0 → 0.27.0-next.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,10 +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, idCreator, isNullOrUndefined, Transforms, clearSelectedElement, addSelectedElement, PlaitBoard, Path, PlaitNode, PlaitContextService, depthFirstRecursion, getIsRecursionFunc, drawLinearPath, drawBezierPath, createG, updateForeignObject, drawRoundRectangle, getRectangleByElements, getSelectedElements, NODE_TO_PARENT, distanceBetweenPointAndRectangle, createForeignObject, createText, PlaitPointerType, PlaitPluginElementComponent, NODE_TO_INDEX, PlaitModule, isMainPointer, transformPoint, toPoint, getHitElements, distanceBetweenPointAndPoint, CLIP_BOARD_FORMAT_KEY, CLIP_BOARD_IMAGE_FORMAT_KEY, BOARD_TO_HOST, throttleRAF, BoardTransforms, removeSelectedElement, PlaitHistoryBoard, hotkeys, PRESS_AND_MOVE_BUFFER, MERGING, ResizeCursorClass } 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, createText, PlaitPointerType, PlaitPluginElementComponent, NODE_TO_INDEX, PlaitModule, isMainPointer, transformPoint, toPoint, getHitElements, distanceBetweenPointAndPoint, setClipboardData, setClipboardDataByText, BOARD_TO_HOST, throttleRAF, BoardTransforms, removeSelectedElement, PlaitHistoryBoard, hotkeys, setClipboardDataByMedia, getClipboardDataByMedia, ResizeCursorClass, preventTouchMove, PRESS_AND_MOVE_BUFFER, MERGING, getDataFromClipboard } from '@plait/core';
5
5
  import { MindLayoutType, isIndentedLayout, AbstractNode, isStandardLayout, isHorizontalLogicLayout, isVerticalLogicLayout, getNonAbstractChildren, isLeftLayout, isRightLayout, isTopLayout, isBottomLayout, isHorizontalLayout, getCorrectStartEnd, ConnectingPosition, 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, getRectangleResizeTargets, MediaKeys, ResizeDirection, withResize, ActiveGenerator } from '@plait/common';
8
9
  import { Node as Node$1, Path as Path$1 } from 'slate';
9
10
  import { isKeyHotkey } from 'is-hotkey';
10
11
  import { pointsOnBezierCurves } from 'points-on-curve';
@@ -409,11 +410,20 @@ function getImageForeignRectangle(board, element) {
409
410
  width,
410
411
  height
411
412
  };
412
- return RectangleClient.getOutlineRectangle(rectangle, -6);
413
+ return rectangle;
413
414
  }
414
415
  const isHitImage = (board, element, range) => {
415
- const client = getImageForeignRectangle(board, element);
416
- return RectangleClient.isHit(RectangleClient.toRectangleClient([range.anchor, range.focus]), client);
416
+ const imageRectangle = getImageForeignRectangle(board, element);
417
+ const imageOutlineRectangle = RectangleClient.getOutlineRectangle(imageRectangle, -RESIZE_HANDLE_DIAMETER / 2);
418
+ return RectangleClient.isHit(RectangleClient.toRectangleClient([range.anchor, range.focus]), imageOutlineRectangle);
419
+ };
420
+ const getHitImageResizeHandleDirection = (board, element, point) => {
421
+ const imageRectangle = getImageForeignRectangle(board, element);
422
+ const resizeTargets = getRectangleResizeTargets(imageRectangle, RESIZE_HANDLE_DIAMETER);
423
+ const result = resizeTargets.find(resizeTarget => {
424
+ return RectangleClient.isHit(RectangleClient.toRectangleClient([point, point]), resizeTarget.rectangle);
425
+ });
426
+ return result;
417
427
  };
418
428
 
419
429
  function editTopic(element) {
@@ -429,6 +439,10 @@ const temporaryDisableSelection = (board) => {
429
439
  board.setPluginOptions(PlaitPluginKey.withSelection, { ...currentOptions });
430
440
  }, 0);
431
441
  };
442
+ const getSelectedMindElements = (board) => {
443
+ const selectedElements = getSelectedElements(board).filter(value => MindElement.isMindElement(board, value));
444
+ return selectedElements;
445
+ };
432
446
 
433
447
  const createEmptyMind = (point) => {
434
448
  const element = createMindElement('思维导图', 72, ROOT_TOPIC_HEIGHT, { layout: MindLayoutType.right });
@@ -2373,9 +2387,7 @@ const MindElement = {
2373
2387
  return isIndentedLayout(_layout);
2374
2388
  },
2375
2389
  isMindElement(board, element) {
2376
- const path = PlaitBoard.findPath(board, element);
2377
- const rootElement = PlaitNode.get(board, path.slice(0, 1));
2378
- if (PlaitMind.isMind(rootElement)) {
2390
+ if (element.data && element.data.topic && element.width && element.height) {
2379
2391
  return true;
2380
2392
  }
2381
2393
  else {
@@ -3002,7 +3014,6 @@ class NodeImageDrawer {
3002
3014
  this.g = createG();
3003
3015
  const foreignRectangle = getImageForeignRectangle(this.board, element);
3004
3016
  this.foreignObject = createForeignObject(foreignRectangle.x, foreignRectangle.y, foreignRectangle.width, foreignRectangle.height);
3005
- this.foreignObject.style.padding = `6px`;
3006
3017
  this.g.append(this.foreignObject);
3007
3018
  const componentType = this.board.getPluginOptions(WithMindPluginKey).imageComponentType;
3008
3019
  if (!componentType) {
@@ -3065,19 +3076,23 @@ class MindNodeComponent extends PlaitPluginElementComponent {
3065
3076
  this.collapseDrawer = new CollapseDrawer(this.board);
3066
3077
  this.imageDrawer = new NodeImageDrawer(this.board, this.viewContainerRef);
3067
3078
  const plugins = this.board.getPluginOptions(WithMindPluginKey).textPlugins;
3068
- this.textManage = new TextManage(this.board, this.viewContainerRef, () => {
3069
- const rect = getTopicRectangleByNode(this.board, this.node);
3070
- return rect;
3071
- }, (textManageRef) => {
3072
- const width = textManageRef.width;
3073
- const height = textManageRef.height;
3074
- if (textManageRef.newValue) {
3075
- MindTransforms.setTopic(this.board, this.element, textManageRef.newValue, width, height);
3076
- }
3077
- else {
3078
- MindTransforms.setTopicSize(this.board, this.element, width, height);
3079
- }
3080
- }, plugins);
3079
+ this.textManage = new TextManage(this.board, this.viewContainerRef, {
3080
+ getRectangle: () => {
3081
+ const rect = getTopicRectangleByNode(this.board, this.node);
3082
+ return rect;
3083
+ },
3084
+ onValueChangeHandle: (textManageRef) => {
3085
+ const width = textManageRef.width;
3086
+ const height = textManageRef.height;
3087
+ if (textManageRef.newValue) {
3088
+ MindTransforms.setTopic(this.board, this.element, textManageRef.newValue, width, height);
3089
+ }
3090
+ else {
3091
+ MindTransforms.setTopicSize(this.board, this.element, width, height);
3092
+ }
3093
+ },
3094
+ textPlugins: plugins
3095
+ });
3081
3096
  }
3082
3097
  ngOnInit() {
3083
3098
  super.ngOnInit();
@@ -3320,7 +3335,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImpor
3320
3335
 
3321
3336
  const DRAG_MOVE_BUFFER = 5;
3322
3337
  const withNodeDnd = (board) => {
3323
- const { mousedown, mousemove, globalMouseup } = board;
3338
+ const { pointerDown, pointerMove, globalPointerUp } = board;
3324
3339
  let activeElements = [];
3325
3340
  let correspondingElements = [];
3326
3341
  let startPoint;
@@ -3328,12 +3343,12 @@ const withNodeDnd = (board) => {
3328
3343
  let fakeDropNodeG;
3329
3344
  let dropTarget = null;
3330
3345
  let targetPath;
3331
- board.mousedown = (event) => {
3346
+ board.pointerDown = (event) => {
3332
3347
  if (PlaitBoard.isReadonly(board) ||
3333
3348
  PlaitBoard.hasBeenTextEditing(board) ||
3334
3349
  !PlaitBoard.isPointer(board, PlaitPointerType.selection) ||
3335
3350
  !isMainPointer(event)) {
3336
- mousedown(event);
3351
+ pointerDown(event);
3337
3352
  return;
3338
3353
  }
3339
3354
  const point = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
@@ -3358,14 +3373,14 @@ const withNodeDnd = (board) => {
3358
3373
  }
3359
3374
  }
3360
3375
  if (activeElements.length) {
3361
- // prevent text from being selected
3362
- event.preventDefault();
3363
3376
  correspondingElements = getOverallAbstracts(board, activeElements);
3364
3377
  }
3365
- mousedown(event);
3378
+ pointerDown(event);
3366
3379
  };
3367
- board.mousemove = (event) => {
3380
+ board.pointerMove = (event) => {
3368
3381
  if (!board.options.readonly && activeElements?.length && startPoint) {
3382
+ // prevent text from being selected
3383
+ event.preventDefault();
3369
3384
  const endPoint = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
3370
3385
  const distance = distanceBetweenPointAndPoint(startPoint[0], startPoint[1], endPoint[0], endPoint[1]);
3371
3386
  if (distance < DRAG_MOVE_BUFFER) {
@@ -3393,9 +3408,9 @@ const withNodeDnd = (board) => {
3393
3408
  });
3394
3409
  PlaitBoard.getHost(board).appendChild(dragFakeNodeG);
3395
3410
  }
3396
- mousemove(event);
3411
+ pointerMove(event);
3397
3412
  };
3398
- board.globalMouseup = (event) => {
3413
+ board.globalPointerUp = (event) => {
3399
3414
  const firstLevelElements = getFirstLevelElement(activeElements);
3400
3415
  if (!board.options.readonly && firstLevelElements.length) {
3401
3416
  firstLevelElements.push(...correspondingElements);
@@ -3484,12 +3499,12 @@ const withNodeDnd = (board) => {
3484
3499
  fakeDropNodeG = undefined;
3485
3500
  dropTarget = null;
3486
3501
  }
3487
- globalMouseup(event);
3502
+ globalPointerUp(event);
3488
3503
  };
3489
3504
  return board;
3490
3505
  };
3491
3506
 
3492
- const buildClipboardData = (board, selectedElements) => {
3507
+ const buildClipboardData = (board, selectedElements, startPoint) => {
3493
3508
  let result = [];
3494
3509
  // get overall abstract
3495
3510
  const overallAbstracts = getOverallAbstracts(board, selectedElements);
@@ -3499,11 +3514,10 @@ const buildClipboardData = (board, selectedElements) => {
3499
3514
  const newSelectedElements = selectedElements.filter(value => !validAbstractRefs.find(ref => ref.abstract === value));
3500
3515
  newSelectedElements.push(...validAbstractRefs.map(value => value.abstract));
3501
3516
  const selectedMindNodes = newSelectedElements.map(value => MindElement.getNode(value));
3502
- const nodesRectangle = getRectangleByElements(board, newSelectedElements, true);
3503
3517
  newSelectedElements.forEach((element, index) => {
3504
3518
  // handle relative location
3505
3519
  const nodeRectangle = getRectangleByNode(selectedMindNodes[index]);
3506
- const points = [[nodeRectangle.x - nodesRectangle.x, nodeRectangle.y - nodesRectangle.y]];
3520
+ const points = [[nodeRectangle.x - startPoint[0], nodeRectangle.y - startPoint[1]]];
3507
3521
  // handle invalid abstract
3508
3522
  const abstractRef = validAbstractRefs.find(ref => ref.abstract === element);
3509
3523
  if (AbstractNode.isAbstract(element) && abstractRef) {
@@ -3532,37 +3546,12 @@ const buildClipboardData = (board, selectedElements) => {
3532
3546
  });
3533
3547
  return result;
3534
3548
  };
3535
- const setClipboardData = (data, elements) => {
3536
- const stringObj = JSON.stringify(elements);
3537
- const encoded = window.btoa(encodeURIComponent(stringObj));
3549
+ const setMindClipboardData = (data, elements) => {
3538
3550
  const text = elements.reduce((string, currentNode) => {
3539
3551
  return string + extractNodesText(currentNode);
3540
3552
  }, '');
3541
- data?.setData(`application/${CLIP_BOARD_FORMAT_KEY}`, encoded);
3542
- data?.setData(`text/plain`, text);
3543
- };
3544
- const setClipboardDataByImage = (data, image) => {
3545
- const stringObj = JSON.stringify(image);
3546
- const encoded = window.btoa(encodeURIComponent(stringObj));
3547
- data?.setData(`application/${CLIP_BOARD_IMAGE_FORMAT_KEY}`, encoded);
3548
- };
3549
- const getImageItemFromClipboard = (data) => {
3550
- const encoded = data?.getData(`application/${CLIP_BOARD_IMAGE_FORMAT_KEY}`);
3551
- let imageItem = null;
3552
- if (encoded) {
3553
- const decoded = decodeURIComponent(window.atob(encoded));
3554
- imageItem = JSON.parse(decoded);
3555
- }
3556
- return imageItem;
3557
- };
3558
- const getDataFromClipboard = (data) => {
3559
- const encoded = data?.getData(`application/${CLIP_BOARD_FORMAT_KEY}`);
3560
- let nodesData = [];
3561
- if (encoded) {
3562
- const decoded = decodeURIComponent(window.atob(encoded));
3563
- nodesData = JSON.parse(decoded);
3564
- }
3565
- return nodesData;
3553
+ setClipboardData(data, elements);
3554
+ setClipboardDataByText(data, text);
3566
3555
  };
3567
3556
  const insertClipboardData = (board, elements, targetPoint) => {
3568
3557
  let newElement, path;
@@ -3638,8 +3627,6 @@ const withAbstract = (board) => {
3638
3627
  return abstractHandlePosition;
3639
3628
  });
3640
3629
  if (activeAbstractElement) {
3641
- // prevent text from being selected
3642
- event.preventDefault();
3643
3630
  if (newBoard?.onAbstractResize) {
3644
3631
  newBoard.onAbstractResize(AbstractResizeState.start);
3645
3632
  }
@@ -3654,6 +3641,8 @@ const withAbstract = (board) => {
3654
3641
  const endPoint = transformPoint(board, toPoint(event.x, event.y, host));
3655
3642
  touchedAbstract = handleTouchedAbstract(board, touchedAbstract, endPoint);
3656
3643
  if (abstractHandlePosition && activeAbstractElement) {
3644
+ // prevent text from being selected
3645
+ event.preventDefault();
3657
3646
  const abstractComponent = PlaitElement.getComponent(activeAbstractElement);
3658
3647
  const element = abstractComponent.element;
3659
3648
  const nodeLayout = MindQueries.getCorrectLayoutByElement(board, activeAbstractElement);
@@ -3763,8 +3752,10 @@ const withCreateMind = (board) => {
3763
3752
  const nodeG = drawRoundRectangleByElement(board, nodeRectangle, emptyMind);
3764
3753
  const topicRectangle = getTopicRectangleByElement(newBoard, nodeRectangle, emptyMind);
3765
3754
  if (!fakeCreateNodeRef) {
3766
- const textManage = new TextManage(board, PlaitBoard.getComponent(board).viewContainerRef, () => {
3767
- return topicRectangle;
3755
+ const textManage = new TextManage(board, PlaitBoard.getComponent(board).viewContainerRef, {
3756
+ getRectangle: () => {
3757
+ return topicRectangle;
3758
+ }
3768
3759
  });
3769
3760
  PlaitBoard.getComponent(board)
3770
3761
  .viewContainerRef.injector.get(NgZone)
@@ -3833,7 +3824,7 @@ const withCreateMind = (board) => {
3833
3824
 
3834
3825
  const withMindHotkey = (baseBoard) => {
3835
3826
  const board = baseBoard;
3836
- const { keydown } = board;
3827
+ const { keydown, deleteFragment } = board;
3837
3828
  board.keydown = (event) => {
3838
3829
  const selectedElements = getSelectedElements(board);
3839
3830
  const isSingleSelection = selectedElements.length === 1;
@@ -3873,24 +3864,6 @@ const withMindHotkey = (baseBoard) => {
3873
3864
  insertMindElement(board, targetElement, findNewSiblingNodePath(board, targetElement));
3874
3865
  return;
3875
3866
  }
3876
- if (selectedElements.length > 0 && (hotkeys.isDeleteBackward(event) || hotkeys.isDeleteForward(event))) {
3877
- event.preventDefault();
3878
- const targetMindElements = selectedElements.filter(el => MindElement.isMindElement(board, el));
3879
- const firstLevelElements = getFirstLevelElement(targetMindElements);
3880
- if (firstLevelElements.length > 0) {
3881
- const deletableElements = [...firstLevelElements].reverse();
3882
- const abstractRefs = deleteElementHandleAbstract(board, deletableElements);
3883
- MindTransforms.setAbstractsByRefs(board, abstractRefs);
3884
- const refs = deleteElementsHandleRightNodeCount(board, targetMindElements);
3885
- MindTransforms.setRightNodeCountByRefs(board, refs);
3886
- MindTransforms.removeElements(board, targetMindElements);
3887
- const nextSelected = getNextSelectedElement(board, firstLevelElements);
3888
- if (nextSelected) {
3889
- addSelectedElement(board, nextSelected);
3890
- }
3891
- }
3892
- return;
3893
- }
3894
3867
  if (!isVirtualKey(event) && !isSpaceHotkey(event) && isSingleSelection) {
3895
3868
  event.preventDefault();
3896
3869
  editTopic(targetElement);
@@ -3899,6 +3872,22 @@ const withMindHotkey = (baseBoard) => {
3899
3872
  }
3900
3873
  keydown(event);
3901
3874
  };
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
+ };
3902
3891
  return board;
3903
3892
  };
3904
3893
  const getNextSelectedElement = (board, firstLevelElements) => {
@@ -4011,24 +4000,24 @@ const withNodeHoverDetect = (board) => {
4011
4000
  };
4012
4001
 
4013
4002
  const withNodeImage = (board) => {
4014
- const { keydown, mousedown, globalMouseup, setFragment, insertFragment, deleteFragment } = board;
4015
- board.mousedown = (event) => {
4003
+ const { keydown, pointerDown, globalPointerUp, setFragment, insertFragment, deleteFragment } = board;
4004
+ board.pointerDown = (event) => {
4016
4005
  const selectedImageElement = getSelectedImageElement(board);
4017
4006
  if (PlaitBoard.isReadonly(board) || !isMainPointer(event) || !PlaitBoard.isPointer(board, PlaitPointerType.selection)) {
4018
4007
  if (selectedImageElement) {
4019
4008
  setImageFocus(board, selectedImageElement, false);
4020
4009
  }
4021
- mousedown(event);
4010
+ pointerDown(event);
4022
4011
  return;
4023
4012
  }
4024
4013
  const point = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
4025
4014
  const range = { anchor: point, focus: point };
4026
- const hitElements = getHitElements(board, { ranges: [range] });
4027
- const hasImage = hitElements.length && MindElement.hasImage(hitElements[0]);
4028
- const hitImage = hasImage && isHitImage(board, hitElements[0], range);
4029
- if (selectedImageElement && hitImage && hitElements[0] === selectedImageElement) {
4015
+ const hitImageElements = getHitElements(board, { ranges: [range] }, (value) => MindElement.isMindElement(board, value) && MindElement.hasImage(value));
4016
+ const hasImage = hitImageElements.length;
4017
+ const hitImage = hasImage > 0 && isHitImage(board, hitImageElements[0], range);
4018
+ if (selectedImageElement && hitImage && hitImageElements[0] === selectedImageElement) {
4030
4019
  temporaryDisableSelection(board);
4031
- mousedown(event);
4020
+ pointerDown(event);
4032
4021
  return;
4033
4022
  }
4034
4023
  if (selectedImageElement) {
@@ -4036,9 +4025,9 @@ const withNodeImage = (board) => {
4036
4025
  }
4037
4026
  if (hitImage) {
4038
4027
  temporaryDisableSelection(board);
4039
- setImageFocus(board, hitElements[0], true);
4028
+ setImageFocus(board, hitImageElements[0], true);
4040
4029
  }
4041
- mousedown(event);
4030
+ pointerDown(event);
4042
4031
  };
4043
4032
  board.keydown = (event) => {
4044
4033
  const selectedImageElement = getSelectedImageElement(board);
@@ -4049,7 +4038,7 @@ const withNodeImage = (board) => {
4049
4038
  }
4050
4039
  keydown(event);
4051
4040
  };
4052
- board.globalMouseup = (event) => {
4041
+ board.globalPointerUp = (event) => {
4053
4042
  if (PlaitBoard.isFocus(board)) {
4054
4043
  const isInBoard = event.target instanceof Node && PlaitBoard.getBoardContainer(board).contains(event.target);
4055
4044
  const selectedImageElement = getSelectedImageElement(board);
@@ -4058,15 +4047,15 @@ const withNodeImage = (board) => {
4058
4047
  setImageFocus(board, selectedImageElement, false);
4059
4048
  }
4060
4049
  }
4061
- globalMouseup(event);
4050
+ globalPointerUp(event);
4062
4051
  };
4063
- board.setFragment = (data) => {
4052
+ board.setFragment = (data, rectangle) => {
4064
4053
  const selectedImageElement = getSelectedImageElement(board);
4065
4054
  if (selectedImageElement) {
4066
- setClipboardDataByImage(data, selectedImageElement.data.image);
4055
+ setClipboardDataByMedia(data, selectedImageElement.data.image, MediaKeys.image);
4067
4056
  return;
4068
4057
  }
4069
- setFragment(data);
4058
+ setFragment(data, rectangle);
4070
4059
  };
4071
4060
  board.deleteFragment = (data) => {
4072
4061
  const selectedImageElement = getSelectedImageElement(board);
@@ -4088,10 +4077,11 @@ const withNodeImage = (board) => {
4088
4077
  return;
4089
4078
  }
4090
4079
  }
4091
- const imageItem = getImageItemFromClipboard(data);
4080
+ const imageItem = getClipboardDataByMedia(data, MediaKeys.image);
4092
4081
  if (imageItem && (isSingleSelection || isSelectedImage)) {
4093
4082
  const selectedElement = (selectedElements[0] || getSelectedImageElement(board));
4094
4083
  MindTransforms.setImage(board, selectedElement, imageItem);
4084
+ return;
4095
4085
  }
4096
4086
  insertFragment(data, targetPoint);
4097
4087
  };
@@ -4099,25 +4089,30 @@ const withNodeImage = (board) => {
4099
4089
  };
4100
4090
 
4101
4091
  const withNodeResize = (board) => {
4102
- const { mousedown, mousemove, globalMouseup } = board;
4092
+ const { pointerDown, pointerMove, globalPointerUp } = board;
4103
4093
  let targetElement = null;
4104
4094
  let targetElementRef = null;
4105
4095
  let startPoint = null;
4106
- board.mousedown = (event) => {
4107
- if (targetElement) {
4096
+ board.pointerDown = (event) => {
4097
+ const point = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
4098
+ const newTargetElement = getSelectedTarget(board, point);
4099
+ if (newTargetElement) {
4100
+ PlaitBoard.getBoardContainer(board).classList.add(ResizeCursorClass['ew-resize']);
4101
+ targetElement = newTargetElement;
4108
4102
  startPoint = [event.x, event.y];
4109
- // prevent text from being selected
4110
- event.preventDefault();
4111
4103
  return;
4112
4104
  }
4113
- mousedown(event);
4105
+ pointerDown(event);
4114
4106
  };
4115
- board.mousemove = (event) => {
4107
+ board.pointerMove = (event) => {
4116
4108
  if (PlaitBoard.isReadonly(board) || PlaitBoard.hasBeenTextEditing(board)) {
4117
- mousemove(event);
4109
+ pointerMove(event);
4118
4110
  return;
4119
4111
  }
4120
4112
  if (startPoint && targetElement && !isMindNodeResizing(board)) {
4113
+ // prevent text from being selected
4114
+ event.preventDefault();
4115
+ preventTouchMove(board, true);
4121
4116
  const endPoint = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
4122
4117
  const distance = distanceBetweenPointAndPoint(startPoint[0], startPoint[1], endPoint[0], endPoint[1]);
4123
4118
  if (distance > PRESS_AND_MOVE_BUFFER) {
@@ -4132,6 +4127,9 @@ const withNodeResize = (board) => {
4132
4127
  }
4133
4128
  }
4134
4129
  if (isMindNodeResizing(board) && startPoint && targetElementRef) {
4130
+ // prevent text from being selected
4131
+ event.preventDefault();
4132
+ preventTouchMove(board, true);
4135
4133
  throttleRAF(() => {
4136
4134
  if (!startPoint) {
4137
4135
  return;
@@ -4156,26 +4154,26 @@ const withNodeResize = (board) => {
4156
4154
  // press and start drag when node is non selected
4157
4155
  if (!isDragging(board)) {
4158
4156
  const point = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
4159
- const newTargetElement = getTargetElement(board, point);
4157
+ const newTargetElement = getSelectedTarget(board, point);
4160
4158
  if (newTargetElement) {
4161
4159
  PlaitBoard.getBoardContainer(board).classList.add(ResizeCursorClass['ew-resize']);
4162
4160
  }
4163
4161
  else {
4164
4162
  PlaitBoard.getBoardContainer(board).classList.remove(ResizeCursorClass['ew-resize']);
4165
4163
  }
4166
- targetElement = newTargetElement;
4167
4164
  }
4168
4165
  }
4169
- mousemove(event);
4166
+ pointerMove(event);
4170
4167
  };
4171
- board.globalMouseup = (event) => {
4172
- globalMouseup(event);
4168
+ board.globalPointerUp = (event) => {
4169
+ globalPointerUp(event);
4173
4170
  if (isMindNodeResizing(board) || targetElement) {
4174
4171
  targetElement && removeResizing(board, targetElement);
4175
4172
  targetElementRef = null;
4176
4173
  targetElement = null;
4177
4174
  startPoint = null;
4178
4175
  MERGING.set(board, false);
4176
+ preventTouchMove(board, false);
4179
4177
  }
4180
4178
  };
4181
4179
  return board;
@@ -4199,7 +4197,7 @@ const removeResizing = (board, element) => {
4199
4197
  }
4200
4198
  IS_MIND_NODE_RESIZING.set(board, false);
4201
4199
  };
4202
- const getTargetElement = (board, point) => {
4200
+ const getSelectedTarget = (board, point) => {
4203
4201
  const selectedElements = getSelectedElements(board).filter(value => MindElement.isMindElement(board, value));
4204
4202
  if (selectedElements.length > 0) {
4205
4203
  const target = selectedElements.find(value => {
@@ -4216,9 +4214,52 @@ const getResizeActiveRectangle = (board, element) => {
4216
4214
  return { x: rectangle.x + rectangle.width - EXTEND_OFFSET, y: rectangle.y, width: EXTEND_OFFSET * 2, height: rectangle.height };
4217
4215
  };
4218
4216
 
4217
+ const withNodeImageResize = (board) => {
4218
+ const options = {
4219
+ key: 'mind-node-image',
4220
+ canResize: () => {
4221
+ return true;
4222
+ },
4223
+ detect: (point) => {
4224
+ const selectedMindElement = getSelectedImageElement(board);
4225
+ if (selectedMindElement) {
4226
+ const result = getHitImageResizeHandleDirection(board, selectedMindElement, point);
4227
+ if (result) {
4228
+ return {
4229
+ element: selectedMindElement,
4230
+ direction: result.direction,
4231
+ cursorClass: result.cursorClass
4232
+ };
4233
+ }
4234
+ }
4235
+ return null;
4236
+ },
4237
+ onResize: (resizeRef, resizeState) => {
4238
+ let offsetX = resizeState.offsetX;
4239
+ let offsetY = resizeState.offsetY;
4240
+ if (resizeRef.direction === ResizeDirection.nw || resizeRef.direction === ResizeDirection.sw) {
4241
+ offsetX = -offsetX;
4242
+ }
4243
+ const originWidth = resizeRef.element.data.image.width;
4244
+ const originHeight = resizeRef.element.data.image.height;
4245
+ let width = originWidth + offsetX;
4246
+ if (width <= 100) {
4247
+ width = 100;
4248
+ }
4249
+ const ratio = originWidth / width;
4250
+ const height = originHeight / ratio;
4251
+ const imageItem = { ...resizeRef.element.data.image, width, height };
4252
+ MindTransforms.setImage(board, PlaitNode.get(board, resizeRef.path), imageItem);
4253
+ addSelectedImageElement(board, PlaitNode.get(board, resizeRef.path));
4254
+ }
4255
+ };
4256
+ withResize(board, options);
4257
+ return board;
4258
+ };
4259
+
4219
4260
  const withMind = (baseBoard) => {
4220
4261
  const board = baseBoard;
4221
- const { drawElement, dblclick, insertFragment, setFragment, deleteFragment, isHitSelection, getRectangle, isMovable, isRecursion } = board;
4262
+ const { drawElement, dblclick, insertFragment, setFragment, isHitSelection, getRectangle, isMovable, isRecursion } = board;
4222
4263
  board.drawElement = (context) => {
4223
4264
  if (PlaitMind.isMind(context.element)) {
4224
4265
  return PlaitMindComponent;
@@ -4282,48 +4323,34 @@ const withMind = (baseBoard) => {
4282
4323
  }
4283
4324
  dblclick(event);
4284
4325
  };
4285
- board.setFragment = (data) => {
4286
- const selectedElements = getFirstLevelElement(getSelectedElements(board));
4287
- if (selectedElements.length) {
4288
- const elements = buildClipboardData(board, selectedElements);
4289
- setClipboardData(data, elements);
4290
- return;
4291
- }
4292
- setFragment(data);
4326
+ board.setFragment = (data, rectangle) => {
4327
+ const targetMindElements = getSelectedMindElements(board);
4328
+ const firstLevelElements = getFirstLevelElement(targetMindElements);
4329
+ if (firstLevelElements.length) {
4330
+ const elements = buildClipboardData(board, firstLevelElements, rectangle ? [rectangle.x, rectangle.y] : [0, 0]);
4331
+ setMindClipboardData(data, elements);
4332
+ }
4333
+ setFragment(data, rectangle);
4293
4334
  };
4294
4335
  board.insertFragment = (data, targetPoint) => {
4295
- if (board.options.readonly) {
4296
- insertFragment(data, targetPoint);
4297
- return;
4298
- }
4299
4336
  const elements = getDataFromClipboard(data);
4300
- if (elements.length) {
4301
- insertClipboardData(board, elements, targetPoint || [0, 0]);
4337
+ const mindElements = elements.filter(value => MindElement.isMindElement(board, value));
4338
+ if (elements.length > 0 && mindElements.length > 0) {
4339
+ insertClipboardData(board, mindElements, targetPoint);
4302
4340
  }
4303
- else {
4304
- const selectedElements = getSelectedElements(board);
4305
- if (selectedElements.length === 1) {
4341
+ else if (elements.length === 0) {
4342
+ const mindElements = getSelectedMindElements(board);
4343
+ if (mindElements.length === 1) {
4306
4344
  const text = getTextFromClipboard(data);
4307
4345
  if (text) {
4308
- insertClipboardText(board, selectedElements[0], buildText(text));
4346
+ insertClipboardText(board, mindElements[0], buildText(text));
4347
+ return;
4309
4348
  }
4310
4349
  }
4311
4350
  }
4312
4351
  insertFragment(data, targetPoint);
4313
4352
  };
4314
- board.deleteFragment = (data) => {
4315
- const selectedElements = getSelectedElements(board);
4316
- if (selectedElements.length) {
4317
- const deletableElements = getFirstLevelElement(selectedElements).reverse();
4318
- const abstractRefs = deleteElementHandleAbstract(board, deletableElements);
4319
- MindTransforms.setAbstractsByRefs(board, abstractRefs);
4320
- const refs = deleteElementsHandleRightNodeCount(board, selectedElements);
4321
- MindTransforms.setRightNodeCountByRefs(board, refs);
4322
- MindTransforms.removeElements(board, selectedElements);
4323
- }
4324
- deleteFragment(data);
4325
- };
4326
- return withNodeResize(withNodeImage(withNodeHoverDetect(withMindHotkey(withMindExtend(withCreateMind(withAbstract(withNodeDnd(board))))))));
4353
+ return withNodeResize(withNodeImageResize(withNodeImage(withNodeHoverDetect(withMindHotkey(withMindExtend(withCreateMind(withAbstract(withNodeDnd(board)))))))));
4327
4354
  };
4328
4355
 
4329
4356
  class MindEmojiBaseComponent {
@@ -4373,17 +4400,43 @@ class MindImageBaseComponent {
4373
4400
  set imageItem(value) {
4374
4401
  this.afterImageItemChange(this._imageItem, value);
4375
4402
  this._imageItem = value;
4403
+ this.drawFocus();
4376
4404
  }
4377
4405
  get imageItem() {
4378
4406
  return this._imageItem;
4379
4407
  }
4408
+ set isFocus(value) {
4409
+ this._isFocus = value;
4410
+ this.drawFocus();
4411
+ }
4412
+ get isFocus() {
4413
+ return this._isFocus;
4414
+ }
4380
4415
  get nativeElement() {
4381
4416
  return this.elementRef.nativeElement;
4382
4417
  }
4383
4418
  constructor(elementRef, cdr) {
4384
4419
  this.elementRef = elementRef;
4385
4420
  this.cdr = cdr;
4386
- this.isFocus = false;
4421
+ this.initialized = false;
4422
+ }
4423
+ ngOnInit() {
4424
+ this.activeGenerator = new ActiveGenerator(this.board, {
4425
+ activeStrokeWidth: 1,
4426
+ getRectangle: (element) => {
4427
+ return getImageForeignRectangle(this.board, this.element);
4428
+ },
4429
+ getStrokeWidthByElement: () => {
4430
+ return 0;
4431
+ }
4432
+ });
4433
+ this.initialized = true;
4434
+ }
4435
+ drawFocus() {
4436
+ if (this.initialized) {
4437
+ const com = PlaitElement.getComponent(this.element);
4438
+ this.activeGenerator.draw(this.element, com.g, { selected: this._isFocus });
4439
+ }
4387
4440
  }
4388
4441
  }
4389
4442
  MindImageBaseComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: MindImageBaseComponent, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive });
@@ -4413,5 +4466,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImpor
4413
4466
  * Generated bundle index. Do not edit.
4414
4467
  */
4415
4468
 
4416
- 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, MindImageBaseComponent, MindModule, MindNode, MindNodeComponent, MindPointerType, MindQueries, MindRetroThemeColor, MindSoftThemeColor, MindStarryThemeColor, MindThemeColor, MindThemeColors, MindTransforms, NodeSpace, 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, addSelectedImageElement, adjustAbstractToNode, adjustNodeToRoot, adjustRootToNode, buildImage, 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, getEmojiFontSize, getEmojiForeignRectangle, getEmojiRectangle, getEmojisWidthHeight, getFillByElement, getFirstLevelElement, getFontSizeBySlateElement, getHitAbstractHandle, getImageForeignRectangle, getInCorrectLayoutDirection, getLayoutDirection$1 as getLayoutDirection, getLayoutOptions, getLayoutReverseDirection, getLocationScope, getMindThemeColor, getNewNodeHeight, getNextBranchColor, getNodeDefaultFontSize, getOverallAbstracts, getPathByDropTarget, getRectangleByElement, getRectangleByNode, getRectangleByResizingLocation, getRelativeStartEndByAbstractRef, getRootLayout, getSelectedImageElement, getShapeByElement, getStrokeByMindElement, getStrokeWidthByElement, getTopicRectangleByElement, getTopicRectangleByNode, getValidAbstractRefs, handleTouchedAbstract, hasAfterDraw, hasPreviousOrNextOfDropPath, insertElementHandleAbstract, insertElementHandleRightNodeCount, insertMindElement, isChildElement, isChildOfAbstract, isChildRight, isChildUp, isCorrectLayout, isDragging, isDropStandardRight, isHitEmojis, isHitImage, isHitMindElement, isInRightBranchOfStandardLayout, isMixedLayout, isSetAbstract, isValidTarget, isVirtualKey, removeActiveOnDragOrigin, removeSelectedImageElement, selectImage, separateChildren, setImageFocus, setIsDragging, temporaryDisableSelection, withMind, withMindExtend };
4469
+ 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, MindImageBaseComponent, MindModule, MindNode, MindNodeComponent, MindPointerType, MindQueries, MindRetroThemeColor, MindSoftThemeColor, MindStarryThemeColor, MindThemeColor, MindThemeColors, MindTransforms, NodeSpace, 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, addSelectedImageElement, adjustAbstractToNode, adjustNodeToRoot, adjustRootToNode, buildImage, 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, getEmojiFontSize, getEmojiForeignRectangle, getEmojiRectangle, getEmojisWidthHeight, getFillByElement, getFirstLevelElement, getFontSizeBySlateElement, getHitAbstractHandle, getHitImageResizeHandleDirection, getImageForeignRectangle, getInCorrectLayoutDirection, getLayoutDirection$1 as getLayoutDirection, getLayoutOptions, getLayoutReverseDirection, getLocationScope, getMindThemeColor, getNewNodeHeight, getNextBranchColor, getNodeDefaultFontSize, getOverallAbstracts, getPathByDropTarget, getRectangleByElement, getRectangleByNode, getRectangleByResizingLocation, getRelativeStartEndByAbstractRef, getRootLayout, getSelectedImageElement, getSelectedMindElements, getShapeByElement, getStrokeByMindElement, getStrokeWidthByElement, getTopicRectangleByElement, getTopicRectangleByNode, getValidAbstractRefs, handleTouchedAbstract, hasAfterDraw, hasPreviousOrNextOfDropPath, insertElementHandleAbstract, insertElementHandleRightNodeCount, insertMindElement, isChildElement, isChildOfAbstract, isChildRight, isChildUp, isCorrectLayout, isDragging, isDropStandardRight, isHitEmojis, isHitImage, isHitMindElement, isInRightBranchOfStandardLayout, isMixedLayout, isSetAbstract, isValidTarget, isVirtualKey, removeActiveOnDragOrigin, removeSelectedImageElement, selectImage, separateChildren, setImageFocus, setIsDragging, temporaryDisableSelection, withMind, withMindExtend };
4417
4470
  //# sourceMappingURL=plait-mind.mjs.map