@plait/mind 0.48.0 → 0.50.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,10 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { Component, ChangeDetectionStrategy, NgZone, Directive, Input, HostListener } from '@angular/core';
3
- import { DefaultThemeColor, ColorfulThemeColor, SoftThemeColor, RetroThemeColor, DarkThemeColor, StarryThemeColor, PlaitElement, PlaitNode, Path, isNullOrUndefined, PlaitBoard, distanceBetweenPointAndRectangle, RectangleClient, getSelectedElements, idCreator, Transforms, clearSelectedElement, addSelectedElement, depthFirstRecursion, getIsRecursionFunc, drawRoundRectangle, drawLinearPath, drawBezierPath, createG, updateForeignObject, getRectangleByElements, NODE_TO_PARENT, createForeignObject, removeSelectedElement, PlaitHistoryBoard, setStrokeLinecap, ACTIVE_STROKE_WIDTH, createText, PlaitPointerType, NODE_TO_INDEX, PlaitChildrenElementComponent, isMainPointer, transformPoint, toPoint, getHitElementByPoint, distanceBetweenPointAndPoint, CoreTransforms, BOARD_TO_HOST, BoardTransforms, throttleRAF, temporaryDisableSelection, hotkeys, setClipboardDataByMedia, getClipboardDataByMedia, ResizeCursorClass, setClipboardData, setClipboardDataByText, getDataFromClipboard, PlaitPluginKey } from '@plait/core';
3
+ import { DefaultThemeColor, ColorfulThemeColor, SoftThemeColor, RetroThemeColor, DarkThemeColor, StarryThemeColor, PlaitElement, PlaitNode, Path, isNullOrUndefined, PlaitBoard, getSelectedElements, idCreator, Transforms, clearSelectedElement, addSelectedElement, distanceBetweenPointAndRectangle, RectangleClient, depthFirstRecursion, getIsRecursionFunc, drawRoundRectangle, drawLinearPath, drawBezierPath, createG, updateForeignObject, getRectangleByElements, NODE_TO_PARENT, createForeignObject, removeSelectedElement, PlaitHistoryBoard, setStrokeLinecap, ACTIVE_STROKE_WIDTH, createText, PlaitPointerType, NODE_TO_INDEX, PlaitChildrenElementComponent, isMainPointer, toViewBoxPoint, toHostPoint, getHitElementByPoint, distanceBetweenPointAndPoint, CoreTransforms, BOARD_TO_HOST, BoardTransforms, throttleRAF, temporaryDisableSelection, hotkeys, createClipboardContext, WritableClipboardType, ResizeCursorClass, addClipboardContext, PlaitPluginKey } from '@plait/core';
4
4
  import { MindLayoutType, AbstractNode, isIndentedLayout, isHorizontalLayout, isHorizontalLogicLayout, ConnectingPosition, getNonAbstractChildren, isStandardLayout, isLeftLayout, isRightLayout, isVerticalLogicLayout, isTopLayout, isBottomLayout, getCorrectStartEnd, getAbstractLayout, GlobalLayout } from '@plait/layouts';
5
- import { PlaitMarkEditor, MarkTypes, DEFAULT_FONT_SIZE, TEXT_DEFAULT_HEIGHT, buildText, getTextSize, TextManage, ExitOrigin, getTextFromClipboard } from '@plait/text';
5
+ import { TEXT_DEFAULT_HEIGHT, buildText, PlaitMarkEditor, MarkTypes, DEFAULT_FONT_SIZE, getTextSize, TextManage, ExitOrigin } from '@plait/text';
6
6
  import { fromEvent, Subject } from 'rxjs';
7
- import { getFirstTextEditor, RESIZE_HANDLE_DIAMETER, getRectangleResizeHandleRefs, addElementOfFocusedImage, removeElementOfFocusedImage, getFirstTextManage, Generator, CommonPluginElement, ImageGenerator, WithTextPluginKey, isDrawingMode, isDndMode, setCreationMode, BoardCreationMode, isExpandHotkey, isTabHotkey, isEnterHotkey, isVirtualKey, isDelete, isSpaceHotkey, getElementOfFocusedImage, MediaKeys, acceptImageTypes, buildImage, withResize, ResizeHandle } from '@plait/common';
7
+ import { getFirstTextEditor, RESIZE_HANDLE_DIAMETER, getRectangleResizeHandleRefs, addElementOfFocusedImage, removeElementOfFocusedImage, getFirstTextManage, PropertyTransforms, Generator, CommonPluginElement, ImageGenerator, WithTextPluginKey, isDrawingMode, isDndMode, setCreationMode, BoardCreationMode, isExpandHotkey, isTabHotkey, isEnterHotkey, isVirtualKey, isDelete, isSpaceHotkey, getElementOfFocusedImage, acceptImageTypes, buildImage, withResize, ResizeHandle, getElementsText } from '@plait/common';
8
8
  import { Node as Node$1, Path as Path$1 } from 'slate';
9
9
  import { pointsOnBezierCurves } from 'points-on-curve';
10
10
  import { take, filter } from 'rxjs/operators';
@@ -208,18 +208,6 @@ function getEmojiFontSize(element) {
208
208
  }
209
209
  }
210
210
 
211
- const TOPIC_COLOR = '#333';
212
- const TOPIC_FONT_SIZE = 14;
213
- const ROOT_TOPIC_FONT_SIZE = 18;
214
- const ROOT_TOPIC_HEIGHT = 25;
215
- const ROOT_TOPIC_WIDTH = 72;
216
- const TOPIC_DEFAULT_MAX_WORD_COUNT = 34;
217
- const DEFAULT_FONT_FAMILY = 'PingFangSC-Regular, "PingFang SC"';
218
- const BRANCH_FONT_FAMILY = 'PingFangSC-Medium, "PingFang SC"';
219
- const NodeTopicThreshold = {
220
- defaultTextMaxWidth: 34 * 14
221
- };
222
-
223
211
  const getAvailableProperty = (board, element, propertyKey) => {
224
212
  return element[propertyKey];
225
213
  };
@@ -491,240 +479,6 @@ const getShapeByElement = (board, element) => {
491
479
  return shape || MindElementShape.roundRectangle;
492
480
  };
493
481
 
494
- const NodeDefaultSpace = {
495
- horizontal: {
496
- nodeAndText: BASE * 2.5,
497
- emojiAndText: BASE * 1.5
498
- },
499
- vertical: {
500
- nodeAndText: BASE,
501
- nodeAndImage: BASE,
502
- imageAndText: BASE * 1.5
503
- }
504
- };
505
- const RootDefaultSpace = {
506
- horizontal: {
507
- nodeAndText: BASE * 4,
508
- emojiAndText: BASE * 2
509
- },
510
- vertical: {
511
- nodeAndText: BASE * 2
512
- }
513
- };
514
- const getHorizontalSpaceBetweenNodeAndText = (board, element) => {
515
- const isMind = PlaitMind.isMind(element);
516
- const nodeAndText = isMind ? RootDefaultSpace.horizontal.nodeAndText : NodeDefaultSpace.horizontal.nodeAndText;
517
- const strokeWidth = getStrokeWidthByElement(board, element);
518
- return nodeAndText + strokeWidth;
519
- };
520
- const getVerticalSpaceBetweenNodeAndText = (board, element) => {
521
- const isMind = PlaitMind.isMind(element);
522
- const strokeWidth = getStrokeWidthByElement(board, element);
523
- const nodeAndText = isMind ? RootDefaultSpace.vertical.nodeAndText : NodeDefaultSpace.vertical.nodeAndText;
524
- return nodeAndText + strokeWidth;
525
- };
526
- const getSpaceEmojiAndText = (element) => {
527
- const isMind = PlaitMind.isMind(element);
528
- const emojiAndText = isMind ? RootDefaultSpace.horizontal.emojiAndText : NodeDefaultSpace.horizontal.emojiAndText;
529
- return emojiAndText;
530
- };
531
- const NodeSpace = {
532
- getNodeWidth(board, element) {
533
- const nodeAndText = getHorizontalSpaceBetweenNodeAndText(board, element);
534
- if (MindElement.hasEmojis(element)) {
535
- return (NodeSpace.getEmojiLeftSpace(board, element) +
536
- getEmojisWidthHeight(board, element).width +
537
- getSpaceEmojiAndText(element) +
538
- NodeSpace.getNodeDynamicWidth(board, element) +
539
- nodeAndText);
540
- }
541
- return nodeAndText + NodeSpace.getNodeDynamicWidth(board, element) + nodeAndText;
542
- },
543
- getNodeHeight(board, element) {
544
- const nodeAndText = getVerticalSpaceBetweenNodeAndText(board, element);
545
- if (MindElement.hasImage(element)) {
546
- return NodeSpace.getTextTopSpace(board, element) + element.height + nodeAndText;
547
- }
548
- return nodeAndText + element.height + nodeAndText;
549
- },
550
- getNodeDynamicWidth(board, element) {
551
- const width = element.manualWidth || element.width;
552
- const imageWidth = MindElement.hasImage(element) ? element.data.image?.width : 0;
553
- return Math.max(width, imageWidth);
554
- },
555
- /**
556
- * use it when upload image first or resize image
557
- */
558
- getNodeNewDynamicWidth(board, element, imageWidth) {
559
- const width = element.manualWidth || element.width;
560
- return Math.max(width, imageWidth);
561
- },
562
- getNodeResizableMinWidth(board, element) {
563
- const minTopicWidth = NodeSpace.getNodeTopicMinWidth(board, element);
564
- if (MindElement.hasImage(element) && element.data.image.width > minTopicWidth) {
565
- return element.data.image.width;
566
- }
567
- else {
568
- return minTopicWidth;
569
- }
570
- },
571
- getNodeTopicMinWidth(board, element, isRoot = false) {
572
- const defaultFontSize = getNodeDefaultFontSize(isRoot);
573
- const editor = getFirstTextEditor(element);
574
- const marks = PlaitMarkEditor.getMarks(editor);
575
- const fontSize = marks[MarkTypes.fontSize] || defaultFontSize;
576
- return fontSize;
577
- },
578
- getTextLeftSpace(board, element) {
579
- const nodeAndText = getHorizontalSpaceBetweenNodeAndText(board, element);
580
- if (MindElement.hasEmojis(element)) {
581
- return NodeSpace.getEmojiLeftSpace(board, element) + getEmojisWidthHeight(board, element).width + getSpaceEmojiAndText(element);
582
- }
583
- else {
584
- return nodeAndText;
585
- }
586
- },
587
- getTextTopSpace(board, element) {
588
- const nodeAndText = getVerticalSpaceBetweenNodeAndText(board, element);
589
- if (MindElement.hasImage(element)) {
590
- return NodeSpace.getImageTopSpace(board, element) + element.data.image.height + NodeDefaultSpace.vertical.imageAndText;
591
- }
592
- else {
593
- return nodeAndText;
594
- }
595
- },
596
- getImageTopSpace(board, element) {
597
- const strokeWidth = getStrokeWidthByElement(board, element);
598
- return strokeWidth + NodeDefaultSpace.vertical.nodeAndImage;
599
- },
600
- getEmojiLeftSpace(board, element) {
601
- const options = board.getPluginOptions(WithMindPluginKey);
602
- const nodeAndText = getHorizontalSpaceBetweenNodeAndText(board, element);
603
- return nodeAndText - options.emojiPadding;
604
- },
605
- getEmojiTopSpace(board, element) {
606
- const nodeAndText = getVerticalSpaceBetweenNodeAndText(board, element);
607
- return nodeAndText;
608
- }
609
- };
610
- const getFontSizeBySlateElement = (text) => {
611
- const defaultFontSize = DEFAULT_FONT_SIZE;
612
- if (typeof text === 'string') {
613
- return defaultFontSize;
614
- }
615
- const marks = PlaitMarkEditor.getMarksByElement(text);
616
- const fontSize = marks[MarkTypes.fontSize] || defaultFontSize;
617
- return fontSize;
618
- };
619
- const getNodeDefaultFontSize = (isRoot = false) => {
620
- const defaultFontSize = isRoot ? ROOT_TOPIC_FONT_SIZE : DEFAULT_FONT_SIZE;
621
- return defaultFontSize;
622
- };
623
-
624
- function getRectangleByNode(node) {
625
- const x = node.x + node.hGap;
626
- let y = node.y + node.vGap;
627
- const width = node.width - node.hGap * 2;
628
- const height = node.height - node.vGap * 2;
629
- return {
630
- x,
631
- y,
632
- width,
633
- height
634
- };
635
- }
636
- function getRectangleByElement(board, element) {
637
- const width = NodeSpace.getNodeWidth(board, element);
638
- const height = NodeSpace.getNodeHeight(board, element);
639
- const nodeRectangle = {
640
- x: element.points[0][0],
641
- y: element.points[0][1],
642
- width,
643
- height
644
- };
645
- return nodeRectangle;
646
- }
647
- function isHitMindElement(board, point, element) {
648
- const node = MindElement.getNode(element);
649
- if (node && distanceBetweenPointAndRectangle(point[0], point[1], getRectangleByNode(node)) === 0) {
650
- return true;
651
- }
652
- else {
653
- return false;
654
- }
655
- }
656
-
657
- function getEmojiRectangle(board, element) {
658
- let { x, y } = getRectangleByNode(MindElement.getNode(element));
659
- x = x + NodeSpace.getEmojiLeftSpace(board, element);
660
- const { width, height } = getEmojisWidthHeight(board, element);
661
- return {
662
- x,
663
- y,
664
- width,
665
- height
666
- };
667
- }
668
- function getEmojiForeignRectangle(board, element) {
669
- let { x, y } = getRectangleByNode(MindElement.getNode(element));
670
- x = x + NodeSpace.getEmojiLeftSpace(board, element);
671
- const { width } = getEmojisWidthHeight(board, element);
672
- return {
673
- x,
674
- y,
675
- width,
676
- height: NodeSpace.getNodeHeight(board, element)
677
- };
678
- }
679
- const isHitEmojis = (board, element, point) => {
680
- return RectangleClient.isHit(RectangleClient.toRectangleClient([point, point]), getEmojiRectangle(board, element));
681
- };
682
-
683
- function getTopicRectangleByNode(board, node) {
684
- let nodeRectangle = getRectangleByNode(node);
685
- const result = getTopicRectangleByElement(board, nodeRectangle, node.origin);
686
- result.width = result.width;
687
- return result;
688
- }
689
- function getTopicRectangleByElement(board, nodeRectangle, element) {
690
- const x = nodeRectangle.x + NodeSpace.getTextLeftSpace(board, element);
691
- const y = nodeRectangle.y + NodeSpace.getTextTopSpace(board, element);
692
- const width = NodeSpace.getNodeDynamicWidth(board, element);
693
- const height = Math.ceil(element.height);
694
- return { height, width, x, y };
695
- }
696
-
697
- function getImageForeignRectangle(board, element) {
698
- let { x, y } = getRectangleByNode(MindElement.getNode(element));
699
- const elementWidth = element.manualWidth || element.width;
700
- x =
701
- elementWidth > element.data.image.width
702
- ? x + NodeSpace.getTextLeftSpace(board, element) + (elementWidth - element.data.image.width) / 2
703
- : x + NodeSpace.getTextLeftSpace(board, element);
704
- y = NodeSpace.getImageTopSpace(board, element) + y;
705
- const { width, height } = element.data.image;
706
- const rectangle = {
707
- x,
708
- y,
709
- width,
710
- height
711
- };
712
- return rectangle;
713
- }
714
- const isHitImage = (board, element, point) => {
715
- const imageRectangle = getImageForeignRectangle(board, element);
716
- const imageOutlineRectangle = RectangleClient.getOutlineRectangle(imageRectangle, -RESIZE_HANDLE_DIAMETER / 2);
717
- return RectangleClient.isPointInRectangle(imageOutlineRectangle, point);
718
- };
719
- const getHitImageResizeHandleDirection = (board, element, point) => {
720
- const imageRectangle = getImageForeignRectangle(board, element);
721
- const resizeHandleRefs = getRectangleResizeHandleRefs(imageRectangle, RESIZE_HANDLE_DIAMETER);
722
- const result = resizeHandleRefs.find(resizeHandleRef => {
723
- return RectangleClient.isHit(RectangleClient.toRectangleClient([point, point]), resizeHandleRef.rectangle);
724
- });
725
- return result;
726
- };
727
-
728
482
  function editTopic(element) {
729
483
  const component = PlaitElement.getComponent(element);
730
484
  component?.editTopic();
@@ -734,6 +488,18 @@ const getSelectedMindElements = (board) => {
734
488
  return selectedElements;
735
489
  };
736
490
 
491
+ const TOPIC_COLOR = '#333';
492
+ const TOPIC_FONT_SIZE = 14;
493
+ const ROOT_TOPIC_FONT_SIZE = 18;
494
+ const ROOT_TOPIC_HEIGHT = 25;
495
+ const ROOT_TOPIC_WIDTH = 72;
496
+ const TOPIC_DEFAULT_MAX_WORD_COUNT = 34;
497
+ const DEFAULT_FONT_FAMILY = 'PingFangSC-Regular, "PingFang SC"';
498
+ const BRANCH_FONT_FAMILY = 'PingFangSC-Medium, "PingFang SC"';
499
+ const NodeTopicThreshold = {
500
+ defaultTextMaxWidth: 34 * 14
501
+ };
502
+
737
503
  const getBranchDirectionsByLayouts = (branchLayouts) => {
738
504
  const branchDirections = [];
739
505
  branchLayouts.forEach(l => {
@@ -963,85 +729,314 @@ const isChildElement = (origin, child) => {
963
729
  if (parent === origin) {
964
730
  return true;
965
731
  }
966
- parent = MindElement.findParent(parent);
967
- }
968
- return false;
969
- };
970
- const getFirstLevelElement = (elements) => {
971
- let result = [];
972
- elements.forEach(element => {
973
- const isChild = elements.some(node => {
974
- return isChildElement(node, element);
975
- });
976
- if (!isChild) {
977
- result.push(element);
732
+ parent = MindElement.findParent(parent);
733
+ }
734
+ return false;
735
+ };
736
+ const getFirstLevelElement = (elements) => {
737
+ let result = [];
738
+ elements.forEach(element => {
739
+ const isChild = elements.some(node => {
740
+ return isChildElement(node, element);
741
+ });
742
+ if (!isChild) {
743
+ result.push(element);
744
+ }
745
+ });
746
+ return result;
747
+ };
748
+ const isChildRight = (node, child) => {
749
+ return node.x < child.x;
750
+ };
751
+ const isChildUp = (node, child) => {
752
+ return node.y > child.y;
753
+ };
754
+ const copyNewNode = (node) => {
755
+ const newNode = { ...node };
756
+ newNode.id = idCreator();
757
+ newNode.children = [];
758
+ for (const childNode of node.children) {
759
+ newNode.children.push(copyNewNode(childNode));
760
+ }
761
+ return newNode;
762
+ };
763
+ const insertMindElement = (board, inheritNode, path) => {
764
+ const newNode = {};
765
+ if (!inheritNode.isRoot) {
766
+ INHERIT_ATTRIBUTE_KEYS.forEach(attr => {
767
+ newNode[attr] = inheritNode[attr];
768
+ });
769
+ delete newNode.layout;
770
+ }
771
+ const newElement = createMindElement('', TOPIC_FONT_SIZE, TEXT_DEFAULT_HEIGHT, newNode);
772
+ Transforms.insertNode(board, newElement, path);
773
+ clearSelectedElement(board);
774
+ addSelectedElement(board, newElement);
775
+ setTimeout(() => {
776
+ editTopic(newElement);
777
+ });
778
+ };
779
+ const findLastChild = (child) => {
780
+ let result = child;
781
+ while (result.children.length !== 0) {
782
+ result = result.children[result.children.length - 1];
783
+ }
784
+ return result;
785
+ };
786
+ const divideElementByParent = (elements) => {
787
+ const abstractIncludedGroups = [];
788
+ const parentElements = [];
789
+ for (let i = 0; i < elements.length; i++) {
790
+ const parent = MindElement.getParent(elements[i]);
791
+ const parentIndex = parentElements.indexOf(parent);
792
+ if (parentIndex === -1) {
793
+ parentElements.push(parent);
794
+ abstractIncludedGroups.push([elements[i]]);
795
+ }
796
+ else {
797
+ abstractIncludedGroups[parentIndex].push(elements[i]);
798
+ }
799
+ }
800
+ return { parentElements, abstractIncludedGroups };
801
+ };
802
+ const getDefaultMindElementFontSize = (board, element) => {
803
+ if (PlaitMind.isMind(element)) {
804
+ return ROOT_TOPIC_FONT_SIZE;
805
+ }
806
+ if (MindElement.isMindElement(board, element)) {
807
+ return TOPIC_FONT_SIZE;
808
+ }
809
+ throw new Error('can not find default font-size');
810
+ };
811
+
812
+ const NodeDefaultSpace = {
813
+ horizontal: {
814
+ nodeAndText: BASE * 2.5,
815
+ emojiAndText: BASE * 1.5
816
+ },
817
+ vertical: {
818
+ nodeAndText: BASE,
819
+ nodeAndImage: BASE,
820
+ imageAndText: BASE * 1.5
821
+ }
822
+ };
823
+ const RootDefaultSpace = {
824
+ horizontal: {
825
+ nodeAndText: BASE * 4,
826
+ emojiAndText: BASE * 2
827
+ },
828
+ vertical: {
829
+ nodeAndText: BASE * 2
830
+ }
831
+ };
832
+ const getHorizontalSpaceBetweenNodeAndText = (board, element) => {
833
+ const isMind = PlaitMind.isMind(element);
834
+ const nodeAndText = isMind ? RootDefaultSpace.horizontal.nodeAndText : NodeDefaultSpace.horizontal.nodeAndText;
835
+ const strokeWidth = getStrokeWidthByElement(board, element);
836
+ return nodeAndText + strokeWidth;
837
+ };
838
+ const getVerticalSpaceBetweenNodeAndText = (board, element) => {
839
+ const isMind = PlaitMind.isMind(element);
840
+ const strokeWidth = getStrokeWidthByElement(board, element);
841
+ const nodeAndText = isMind ? RootDefaultSpace.vertical.nodeAndText : NodeDefaultSpace.vertical.nodeAndText;
842
+ return nodeAndText + strokeWidth;
843
+ };
844
+ const getSpaceEmojiAndText = (element) => {
845
+ const isMind = PlaitMind.isMind(element);
846
+ const emojiAndText = isMind ? RootDefaultSpace.horizontal.emojiAndText : NodeDefaultSpace.horizontal.emojiAndText;
847
+ return emojiAndText;
848
+ };
849
+ const NodeSpace = {
850
+ getNodeWidth(board, element) {
851
+ const nodeAndText = getHorizontalSpaceBetweenNodeAndText(board, element);
852
+ if (MindElement.hasEmojis(element)) {
853
+ return (NodeSpace.getEmojiLeftSpace(board, element) +
854
+ getEmojisWidthHeight(board, element).width +
855
+ getSpaceEmojiAndText(element) +
856
+ NodeSpace.getNodeDynamicWidth(board, element) +
857
+ nodeAndText);
858
+ }
859
+ return nodeAndText + NodeSpace.getNodeDynamicWidth(board, element) + nodeAndText;
860
+ },
861
+ getNodeHeight(board, element) {
862
+ const nodeAndText = getVerticalSpaceBetweenNodeAndText(board, element);
863
+ if (MindElement.hasImage(element)) {
864
+ return NodeSpace.getTextTopSpace(board, element) + element.height + nodeAndText;
865
+ }
866
+ return nodeAndText + element.height + nodeAndText;
867
+ },
868
+ getNodeDynamicWidth(board, element) {
869
+ const width = element.manualWidth || element.width;
870
+ const imageWidth = MindElement.hasImage(element) ? element.data.image?.width : 0;
871
+ return Math.max(width, imageWidth);
872
+ },
873
+ /**
874
+ * use it when upload image first or resize image
875
+ */
876
+ getNodeNewDynamicWidth(board, element, imageWidth) {
877
+ const width = element.manualWidth || element.width;
878
+ return Math.max(width, imageWidth);
879
+ },
880
+ getNodeResizableMinWidth(board, element) {
881
+ const minTopicWidth = NodeSpace.getNodeTopicMinWidth(board, element);
882
+ if (MindElement.hasImage(element) && element.data.image.width > minTopicWidth) {
883
+ return element.data.image.width;
884
+ }
885
+ else {
886
+ return minTopicWidth;
887
+ }
888
+ },
889
+ getNodeTopicMinWidth(board, element) {
890
+ const defaultFontSize = getDefaultMindElementFontSize(board, element);
891
+ const editor = getFirstTextEditor(element);
892
+ const marks = PlaitMarkEditor.getMarks(editor);
893
+ const fontSize = marks[MarkTypes.fontSize] || defaultFontSize;
894
+ return fontSize;
895
+ },
896
+ getTextLeftSpace(board, element) {
897
+ const nodeAndText = getHorizontalSpaceBetweenNodeAndText(board, element);
898
+ if (MindElement.hasEmojis(element)) {
899
+ return NodeSpace.getEmojiLeftSpace(board, element) + getEmojisWidthHeight(board, element).width + getSpaceEmojiAndText(element);
900
+ }
901
+ else {
902
+ return nodeAndText;
903
+ }
904
+ },
905
+ getTextTopSpace(board, element) {
906
+ const nodeAndText = getVerticalSpaceBetweenNodeAndText(board, element);
907
+ if (MindElement.hasImage(element)) {
908
+ return NodeSpace.getImageTopSpace(board, element) + element.data.image.height + NodeDefaultSpace.vertical.imageAndText;
978
909
  }
979
- });
980
- return result;
981
- };
982
- const isChildRight = (node, child) => {
983
- return node.x < child.x;
984
- };
985
- const isChildUp = (node, child) => {
986
- return node.y > child.y;
987
- };
988
- const copyNewNode = (node) => {
989
- const newNode = { ...node };
990
- newNode.id = idCreator();
991
- newNode.children = [];
992
- for (const childNode of node.children) {
993
- newNode.children.push(copyNewNode(childNode));
994
- }
995
- return newNode;
996
- };
997
- const extractNodesText = (node) => {
998
- let str = '';
999
- if (node) {
1000
- str += Node$1.string(node.data.topic) + ' ';
1001
- for (const childNode of node.children) {
1002
- str += extractNodesText(childNode);
910
+ else {
911
+ return nodeAndText;
1003
912
  }
913
+ },
914
+ getImageTopSpace(board, element) {
915
+ const strokeWidth = getStrokeWidthByElement(board, element);
916
+ return strokeWidth + NodeDefaultSpace.vertical.nodeAndImage;
917
+ },
918
+ getEmojiLeftSpace(board, element) {
919
+ const options = board.getPluginOptions(WithMindPluginKey);
920
+ const nodeAndText = getHorizontalSpaceBetweenNodeAndText(board, element);
921
+ return nodeAndText - options.emojiPadding;
922
+ },
923
+ getEmojiTopSpace(board, element) {
924
+ const nodeAndText = getVerticalSpaceBetweenNodeAndText(board, element);
925
+ return nodeAndText;
1004
926
  }
1005
- return str;
1006
927
  };
1007
- const insertMindElement = (board, inheritNode, path) => {
1008
- const newNode = {};
1009
- if (!inheritNode.isRoot) {
1010
- INHERIT_ATTRIBUTE_KEYS.forEach(attr => {
1011
- newNode[attr] = inheritNode[attr];
1012
- });
1013
- delete newNode.layout;
928
+ const getFontSizeBySlateElement = (text) => {
929
+ const defaultFontSize = DEFAULT_FONT_SIZE;
930
+ if (typeof text === 'string') {
931
+ return defaultFontSize;
1014
932
  }
1015
- const newElement = createMindElement('', getNodeDefaultFontSize(), TEXT_DEFAULT_HEIGHT, newNode);
1016
- Transforms.insertNode(board, newElement, path);
1017
- clearSelectedElement(board);
1018
- addSelectedElement(board, newElement);
1019
- setTimeout(() => {
1020
- editTopic(newElement);
1021
- });
933
+ const marks = PlaitMarkEditor.getMarksByElement(text);
934
+ const fontSize = marks[MarkTypes.fontSize] || defaultFontSize;
935
+ return fontSize;
1022
936
  };
1023
- const findLastChild = (child) => {
1024
- let result = child;
1025
- while (result.children.length !== 0) {
1026
- result = result.children[result.children.length - 1];
937
+
938
+ function getRectangleByNode(node) {
939
+ const x = node.x + node.hGap;
940
+ let y = node.y + node.vGap;
941
+ const width = node.width - node.hGap * 2;
942
+ const height = node.height - node.vGap * 2;
943
+ return {
944
+ x,
945
+ y,
946
+ width,
947
+ height
948
+ };
949
+ }
950
+ function getRectangleByElement(board, element) {
951
+ const width = NodeSpace.getNodeWidth(board, element);
952
+ const height = NodeSpace.getNodeHeight(board, element);
953
+ const nodeRectangle = {
954
+ x: element.points[0][0],
955
+ y: element.points[0][1],
956
+ width,
957
+ height
958
+ };
959
+ return nodeRectangle;
960
+ }
961
+ function isHitMindElement(board, point, element) {
962
+ const node = MindElement.getNode(element);
963
+ if (node && distanceBetweenPointAndRectangle(point[0], point[1], getRectangleByNode(node)) === 0) {
964
+ return true;
965
+ }
966
+ else {
967
+ return false;
1027
968
  }
969
+ }
970
+
971
+ function getEmojiRectangle(board, element) {
972
+ let { x, y } = getRectangleByNode(MindElement.getNode(element));
973
+ x = x + NodeSpace.getEmojiLeftSpace(board, element);
974
+ const { width, height } = getEmojisWidthHeight(board, element);
975
+ return {
976
+ x,
977
+ y,
978
+ width,
979
+ height
980
+ };
981
+ }
982
+ function getEmojiForeignRectangle(board, element) {
983
+ let { x, y } = getRectangleByNode(MindElement.getNode(element));
984
+ x = x + NodeSpace.getEmojiLeftSpace(board, element);
985
+ const { width } = getEmojisWidthHeight(board, element);
986
+ return {
987
+ x,
988
+ y,
989
+ width,
990
+ height: NodeSpace.getNodeHeight(board, element)
991
+ };
992
+ }
993
+ const isHitEmojis = (board, element, point) => {
994
+ return RectangleClient.isHit(RectangleClient.toRectangleClient([point, point]), getEmojiRectangle(board, element));
995
+ };
996
+
997
+ function getTopicRectangleByNode(board, node) {
998
+ let nodeRectangle = getRectangleByNode(node);
999
+ const result = getTopicRectangleByElement(board, nodeRectangle, node.origin);
1000
+ result.width = result.width;
1028
1001
  return result;
1002
+ }
1003
+ function getTopicRectangleByElement(board, nodeRectangle, element) {
1004
+ const x = nodeRectangle.x + NodeSpace.getTextLeftSpace(board, element);
1005
+ const y = nodeRectangle.y + NodeSpace.getTextTopSpace(board, element);
1006
+ const width = NodeSpace.getNodeDynamicWidth(board, element);
1007
+ const height = Math.ceil(element.height);
1008
+ return { height, width, x, y };
1009
+ }
1010
+
1011
+ function getImageForeignRectangle(board, element) {
1012
+ let { x, y } = getRectangleByNode(MindElement.getNode(element));
1013
+ const elementWidth = element.manualWidth || element.width;
1014
+ x =
1015
+ elementWidth > element.data.image.width
1016
+ ? x + NodeSpace.getTextLeftSpace(board, element) + (elementWidth - element.data.image.width) / 2
1017
+ : x + NodeSpace.getTextLeftSpace(board, element);
1018
+ y = NodeSpace.getImageTopSpace(board, element) + y;
1019
+ const { width, height } = element.data.image;
1020
+ const rectangle = {
1021
+ x,
1022
+ y,
1023
+ width,
1024
+ height
1025
+ };
1026
+ return rectangle;
1027
+ }
1028
+ const isHitImage = (board, element, point) => {
1029
+ const imageRectangle = getImageForeignRectangle(board, element);
1030
+ const imageOutlineRectangle = RectangleClient.getOutlineRectangle(imageRectangle, -RESIZE_HANDLE_DIAMETER / 2);
1031
+ return RectangleClient.isPointInRectangle(imageOutlineRectangle, point);
1029
1032
  };
1030
- const divideElementByParent = (elements) => {
1031
- const abstractIncludedGroups = [];
1032
- const parentElements = [];
1033
- for (let i = 0; i < elements.length; i++) {
1034
- const parent = MindElement.getParent(elements[i]);
1035
- const parentIndex = parentElements.indexOf(parent);
1036
- if (parentIndex === -1) {
1037
- parentElements.push(parent);
1038
- abstractIncludedGroups.push([elements[i]]);
1039
- }
1040
- else {
1041
- abstractIncludedGroups[parentIndex].push(elements[i]);
1042
- }
1043
- }
1044
- return { parentElements, abstractIncludedGroups };
1033
+ const getHitImageResizeHandleDirection = (board, element, point) => {
1034
+ const imageRectangle = getImageForeignRectangle(board, element);
1035
+ const resizeHandleRefs = getRectangleResizeHandleRefs(imageRectangle, RESIZE_HANDLE_DIAMETER);
1036
+ const result = resizeHandleRefs.find(resizeHandleRef => {
1037
+ return RectangleClient.isHit(RectangleClient.toRectangleClient([point, point]), resizeHandleRef.rectangle);
1038
+ });
1039
+ return result;
1045
1040
  };
1046
1041
 
1047
1042
  const adjustRootToNode = (board, node) => {
@@ -1075,7 +1070,7 @@ const adjustNodeToRoot = (board, node) => {
1075
1070
  fontFamily: BRANCH_FONT_FAMILY,
1076
1071
  width: node.manualWidth ? node.manualWidth : undefined
1077
1072
  });
1078
- newElement.width = Math.max(width, getNodeDefaultFontSize(true));
1073
+ newElement.width = Math.max(width, ROOT_TOPIC_FONT_SIZE);
1079
1074
  newElement.height = height;
1080
1075
  return {
1081
1076
  ...newElement,
@@ -2376,33 +2371,8 @@ const insertAbstractNode = (board, path, start, end) => {
2376
2371
  addSelectedElement(board, mindElement);
2377
2372
  };
2378
2373
 
2379
- const setLayout = (board, layout, path) => {
2380
- correctLogicLayoutNode(board, layout, path);
2381
- const element = PlaitNode.get(board, path);
2382
- if (PlaitMind.isMind(element) && isStandardLayout(layout)) {
2383
- MindTransforms.setAbstractByStandardLayout(board, element);
2384
- }
2385
- Transforms.setNode(board, { layout }, path);
2386
- };
2387
- const correctLogicLayoutNode = (board, layout, path) => {
2388
- const node = PlaitNode.get(board, path);
2389
- if (node && layout) {
2390
- node.children?.forEach((value, index) => {
2391
- if (value.layout) {
2392
- if ((isHorizontalLogicLayout(layout) && isVerticalLogicLayout(value.layout)) ||
2393
- (isVerticalLogicLayout(layout) && isHorizontalLogicLayout(value.layout))) {
2394
- Transforms.setNode(board, { layout: null }, [...path, index]);
2395
- }
2396
- if (value.children?.length) {
2397
- correctLogicLayoutNode(board, layout, [...path, index]);
2398
- }
2399
- }
2400
- });
2401
- }
2402
- };
2403
-
2404
2374
  const normalizeWidthAndHeight = (board, element, width, height) => {
2405
- const minWidth = NodeSpace.getNodeTopicMinWidth(board, element, element.isRoot);
2375
+ const minWidth = NodeSpace.getNodeTopicMinWidth(board, element);
2406
2376
  const newWidth = width < minWidth * board.viewport.zoom ? minWidth : width / board.viewport.zoom;
2407
2377
  const newHeight = height / board.viewport.zoom;
2408
2378
  return { width: Math.ceil(newWidth), height: newHeight };
@@ -2554,8 +2524,57 @@ const setImage = (board, element, imageItem) => {
2554
2524
  Transforms.setNode(board, newElement, path);
2555
2525
  };
2556
2526
 
2527
+ const correctLogicLayoutNode = (board, layout, path) => {
2528
+ const node = PlaitNode.get(board, path);
2529
+ if (node && layout) {
2530
+ node.children?.forEach((value, index) => {
2531
+ if (value.layout) {
2532
+ if ((isHorizontalLogicLayout(layout) && isVerticalLogicLayout(value.layout)) ||
2533
+ (isVerticalLogicLayout(layout) && isHorizontalLogicLayout(value.layout))) {
2534
+ Transforms.setNode(board, { layout: null }, [...path, index]);
2535
+ }
2536
+ if (value.children?.length) {
2537
+ correctLogicLayoutNode(board, layout, [...path, index]);
2538
+ }
2539
+ }
2540
+ });
2541
+ }
2542
+ };
2543
+
2544
+ const setLayout = (board, type) => {
2545
+ const callback = (element, path) => {
2546
+ if (MindElement.isMindElement(board, element)) {
2547
+ correctLogicLayoutNode(board, type, path);
2548
+ const element = PlaitNode.get(board, path);
2549
+ if (PlaitMind.isMind(element) && isStandardLayout(type)) {
2550
+ let properties = { rightNodeCount: element.children.length / 2 };
2551
+ Transforms.setNode(board, properties, path);
2552
+ setAbstractByStandardLayout(board, element);
2553
+ }
2554
+ Transforms.setNode(board, { layout: type }, path);
2555
+ }
2556
+ };
2557
+ PropertyTransforms.setProperty(board, {}, { callback });
2558
+ };
2559
+ const setShape = (board, shape) => {
2560
+ PropertyTransforms.setProperty(board, { shape });
2561
+ };
2562
+ const setBranchShape = (board, branchShape) => {
2563
+ PropertyTransforms.setProperty(board, { branchShape });
2564
+ };
2565
+ const setBranchWidth = (board, branchWidth) => {
2566
+ PropertyTransforms.setProperty(board, { branchWidth });
2567
+ };
2568
+ const setBranchColor = (board, branchColor) => {
2569
+ PropertyTransforms.setProperty(board, { branchColor });
2570
+ };
2571
+
2557
2572
  const MindTransforms = {
2558
2573
  setLayout,
2574
+ setShape,
2575
+ setBranchShape,
2576
+ setBranchWidth,
2577
+ setBranchColor,
2559
2578
  setTopic,
2560
2579
  setTopicSize,
2561
2580
  setNodeManualWidth,
@@ -3189,7 +3208,7 @@ const withNodeDnd = (board) => {
3189
3208
  pointerDown(event);
3190
3209
  return;
3191
3210
  }
3192
- const point = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
3211
+ const point = toViewBoxPoint(board, toHostPoint(board, event.x, event.y));
3193
3212
  const selectedElements = getSelectedElements(board);
3194
3213
  const hitElement = getHitElementByPoint(board, point);
3195
3214
  if (hitElement &&
@@ -3217,14 +3236,14 @@ const withNodeDnd = (board) => {
3217
3236
  if (!board.options.readonly && activeElements.length && startPoint) {
3218
3237
  // prevent text from being selected
3219
3238
  event.preventDefault();
3220
- const endPoint = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
3239
+ const endPoint = toViewBoxPoint(board, toHostPoint(board, event.x, event.y));
3221
3240
  const distance = distanceBetweenPointAndPoint(startPoint[0], startPoint[1], endPoint[0], endPoint[1]);
3222
3241
  if (distance < DRAG_MOVE_BUFFER) {
3223
3242
  return;
3224
3243
  }
3225
3244
  setIsDragging(board, true);
3226
3245
  fakeDropNodeG?.remove();
3227
- const detectPoint = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
3246
+ const detectPoint = toViewBoxPoint(board, toHostPoint(board, event.x, event.y));
3228
3247
  dropTarget = detectDropTarget(board, detectPoint, dropTarget, [...activeElements, ...correspondingElements]);
3229
3248
  if (dropTarget?.target) {
3230
3249
  targetPath = getPathByDropTarget(board, dropTarget);
@@ -3354,8 +3373,7 @@ const withAbstract = (board) => {
3354
3373
  return;
3355
3374
  }
3356
3375
  const activeAbstractElements = getSelectedElements(board).filter(element => AbstractNode.isAbstract(element));
3357
- const host = BOARD_TO_HOST.get(board);
3358
- const point = transformPoint(board, toPoint(event.x, event.y, host));
3376
+ const point = toViewBoxPoint(board, toHostPoint(board, event.x, event.y));
3359
3377
  activeAbstractElement = activeAbstractElements.find(element => {
3360
3378
  abstractHandlePosition = getHitAbstractHandle(board, element, point);
3361
3379
  return abstractHandlePosition;
@@ -3372,7 +3390,7 @@ const withAbstract = (board) => {
3372
3390
  board.pointerMove = (event) => {
3373
3391
  getSelectedElements(board);
3374
3392
  const host = BOARD_TO_HOST.get(board);
3375
- const endPoint = transformPoint(board, toPoint(event.x, event.y, host));
3393
+ const endPoint = toViewBoxPoint(board, toHostPoint(board, event.x, event.y));
3376
3394
  touchedAbstract = handleTouchedAbstract(board, touchedAbstract, endPoint);
3377
3395
  if (abstractHandlePosition && activeAbstractElement) {
3378
3396
  // prevent text from being selected
@@ -3454,25 +3472,25 @@ const withMindExtend = (board) => {
3454
3472
  const DefaultHotkey = 'm';
3455
3473
  const withCreateMind = (board) => {
3456
3474
  const newBoard = board;
3457
- const { keydown, mousedown, mousemove, mouseup } = board;
3475
+ const { keydown, pointerDown, pointerMove, pointerUp } = board;
3458
3476
  let fakeCreateNodeRef = null;
3459
3477
  let emptyMind = null;
3460
- newBoard.mousedown = (event) => {
3478
+ newBoard.pointerDown = (event) => {
3461
3479
  const isMindPointer = PlaitBoard.isPointer(board, MindPointerType.mind);
3462
3480
  let movingPoint = PlaitBoard.getMovingPointInBoard(board);
3463
3481
  if (!PlaitBoard.isReadonly(board) && movingPoint && isDrawingMode(board) && isMindPointer) {
3464
- movingPoint = transformPoint(board, toPoint(movingPoint[0], movingPoint[1], PlaitBoard.getHost(board)));
3482
+ movingPoint = toViewBoxPoint(board, toHostPoint(board, movingPoint[0], movingPoint[1]));
3465
3483
  const emptyMind = createEmptyMind(newBoard, movingPoint);
3466
3484
  Transforms.insertNode(board, emptyMind, [board.children.length]);
3467
3485
  clearSelectedElement(board);
3468
3486
  addSelectedElement(board, emptyMind);
3469
3487
  BoardTransforms.updatePointerType(board, PlaitPointerType.selection);
3470
3488
  }
3471
- mousedown(event);
3489
+ pointerDown(event);
3472
3490
  };
3473
- newBoard.mousemove = (event) => {
3491
+ newBoard.pointerMove = (event) => {
3474
3492
  if (PlaitBoard.isReadonly(board)) {
3475
- mousemove(event);
3493
+ pointerMove(event);
3476
3494
  return;
3477
3495
  }
3478
3496
  const isMindPointer = PlaitBoard.isPointer(board, MindPointerType.mind);
@@ -3480,7 +3498,7 @@ const withCreateMind = (board) => {
3480
3498
  throttleRAF(() => {
3481
3499
  let movingPoint = PlaitBoard.getMovingPointInBoard(board);
3482
3500
  if (movingPoint) {
3483
- movingPoint = transformPoint(newBoard, toPoint(movingPoint[0], movingPoint[1], PlaitBoard.getHost(board)));
3501
+ movingPoint = toViewBoxPoint(newBoard, toHostPoint(board, movingPoint[0], movingPoint[1]));
3484
3502
  emptyMind = createEmptyMind(newBoard, movingPoint);
3485
3503
  const nodeRectangle = getRectangleByElement(newBoard, emptyMind);
3486
3504
  const nodeG = drawRoundRectangleByElement(board, nodeRectangle, emptyMind);
@@ -3519,9 +3537,9 @@ const withCreateMind = (board) => {
3519
3537
  else {
3520
3538
  destroy();
3521
3539
  }
3522
- mousemove(event);
3540
+ pointerMove(event);
3523
3541
  };
3524
- newBoard.mouseup = (event) => {
3542
+ newBoard.pointerUp = (event) => {
3525
3543
  if (emptyMind) {
3526
3544
  Transforms.insertNode(board, emptyMind, [board.children.length]);
3527
3545
  clearSelectedElement(board);
@@ -3530,7 +3548,7 @@ const withCreateMind = (board) => {
3530
3548
  emptyMind = null;
3531
3549
  }
3532
3550
  destroy();
3533
- mouseup(event);
3551
+ pointerUp(event);
3534
3552
  };
3535
3553
  board.keydown = (event) => {
3536
3554
  if (PlaitBoard.isReadonly(board) || getSelectedElements(board).length > 0) {
@@ -3599,7 +3617,7 @@ const withMindHotkey = (baseBoard) => {
3599
3617
 
3600
3618
  const mouseMoveHandle = (board, event, nodeHoveredExtendRef) => {
3601
3619
  let target = null;
3602
- const point = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
3620
+ const point = toViewBoxPoint(board, toHostPoint(board, event.x, event.y));
3603
3621
  depthFirstRecursion(board, element => {
3604
3622
  if (target) {
3605
3623
  return;
@@ -3674,7 +3692,7 @@ const withNodeImage = (board) => {
3674
3692
  pointerDown(event);
3675
3693
  return;
3676
3694
  }
3677
- const point = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
3695
+ const point = toViewBoxPoint(board, toHostPoint(board, event.x, event.y));
3678
3696
  const hitElement = getHitElementByPoint(board, point);
3679
3697
  const isHitImageResult = hitElement &&
3680
3698
  MindElement.isMindElement(board, hitElement) &&
@@ -3714,13 +3732,13 @@ const withNodeImage = (board) => {
3714
3732
  }
3715
3733
  globalPointerUp(event);
3716
3734
  };
3717
- board.setFragment = (data, rectangle, type) => {
3735
+ board.setFragment = (data, clipboardContext, rectangle, type) => {
3718
3736
  const selectedImageElement = getElementOfFocusedImage(board);
3719
3737
  if (selectedImageElement) {
3720
- setClipboardDataByMedia(data, selectedImageElement.data.image, MediaKeys.image);
3738
+ clipboardContext = createClipboardContext(WritableClipboardType.medias, [selectedImageElement.data.image], '');
3721
3739
  return;
3722
3740
  }
3723
- setFragment(data, rectangle, type);
3741
+ setFragment(data, clipboardContext, rectangle, type);
3724
3742
  };
3725
3743
  board.deleteFragment = (data) => {
3726
3744
  const selectedImageElement = getElementOfFocusedImage(board);
@@ -3729,28 +3747,29 @@ const withNodeImage = (board) => {
3729
3747
  }
3730
3748
  deleteFragment(data);
3731
3749
  };
3732
- board.insertFragment = (data, targetPoint) => {
3750
+ board.insertFragment = (data, clipboardData, targetPoint) => {
3733
3751
  const selectedElements = getSelectedElements(board);
3734
3752
  const isSelectedImage = !!getElementOfFocusedImage(board);
3735
3753
  const isSingleSelection = selectedElements.length === 1 && MindElement.isMindElement(board, selectedElements[0]);
3736
- if (data?.files.length && (isSingleSelection || isSelectedImage)) {
3737
- const acceptImageArray = acceptImageTypes.map(type => 'image/' + type);
3738
- const selectedElement = (selectedElements[0] || getElementOfFocusedImage(board));
3739
- if (acceptImageArray.includes(data?.files[0].type)) {
3740
- const imageFile = data.files[0];
3741
- buildImage(board, imageFile, DEFAULT_MIND_IMAGE_WIDTH, imageItem => {
3742
- MindTransforms.setImage(board, selectedElement, imageItem);
3743
- });
3754
+ if (isSelectedImage || isSingleSelection) {
3755
+ if (clipboardData?.files?.length) {
3756
+ const acceptImageArray = acceptImageTypes.map(type => 'image/' + type);
3757
+ const selectedElement = (selectedElements[0] || getElementOfFocusedImage(board));
3758
+ if (acceptImageArray.includes(clipboardData.files[0].type)) {
3759
+ const imageFile = clipboardData.files[0];
3760
+ buildImage(board, imageFile, DEFAULT_MIND_IMAGE_WIDTH, imageItem => {
3761
+ MindTransforms.setImage(board, selectedElement, imageItem);
3762
+ });
3763
+ return;
3764
+ }
3765
+ }
3766
+ if (clipboardData?.medias?.length) {
3767
+ const selectedElement = (selectedElements[0] || getElementOfFocusedImage(board));
3768
+ MindTransforms.setImage(board, selectedElement, clipboardData.medias[0]);
3744
3769
  return;
3745
3770
  }
3746
3771
  }
3747
- const imageItem = getClipboardDataByMedia(data, MediaKeys.image);
3748
- if (imageItem && (isSingleSelection || isSelectedImage)) {
3749
- const selectedElement = (selectedElements[0] || getElementOfFocusedImage(board));
3750
- MindTransforms.setImage(board, selectedElement, imageItem);
3751
- return;
3752
- }
3753
- insertFragment(data, targetPoint);
3772
+ insertFragment(data, clipboardData, targetPoint);
3754
3773
  };
3755
3774
  return board;
3756
3775
  };
@@ -3904,13 +3923,6 @@ const buildClipboardData = (board, selectedElements, startPoint) => {
3904
3923
  });
3905
3924
  return result;
3906
3925
  };
3907
- const setMindClipboardData = (data, elements) => {
3908
- const text = elements.reduce((string, currentNode) => {
3909
- return string + extractNodesText(currentNode);
3910
- }, '');
3911
- setClipboardData(data, elements);
3912
- setClipboardDataByText(data, text);
3913
- };
3914
3926
  const insertClipboardData = (board, elements, targetPoint) => {
3915
3927
  let newElement, path;
3916
3928
  const selectedElements = getSelectedElements(board);
@@ -3929,7 +3941,7 @@ const insertClipboardData = (board, elements, targetPoint) => {
3929
3941
  ...styles,
3930
3942
  width: newElement.manualWidth ? newElement.manualWidth : undefined
3931
3943
  });
3932
- newElement.width = Math.max(width, getNodeDefaultFontSize());
3944
+ newElement.width = Math.max(width, ROOT_TOPIC_FONT_SIZE);
3933
3945
  newElement.height = height;
3934
3946
  }
3935
3947
  // handle abstract start and end
@@ -3984,32 +3996,40 @@ const withMindFragment = (baseBoard) => {
3984
3996
  }
3985
3997
  return getDeletedFragment(data);
3986
3998
  };
3987
- board.setFragment = (data, rectangle, type) => {
3999
+ board.setFragment = (data, clipboardContext, rectangle, type) => {
3988
4000
  const targetMindElements = getSelectedMindElements(board);
3989
4001
  const firstLevelElements = getFirstLevelElement(targetMindElements);
3990
4002
  if (firstLevelElements.length) {
3991
4003
  const elements = buildClipboardData(board, firstLevelElements, rectangle ? [rectangle.x, rectangle.y] : [0, 0]);
3992
- setMindClipboardData(data, elements);
4004
+ const text = getElementsText(targetMindElements);
4005
+ if (!clipboardContext) {
4006
+ clipboardContext = createClipboardContext(WritableClipboardType.elements, elements, text);
4007
+ }
4008
+ else {
4009
+ clipboardContext = addClipboardContext(clipboardContext, {
4010
+ text,
4011
+ type: WritableClipboardType.elements,
4012
+ data: elements
4013
+ });
4014
+ }
3993
4015
  }
3994
- setFragment(data, rectangle, type);
4016
+ setFragment(data, clipboardContext, rectangle, type);
3995
4017
  };
3996
- board.insertFragment = (data, targetPoint) => {
3997
- const elements = getDataFromClipboard(data);
3998
- const mindElements = elements.filter(value => MindElement.isMindElement(board, value));
3999
- if (elements.length > 0 && mindElements.length > 0) {
4000
- insertClipboardData(board, mindElements, targetPoint);
4018
+ board.insertFragment = (data, clipboardData, targetPoint) => {
4019
+ if (clipboardData?.elements?.length) {
4020
+ const mindElements = clipboardData.elements?.filter(value => MindElement.isMindElement(board, value));
4021
+ if (mindElements && mindElements.length > 0) {
4022
+ insertClipboardData(board, mindElements, targetPoint);
4023
+ }
4001
4024
  }
4002
- else if (elements.length === 0) {
4025
+ if (clipboardData?.text) {
4003
4026
  const mindElements = getSelectedMindElements(board);
4004
4027
  if (mindElements.length === 1) {
4005
- const text = getTextFromClipboard(data);
4006
- if (text) {
4007
- insertClipboardText(board, mindElements[0], buildText(text));
4008
- return;
4009
- }
4028
+ insertClipboardText(board, mindElements[0], buildText(clipboardData.text));
4029
+ return;
4010
4030
  }
4011
4031
  }
4012
- insertFragment(data, targetPoint);
4032
+ insertFragment(data, clipboardData, targetPoint);
4013
4033
  };
4014
4034
  return board;
4015
4035
  };
@@ -4115,7 +4135,7 @@ const withMind = (baseBoard) => {
4115
4135
  dblclick(event);
4116
4136
  return;
4117
4137
  }
4118
- const point = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
4138
+ const point = toViewBoxPoint(board, toHostPoint(board, event.x, event.y));
4119
4139
  board.children
4120
4140
  .filter(value => PlaitMind.isMind(value))
4121
4141
  .forEach(mindMap => {
@@ -4184,5 +4204,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
4184
4204
  * Generated bundle index. Do not edit.
4185
4205
  */
4186
4206
 
4187
- export { ABSTRACT_HANDLE_COLOR, ABSTRACT_HANDLE_LENGTH, ABSTRACT_HANDLE_MASK_WIDTH, ABSTRACT_INCLUDED_OUTLINE_OFFSET, AbstractHandlePosition, AbstractResizeState, BASE, BRANCH_FONT_FAMILY, BRANCH_WIDTH, BranchShape, DEFAULT_FONT_FAMILY, DEFAULT_MIND_IMAGE_WIDTH, DefaultAbstractNodeStyle, DefaultNodeStyle, ELEMENT_TO_NODE, EXTEND_DIAMETER, EXTEND_OFFSET, GRAY_COLOR, INHERIT_ATTRIBUTE_KEYS, IS_DRAGGING, LayoutDirection, LayoutDirectionsMap, MindColorfulThemeColor, MindDarkThemeColor, MindDefaultThemeColor, MindElement, MindElementShape, MindEmojiBaseComponent, MindNode, MindNodeComponent, MindPointerType, MindQueries, MindRetroThemeColor, MindSoftThemeColor, MindStarryThemeColor, MindThemeColor, MindThemeColors, MindTransforms, NodeSpace, NodeTopicThreshold, PRIMARY_COLOR, PlaitMind, PlaitMindComponent, QUICK_INSERT_CIRCLE_COLOR, QUICK_INSERT_CIRCLE_OFFSET, QUICK_INSERT_INNER_CROSS_COLOR, ROOT_TOPIC_FONT_SIZE, ROOT_TOPIC_HEIGHT, ROOT_TOPIC_WIDTH, STROKE_WIDTH, TOPIC_COLOR, TOPIC_DEFAULT_MAX_WORD_COUNT, TOPIC_FONT_SIZE, WithMindPluginKey, addActiveOnDragOrigin, addImageFocus, adjustAbstractToNode, adjustNodeToRoot, adjustRootToNode, canSetAbstract, copyNewNode, correctLayoutByDirection, createDefaultMind, createEmptyMind, createMindElement, deleteElementHandleAbstract, deleteElementsHandleRightNodeCount, detectDropTarget, directionCorrector, directionDetector, divideElementByParent, drawFakeDragNode, drawFakeDropNode, editTopic, extractNodesText, findLastChild, findLocationLeftIndex, findNewChildNodePath, findNewSiblingNodePath, 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, getSelectedMindElements, getShapeByElement, getStrokeByMindElement, getStrokeWidthByElement, getTopicRectangleByElement, getTopicRectangleByNode, getValidAbstractRefs, handleTouchedAbstract, hasPreviousOrNextOfDropPath, insertElementHandleAbstract, insertElementHandleRightNodeCount, insertMindElement, isChildElement, isChildOfAbstract, isChildRight, isChildUp, isCorrectLayout, isDragging, isDropStandardRight, isHitEmojis, isHitImage, isHitMindElement, isInRightBranchOfStandardLayout, isMixedLayout, isSetAbstract, isValidTarget, removeActiveOnDragOrigin, removeImageFocus, separateChildren, setIsDragging, withMind, withMindExtend };
4207
+ export { ABSTRACT_HANDLE_COLOR, ABSTRACT_HANDLE_LENGTH, ABSTRACT_HANDLE_MASK_WIDTH, ABSTRACT_INCLUDED_OUTLINE_OFFSET, AbstractHandlePosition, AbstractResizeState, BASE, BRANCH_FONT_FAMILY, BRANCH_WIDTH, BranchShape, DEFAULT_FONT_FAMILY, DEFAULT_MIND_IMAGE_WIDTH, DefaultAbstractNodeStyle, DefaultNodeStyle, ELEMENT_TO_NODE, EXTEND_DIAMETER, EXTEND_OFFSET, GRAY_COLOR, INHERIT_ATTRIBUTE_KEYS, IS_DRAGGING, LayoutDirection, LayoutDirectionsMap, MindColorfulThemeColor, MindDarkThemeColor, MindDefaultThemeColor, MindElement, MindElementShape, MindEmojiBaseComponent, MindNode, MindNodeComponent, MindPointerType, MindQueries, MindRetroThemeColor, MindSoftThemeColor, MindStarryThemeColor, MindThemeColor, MindThemeColors, MindTransforms, NodeSpace, NodeTopicThreshold, PRIMARY_COLOR, PlaitMind, PlaitMindComponent, QUICK_INSERT_CIRCLE_COLOR, QUICK_INSERT_CIRCLE_OFFSET, QUICK_INSERT_INNER_CROSS_COLOR, ROOT_TOPIC_FONT_SIZE, ROOT_TOPIC_HEIGHT, ROOT_TOPIC_WIDTH, STROKE_WIDTH, TOPIC_COLOR, TOPIC_DEFAULT_MAX_WORD_COUNT, TOPIC_FONT_SIZE, WithMindPluginKey, addActiveOnDragOrigin, addImageFocus, adjustAbstractToNode, adjustNodeToRoot, adjustRootToNode, canSetAbstract, copyNewNode, correctLayoutByDirection, createDefaultMind, createEmptyMind, createMindElement, deleteElementHandleAbstract, deleteElementsHandleRightNodeCount, detectDropTarget, directionCorrector, directionDetector, divideElementByParent, drawFakeDragNode, drawFakeDropNode, editTopic, findLastChild, findLocationLeftIndex, findNewChildNodePath, findNewSiblingNodePath, getAbstractBranchColor, getAbstractBranchWidth, getAbstractHandleRectangle, getAllowedDirection, getAvailableSubLayoutsByLayoutDirections, getBehindAbstracts, getBranchColorByMindElement, getBranchDirectionsByLayouts, getBranchShapeByMindElement, getBranchWidthByMindElement, getChildrenCount, getCorrespondingAbstract, getDefaultBranchColor, getDefaultBranchColorByIndex, getDefaultLayout, getDefaultMindElementFontSize, getEmojiFontSize, getEmojiForeignRectangle, getEmojiRectangle, getEmojisWidthHeight, getFillByElement, getFirstLevelElement, getFontSizeBySlateElement, getHitAbstractHandle, getHitImageResizeHandleDirection, getImageForeignRectangle, getInCorrectLayoutDirection, getLayoutDirection$1 as getLayoutDirection, getLayoutOptions, getLayoutReverseDirection, getLocationScope, getMindThemeColor, getNewNodeHeight, getNextBranchColor, getOverallAbstracts, getPathByDropTarget, getRectangleByElement, getRectangleByNode, getRectangleByResizingLocation, getRelativeStartEndByAbstractRef, getRootLayout, getSelectedMindElements, getShapeByElement, getStrokeByMindElement, getStrokeWidthByElement, getTopicRectangleByElement, getTopicRectangleByNode, getValidAbstractRefs, handleTouchedAbstract, hasPreviousOrNextOfDropPath, insertElementHandleAbstract, insertElementHandleRightNodeCount, insertMindElement, isChildElement, isChildOfAbstract, isChildRight, isChildUp, isCorrectLayout, isDragging, isDropStandardRight, isHitEmojis, isHitImage, isHitMindElement, isInRightBranchOfStandardLayout, isMixedLayout, isSetAbstract, isValidTarget, removeActiveOnDragOrigin, removeImageFocus, separateChildren, setIsDragging, withMind, withMindExtend };
4188
4208
  //# sourceMappingURL=plait-mind.mjs.map