@plait/mind 0.26.0 → 0.27.0-next.1

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,12 +1,12 @@
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, getRectangleResizeHandleRefs, isExpandHotkey, isTabHotkey, isEnterHotkey, isVirtualKey, isSpaceHotkey, MediaKeys, ResizeHandle, withResize, ActiveGenerator } from '@plait/common';
8
9
  import { Node as Node$1, Path as Path$1 } from 'slate';
9
- import { isKeyHotkey } from 'is-hotkey';
10
10
  import { pointsOnBezierCurves } from 'points-on-curve';
11
11
  import { take, filter } from 'rxjs/operators';
12
12
  import * as i1 from '@angular/common';
@@ -409,11 +409,20 @@ function getImageForeignRectangle(board, element) {
409
409
  width,
410
410
  height
411
411
  };
412
- return RectangleClient.getOutlineRectangle(rectangle, -6);
412
+ return rectangle;
413
413
  }
414
414
  const isHitImage = (board, element, range) => {
415
- const client = getImageForeignRectangle(board, element);
416
- return RectangleClient.isHit(RectangleClient.toRectangleClient([range.anchor, range.focus]), client);
415
+ const imageRectangle = getImageForeignRectangle(board, element);
416
+ const imageOutlineRectangle = RectangleClient.getOutlineRectangle(imageRectangle, -RESIZE_HANDLE_DIAMETER / 2);
417
+ return RectangleClient.isHit(RectangleClient.toRectangleClient([range.anchor, range.focus]), imageOutlineRectangle);
418
+ };
419
+ const getHitImageResizeHandleDirection = (board, element, point) => {
420
+ const imageRectangle = getImageForeignRectangle(board, element);
421
+ const resizeHandleRefs = getRectangleResizeHandleRefs(imageRectangle, RESIZE_HANDLE_DIAMETER);
422
+ const result = resizeHandleRefs.find(resizeHandleRef => {
423
+ return RectangleClient.isHit(RectangleClient.toRectangleClient([point, point]), resizeHandleRef.rectangle);
424
+ });
425
+ return result;
417
426
  };
418
427
 
419
428
  function editTopic(element) {
@@ -429,6 +438,10 @@ const temporaryDisableSelection = (board) => {
429
438
  board.setPluginOptions(PlaitPluginKey.withSelection, { ...currentOptions });
430
439
  }, 0);
431
440
  };
441
+ const getSelectedMindElements = (board) => {
442
+ const selectedElements = getSelectedElements(board).filter(value => MindElement.isMindElement(board, value));
443
+ return selectedElements;
444
+ };
432
445
 
433
446
  const createEmptyMind = (point) => {
434
447
  const element = createMindElement('思维导图', 72, ROOT_TOPIC_HEIGHT, { layout: MindLayoutType.right });
@@ -1321,18 +1334,6 @@ const getShapeByElement = (board, element) => {
1321
1334
  return shape || MindElementShape.roundRectangle;
1322
1335
  };
1323
1336
 
1324
- function isVirtualKey(e) {
1325
- const isMod = e.ctrlKey || e.metaKey;
1326
- const isAlt = isKeyHotkey('alt', e);
1327
- const isShift = isKeyHotkey('shift', e);
1328
- const isCapsLock = e.key.includes('CapsLock');
1329
- const isTab = e.key.includes('Tab');
1330
- const isEsc = e.key.includes('Escape');
1331
- const isF = e.key.startsWith('F');
1332
- const isArrow = e.key.includes('Arrow') ? true : false;
1333
- return isCapsLock || isMod || isAlt || isArrow || isShift || isTab || isEsc || isF;
1334
- }
1335
-
1336
1337
  const IS_DRAGGING = new WeakMap();
1337
1338
  const addActiveOnDragOrigin = (activeElement) => {
1338
1339
  const activeComponent = PlaitElement.getComponent(activeElement);
@@ -2373,9 +2374,7 @@ const MindElement = {
2373
2374
  return isIndentedLayout(_layout);
2374
2375
  },
2375
2376
  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)) {
2377
+ if (element.data && element.data.topic && element.width && element.height) {
2379
2378
  return true;
2380
2379
  }
2381
2380
  else {
@@ -3002,7 +3001,6 @@ class NodeImageDrawer {
3002
3001
  this.g = createG();
3003
3002
  const foreignRectangle = getImageForeignRectangle(this.board, element);
3004
3003
  this.foreignObject = createForeignObject(foreignRectangle.x, foreignRectangle.y, foreignRectangle.width, foreignRectangle.height);
3005
- this.foreignObject.style.padding = `6px`;
3006
3004
  this.g.append(this.foreignObject);
3007
3005
  const componentType = this.board.getPluginOptions(WithMindPluginKey).imageComponentType;
3008
3006
  if (!componentType) {
@@ -3065,19 +3063,23 @@ class MindNodeComponent extends PlaitPluginElementComponent {
3065
3063
  this.collapseDrawer = new CollapseDrawer(this.board);
3066
3064
  this.imageDrawer = new NodeImageDrawer(this.board, this.viewContainerRef);
3067
3065
  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);
3066
+ this.textManage = new TextManage(this.board, this.viewContainerRef, {
3067
+ getRectangle: () => {
3068
+ const rect = getTopicRectangleByNode(this.board, this.node);
3069
+ return rect;
3070
+ },
3071
+ onValueChangeHandle: (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
+ },
3081
+ textPlugins: plugins
3082
+ });
3081
3083
  }
3082
3084
  ngOnInit() {
3083
3085
  super.ngOnInit();
@@ -3320,7 +3322,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImpor
3320
3322
 
3321
3323
  const DRAG_MOVE_BUFFER = 5;
3322
3324
  const withNodeDnd = (board) => {
3323
- const { mousedown, mousemove, globalMouseup } = board;
3325
+ const { pointerDown, pointerMove, globalPointerUp } = board;
3324
3326
  let activeElements = [];
3325
3327
  let correspondingElements = [];
3326
3328
  let startPoint;
@@ -3328,12 +3330,12 @@ const withNodeDnd = (board) => {
3328
3330
  let fakeDropNodeG;
3329
3331
  let dropTarget = null;
3330
3332
  let targetPath;
3331
- board.mousedown = (event) => {
3333
+ board.pointerDown = (event) => {
3332
3334
  if (PlaitBoard.isReadonly(board) ||
3333
3335
  PlaitBoard.hasBeenTextEditing(board) ||
3334
3336
  !PlaitBoard.isPointer(board, PlaitPointerType.selection) ||
3335
3337
  !isMainPointer(event)) {
3336
- mousedown(event);
3338
+ pointerDown(event);
3337
3339
  return;
3338
3340
  }
3339
3341
  const point = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
@@ -3360,9 +3362,9 @@ const withNodeDnd = (board) => {
3360
3362
  if (activeElements.length) {
3361
3363
  correspondingElements = getOverallAbstracts(board, activeElements);
3362
3364
  }
3363
- mousedown(event);
3365
+ pointerDown(event);
3364
3366
  };
3365
- board.mousemove = (event) => {
3367
+ board.pointerMove = (event) => {
3366
3368
  if (!board.options.readonly && activeElements?.length && startPoint) {
3367
3369
  // prevent text from being selected
3368
3370
  event.preventDefault();
@@ -3393,9 +3395,9 @@ const withNodeDnd = (board) => {
3393
3395
  });
3394
3396
  PlaitBoard.getHost(board).appendChild(dragFakeNodeG);
3395
3397
  }
3396
- mousemove(event);
3398
+ pointerMove(event);
3397
3399
  };
3398
- board.globalMouseup = (event) => {
3400
+ board.globalPointerUp = (event) => {
3399
3401
  const firstLevelElements = getFirstLevelElement(activeElements);
3400
3402
  if (!board.options.readonly && firstLevelElements.length) {
3401
3403
  firstLevelElements.push(...correspondingElements);
@@ -3484,12 +3486,12 @@ const withNodeDnd = (board) => {
3484
3486
  fakeDropNodeG = undefined;
3485
3487
  dropTarget = null;
3486
3488
  }
3487
- globalMouseup(event);
3489
+ globalPointerUp(event);
3488
3490
  };
3489
3491
  return board;
3490
3492
  };
3491
3493
 
3492
- const buildClipboardData = (board, selectedElements) => {
3494
+ const buildClipboardData = (board, selectedElements, startPoint) => {
3493
3495
  let result = [];
3494
3496
  // get overall abstract
3495
3497
  const overallAbstracts = getOverallAbstracts(board, selectedElements);
@@ -3499,11 +3501,10 @@ const buildClipboardData = (board, selectedElements) => {
3499
3501
  const newSelectedElements = selectedElements.filter(value => !validAbstractRefs.find(ref => ref.abstract === value));
3500
3502
  newSelectedElements.push(...validAbstractRefs.map(value => value.abstract));
3501
3503
  const selectedMindNodes = newSelectedElements.map(value => MindElement.getNode(value));
3502
- const nodesRectangle = getRectangleByElements(board, newSelectedElements, true);
3503
3504
  newSelectedElements.forEach((element, index) => {
3504
3505
  // handle relative location
3505
3506
  const nodeRectangle = getRectangleByNode(selectedMindNodes[index]);
3506
- const points = [[nodeRectangle.x - nodesRectangle.x, nodeRectangle.y - nodesRectangle.y]];
3507
+ const points = [[nodeRectangle.x - startPoint[0], nodeRectangle.y - startPoint[1]]];
3507
3508
  // handle invalid abstract
3508
3509
  const abstractRef = validAbstractRefs.find(ref => ref.abstract === element);
3509
3510
  if (AbstractNode.isAbstract(element) && abstractRef) {
@@ -3532,37 +3533,12 @@ const buildClipboardData = (board, selectedElements) => {
3532
3533
  });
3533
3534
  return result;
3534
3535
  };
3535
- const setClipboardData = (data, elements) => {
3536
- const stringObj = JSON.stringify(elements);
3537
- const encoded = window.btoa(encodeURIComponent(stringObj));
3536
+ const setMindClipboardData = (data, elements) => {
3538
3537
  const text = elements.reduce((string, currentNode) => {
3539
3538
  return string + extractNodesText(currentNode);
3540
3539
  }, '');
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;
3540
+ setClipboardData(data, elements);
3541
+ setClipboardDataByText(data, text);
3566
3542
  };
3567
3543
  const insertClipboardData = (board, elements, targetPoint) => {
3568
3544
  let newElement, path;
@@ -3763,8 +3739,10 @@ const withCreateMind = (board) => {
3763
3739
  const nodeG = drawRoundRectangleByElement(board, nodeRectangle, emptyMind);
3764
3740
  const topicRectangle = getTopicRectangleByElement(newBoard, nodeRectangle, emptyMind);
3765
3741
  if (!fakeCreateNodeRef) {
3766
- const textManage = new TextManage(board, PlaitBoard.getComponent(board).viewContainerRef, () => {
3767
- return topicRectangle;
3742
+ const textManage = new TextManage(board, PlaitBoard.getComponent(board).viewContainerRef, {
3743
+ getRectangle: () => {
3744
+ return topicRectangle;
3745
+ }
3768
3746
  });
3769
3747
  PlaitBoard.getComponent(board)
3770
3748
  .viewContainerRef.injector.get(NgZone)
@@ -3833,7 +3811,7 @@ const withCreateMind = (board) => {
3833
3811
 
3834
3812
  const withMindHotkey = (baseBoard) => {
3835
3813
  const board = baseBoard;
3836
- const { keydown } = board;
3814
+ const { keydown, deleteFragment } = board;
3837
3815
  board.keydown = (event) => {
3838
3816
  const selectedElements = getSelectedElements(board);
3839
3817
  const isSingleSelection = selectedElements.length === 1;
@@ -3873,25 +3851,7 @@ const withMindHotkey = (baseBoard) => {
3873
3851
  insertMindElement(board, targetElement, findNewSiblingNodePath(board, targetElement));
3874
3852
  return;
3875
3853
  }
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
- if (!isVirtualKey(event) && !isSpaceHotkey(event) && isSingleSelection) {
3854
+ if (!isVirtualKey(event) && !isSpaceHotkey(event) && isSingleSelection && MindElement.isMindElement(board, targetElement)) {
3895
3855
  event.preventDefault();
3896
3856
  editTopic(targetElement);
3897
3857
  return;
@@ -3899,6 +3859,22 @@ const withMindHotkey = (baseBoard) => {
3899
3859
  }
3900
3860
  keydown(event);
3901
3861
  };
3862
+ board.deleteFragment = (data) => {
3863
+ const targetMindElements = getSelectedMindElements(board);
3864
+ if (targetMindElements.length) {
3865
+ const firstLevelElements = getFirstLevelElement(targetMindElements).reverse();
3866
+ const abstractRefs = deleteElementHandleAbstract(board, firstLevelElements);
3867
+ MindTransforms.setAbstractsByRefs(board, abstractRefs);
3868
+ const refs = deleteElementsHandleRightNodeCount(board, targetMindElements);
3869
+ MindTransforms.setRightNodeCountByRefs(board, refs);
3870
+ MindTransforms.removeElements(board, targetMindElements);
3871
+ const nextSelected = getNextSelectedElement(board, firstLevelElements);
3872
+ if (nextSelected) {
3873
+ addSelectedElement(board, nextSelected);
3874
+ }
3875
+ }
3876
+ deleteFragment(data);
3877
+ };
3902
3878
  return board;
3903
3879
  };
3904
3880
  const getNextSelectedElement = (board, firstLevelElements) => {
@@ -3931,18 +3907,6 @@ const getNextSelectedElement = (board, firstLevelElements) => {
3931
3907
  }
3932
3908
  return activeElement;
3933
3909
  };
3934
- const isExpandHotkey = (event) => {
3935
- return isKeyHotkey('mod+/', event);
3936
- };
3937
- const isTabHotkey = (event) => {
3938
- return event.key === 'Tab';
3939
- };
3940
- const isEnterHotkey = (event) => {
3941
- return event.key === 'Enter';
3942
- };
3943
- const isSpaceHotkey = (event) => {
3944
- return event.code === 'Space';
3945
- };
3946
3910
 
3947
3911
  const mouseMoveHandle = (board, event, nodeHoveredExtendRef) => {
3948
3912
  let target = null;
@@ -4011,24 +3975,24 @@ const withNodeHoverDetect = (board) => {
4011
3975
  };
4012
3976
 
4013
3977
  const withNodeImage = (board) => {
4014
- const { keydown, mousedown, globalMouseup, setFragment, insertFragment, deleteFragment } = board;
4015
- board.mousedown = (event) => {
3978
+ const { keydown, pointerDown, globalPointerUp, setFragment, insertFragment, deleteFragment } = board;
3979
+ board.pointerDown = (event) => {
4016
3980
  const selectedImageElement = getSelectedImageElement(board);
4017
3981
  if (PlaitBoard.isReadonly(board) || !isMainPointer(event) || !PlaitBoard.isPointer(board, PlaitPointerType.selection)) {
4018
3982
  if (selectedImageElement) {
4019
3983
  setImageFocus(board, selectedImageElement, false);
4020
3984
  }
4021
- mousedown(event);
3985
+ pointerDown(event);
4022
3986
  return;
4023
3987
  }
4024
3988
  const point = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
4025
3989
  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) {
3990
+ const hitImageElements = getHitElements(board, { ranges: [range] }, (value) => MindElement.isMindElement(board, value) && MindElement.hasImage(value));
3991
+ const hasImage = hitImageElements.length;
3992
+ const hitImage = hasImage > 0 && isHitImage(board, hitImageElements[0], range);
3993
+ if (selectedImageElement && hitImage && hitImageElements[0] === selectedImageElement) {
4030
3994
  temporaryDisableSelection(board);
4031
- mousedown(event);
3995
+ pointerDown(event);
4032
3996
  return;
4033
3997
  }
4034
3998
  if (selectedImageElement) {
@@ -4036,9 +4000,9 @@ const withNodeImage = (board) => {
4036
4000
  }
4037
4001
  if (hitImage) {
4038
4002
  temporaryDisableSelection(board);
4039
- setImageFocus(board, hitElements[0], true);
4003
+ setImageFocus(board, hitImageElements[0], true);
4040
4004
  }
4041
- mousedown(event);
4005
+ pointerDown(event);
4042
4006
  };
4043
4007
  board.keydown = (event) => {
4044
4008
  const selectedImageElement = getSelectedImageElement(board);
@@ -4049,7 +4013,7 @@ const withNodeImage = (board) => {
4049
4013
  }
4050
4014
  keydown(event);
4051
4015
  };
4052
- board.globalMouseup = (event) => {
4016
+ board.globalPointerUp = (event) => {
4053
4017
  if (PlaitBoard.isFocus(board)) {
4054
4018
  const isInBoard = event.target instanceof Node && PlaitBoard.getBoardContainer(board).contains(event.target);
4055
4019
  const selectedImageElement = getSelectedImageElement(board);
@@ -4058,15 +4022,15 @@ const withNodeImage = (board) => {
4058
4022
  setImageFocus(board, selectedImageElement, false);
4059
4023
  }
4060
4024
  }
4061
- globalMouseup(event);
4025
+ globalPointerUp(event);
4062
4026
  };
4063
- board.setFragment = (data) => {
4027
+ board.setFragment = (data, rectangle) => {
4064
4028
  const selectedImageElement = getSelectedImageElement(board);
4065
4029
  if (selectedImageElement) {
4066
- setClipboardDataByImage(data, selectedImageElement.data.image);
4030
+ setClipboardDataByMedia(data, selectedImageElement.data.image, MediaKeys.image);
4067
4031
  return;
4068
4032
  }
4069
- setFragment(data);
4033
+ setFragment(data, rectangle);
4070
4034
  };
4071
4035
  board.deleteFragment = (data) => {
4072
4036
  const selectedImageElement = getSelectedImageElement(board);
@@ -4088,10 +4052,11 @@ const withNodeImage = (board) => {
4088
4052
  return;
4089
4053
  }
4090
4054
  }
4091
- const imageItem = getImageItemFromClipboard(data);
4055
+ const imageItem = getClipboardDataByMedia(data, MediaKeys.image);
4092
4056
  if (imageItem && (isSingleSelection || isSelectedImage)) {
4093
4057
  const selectedElement = (selectedElements[0] || getSelectedImageElement(board));
4094
4058
  MindTransforms.setImage(board, selectedElement, imageItem);
4059
+ return;
4095
4060
  }
4096
4061
  insertFragment(data, targetPoint);
4097
4062
  };
@@ -4099,25 +4064,30 @@ const withNodeImage = (board) => {
4099
4064
  };
4100
4065
 
4101
4066
  const withNodeResize = (board) => {
4102
- const { mousedown, mousemove, globalMouseup } = board;
4067
+ const { pointerDown, pointerMove, globalPointerUp } = board;
4103
4068
  let targetElement = null;
4104
4069
  let targetElementRef = null;
4105
4070
  let startPoint = null;
4106
- board.mousedown = (event) => {
4107
- if (targetElement) {
4071
+ board.pointerDown = (event) => {
4072
+ const point = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
4073
+ const newTargetElement = getSelectedTarget(board, point);
4074
+ if (newTargetElement) {
4075
+ PlaitBoard.getBoardContainer(board).classList.add(ResizeCursorClass['ew-resize']);
4076
+ targetElement = newTargetElement;
4108
4077
  startPoint = [event.x, event.y];
4109
4078
  return;
4110
4079
  }
4111
- mousedown(event);
4080
+ pointerDown(event);
4112
4081
  };
4113
- board.mousemove = (event) => {
4082
+ board.pointerMove = (event) => {
4114
4083
  if (PlaitBoard.isReadonly(board) || PlaitBoard.hasBeenTextEditing(board)) {
4115
- mousemove(event);
4084
+ pointerMove(event);
4116
4085
  return;
4117
4086
  }
4118
4087
  if (startPoint && targetElement && !isMindNodeResizing(board)) {
4119
4088
  // prevent text from being selected
4120
4089
  event.preventDefault();
4090
+ preventTouchMove(board, true);
4121
4091
  const endPoint = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
4122
4092
  const distance = distanceBetweenPointAndPoint(startPoint[0], startPoint[1], endPoint[0], endPoint[1]);
4123
4093
  if (distance > PRESS_AND_MOVE_BUFFER) {
@@ -4134,6 +4104,7 @@ const withNodeResize = (board) => {
4134
4104
  if (isMindNodeResizing(board) && startPoint && targetElementRef) {
4135
4105
  // prevent text from being selected
4136
4106
  event.preventDefault();
4107
+ preventTouchMove(board, true);
4137
4108
  throttleRAF(() => {
4138
4109
  if (!startPoint) {
4139
4110
  return;
@@ -4158,26 +4129,26 @@ const withNodeResize = (board) => {
4158
4129
  // press and start drag when node is non selected
4159
4130
  if (!isDragging(board)) {
4160
4131
  const point = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
4161
- const newTargetElement = getTargetElement(board, point);
4132
+ const newTargetElement = getSelectedTarget(board, point);
4162
4133
  if (newTargetElement) {
4163
4134
  PlaitBoard.getBoardContainer(board).classList.add(ResizeCursorClass['ew-resize']);
4164
4135
  }
4165
4136
  else {
4166
4137
  PlaitBoard.getBoardContainer(board).classList.remove(ResizeCursorClass['ew-resize']);
4167
4138
  }
4168
- targetElement = newTargetElement;
4169
4139
  }
4170
4140
  }
4171
- mousemove(event);
4141
+ pointerMove(event);
4172
4142
  };
4173
- board.globalMouseup = (event) => {
4174
- globalMouseup(event);
4143
+ board.globalPointerUp = (event) => {
4144
+ globalPointerUp(event);
4175
4145
  if (isMindNodeResizing(board) || targetElement) {
4176
4146
  targetElement && removeResizing(board, targetElement);
4177
4147
  targetElementRef = null;
4178
4148
  targetElement = null;
4179
4149
  startPoint = null;
4180
4150
  MERGING.set(board, false);
4151
+ preventTouchMove(board, false);
4181
4152
  }
4182
4153
  };
4183
4154
  return board;
@@ -4201,7 +4172,7 @@ const removeResizing = (board, element) => {
4201
4172
  }
4202
4173
  IS_MIND_NODE_RESIZING.set(board, false);
4203
4174
  };
4204
- const getTargetElement = (board, point) => {
4175
+ const getSelectedTarget = (board, point) => {
4205
4176
  const selectedElements = getSelectedElements(board).filter(value => MindElement.isMindElement(board, value));
4206
4177
  if (selectedElements.length > 0) {
4207
4178
  const target = selectedElements.find(value => {
@@ -4218,9 +4189,52 @@ const getResizeActiveRectangle = (board, element) => {
4218
4189
  return { x: rectangle.x + rectangle.width - EXTEND_OFFSET, y: rectangle.y, width: EXTEND_OFFSET * 2, height: rectangle.height };
4219
4190
  };
4220
4191
 
4192
+ const withNodeImageResize = (board) => {
4193
+ const options = {
4194
+ key: 'mind-node-image',
4195
+ canResize: () => {
4196
+ return true;
4197
+ },
4198
+ detect: (point) => {
4199
+ const selectedMindElement = getSelectedImageElement(board);
4200
+ if (selectedMindElement) {
4201
+ const result = getHitImageResizeHandleDirection(board, selectedMindElement, point);
4202
+ if (result) {
4203
+ return {
4204
+ element: selectedMindElement,
4205
+ handle: result.handle,
4206
+ cursorClass: result.cursorClass
4207
+ };
4208
+ }
4209
+ }
4210
+ return null;
4211
+ },
4212
+ onResize: (resizeRef, resizeState) => {
4213
+ let offsetX = resizeState.offsetX;
4214
+ let offsetY = resizeState.offsetY;
4215
+ if (resizeRef.handle === ResizeHandle.nw || resizeRef.handle === ResizeHandle.sw) {
4216
+ offsetX = -offsetX;
4217
+ }
4218
+ const originWidth = resizeRef.element.data.image.width;
4219
+ const originHeight = resizeRef.element.data.image.height;
4220
+ let width = originWidth + offsetX;
4221
+ if (width <= 100) {
4222
+ width = 100;
4223
+ }
4224
+ const ratio = originWidth / width;
4225
+ const height = originHeight / ratio;
4226
+ const imageItem = { ...resizeRef.element.data.image, width, height };
4227
+ MindTransforms.setImage(board, PlaitNode.get(board, resizeRef.path), imageItem);
4228
+ addSelectedImageElement(board, PlaitNode.get(board, resizeRef.path));
4229
+ }
4230
+ };
4231
+ withResize(board, options);
4232
+ return board;
4233
+ };
4234
+
4221
4235
  const withMind = (baseBoard) => {
4222
4236
  const board = baseBoard;
4223
- const { drawElement, dblclick, insertFragment, setFragment, deleteFragment, isHitSelection, getRectangle, isMovable, isRecursion } = board;
4237
+ const { drawElement, dblclick, insertFragment, setFragment, isHitSelection, getRectangle, isMovable, isRecursion } = board;
4224
4238
  board.drawElement = (context) => {
4225
4239
  if (PlaitMind.isMind(context.element)) {
4226
4240
  return PlaitMindComponent;
@@ -4284,48 +4298,34 @@ const withMind = (baseBoard) => {
4284
4298
  }
4285
4299
  dblclick(event);
4286
4300
  };
4287
- board.setFragment = (data) => {
4288
- const selectedElements = getFirstLevelElement(getSelectedElements(board));
4289
- if (selectedElements.length) {
4290
- const elements = buildClipboardData(board, selectedElements);
4291
- setClipboardData(data, elements);
4292
- return;
4293
- }
4294
- setFragment(data);
4301
+ board.setFragment = (data, rectangle) => {
4302
+ const targetMindElements = getSelectedMindElements(board);
4303
+ const firstLevelElements = getFirstLevelElement(targetMindElements);
4304
+ if (firstLevelElements.length) {
4305
+ const elements = buildClipboardData(board, firstLevelElements, rectangle ? [rectangle.x, rectangle.y] : [0, 0]);
4306
+ setMindClipboardData(data, elements);
4307
+ }
4308
+ setFragment(data, rectangle);
4295
4309
  };
4296
4310
  board.insertFragment = (data, targetPoint) => {
4297
- if (board.options.readonly) {
4298
- insertFragment(data, targetPoint);
4299
- return;
4300
- }
4301
4311
  const elements = getDataFromClipboard(data);
4302
- if (elements.length) {
4303
- insertClipboardData(board, elements, targetPoint || [0, 0]);
4312
+ const mindElements = elements.filter(value => MindElement.isMindElement(board, value));
4313
+ if (elements.length > 0 && mindElements.length > 0) {
4314
+ insertClipboardData(board, mindElements, targetPoint);
4304
4315
  }
4305
- else {
4306
- const selectedElements = getSelectedElements(board);
4307
- if (selectedElements.length === 1) {
4316
+ else if (elements.length === 0) {
4317
+ const mindElements = getSelectedMindElements(board);
4318
+ if (mindElements.length === 1) {
4308
4319
  const text = getTextFromClipboard(data);
4309
4320
  if (text) {
4310
- insertClipboardText(board, selectedElements[0], buildText(text));
4321
+ insertClipboardText(board, mindElements[0], buildText(text));
4322
+ return;
4311
4323
  }
4312
4324
  }
4313
4325
  }
4314
4326
  insertFragment(data, targetPoint);
4315
4327
  };
4316
- board.deleteFragment = (data) => {
4317
- const selectedElements = getSelectedElements(board);
4318
- if (selectedElements.length) {
4319
- const deletableElements = getFirstLevelElement(selectedElements).reverse();
4320
- const abstractRefs = deleteElementHandleAbstract(board, deletableElements);
4321
- MindTransforms.setAbstractsByRefs(board, abstractRefs);
4322
- const refs = deleteElementsHandleRightNodeCount(board, selectedElements);
4323
- MindTransforms.setRightNodeCountByRefs(board, refs);
4324
- MindTransforms.removeElements(board, selectedElements);
4325
- }
4326
- deleteFragment(data);
4327
- };
4328
- return withNodeResize(withNodeImage(withNodeHoverDetect(withMindHotkey(withMindExtend(withCreateMind(withAbstract(withNodeDnd(board))))))));
4328
+ return withNodeResize(withNodeImageResize(withNodeImage(withNodeHoverDetect(withMindHotkey(withMindExtend(withCreateMind(withAbstract(withNodeDnd(board)))))))));
4329
4329
  };
4330
4330
 
4331
4331
  class MindEmojiBaseComponent {
@@ -4375,17 +4375,48 @@ class MindImageBaseComponent {
4375
4375
  set imageItem(value) {
4376
4376
  this.afterImageItemChange(this._imageItem, value);
4377
4377
  this._imageItem = value;
4378
+ this.drawFocus();
4378
4379
  }
4379
4380
  get imageItem() {
4380
4381
  return this._imageItem;
4381
4382
  }
4383
+ set isFocus(value) {
4384
+ this._isFocus = value;
4385
+ this.drawFocus();
4386
+ }
4387
+ get isFocus() {
4388
+ return this._isFocus;
4389
+ }
4382
4390
  get nativeElement() {
4383
4391
  return this.elementRef.nativeElement;
4384
4392
  }
4385
4393
  constructor(elementRef, cdr) {
4386
4394
  this.elementRef = elementRef;
4387
4395
  this.cdr = cdr;
4388
- this.isFocus = false;
4396
+ this.initialized = false;
4397
+ }
4398
+ ngOnInit() {
4399
+ this.activeGenerator = new ActiveGenerator(this.board, {
4400
+ activeStrokeWidth: 1,
4401
+ getRectangle: (element) => {
4402
+ return getImageForeignRectangle(this.board, this.element);
4403
+ },
4404
+ getStrokeWidthByElement: () => {
4405
+ return 0;
4406
+ }
4407
+ });
4408
+ this.initialized = true;
4409
+ }
4410
+ drawFocus() {
4411
+ if (this.initialized) {
4412
+ const com = PlaitElement.getComponent(this.element);
4413
+ this.activeGenerator.draw(this.element, com.g, { selected: this._isFocus });
4414
+ }
4415
+ }
4416
+ ngOnDestroy() {
4417
+ if (this.activeGenerator) {
4418
+ this.activeGenerator.destroy();
4419
+ }
4389
4420
  }
4390
4421
  }
4391
4422
  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 });
@@ -4415,5 +4446,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImpor
4415
4446
  * Generated bundle index. Do not edit.
4416
4447
  */
4417
4448
 
4418
- 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 };
4449
+ 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, removeActiveOnDragOrigin, removeSelectedImageElement, selectImage, separateChildren, setImageFocus, setIsDragging, temporaryDisableSelection, withMind, withMindExtend };
4419
4450
  //# sourceMappingURL=plait-mind.mjs.map