@plait/mind 0.15.0 → 0.17.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.
- package/base/image-base.component.d.ts +16 -0
- package/base/index.d.ts +1 -0
- package/constants/default.d.ts +1 -0
- package/drawer/node-image.drawer.d.ts +16 -0
- package/esm2020/base/image-base.component.mjs +28 -0
- package/esm2020/base/index.mjs +2 -1
- package/esm2020/constants/default.mjs +2 -1
- package/esm2020/drawer/node-image.drawer.mjs +61 -0
- package/esm2020/interfaces/element-data.mjs +1 -1
- package/esm2020/interfaces/element.mjs +9 -1
- package/esm2020/interfaces/options.mjs +1 -1
- package/esm2020/node.component.mjs +19 -5
- package/esm2020/plugins/with-abstract-resize.board.mjs +1 -1
- package/esm2020/plugins/with-mind-extend.mjs +3 -4
- package/esm2020/plugins/with-mind-hotkey.mjs +42 -32
- package/esm2020/plugins/with-mind-image.mjs +49 -0
- package/esm2020/plugins/with-mind.board.mjs +1 -1
- package/esm2020/plugins/with-mind.mjs +3 -2
- package/esm2020/plugins/with-node-dnd.mjs +13 -6
- package/esm2020/transforms/abstract-node.mjs +1 -3
- package/esm2020/transforms/emoji.mjs +2 -2
- package/esm2020/transforms/image.mjs +10 -0
- package/esm2020/transforms/index.mjs +4 -2
- package/esm2020/transforms/node.mjs +2 -6
- package/esm2020/utils/abstract/common.mjs +5 -1
- package/esm2020/utils/draw/node-dnd.mjs +8 -1
- package/esm2020/utils/mind.mjs +2 -2
- package/esm2020/utils/node-style/branch.mjs +6 -1
- package/esm2020/utils/node-style/shape.mjs +8 -1
- package/esm2020/utils/position/emoji.mjs +8 -8
- package/esm2020/utils/position/image.mjs +21 -0
- package/esm2020/utils/position/index.mjs +2 -1
- package/esm2020/utils/space/emoji.mjs +3 -2
- package/esm2020/utils/space/node-space.mjs +25 -6
- package/fesm2015/plait-mind.mjs +451 -227
- package/fesm2015/plait-mind.mjs.map +1 -1
- package/fesm2020/plait-mind.mjs +448 -227
- package/fesm2020/plait-mind.mjs.map +1 -1
- package/interfaces/element-data.d.ts +9 -0
- package/interfaces/element.d.ts +2 -1
- package/interfaces/options.d.ts +4 -1
- package/node.component.d.ts +3 -0
- package/package.json +1 -1
- package/plugins/with-abstract-resize.board.d.ts +2 -2
- package/plugins/with-mind-hotkey.d.ts +2 -0
- package/plugins/with-mind-image.d.ts +2 -0
- package/plugins/with-mind.board.d.ts +0 -2
- package/transforms/image.d.ts +3 -0
- package/transforms/index.d.ts +1 -0
- package/utils/abstract/common.d.ts +1 -0
- package/utils/position/emoji.d.ts +4 -4
- package/utils/position/image.d.ts +6 -0
- package/utils/position/index.d.ts +1 -0
- package/utils/space/node-space.d.ts +1 -0
package/fesm2020/plait-mind.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { Component, ChangeDetectionStrategy, NgModule, NgZone,
|
|
2
|
+
import { Directive, Input, Component, ChangeDetectionStrategy, NgModule, NgZone, HostListener } from '@angular/core';
|
|
3
3
|
import * as i2 from '@plait/core';
|
|
4
|
-
import { DefaultThemeColor, ColorfulThemeColor, SoftThemeColor, RetroThemeColor, DarkThemeColor, StarryThemeColor, RectangleClient, PlaitElement, idCreator, isNullOrUndefined, Transforms, clearSelectedElement, addSelectedElement, PlaitBoard, depthFirstRecursion,
|
|
5
|
-
import { MindLayoutType, isIndentedLayout, getNonAbstractChildren, isStandardLayout,
|
|
6
|
-
import { TEXT_DEFAULT_HEIGHT, buildText, getTextSize, TextManage, TextModule, getTextFromClipboard } from '@plait/text';
|
|
4
|
+
import { DefaultThemeColor, ColorfulThemeColor, SoftThemeColor, RetroThemeColor, DarkThemeColor, StarryThemeColor, RectangleClient, PlaitElement, idCreator, isNullOrUndefined, Transforms, clearSelectedElement, addSelectedElement, PlaitNode, Path, PlaitBoard, depthFirstRecursion, drawLinearPath, drawBezierPath, createG, updateForeignObject, drawRoundRectangle, getRectangleByElements, getSelectedElements, NODE_TO_PARENT, distanceBetweenPointAndRectangle, createForeignObject, drawAbstractRoundRectangle, createText, PlaitPointerType, PlaitPluginElementComponent, NODE_TO_INDEX, PlaitModule, transformPoint, toPoint, getHitElements, distanceBetweenPointAndPoint, CLIP_BOARD_FORMAT_KEY, isMainPointer, BOARD_TO_HOST, PlaitPluginKey, throttleRAF, BoardTransforms, removeSelectedElement, PlaitHistoryBoard, hotkeys } from '@plait/core';
|
|
5
|
+
import { MindLayoutType, isIndentedLayout, AbstractNode, getNonAbstractChildren, isStandardLayout, isLeftLayout, isRightLayout, isVerticalLogicLayout, isHorizontalLogicLayout, isTopLayout, isBottomLayout, isHorizontalLayout, getCorrectStartEnd, getAbstractLayout, ConnectingPosition, GlobalLayout } from '@plait/layouts';
|
|
6
|
+
import { TEXT_DEFAULT_HEIGHT, buildText, getTextSize, TextManage, ExitOrigin, TextModule, getTextFromClipboard } from '@plait/text';
|
|
7
7
|
import { fromEvent, Subject } from 'rxjs';
|
|
8
8
|
import { Node, Path as Path$1 } from 'slate';
|
|
9
9
|
import { isKeyHotkey } from 'is-hotkey';
|
|
@@ -179,6 +179,7 @@ const MindThemeColor = {
|
|
|
179
179
|
}
|
|
180
180
|
};
|
|
181
181
|
|
|
182
|
+
const WithMindPluginKey = 'plait-mind-plugin-key';
|
|
182
183
|
const BASE = 4;
|
|
183
184
|
const PRIMARY_COLOR = '#6698FF';
|
|
184
185
|
const TRANSPARENT = 'transparent';
|
|
@@ -192,7 +193,7 @@ const QUICK_INSERT_CIRCLE_COLOR = '#6698FF';
|
|
|
192
193
|
const QUICK_INSERT_INNER_CROSS_COLOR = 'white';
|
|
193
194
|
|
|
194
195
|
function getEmojisWidthHeight(board, element) {
|
|
195
|
-
const options = board.
|
|
196
|
+
const options = board.getPluginOptions(WithMindPluginKey);
|
|
196
197
|
const count = element.data.emojis.length;
|
|
197
198
|
const fontSize = getEmojiFontSize(element);
|
|
198
199
|
return {
|
|
@@ -215,7 +216,9 @@ const NodeDefaultSpace = {
|
|
|
215
216
|
emojiAndText: BASE * 1.5
|
|
216
217
|
},
|
|
217
218
|
vertical: {
|
|
218
|
-
nodeAndText: BASE * 1.5
|
|
219
|
+
nodeAndText: BASE * 1.5,
|
|
220
|
+
nodeAndImage: BASE,
|
|
221
|
+
imageAndText: BASE * 1.5
|
|
219
222
|
}
|
|
220
223
|
};
|
|
221
224
|
const RootDefaultSpace = {
|
|
@@ -245,17 +248,25 @@ const getSpaceEmojiAndText = (element) => {
|
|
|
245
248
|
const NodeSpace = {
|
|
246
249
|
getNodeWidth(board, element) {
|
|
247
250
|
const nodeAndText = getHorizontalSpaceBetweenNodeAndText(board, element);
|
|
251
|
+
const imageWidth = MindElement.hasImage(element) ? element.data.image?.width : 0;
|
|
248
252
|
if (MindElement.hasEmojis(element)) {
|
|
249
253
|
return (NodeSpace.getEmojiLeftSpace(board, element) +
|
|
250
254
|
getEmojisWidthHeight(board, element).width +
|
|
251
255
|
getSpaceEmojiAndText(element) +
|
|
252
|
-
element.width +
|
|
256
|
+
Math.max(element.width, imageWidth) +
|
|
253
257
|
nodeAndText);
|
|
254
258
|
}
|
|
255
|
-
return nodeAndText + element.width + nodeAndText;
|
|
259
|
+
return nodeAndText + Math.max(element.width, imageWidth) + nodeAndText;
|
|
256
260
|
},
|
|
257
261
|
getNodeHeight(board, element) {
|
|
258
262
|
const nodeAndText = getVerticalSpaceBetweenNodeAndText(element);
|
|
263
|
+
if (MindElement.hasImage(element)) {
|
|
264
|
+
return (NodeDefaultSpace.vertical.nodeAndImage +
|
|
265
|
+
element.data.image.height +
|
|
266
|
+
NodeDefaultSpace.vertical.imageAndText +
|
|
267
|
+
element.height +
|
|
268
|
+
nodeAndText);
|
|
269
|
+
}
|
|
259
270
|
return nodeAndText + element.height + nodeAndText;
|
|
260
271
|
},
|
|
261
272
|
getTextLeftSpace(board, element) {
|
|
@@ -269,10 +280,18 @@ const NodeSpace = {
|
|
|
269
280
|
},
|
|
270
281
|
getTextTopSpace(element) {
|
|
271
282
|
const nodeAndText = getVerticalSpaceBetweenNodeAndText(element);
|
|
272
|
-
|
|
283
|
+
if (MindElement.hasImage(element)) {
|
|
284
|
+
return element.data.image.height + NodeDefaultSpace.vertical.nodeAndImage + NodeDefaultSpace.vertical.imageAndText;
|
|
285
|
+
}
|
|
286
|
+
else {
|
|
287
|
+
return nodeAndText;
|
|
288
|
+
}
|
|
289
|
+
},
|
|
290
|
+
getImageTopSpace(element) {
|
|
291
|
+
return NodeDefaultSpace.vertical.nodeAndImage;
|
|
273
292
|
},
|
|
274
293
|
getEmojiLeftSpace(board, element) {
|
|
275
|
-
const options = board.
|
|
294
|
+
const options = board.getPluginOptions(WithMindPluginKey);
|
|
276
295
|
const nodeAndText = getHorizontalSpaceBetweenNodeAndText(board, element);
|
|
277
296
|
return nodeAndText - options.emojiPadding;
|
|
278
297
|
},
|
|
@@ -296,12 +315,12 @@ function getEmojiRectangle(board, element) {
|
|
|
296
315
|
function getEmojiForeignRectangle(board, element) {
|
|
297
316
|
let { x, y } = getRectangleByNode(MindElement.getNode(element));
|
|
298
317
|
x = x + NodeSpace.getEmojiLeftSpace(board, element);
|
|
299
|
-
const { width
|
|
318
|
+
const { width } = getEmojisWidthHeight(board, element);
|
|
300
319
|
return {
|
|
301
320
|
x,
|
|
302
321
|
y,
|
|
303
322
|
width,
|
|
304
|
-
height:
|
|
323
|
+
height: NodeSpace.getNodeHeight(board, element)
|
|
305
324
|
};
|
|
306
325
|
}
|
|
307
326
|
const isHitEmojis = (board, element, point) => {
|
|
@@ -323,6 +342,23 @@ function getTopicRectangleByElement(board, nodeRectangle, element) {
|
|
|
323
342
|
return { height, width, x, y };
|
|
324
343
|
}
|
|
325
344
|
|
|
345
|
+
function getImageForeignRectangle(board, element) {
|
|
346
|
+
let { x, y } = getRectangleByNode(MindElement.getNode(element));
|
|
347
|
+
x = x + NodeSpace.getTextLeftSpace(board, element);
|
|
348
|
+
y = NodeSpace.getImageTopSpace(element) + y;
|
|
349
|
+
const { width, height } = element.data.image;
|
|
350
|
+
return {
|
|
351
|
+
x,
|
|
352
|
+
y,
|
|
353
|
+
width,
|
|
354
|
+
height
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
const isHitImage = (board, element, range) => {
|
|
358
|
+
const client = getImageForeignRectangle(board, element);
|
|
359
|
+
return RectangleClient.isHit(RectangleClient.toRectangleClient([range.anchor, range.focus]), client);
|
|
360
|
+
};
|
|
361
|
+
|
|
326
362
|
const NODE_MIN_WIDTH = 18;
|
|
327
363
|
|
|
328
364
|
function editTopic(element) {
|
|
@@ -432,7 +468,7 @@ const copyNewNode = (node) => {
|
|
|
432
468
|
const extractNodesText = (node) => {
|
|
433
469
|
let str = '';
|
|
434
470
|
if (node) {
|
|
435
|
-
str += Node.string(node.data.topic
|
|
471
|
+
str += Node.string(node.data.topic) + ' ';
|
|
436
472
|
for (const childNode of node.children) {
|
|
437
473
|
str += extractNodesText(childNode);
|
|
438
474
|
}
|
|
@@ -638,10 +674,180 @@ const getAvailableProperty = (board, element, propertyKey) => {
|
|
|
638
674
|
return element[propertyKey];
|
|
639
675
|
};
|
|
640
676
|
|
|
677
|
+
const separateChildren = (parentElement) => {
|
|
678
|
+
const rightNodeCount = parentElement.rightNodeCount;
|
|
679
|
+
const children = parentElement.children;
|
|
680
|
+
let rightChildren = [], leftChildren = [];
|
|
681
|
+
for (let i = 0; i < children.length; i++) {
|
|
682
|
+
const child = children[i];
|
|
683
|
+
if (AbstractNode.isAbstract(child) && child.end < rightNodeCount) {
|
|
684
|
+
rightChildren.push(child);
|
|
685
|
+
continue;
|
|
686
|
+
}
|
|
687
|
+
if (AbstractNode.isAbstract(child) && child.start >= rightNodeCount) {
|
|
688
|
+
leftChildren.push(child);
|
|
689
|
+
continue;
|
|
690
|
+
}
|
|
691
|
+
if (i < rightNodeCount) {
|
|
692
|
+
rightChildren.push(child);
|
|
693
|
+
}
|
|
694
|
+
else {
|
|
695
|
+
leftChildren.push(child);
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
return { leftChildren, rightChildren };
|
|
699
|
+
};
|
|
700
|
+
const isSetAbstract = (element) => {
|
|
701
|
+
return !!getCorrespondingAbstract(element);
|
|
702
|
+
};
|
|
703
|
+
const canSetAbstract = (element) => {
|
|
704
|
+
return !PlaitElement.isRootElement(element) && !AbstractNode.isAbstract(element) && !isSetAbstract(element);
|
|
705
|
+
};
|
|
706
|
+
const getCorrespondingAbstract = (element) => {
|
|
707
|
+
const parent = MindElement.findParent(element);
|
|
708
|
+
if (!parent)
|
|
709
|
+
return undefined;
|
|
710
|
+
const elementIndex = parent.children.indexOf(element);
|
|
711
|
+
return parent.children.find(child => {
|
|
712
|
+
return AbstractNode.isAbstract(child) && elementIndex >= child.start && elementIndex <= child.end;
|
|
713
|
+
});
|
|
714
|
+
};
|
|
715
|
+
const getBehindAbstracts = (element) => {
|
|
716
|
+
const parent = MindElement.findParent(element);
|
|
717
|
+
if (!parent)
|
|
718
|
+
return [];
|
|
719
|
+
const index = parent.children.indexOf(element);
|
|
720
|
+
return parent.children.filter(child => AbstractNode.isAbstract(child) && child.start > index);
|
|
721
|
+
};
|
|
722
|
+
/**
|
|
723
|
+
* return corresponding abstract that is not child of elements
|
|
724
|
+
*/
|
|
725
|
+
const getOverallAbstracts = (board, elements) => {
|
|
726
|
+
const overallAbstracts = [];
|
|
727
|
+
elements
|
|
728
|
+
.filter(value => !AbstractNode.isAbstract(value) && !PlaitMind.isMind(value))
|
|
729
|
+
.forEach(value => {
|
|
730
|
+
const abstract = getCorrespondingAbstract(value);
|
|
731
|
+
if (abstract && elements.indexOf(abstract) === -1 && overallAbstracts.indexOf(abstract) === -1) {
|
|
732
|
+
const { start, end } = abstract;
|
|
733
|
+
const parent = MindElement.getParent(value);
|
|
734
|
+
const isOverall = parent.children.slice(start, end + 1).every(includedElement => elements.indexOf(includedElement) > -1);
|
|
735
|
+
if (isOverall) {
|
|
736
|
+
overallAbstracts.push(abstract);
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
});
|
|
740
|
+
return overallAbstracts;
|
|
741
|
+
};
|
|
742
|
+
/**
|
|
743
|
+
* abstract node is valid when elements contains at least one element it is referenced with
|
|
744
|
+
*/
|
|
745
|
+
const getValidAbstractRefs = (board, elements) => {
|
|
746
|
+
const validAbstractRefs = [];
|
|
747
|
+
elements
|
|
748
|
+
.filter(value => !AbstractNode.isAbstract(value) && !PlaitMind.isMind(value))
|
|
749
|
+
.forEach(value => {
|
|
750
|
+
const abstract = getCorrespondingAbstract(value);
|
|
751
|
+
if (abstract && elements.indexOf(abstract) > 0) {
|
|
752
|
+
const index = validAbstractRefs.findIndex(value => value.abstract === abstract);
|
|
753
|
+
if (index === -1) {
|
|
754
|
+
validAbstractRefs.push({
|
|
755
|
+
abstract: abstract,
|
|
756
|
+
references: [value]
|
|
757
|
+
});
|
|
758
|
+
}
|
|
759
|
+
else {
|
|
760
|
+
validAbstractRefs[index].references.push(value);
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
});
|
|
764
|
+
return validAbstractRefs;
|
|
765
|
+
};
|
|
766
|
+
function getRelativeStartEndByAbstractRef(abstractRef, elements) {
|
|
767
|
+
const start = elements.indexOf(abstractRef.references[0]);
|
|
768
|
+
const end = elements.indexOf(abstractRef.references[abstractRef.references.length - 1]);
|
|
769
|
+
return { start, end };
|
|
770
|
+
}
|
|
771
|
+
const insertElementHandleAbstract = (board, path, step = 1,
|
|
772
|
+
//由此区分拖拽和新增到概要概括最后一个节点
|
|
773
|
+
isExtendPreviousNode = true, effectedAbstracts = new Map()) => {
|
|
774
|
+
const parent = PlaitNode.parent(board, path);
|
|
775
|
+
const hasPreviousNode = path[path.length - 1] !== 0;
|
|
776
|
+
let behindAbstracts;
|
|
777
|
+
if (!hasPreviousNode) {
|
|
778
|
+
behindAbstracts = parent.children.filter(child => AbstractNode.isAbstract(child));
|
|
779
|
+
}
|
|
780
|
+
else {
|
|
781
|
+
const selectedElement = PlaitNode.get(board, Path.previous(path));
|
|
782
|
+
behindAbstracts = getBehindAbstracts(selectedElement);
|
|
783
|
+
}
|
|
784
|
+
if (behindAbstracts.length) {
|
|
785
|
+
behindAbstracts.forEach(abstract => {
|
|
786
|
+
let newProperties = effectedAbstracts.get(abstract);
|
|
787
|
+
if (!newProperties) {
|
|
788
|
+
newProperties = { start: 0, end: 0 };
|
|
789
|
+
effectedAbstracts.set(abstract, newProperties);
|
|
790
|
+
}
|
|
791
|
+
newProperties.start = newProperties.start + step;
|
|
792
|
+
newProperties.end = newProperties.end + step;
|
|
793
|
+
});
|
|
794
|
+
}
|
|
795
|
+
if (!hasPreviousNode) {
|
|
796
|
+
return effectedAbstracts;
|
|
797
|
+
}
|
|
798
|
+
const selectedElement = PlaitNode.get(board, Path.previous(path));
|
|
799
|
+
const correspondingAbstract = getCorrespondingAbstract(selectedElement);
|
|
800
|
+
const isDragToLast = !isExtendPreviousNode && correspondingAbstract && correspondingAbstract.end === path[path.length - 1] - 1;
|
|
801
|
+
if (correspondingAbstract && !isDragToLast) {
|
|
802
|
+
let newProperties = effectedAbstracts.get(correspondingAbstract);
|
|
803
|
+
if (!newProperties) {
|
|
804
|
+
newProperties = { start: 0, end: 0 };
|
|
805
|
+
effectedAbstracts.set(correspondingAbstract, newProperties);
|
|
806
|
+
}
|
|
807
|
+
newProperties.end = newProperties.end + step;
|
|
808
|
+
}
|
|
809
|
+
return effectedAbstracts;
|
|
810
|
+
};
|
|
811
|
+
const deleteElementHandleAbstract = (board, deletableElements, effectedAbstracts = new Map()) => {
|
|
812
|
+
deletableElements.forEach(node => {
|
|
813
|
+
if (!PlaitMind.isMind(node)) {
|
|
814
|
+
const behindAbstracts = getBehindAbstracts(node).filter(abstract => !deletableElements.includes(abstract));
|
|
815
|
+
if (behindAbstracts.length) {
|
|
816
|
+
behindAbstracts.forEach(abstract => {
|
|
817
|
+
let newProperties = effectedAbstracts.get(abstract);
|
|
818
|
+
if (!newProperties) {
|
|
819
|
+
newProperties = { start: 0, end: 0 };
|
|
820
|
+
effectedAbstracts.set(abstract, newProperties);
|
|
821
|
+
}
|
|
822
|
+
newProperties.start = newProperties.start - 1;
|
|
823
|
+
newProperties.end = newProperties.end - 1;
|
|
824
|
+
});
|
|
825
|
+
}
|
|
826
|
+
const correspondingAbstract = getCorrespondingAbstract(node);
|
|
827
|
+
if (correspondingAbstract && !deletableElements.includes(correspondingAbstract)) {
|
|
828
|
+
let newProperties = effectedAbstracts.get(correspondingAbstract);
|
|
829
|
+
if (!newProperties) {
|
|
830
|
+
newProperties = { start: 0, end: 0 };
|
|
831
|
+
effectedAbstracts.set(correspondingAbstract, newProperties);
|
|
832
|
+
}
|
|
833
|
+
newProperties.end = newProperties.end - 1;
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
});
|
|
837
|
+
return effectedAbstracts;
|
|
838
|
+
};
|
|
839
|
+
const isChildOfAbstract = (board, element) => {
|
|
840
|
+
const ancestors = MindElement.getAncestors(board, element);
|
|
841
|
+
return !!ancestors.find((value) => AbstractNode.isAbstract(value));
|
|
842
|
+
};
|
|
843
|
+
|
|
641
844
|
/**
|
|
642
845
|
* Processing of branch color, width, style, etc. of the mind node
|
|
643
846
|
*/
|
|
644
847
|
const getBranchColorByMindElement = (board, element) => {
|
|
848
|
+
if (AbstractNode.isAbstract(element) || isChildOfAbstract(board, element)) {
|
|
849
|
+
return getAbstractBranchColor(board, element);
|
|
850
|
+
}
|
|
645
851
|
const branchColor = getAvailableProperty(board, element, 'branchColor');
|
|
646
852
|
return branchColor || getDefaultBranchColor(board, element);
|
|
647
853
|
};
|
|
@@ -695,6 +901,10 @@ const getStrokeByMindElement = (board, element) => {
|
|
|
695
901
|
const defaultRootStroke = getMindThemeColor(board).rootFill;
|
|
696
902
|
return element.strokeColor || defaultRootStroke;
|
|
697
903
|
}
|
|
904
|
+
if (AbstractNode.isAbstract(element) || isChildOfAbstract(board, element)) {
|
|
905
|
+
return element.strokeColor || DefaultAbstractNodeStyle.strokeColor;
|
|
906
|
+
;
|
|
907
|
+
}
|
|
698
908
|
return getAvailableProperty(board, element, 'strokeColor') || getDefaultBranchColor(board, element);
|
|
699
909
|
};
|
|
700
910
|
const getShapeByElement = (board, element) => {
|
|
@@ -1218,6 +1428,12 @@ const drawFakeDragNode = (board, element, offsetX, offsetY) => {
|
|
|
1218
1428
|
updateForeignObject(fakeEmojisG, foreignRectangle.width, foreignRectangle.height, foreignRectangle.x + offsetX, foreignRectangle.y + offsetY);
|
|
1219
1429
|
dragFakeNodeG?.append(fakeEmojisG);
|
|
1220
1430
|
}
|
|
1431
|
+
if (MindElement.hasImage(element)) {
|
|
1432
|
+
const fakeImageG = activeComponent.imageDrawer.g.cloneNode(true);
|
|
1433
|
+
const foreignRectangle = getImageForeignRectangle(board, element);
|
|
1434
|
+
updateForeignObject(fakeImageG, foreignRectangle.width, foreignRectangle.height, foreignRectangle.x + offsetX, foreignRectangle.y + offsetY);
|
|
1435
|
+
dragFakeNodeG?.append(fakeImageG);
|
|
1436
|
+
}
|
|
1221
1437
|
return dragFakeNodeG;
|
|
1222
1438
|
};
|
|
1223
1439
|
const drawFakeDropNode = (board, dropTarget, path) => {
|
|
@@ -1334,169 +1550,6 @@ const drawFakeDropNode = (board, dropTarget, path) => {
|
|
|
1334
1550
|
return fakeDropNodeG;
|
|
1335
1551
|
};
|
|
1336
1552
|
|
|
1337
|
-
const separateChildren = (parentElement) => {
|
|
1338
|
-
const rightNodeCount = parentElement.rightNodeCount;
|
|
1339
|
-
const children = parentElement.children;
|
|
1340
|
-
let rightChildren = [], leftChildren = [];
|
|
1341
|
-
for (let i = 0; i < children.length; i++) {
|
|
1342
|
-
const child = children[i];
|
|
1343
|
-
if (AbstractNode.isAbstract(child) && child.end < rightNodeCount) {
|
|
1344
|
-
rightChildren.push(child);
|
|
1345
|
-
continue;
|
|
1346
|
-
}
|
|
1347
|
-
if (AbstractNode.isAbstract(child) && child.start >= rightNodeCount) {
|
|
1348
|
-
leftChildren.push(child);
|
|
1349
|
-
continue;
|
|
1350
|
-
}
|
|
1351
|
-
if (i < rightNodeCount) {
|
|
1352
|
-
rightChildren.push(child);
|
|
1353
|
-
}
|
|
1354
|
-
else {
|
|
1355
|
-
leftChildren.push(child);
|
|
1356
|
-
}
|
|
1357
|
-
}
|
|
1358
|
-
return { leftChildren, rightChildren };
|
|
1359
|
-
};
|
|
1360
|
-
const isSetAbstract = (element) => {
|
|
1361
|
-
return !!getCorrespondingAbstract(element);
|
|
1362
|
-
};
|
|
1363
|
-
const canSetAbstract = (element) => {
|
|
1364
|
-
return !PlaitElement.isRootElement(element) && !AbstractNode.isAbstract(element) && !isSetAbstract(element);
|
|
1365
|
-
};
|
|
1366
|
-
const getCorrespondingAbstract = (element) => {
|
|
1367
|
-
const parent = MindElement.findParent(element);
|
|
1368
|
-
if (!parent)
|
|
1369
|
-
return undefined;
|
|
1370
|
-
const elementIndex = parent.children.indexOf(element);
|
|
1371
|
-
return parent.children.find(child => {
|
|
1372
|
-
return AbstractNode.isAbstract(child) && elementIndex >= child.start && elementIndex <= child.end;
|
|
1373
|
-
});
|
|
1374
|
-
};
|
|
1375
|
-
const getBehindAbstracts = (element) => {
|
|
1376
|
-
const parent = MindElement.findParent(element);
|
|
1377
|
-
if (!parent)
|
|
1378
|
-
return [];
|
|
1379
|
-
const index = parent.children.indexOf(element);
|
|
1380
|
-
return parent.children.filter(child => AbstractNode.isAbstract(child) && child.start > index);
|
|
1381
|
-
};
|
|
1382
|
-
/**
|
|
1383
|
-
* return corresponding abstract that is not child of elements
|
|
1384
|
-
*/
|
|
1385
|
-
const getOverallAbstracts = (board, elements) => {
|
|
1386
|
-
const overallAbstracts = [];
|
|
1387
|
-
elements
|
|
1388
|
-
.filter(value => !AbstractNode.isAbstract(value) && !PlaitMind.isMind(value))
|
|
1389
|
-
.forEach(value => {
|
|
1390
|
-
const abstract = getCorrespondingAbstract(value);
|
|
1391
|
-
if (abstract && elements.indexOf(abstract) === -1 && overallAbstracts.indexOf(abstract) === -1) {
|
|
1392
|
-
const { start, end } = abstract;
|
|
1393
|
-
const parent = MindElement.getParent(value);
|
|
1394
|
-
const isOverall = parent.children.slice(start, end + 1).every(includedElement => elements.indexOf(includedElement) > -1);
|
|
1395
|
-
if (isOverall) {
|
|
1396
|
-
overallAbstracts.push(abstract);
|
|
1397
|
-
}
|
|
1398
|
-
}
|
|
1399
|
-
});
|
|
1400
|
-
return overallAbstracts;
|
|
1401
|
-
};
|
|
1402
|
-
/**
|
|
1403
|
-
* abstract node is valid when elements contains at least one element it is referenced with
|
|
1404
|
-
*/
|
|
1405
|
-
const getValidAbstractRefs = (board, elements) => {
|
|
1406
|
-
const validAbstractRefs = [];
|
|
1407
|
-
elements
|
|
1408
|
-
.filter(value => !AbstractNode.isAbstract(value) && !PlaitMind.isMind(value))
|
|
1409
|
-
.forEach(value => {
|
|
1410
|
-
const abstract = getCorrespondingAbstract(value);
|
|
1411
|
-
if (abstract && elements.indexOf(abstract) > 0) {
|
|
1412
|
-
const index = validAbstractRefs.findIndex(value => value.abstract === abstract);
|
|
1413
|
-
if (index === -1) {
|
|
1414
|
-
validAbstractRefs.push({
|
|
1415
|
-
abstract: abstract,
|
|
1416
|
-
references: [value]
|
|
1417
|
-
});
|
|
1418
|
-
}
|
|
1419
|
-
else {
|
|
1420
|
-
validAbstractRefs[index].references.push(value);
|
|
1421
|
-
}
|
|
1422
|
-
}
|
|
1423
|
-
});
|
|
1424
|
-
return validAbstractRefs;
|
|
1425
|
-
};
|
|
1426
|
-
function getRelativeStartEndByAbstractRef(abstractRef, elements) {
|
|
1427
|
-
const start = elements.indexOf(abstractRef.references[0]);
|
|
1428
|
-
const end = elements.indexOf(abstractRef.references[abstractRef.references.length - 1]);
|
|
1429
|
-
return { start, end };
|
|
1430
|
-
}
|
|
1431
|
-
const insertElementHandleAbstract = (board, path, step = 1,
|
|
1432
|
-
//由此区分拖拽和新增到概要概括最后一个节点
|
|
1433
|
-
isExtendPreviousNode = true, effectedAbstracts = new Map()) => {
|
|
1434
|
-
const parent = PlaitNode.parent(board, path);
|
|
1435
|
-
const hasPreviousNode = path[path.length - 1] !== 0;
|
|
1436
|
-
let behindAbstracts;
|
|
1437
|
-
if (!hasPreviousNode) {
|
|
1438
|
-
behindAbstracts = parent.children.filter(child => AbstractNode.isAbstract(child));
|
|
1439
|
-
}
|
|
1440
|
-
else {
|
|
1441
|
-
const selectedElement = PlaitNode.get(board, Path.previous(path));
|
|
1442
|
-
behindAbstracts = getBehindAbstracts(selectedElement);
|
|
1443
|
-
}
|
|
1444
|
-
if (behindAbstracts.length) {
|
|
1445
|
-
behindAbstracts.forEach(abstract => {
|
|
1446
|
-
let newProperties = effectedAbstracts.get(abstract);
|
|
1447
|
-
if (!newProperties) {
|
|
1448
|
-
newProperties = { start: 0, end: 0 };
|
|
1449
|
-
effectedAbstracts.set(abstract, newProperties);
|
|
1450
|
-
}
|
|
1451
|
-
newProperties.start = newProperties.start + step;
|
|
1452
|
-
newProperties.end = newProperties.end + step;
|
|
1453
|
-
});
|
|
1454
|
-
}
|
|
1455
|
-
if (!hasPreviousNode) {
|
|
1456
|
-
return effectedAbstracts;
|
|
1457
|
-
}
|
|
1458
|
-
const selectedElement = PlaitNode.get(board, Path.previous(path));
|
|
1459
|
-
const correspondingAbstract = getCorrespondingAbstract(selectedElement);
|
|
1460
|
-
const isDragToLast = !isExtendPreviousNode && correspondingAbstract && correspondingAbstract.end === path[path.length - 1] - 1;
|
|
1461
|
-
if (correspondingAbstract && !isDragToLast) {
|
|
1462
|
-
let newProperties = effectedAbstracts.get(correspondingAbstract);
|
|
1463
|
-
if (!newProperties) {
|
|
1464
|
-
newProperties = { start: 0, end: 0 };
|
|
1465
|
-
effectedAbstracts.set(correspondingAbstract, newProperties);
|
|
1466
|
-
}
|
|
1467
|
-
newProperties.end = newProperties.end + step;
|
|
1468
|
-
}
|
|
1469
|
-
return effectedAbstracts;
|
|
1470
|
-
};
|
|
1471
|
-
const deleteElementHandleAbstract = (board, deletableElements, effectedAbstracts = new Map()) => {
|
|
1472
|
-
deletableElements.forEach(node => {
|
|
1473
|
-
if (!PlaitMind.isMind(node)) {
|
|
1474
|
-
const behindAbstracts = getBehindAbstracts(node).filter(abstract => !deletableElements.includes(abstract));
|
|
1475
|
-
if (behindAbstracts.length) {
|
|
1476
|
-
behindAbstracts.forEach(abstract => {
|
|
1477
|
-
let newProperties = effectedAbstracts.get(abstract);
|
|
1478
|
-
if (!newProperties) {
|
|
1479
|
-
newProperties = { start: 0, end: 0 };
|
|
1480
|
-
effectedAbstracts.set(abstract, newProperties);
|
|
1481
|
-
}
|
|
1482
|
-
newProperties.start = newProperties.start - 1;
|
|
1483
|
-
newProperties.end = newProperties.end - 1;
|
|
1484
|
-
});
|
|
1485
|
-
}
|
|
1486
|
-
const correspondingAbstract = getCorrespondingAbstract(node);
|
|
1487
|
-
if (correspondingAbstract && !deletableElements.includes(correspondingAbstract)) {
|
|
1488
|
-
let newProperties = effectedAbstracts.get(correspondingAbstract);
|
|
1489
|
-
if (!newProperties) {
|
|
1490
|
-
newProperties = { start: 0, end: 0 };
|
|
1491
|
-
effectedAbstracts.set(correspondingAbstract, newProperties);
|
|
1492
|
-
}
|
|
1493
|
-
newProperties.end = newProperties.end - 1;
|
|
1494
|
-
}
|
|
1495
|
-
}
|
|
1496
|
-
});
|
|
1497
|
-
return effectedAbstracts;
|
|
1498
|
-
};
|
|
1499
|
-
|
|
1500
1553
|
var AbstractHandlePosition;
|
|
1501
1554
|
(function (AbstractHandlePosition) {
|
|
1502
1555
|
AbstractHandlePosition["start"] = "start";
|
|
@@ -1911,6 +1964,14 @@ const MindElement = {
|
|
|
1911
1964
|
return false;
|
|
1912
1965
|
}
|
|
1913
1966
|
},
|
|
1967
|
+
hasImage(element) {
|
|
1968
|
+
if (element.data.image) {
|
|
1969
|
+
return true;
|
|
1970
|
+
}
|
|
1971
|
+
else {
|
|
1972
|
+
return false;
|
|
1973
|
+
}
|
|
1974
|
+
},
|
|
1914
1975
|
getEmojis(element) {
|
|
1915
1976
|
return element.data.emojis;
|
|
1916
1977
|
},
|
|
@@ -2155,9 +2216,7 @@ const setAbstractByElements = (board, groupParent, group) => {
|
|
|
2155
2216
|
};
|
|
2156
2217
|
const insertAbstractNode = (board, path, start, end) => {
|
|
2157
2218
|
const mindElement = createMindElement('概要', 28, 20, {
|
|
2158
|
-
strokeColor: DefaultAbstractNodeStyle.strokeColor,
|
|
2159
2219
|
strokeWidth: DefaultAbstractNodeStyle.branchWidth,
|
|
2160
|
-
branchColor: DefaultAbstractNodeStyle.branchColor,
|
|
2161
2220
|
branchWidth: DefaultAbstractNodeStyle.branchWidth
|
|
2162
2221
|
});
|
|
2163
2222
|
mindElement.start = start;
|
|
@@ -2197,12 +2256,9 @@ const normalizeWidthAndHeight = (board, width, height) => {
|
|
|
2197
2256
|
};
|
|
2198
2257
|
const setTopic = (board, element, topic, width, height) => {
|
|
2199
2258
|
const newElement = {
|
|
2200
|
-
data: { topic },
|
|
2259
|
+
data: { ...element.data, topic },
|
|
2201
2260
|
...normalizeWidthAndHeight(board, width, height)
|
|
2202
2261
|
};
|
|
2203
|
-
if (MindElement.hasEmojis(element)) {
|
|
2204
|
-
newElement.data.emojis = element.data.emojis;
|
|
2205
|
-
}
|
|
2206
2262
|
const path = PlaitBoard.findPath(board, element);
|
|
2207
2263
|
Transforms.setNode(board, newElement, path);
|
|
2208
2264
|
};
|
|
@@ -2281,7 +2337,7 @@ const removeEmoji = (board, element, emojiItem) => {
|
|
|
2281
2337
|
};
|
|
2282
2338
|
const replaceEmoji = (board, element, oldEmoji, newEmoji) => {
|
|
2283
2339
|
const newElement = {
|
|
2284
|
-
data: {
|
|
2340
|
+
data: { ...element.data }
|
|
2285
2341
|
};
|
|
2286
2342
|
const newEmojis = element.data.emojis.map(value => {
|
|
2287
2343
|
if (value === oldEmoji) {
|
|
@@ -2294,6 +2350,15 @@ const replaceEmoji = (board, element, oldEmoji, newEmoji) => {
|
|
|
2294
2350
|
Transforms.setNode(board, newElement, path);
|
|
2295
2351
|
};
|
|
2296
2352
|
|
|
2353
|
+
const removeImage = (board, element) => {
|
|
2354
|
+
const newElement = {
|
|
2355
|
+
data: { ...element.data }
|
|
2356
|
+
};
|
|
2357
|
+
delete newElement.data.image;
|
|
2358
|
+
const path = PlaitBoard.findPath(board, element);
|
|
2359
|
+
Transforms.setNode(board, newElement, path);
|
|
2360
|
+
};
|
|
2361
|
+
|
|
2297
2362
|
const MindTransforms = {
|
|
2298
2363
|
setLayout,
|
|
2299
2364
|
setTopic,
|
|
@@ -2307,7 +2372,8 @@ const MindTransforms = {
|
|
|
2307
2372
|
removeElements,
|
|
2308
2373
|
insertNodes,
|
|
2309
2374
|
insertAbstractNodes,
|
|
2310
|
-
setRightNodeCountByRefs
|
|
2375
|
+
setRightNodeCountByRefs,
|
|
2376
|
+
removeImage
|
|
2311
2377
|
};
|
|
2312
2378
|
|
|
2313
2379
|
class BaseDrawer {
|
|
@@ -2626,6 +2692,88 @@ class CollapseDrawer extends BaseDrawer {
|
|
|
2626
2692
|
}
|
|
2627
2693
|
}
|
|
2628
2694
|
|
|
2695
|
+
class MindImageBaseComponent {
|
|
2696
|
+
get nativeElement() {
|
|
2697
|
+
return this.elementRef.nativeElement;
|
|
2698
|
+
}
|
|
2699
|
+
constructor(elementRef) {
|
|
2700
|
+
this.elementRef = elementRef;
|
|
2701
|
+
}
|
|
2702
|
+
ngOnInit() { }
|
|
2703
|
+
}
|
|
2704
|
+
MindImageBaseComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: MindImageBaseComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
|
|
2705
|
+
MindImageBaseComponent.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.5", type: MindImageBaseComponent, inputs: { imageItem: "imageItem", board: "board", element: "element" }, host: { classAttribute: "mind-node-image" }, ngImport: i0 });
|
|
2706
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: MindImageBaseComponent, decorators: [{
|
|
2707
|
+
type: Directive,
|
|
2708
|
+
args: [{
|
|
2709
|
+
host: {
|
|
2710
|
+
class: 'mind-node-image'
|
|
2711
|
+
}
|
|
2712
|
+
}]
|
|
2713
|
+
}], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { imageItem: [{
|
|
2714
|
+
type: Input
|
|
2715
|
+
}], board: [{
|
|
2716
|
+
type: Input
|
|
2717
|
+
}], element: [{
|
|
2718
|
+
type: Input
|
|
2719
|
+
}] } });
|
|
2720
|
+
|
|
2721
|
+
class NodeImageDrawer {
|
|
2722
|
+
constructor(board, viewContainerRef) {
|
|
2723
|
+
this.board = board;
|
|
2724
|
+
this.viewContainerRef = viewContainerRef;
|
|
2725
|
+
this.componentRef = null;
|
|
2726
|
+
}
|
|
2727
|
+
drawImage(element) {
|
|
2728
|
+
this.destroy();
|
|
2729
|
+
if (MindElement.hasImage(element)) {
|
|
2730
|
+
this.g = createG();
|
|
2731
|
+
const foreignRectangle = getImageForeignRectangle(this.board, element);
|
|
2732
|
+
const foreignObject = createForeignObject(foreignRectangle.x, foreignRectangle.y, foreignRectangle.width, foreignRectangle.height);
|
|
2733
|
+
this.g.append(foreignObject);
|
|
2734
|
+
if (this.componentRef) {
|
|
2735
|
+
this.componentRef.destroy();
|
|
2736
|
+
this.componentRef = null;
|
|
2737
|
+
}
|
|
2738
|
+
const componentType = this.board.getPluginOptions(WithMindPluginKey).imageComponentType || MindImageBaseComponent;
|
|
2739
|
+
if (!componentType) {
|
|
2740
|
+
throw new Error('Not implement drawEmoji method error.');
|
|
2741
|
+
}
|
|
2742
|
+
this.componentRef = this.viewContainerRef.createComponent(componentType);
|
|
2743
|
+
this.componentRef.instance.board = this.board;
|
|
2744
|
+
this.componentRef.instance.element = element;
|
|
2745
|
+
this.componentRef.instance.imageItem = element.data.image;
|
|
2746
|
+
foreignObject.append(this.componentRef.instance.nativeElement);
|
|
2747
|
+
return this.g;
|
|
2748
|
+
}
|
|
2749
|
+
return undefined;
|
|
2750
|
+
}
|
|
2751
|
+
drawActive(element) {
|
|
2752
|
+
this.destroyActive();
|
|
2753
|
+
const imageRectangle = getImageForeignRectangle(this.board, element);
|
|
2754
|
+
const rectangle = RectangleClient.getOutlineRectangle(imageRectangle, -1);
|
|
2755
|
+
const roughSVG = PlaitBoard.getRoughSVG(this.board);
|
|
2756
|
+
this.activeG = roughSVG.rectangle(rectangle.x, rectangle.y, rectangle.width, rectangle.height, {
|
|
2757
|
+
stroke: PRIMARY_COLOR,
|
|
2758
|
+
fill: '',
|
|
2759
|
+
fillStyle: 'solid'
|
|
2760
|
+
});
|
|
2761
|
+
this.g?.append(this.activeG);
|
|
2762
|
+
}
|
|
2763
|
+
destroyActive() {
|
|
2764
|
+
this.activeG?.remove();
|
|
2765
|
+
}
|
|
2766
|
+
destroy() {
|
|
2767
|
+
if (this.g) {
|
|
2768
|
+
this.g.remove();
|
|
2769
|
+
}
|
|
2770
|
+
if (this.componentRef) {
|
|
2771
|
+
this.componentRef.destroy();
|
|
2772
|
+
this.componentRef = null;
|
|
2773
|
+
}
|
|
2774
|
+
}
|
|
2775
|
+
}
|
|
2776
|
+
|
|
2629
2777
|
// 1. When the text at the end has an italic attribute, the text is partially covered
|
|
2630
2778
|
// 2. There will be some differences in the width measured by different browsers
|
|
2631
2779
|
const WIDTH_BUFFER = 4;
|
|
@@ -2645,7 +2793,8 @@ class MindNodeComponent extends PlaitPluginElementComponent {
|
|
|
2645
2793
|
this.nodeInsertDrawer = new NodeInsertDrawer(this.board);
|
|
2646
2794
|
this.activeDrawer = new NodeActiveDrawer(this.board);
|
|
2647
2795
|
this.collapseDrawer = new CollapseDrawer(this.board);
|
|
2648
|
-
|
|
2796
|
+
this.imageDrawer = new NodeImageDrawer(this.board, this.viewContainerRef);
|
|
2797
|
+
const plugins = this.board.getPluginOptions(WithMindPluginKey).textPlugins;
|
|
2649
2798
|
this.textManage = new TextManage(this.board, this.viewContainerRef, () => {
|
|
2650
2799
|
const rect = getTopicRectangleByNode(this.board, this.node);
|
|
2651
2800
|
return rect;
|
|
@@ -2675,14 +2824,17 @@ class MindNodeComponent extends PlaitPluginElementComponent {
|
|
|
2675
2824
|
this.activeDrawer.draw(this.element, this.g, { selected: this.selected, isEditing: this.textManage.isEditing });
|
|
2676
2825
|
this.drawEmojis();
|
|
2677
2826
|
this.drawExtend();
|
|
2827
|
+
this.drawImage();
|
|
2678
2828
|
if (PlaitMind.isMind(this.context.parent)) {
|
|
2679
2829
|
this.g.classList.add('branch');
|
|
2680
2830
|
}
|
|
2681
2831
|
}
|
|
2682
2832
|
editTopic() {
|
|
2683
2833
|
this.activeDrawer.draw(this.element, this.g, { selected: this.selected, isEditing: true });
|
|
2684
|
-
this.textManage.edit(() => {
|
|
2685
|
-
|
|
2834
|
+
this.textManage.edit((origin) => {
|
|
2835
|
+
if (origin === ExitOrigin.default) {
|
|
2836
|
+
this.activeDrawer.draw(this.element, this.g, { selected: this.selected, isEditing: false });
|
|
2837
|
+
}
|
|
2686
2838
|
});
|
|
2687
2839
|
}
|
|
2688
2840
|
onContextChanged(value, previous) {
|
|
@@ -2695,6 +2847,7 @@ class MindNodeComponent extends PlaitPluginElementComponent {
|
|
|
2695
2847
|
this.drawShape();
|
|
2696
2848
|
this.drawLink();
|
|
2697
2849
|
this.drawEmojis();
|
|
2850
|
+
this.drawImage();
|
|
2698
2851
|
this.drawExtend();
|
|
2699
2852
|
this.textManage.updateText(this.element.data.topic);
|
|
2700
2853
|
this.textManage.updateRectangle();
|
|
@@ -2716,6 +2869,12 @@ class MindNodeComponent extends PlaitPluginElementComponent {
|
|
|
2716
2869
|
this.g.append(g);
|
|
2717
2870
|
}
|
|
2718
2871
|
}
|
|
2872
|
+
drawImage() {
|
|
2873
|
+
const image = this.imageDrawer.drawImage(this.element);
|
|
2874
|
+
if (image) {
|
|
2875
|
+
this.g.append(image);
|
|
2876
|
+
}
|
|
2877
|
+
}
|
|
2719
2878
|
drawShape() {
|
|
2720
2879
|
this.destroyShape();
|
|
2721
2880
|
const shape = getShapeByElement(this.board, this.node.origin);
|
|
@@ -2784,6 +2943,7 @@ class MindNodeComponent extends PlaitPluginElementComponent {
|
|
|
2784
2943
|
super.ngOnDestroy();
|
|
2785
2944
|
this.textManage.destroy();
|
|
2786
2945
|
this.nodeEmojisDrawer.destroy();
|
|
2946
|
+
this.imageDrawer.destroy();
|
|
2787
2947
|
this.destroy$.next();
|
|
2788
2948
|
this.destroy$.complete();
|
|
2789
2949
|
if (ELEMENT_TO_NODE.get(this.element) === this.node) {
|
|
@@ -2971,12 +3131,11 @@ const withNodeDnd = (board) => {
|
|
|
2971
3131
|
!AbstractNode.isAbstract(targetElement)) {
|
|
2972
3132
|
const targetElements = selectedElements.filter(element => MindElement.isMindElement(board, element) && !element.isRoot && !AbstractNode.isAbstract(element));
|
|
2973
3133
|
const isMultiple = selectedElements.length > 0 && selectedElements.includes(targetElement);
|
|
2974
|
-
const isSingle = !isMultiple && selectedElements.length === 0;
|
|
2975
3134
|
if (isMultiple) {
|
|
2976
3135
|
activeElements = targetElements;
|
|
2977
3136
|
startPoint = point;
|
|
2978
3137
|
}
|
|
2979
|
-
else
|
|
3138
|
+
else {
|
|
2980
3139
|
activeElements = [targetElement];
|
|
2981
3140
|
startPoint = point;
|
|
2982
3141
|
}
|
|
@@ -3030,6 +3189,7 @@ const withNodeDnd = (board) => {
|
|
|
3030
3189
|
}
|
|
3031
3190
|
if (dropTarget) {
|
|
3032
3191
|
const targetPathRef = board.pathRef(targetPath);
|
|
3192
|
+
const targetPreviousPathRef = Path.hasPrevious(targetPath) && board.pathRef(Path.previous(targetPath));
|
|
3033
3193
|
const targetElementPathRef = board.pathRef(PlaitBoard.findPath(board, dropTarget.target));
|
|
3034
3194
|
let abstractRefs = getValidAbstractRefs(board, firstLevelElements);
|
|
3035
3195
|
const normalElements = firstLevelElements
|
|
@@ -3067,9 +3227,16 @@ const withNodeDnd = (board) => {
|
|
|
3067
3227
|
let insertPath = targetPathRef.current;
|
|
3068
3228
|
const parentPath = Path.parent(targetPathRef.current || targetPath);
|
|
3069
3229
|
if (!insertPath) {
|
|
3070
|
-
|
|
3071
|
-
const
|
|
3072
|
-
|
|
3230
|
+
//当插入位置和选中节点位置相同时,使用记录的 previousPath
|
|
3231
|
+
const previousPath = targetPreviousPathRef && targetPreviousPathRef.unref();
|
|
3232
|
+
if (previousPath) {
|
|
3233
|
+
insertPath = Path.next(previousPath);
|
|
3234
|
+
}
|
|
3235
|
+
else {
|
|
3236
|
+
const parent = PlaitNode.get(board, parentPath);
|
|
3237
|
+
const children = getNonAbstractChildren(parent);
|
|
3238
|
+
insertPath = [...parentPath, children.length || 0];
|
|
3239
|
+
}
|
|
3073
3240
|
}
|
|
3074
3241
|
MindTransforms.insertNodes(board, normalElements, insertPath);
|
|
3075
3242
|
if (abstractRefs.length) {
|
|
@@ -3325,9 +3492,7 @@ const withMindExtend = (board) => {
|
|
|
3325
3492
|
newBoard.drawEmoji = (emoji, element) => {
|
|
3326
3493
|
throw new Error('Not implement drawEmoji method error.');
|
|
3327
3494
|
};
|
|
3328
|
-
|
|
3329
|
-
return { spaceBetweenEmojis: 4, emojiPadding: 0 };
|
|
3330
|
-
};
|
|
3495
|
+
board.setPluginOptions(WithMindPluginKey, { spaceBetweenEmojis: 4, emojiPadding: 0 });
|
|
3331
3496
|
return newBoard;
|
|
3332
3497
|
};
|
|
3333
3498
|
|
|
@@ -3476,38 +3641,18 @@ const withMindHotkey = (board) => {
|
|
|
3476
3641
|
event.preventDefault();
|
|
3477
3642
|
const targetMindElements = selectedElements.filter(el => MindElement.isMindElement(board, el));
|
|
3478
3643
|
const firstLevelElements = getFirstLevelElement(targetMindElements);
|
|
3479
|
-
|
|
3480
|
-
|
|
3481
|
-
|
|
3482
|
-
|
|
3483
|
-
|
|
3484
|
-
|
|
3485
|
-
|
|
3486
|
-
|
|
3487
|
-
|
|
3488
|
-
|
|
3489
|
-
}
|
|
3490
|
-
const firstElement = firstLevelElements[0];
|
|
3491
|
-
const firstElementParent = MindElement.findParent(firstElement);
|
|
3492
|
-
const hasSameParent = firstLevelElements.every(element => {
|
|
3493
|
-
return MindElement.findParent(element) === firstElementParent;
|
|
3494
|
-
});
|
|
3495
|
-
if (firstElementParent && hasSameParent && !activeElement) {
|
|
3496
|
-
const firstElementIndex = firstElementParent.children.indexOf(firstElement);
|
|
3497
|
-
const childrenCount = firstElementParent.children.length;
|
|
3498
|
-
// active parent element
|
|
3499
|
-
if (childrenCount === firstLevelElements.length) {
|
|
3500
|
-
activeElement = firstElementParent;
|
|
3501
|
-
}
|
|
3502
|
-
else {
|
|
3503
|
-
if (firstElementIndex > 0) {
|
|
3504
|
-
activeElement = firstElementParent.children[firstElementIndex - 1];
|
|
3505
|
-
}
|
|
3644
|
+
if (firstLevelElements.length > 0) {
|
|
3645
|
+
const deletableElements = [...firstLevelElements].reverse();
|
|
3646
|
+
const abstractRefs = deleteElementHandleAbstract(board, deletableElements);
|
|
3647
|
+
MindTransforms.setAbstractsByRefs(board, abstractRefs);
|
|
3648
|
+
const refs = deleteElementsHandleRightNodeCount(board, targetMindElements);
|
|
3649
|
+
MindTransforms.setRightNodeCountByRefs(board, refs);
|
|
3650
|
+
MindTransforms.removeElements(board, targetMindElements);
|
|
3651
|
+
const nextSelected = getNextSelectedElement(board, firstLevelElements);
|
|
3652
|
+
if (nextSelected) {
|
|
3653
|
+
addSelectedElement(board, nextSelected);
|
|
3506
3654
|
}
|
|
3507
3655
|
}
|
|
3508
|
-
if (activeElement) {
|
|
3509
|
-
addSelectedElement(board, activeElement);
|
|
3510
|
-
}
|
|
3511
3656
|
return;
|
|
3512
3657
|
}
|
|
3513
3658
|
if (!isVirtualKey(event) && !isSpaceHotkey(event) && isSingleSelection) {
|
|
@@ -3520,6 +3665,36 @@ const withMindHotkey = (board) => {
|
|
|
3520
3665
|
};
|
|
3521
3666
|
return board;
|
|
3522
3667
|
};
|
|
3668
|
+
const getNextSelectedElement = (board, firstLevelElements) => {
|
|
3669
|
+
let activeElement;
|
|
3670
|
+
const firstLevelElement = firstLevelElements[0];
|
|
3671
|
+
const firstLevelElementPath = PlaitBoard.findPath(board, firstLevelElement);
|
|
3672
|
+
let nextSelectedPath = firstLevelElementPath;
|
|
3673
|
+
if (Path.hasPrevious(firstLevelElementPath)) {
|
|
3674
|
+
nextSelectedPath = Path.previous(firstLevelElementPath);
|
|
3675
|
+
}
|
|
3676
|
+
if (AbstractNode.isAbstract(firstLevelElement)) {
|
|
3677
|
+
const parent = MindElement.getParent(firstLevelElement);
|
|
3678
|
+
if (!firstLevelElements.includes(parent.children[firstLevelElement.start])) {
|
|
3679
|
+
activeElement = parent.children[firstLevelElement.start];
|
|
3680
|
+
}
|
|
3681
|
+
}
|
|
3682
|
+
try {
|
|
3683
|
+
if (!activeElement) {
|
|
3684
|
+
activeElement = PlaitNode.get(board, nextSelectedPath);
|
|
3685
|
+
}
|
|
3686
|
+
}
|
|
3687
|
+
catch (error) { }
|
|
3688
|
+
const firstElement = firstLevelElements[0];
|
|
3689
|
+
const firstElementParent = MindElement.findParent(firstElement);
|
|
3690
|
+
const hasSameParent = firstLevelElements.every(element => {
|
|
3691
|
+
return MindElement.findParent(element) === firstElementParent;
|
|
3692
|
+
});
|
|
3693
|
+
if (firstElementParent && hasSameParent && !activeElement) {
|
|
3694
|
+
activeElement = firstElementParent;
|
|
3695
|
+
}
|
|
3696
|
+
return activeElement;
|
|
3697
|
+
};
|
|
3523
3698
|
const isExpandHotkey = (event) => {
|
|
3524
3699
|
return isKeyHotkey('mod+/', event);
|
|
3525
3700
|
};
|
|
@@ -3595,6 +3770,52 @@ const removeHovered = (element) => {
|
|
|
3595
3770
|
}
|
|
3596
3771
|
};
|
|
3597
3772
|
|
|
3773
|
+
const withMindImage = (board) => {
|
|
3774
|
+
let selectedImageElement = null;
|
|
3775
|
+
const { keydown, mousedown } = board;
|
|
3776
|
+
board.mousedown = (event) => {
|
|
3777
|
+
if (PlaitBoard.isReadonly(board) || !isMainPointer(event) || !PlaitBoard.isPointer(board, PlaitPointerType.selection)) {
|
|
3778
|
+
mousedown(event);
|
|
3779
|
+
return;
|
|
3780
|
+
}
|
|
3781
|
+
const point = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
|
|
3782
|
+
const range = { anchor: point, focus: point };
|
|
3783
|
+
const hitElements = getHitElements(board, { ranges: [range] });
|
|
3784
|
+
const hasImage = hitElements.length && MindElement.hasImage(hitElements[0]);
|
|
3785
|
+
const hitImage = hasImage && isHitImage(board, hitElements[0], range);
|
|
3786
|
+
if (hitImage) {
|
|
3787
|
+
const currentOptions = board.getPluginOptions(PlaitPluginKey.withSelection);
|
|
3788
|
+
board.setPluginOptions(PlaitPluginKey.withSelection, {
|
|
3789
|
+
isDisabledSelect: true
|
|
3790
|
+
});
|
|
3791
|
+
setTimeout(() => {
|
|
3792
|
+
board.setPluginOptions(PlaitPluginKey.withSelection, { ...currentOptions });
|
|
3793
|
+
}, 0);
|
|
3794
|
+
selectedImageElement = hitElements[0];
|
|
3795
|
+
const component = PlaitElement.getComponent(selectedImageElement);
|
|
3796
|
+
component.imageDrawer.drawActive(selectedImageElement);
|
|
3797
|
+
clearSelectedElement(board);
|
|
3798
|
+
}
|
|
3799
|
+
else {
|
|
3800
|
+
if (selectedImageElement) {
|
|
3801
|
+
const component = PlaitElement.getComponent(selectedImageElement);
|
|
3802
|
+
component && component.imageDrawer.destroyActive();
|
|
3803
|
+
}
|
|
3804
|
+
selectedImageElement = null;
|
|
3805
|
+
}
|
|
3806
|
+
mousedown(event);
|
|
3807
|
+
};
|
|
3808
|
+
board.keydown = (event) => {
|
|
3809
|
+
if (!PlaitBoard.isReadonly(board) && selectedImageElement && (hotkeys.isDeleteBackward(event) || hotkeys.isDeleteForward(event))) {
|
|
3810
|
+
MindTransforms.removeImage(board, selectedImageElement);
|
|
3811
|
+
selectedImageElement = null;
|
|
3812
|
+
return;
|
|
3813
|
+
}
|
|
3814
|
+
keydown(event);
|
|
3815
|
+
};
|
|
3816
|
+
return board;
|
|
3817
|
+
};
|
|
3818
|
+
|
|
3598
3819
|
const withMind = (board) => {
|
|
3599
3820
|
const { drawElement, dblclick, keydown, insertFragment, setFragment, deleteFragment, isHitSelection, getRectangle, isMovable, isRecursion } = board;
|
|
3600
3821
|
board.drawElement = (context) => {
|
|
@@ -3712,7 +3933,7 @@ const withMind = (board) => {
|
|
|
3712
3933
|
MindTransforms.removeElements(board, selectedElements);
|
|
3713
3934
|
deleteFragment(data);
|
|
3714
3935
|
};
|
|
3715
|
-
return withNodeHover(withMindHotkey(withMindExtend(withCreateMind(withAbstract(withNodeDnd(board))))));
|
|
3936
|
+
return withMindImage(withNodeHover(withMindHotkey(withMindExtend(withCreateMind(withAbstract(withNodeDnd(board)))))));
|
|
3716
3937
|
};
|
|
3717
3938
|
|
|
3718
3939
|
class MindEmojiBaseComponent {
|
|
@@ -3766,5 +3987,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImpor
|
|
|
3766
3987
|
* Generated bundle index. Do not edit.
|
|
3767
3988
|
*/
|
|
3768
3989
|
|
|
3769
|
-
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, MindModule, MindNode, MindNodeComponent, MindPointerType, MindQueries, MindRetroThemeColor, MindSoftThemeColor, MindStarryThemeColor, MindThemeColor, MindThemeColors, MindTransforms, NODE_MIN_WIDTH, 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, addActiveOnDragOrigin, adjustAbstractToNode, adjustNodeToRoot, adjustRootToNode, 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, getEmojiForeignRectangle, getEmojiRectangle, getFirstLevelElement, getHitAbstractHandle, getInCorrectLayoutDirection, getLayoutDirection$1 as getLayoutDirection, getLayoutReverseDirection, getLocationScope, getMindThemeColor, getNextBranchColor, getOverallAbstracts, getPathByDropTarget, getRectangleByElement, getRectangleByNode, getRectangleByResizingLocation, getRelativeStartEndByAbstractRef, getRootLayout, getShapeByElement, getStrokeByMindElement, getTopicRectangleByElement, getTopicRectangleByNode, getValidAbstractRefs, handleTouchedAbstract, hasAfterDraw, hasPreviousOrNextOfDropPath, insertElementHandleAbstract, insertElementHandleRightNodeCount, insertMindElement, isChildElement, isChildRight, isChildUp, isCorrectLayout, isDragging, isDropStandardRight, isHitEmojis, isHitMindElement, isInRightBranchOfStandardLayout, isMixedLayout, isSetAbstract, isValidTarget, isVirtualKey, removeActiveOnDragOrigin, separateChildren, setIsDragging, withMind, withMindExtend };
|
|
3990
|
+
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, NODE_MIN_WIDTH, 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, adjustAbstractToNode, adjustNodeToRoot, adjustRootToNode, 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, getEmojiForeignRectangle, getEmojiRectangle, getFirstLevelElement, getHitAbstractHandle, getImageForeignRectangle, getInCorrectLayoutDirection, getLayoutDirection$1 as getLayoutDirection, getLayoutReverseDirection, getLocationScope, getMindThemeColor, getNextBranchColor, getOverallAbstracts, getPathByDropTarget, getRectangleByElement, getRectangleByNode, getRectangleByResizingLocation, getRelativeStartEndByAbstractRef, getRootLayout, getShapeByElement, getStrokeByMindElement, 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, separateChildren, setIsDragging, withMind, withMindExtend };
|
|
3770
3991
|
//# sourceMappingURL=plait-mind.mjs.map
|