@tmagic/editor 1.8.0-beta.2 → 1.8.0-beta.20
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/dist/es/Editor.vue_vue_type_script_setup_true_lang.js +43 -9
- package/dist/es/components/CodeBlockEditor.vue_vue_type_script_setup_true_lang.js +8 -4
- package/dist/es/components/CodeParams.vue_vue_type_script_setup_true_lang.js +3 -2
- package/dist/es/components/CompareForm.vue_vue_type_script_setup_true_lang.js +22 -98
- package/dist/es/components/ContentMenu.vue_vue_type_script_setup_true_lang.js +32 -9
- package/dist/es/components/FloatingBox.vue_vue_type_script_setup_true_lang.js +68 -17
- package/dist/es/components/Icon.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/components/Resizer.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/components/ScrollBar.js +0 -1
- package/dist/es/components/ScrollBar.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/components/ScrollViewer.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/components/SearchInput.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/components/SplitView.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/components/ToolButton.vue_vue_type_script_setup_true_lang.js +7 -7
- package/dist/es/components/Tree.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/components/TreeNode.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/components/ViewForm.js +5 -0
- package/dist/es/components/ViewForm.vue_vue_type_script_setup_true_lang.js +58 -0
- package/dist/es/editorProps.js +9 -1
- package/dist/es/fields/Code.vue_vue_type_script_setup_true_lang.js +16 -5
- package/dist/es/fields/CodeLink.vue_vue_type_script_setup_true_lang.js +7 -7
- package/dist/es/fields/CodeSelect.vue_vue_type_script_setup_true_lang.js +81 -44
- package/dist/es/fields/CodeSelectCol.vue_vue_type_script_setup_true_lang.js +10 -3
- package/dist/es/fields/CondOpSelect.vue_vue_type_script_setup_true_lang.js +7 -19
- package/dist/es/fields/DataSourceFieldSelect/FieldSelect.vue_vue_type_script_setup_true_lang.js +13 -6
- package/dist/es/fields/DataSourceFieldSelect/Index.vue_vue_type_script_setup_true_lang.js +11 -8
- package/dist/es/fields/DataSourceFields.vue_vue_type_script_setup_true_lang.js +39 -12
- package/dist/es/fields/DataSourceInput.vue_vue_type_script_setup_true_lang.js +11 -20
- package/dist/es/fields/DataSourceMethodSelect.vue_vue_type_script_setup_true_name_true_lang.js +11 -6
- package/dist/es/fields/DataSourceMethods.vue_vue_type_script_setup_true_lang.js +30 -14
- package/dist/es/fields/DataSourceMocks.vue_vue_type_script_setup_true_lang.js +11 -4
- package/dist/es/fields/DataSourceSelect.vue_vue_type_script_setup_true_lang.js +5 -2
- package/dist/es/fields/DisplayConds.vue_vue_type_script_setup_true_lang.js +38 -6
- package/dist/es/fields/EventSelect.vue_vue_type_script_setup_true_lang.js +151 -153
- package/dist/es/fields/KeyValue.vue_vue_type_script_setup_true_lang.js +5 -2
- package/dist/es/fields/PageFragmentSelect.vue_vue_type_script_setup_true_lang.js +5 -2
- package/dist/es/fields/StyleSetter/Index.vue_vue_type_script_setup_true_lang.js +8 -10
- package/dist/es/fields/StyleSetter/components/BackgroundPosition.vue_vue_type_script_setup_true_lang.js +5 -2
- package/dist/es/fields/StyleSetter/components/Border.vue_vue_type_script_setup_true_lang.js +28 -6
- package/dist/es/fields/StyleSetter/components/Box.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/fields/StyleSetter/icons/align-items/Center.js +31 -0
- package/dist/es/fields/StyleSetter/icons/align-items/FlexEnd.js +31 -0
- package/dist/es/fields/StyleSetter/icons/align-items/FlexStart.js +31 -0
- package/dist/es/fields/StyleSetter/icons/align-items/SpaceAround.js +50 -0
- package/dist/es/fields/StyleSetter/icons/align-items/SpaceBetween.js +50 -0
- package/dist/es/fields/StyleSetter/icons/background-repeat/NoRepeat.js +7 -7
- package/dist/es/fields/StyleSetter/icons/background-repeat/Repeat.js +6 -3
- package/dist/es/fields/StyleSetter/icons/background-repeat/RepeatX.js +29 -6
- package/dist/es/fields/StyleSetter/icons/background-repeat/RepeatY.js +32 -6
- package/dist/es/fields/StyleSetter/icons/display/Block.js +1 -1
- package/dist/es/fields/StyleSetter/icons/display/Flex.js +1 -1
- package/dist/es/fields/StyleSetter/icons/display/Inline.js +1 -1
- package/dist/es/fields/StyleSetter/icons/display/InlineBlock.js +1 -1
- package/dist/es/fields/StyleSetter/icons/display/None.js +1 -1
- package/dist/es/fields/StyleSetter/icons/flex-direction/Column.js +11 -3
- package/dist/es/fields/StyleSetter/icons/flex-direction/ColumnReverse.js +11 -3
- package/dist/es/fields/StyleSetter/icons/flex-direction/Row.js +11 -3
- package/dist/es/fields/StyleSetter/icons/flex-direction/RowReverse.js +11 -3
- package/dist/es/fields/StyleSetter/icons/justify-content/Center.js +17 -3
- package/dist/es/fields/StyleSetter/icons/justify-content/FlexEnd.js +19 -3
- package/dist/es/fields/StyleSetter/icons/justify-content/FlexStart.js +19 -3
- package/dist/es/fields/StyleSetter/icons/justify-content/SpaceAround.js +37 -3
- package/dist/es/fields/StyleSetter/icons/justify-content/SpaceBetween.js +33 -3
- package/dist/es/fields/StyleSetter/icons/text-align/Center.js +1 -1
- package/dist/es/fields/StyleSetter/icons/text-align/Left.js +1 -1
- package/dist/es/fields/StyleSetter/icons/text-align/Right.js +1 -1
- package/dist/es/fields/StyleSetter/pro/Background.vue_vue_type_script_setup_true_lang.js +56 -30
- package/dist/es/fields/StyleSetter/pro/Border.vue_vue_type_script_setup_true_lang.js +7 -4
- package/dist/es/fields/StyleSetter/pro/Font.vue_vue_type_script_setup_true_lang.js +35 -26
- package/dist/es/fields/StyleSetter/pro/Layout.vue_vue_type_script_setup_true_lang.js +76 -48
- package/dist/es/fields/StyleSetter/pro/Position.vue_vue_type_script_setup_true_lang.js +29 -23
- package/dist/es/fields/StyleSetter/pro/Transform.vue_vue_type_script_setup_true_lang.js +7 -4
- package/dist/es/fields/UISelect.js +0 -1
- package/dist/es/fields/UISelect.vue_vue_type_script_setup_true_lang.js +5 -2
- package/dist/es/hooks/use-code-block-edit.js +6 -3
- package/dist/es/hooks/use-compare-form.js +119 -0
- package/dist/es/hooks/use-data-source-edit.js +5 -2
- package/dist/es/hooks/use-stage.js +9 -4
- package/dist/es/icons/CenterIcon.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/icons/CodeIcon.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/icons/DatasourceIcon.js +17 -0
- package/dist/es/icons/FolderMinusIcon.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/index.js +24 -10
- package/dist/es/initService.js +19 -13
- package/dist/es/layouts/AddPageBox.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/layouts/CodeEditor.vue_vue_type_script_setup_true_lang.js +24 -12
- package/dist/es/layouts/Framework.vue_vue_type_script_setup_true_lang.js +25 -18
- package/dist/es/layouts/NavMenu.vue_vue_type_script_setup_true_lang.js +4 -4
- package/dist/es/layouts/NavMenuColumn.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/layouts/history-list/Bucket.vue_vue_type_script_setup_true_lang.js +25 -38
- package/dist/es/layouts/history-list/BucketTab.js +5 -0
- package/dist/es/layouts/history-list/BucketTab.vue_vue_type_script_setup_true_lang.js +62 -0
- package/dist/es/layouts/history-list/GroupRow.vue_vue_type_script_setup_true_lang.js +177 -88
- package/dist/es/layouts/history-list/HistoryDiffDialog.vue_vue_type_script_setup_true_lang.js +139 -37
- package/dist/es/layouts/history-list/HistoryListPanel.vue_vue_type_script_setup_true_lang.js +164 -107
- package/dist/es/layouts/history-list/InitialRow.vue_vue_type_script_setup_true_lang.js +44 -9
- package/dist/es/layouts/history-list/PageTab.vue_vue_type_script_setup_true_lang.js +49 -53
- package/dist/es/layouts/history-list/composables.js +138 -108
- package/dist/es/layouts/history-list/useHistoryList.js +56 -0
- package/dist/es/layouts/history-list/useHistoryRevert.js +317 -0
- package/dist/es/layouts/page-bar/AddButton.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/layouts/page-bar/PageBar.vue_vue_type_script_setup_true_lang.js +5 -3
- package/dist/es/layouts/page-bar/PageBarScrollContainer.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/layouts/page-bar/PageList.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/layouts/page-bar/Search.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/es/layouts/props-panel/FormPanel.vue_vue_type_script_setup_true_lang.js +50 -7
- package/dist/es/layouts/props-panel/PropsPanel.vue_vue_type_script_setup_true_lang.js +33 -13
- package/dist/es/layouts/props-panel/use-style-panel.js +3 -2
- package/dist/es/layouts/sidebar/ComponentListPanel.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/es/layouts/sidebar/Sidebar.vue_vue_type_script_setup_true_lang.js +26 -38
- package/dist/es/layouts/sidebar/code-block/CodeBlockList.vue_vue_type_script_setup_true_lang.js +4 -4
- package/dist/es/layouts/sidebar/code-block/CodeBlockListPanel.vue_vue_type_script_setup_true_lang.js +4 -4
- package/dist/es/layouts/sidebar/code-block/useContentMenu.js +19 -4
- package/dist/es/layouts/sidebar/data-source/DataSourceAddButton.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/layouts/sidebar/data-source/DataSourceConfigPanel.vue_vue_type_script_setup_true_lang.js +23 -6
- package/dist/es/layouts/sidebar/data-source/DataSourceList.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/layouts/sidebar/data-source/DataSourceListPanel.vue_vue_type_script_setup_true_lang.js +27 -5
- package/dist/es/layouts/sidebar/data-source/useContentMenu.js +19 -4
- package/dist/es/layouts/sidebar/layer/LayerMenu.vue_vue_type_script_setup_true_lang.js +8 -8
- package/dist/es/layouts/sidebar/layer/LayerNodeContent.js +5 -0
- package/dist/es/layouts/sidebar/layer/LayerNodeContent.vue_vue_type_script_setup_true_lang.js +46 -0
- package/dist/es/layouts/sidebar/layer/LayerNodeTool.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/es/layouts/sidebar/layer/LayerPanel.vue_vue_type_script_setup_true_lang.js +3 -2
- package/dist/es/layouts/sidebar/layer/use-click.js +3 -3
- package/dist/es/layouts/sidebar/layer/use-node-status.js +2 -2
- package/dist/es/layouts/workspace/Breadcrumb.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/layouts/workspace/Workspace.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/layouts/workspace/viewer/NodeListMenu.vue_vue_type_script_setup_true_lang.js +9 -3
- package/dist/es/layouts/workspace/viewer/Stage.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/es/layouts/workspace/viewer/StageOverlay.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/layouts/workspace/viewer/ViewerMenu.vue_vue_type_script_setup_true_lang.js +16 -16
- package/dist/es/plugin.js +5 -2
- package/dist/es/services/codeBlock.js +137 -56
- package/dist/es/services/dataSource.js +122 -52
- package/dist/es/services/dep.js +162 -41
- package/dist/es/services/editor.js +613 -179
- package/dist/es/services/history.js +350 -386
- package/dist/es/services/keybinding.js +6 -6
- package/dist/es/services/props.js +3 -2
- package/dist/es/services/storage.js +2 -2
- package/dist/es/services/ui.js +10 -2
- package/dist/es/style.css +549 -113
- package/dist/es/utils/config.js +4 -1
- package/dist/es/utils/const.js +2 -2
- package/dist/es/utils/content-menu.js +19 -11
- package/dist/es/utils/data-source/index.js +34 -11
- package/dist/es/utils/dep/collect-worker-client.js +114 -0
- package/dist/es/utils/dep/idle-task.js +47 -22
- package/dist/es/utils/dep/worker.js +1 -1
- package/dist/es/utils/editor.js +103 -49
- package/dist/es/utils/event.js +123 -0
- package/dist/es/utils/history.js +220 -0
- package/dist/es/utils/indexed-db.js +86 -0
- package/dist/es/utils/monaco-editor.js +22 -6
- package/dist/es/utils/operator.js +2 -2
- package/dist/es/utils/props.js +114 -33
- package/dist/es/utils/type-match-rules.js +367 -0
- package/dist/es/utils/undo-redo.js +60 -1
- package/dist/style.css +549 -113
- package/dist/themes/magic-admin.css +3028 -0
- package/dist/tmagic-editor.umd.cjs +14273 -10029
- package/package.json +8 -8
- package/src/Editor.vue +43 -2
- package/src/components/CodeBlockEditor.vue +3 -0
- package/src/components/CompareForm.vue +18 -146
- package/src/components/ContentMenu.vue +44 -8
- package/src/components/FloatingBox.vue +84 -9
- package/src/components/ScrollBar.vue +0 -67
- package/src/components/ToolButton.vue +2 -2
- package/src/components/ViewForm.vue +55 -0
- package/src/editorProps.ts +30 -0
- package/src/fields/Code.vue +10 -2
- package/src/fields/CodeLink.vue +2 -5
- package/src/fields/CodeSelect.vue +54 -40
- package/src/fields/CodeSelectCol.vue +8 -1
- package/src/fields/CondOpSelect.vue +2 -24
- package/src/fields/DataSourceFieldSelect/FieldSelect.vue +16 -2
- package/src/fields/DataSourceFieldSelect/Index.vue +14 -5
- package/src/fields/DataSourceFields.vue +42 -8
- package/src/fields/DataSourceInput.vue +10 -28
- package/src/fields/DataSourceMethodSelect.vue +9 -4
- package/src/fields/DataSourceMethods.vue +42 -21
- package/src/fields/DataSourceMocks.vue +3 -0
- package/src/fields/DisplayConds.vue +18 -1
- package/src/fields/EventSelect.vue +145 -161
- package/src/fields/StyleSetter/Index.vue +3 -12
- package/src/fields/StyleSetter/components/Border.vue +15 -6
- package/src/fields/StyleSetter/icons/align-items/Center.vue +19 -0
- package/src/fields/StyleSetter/icons/align-items/FlexEnd.vue +19 -0
- package/src/fields/StyleSetter/icons/align-items/FlexStart.vue +19 -0
- package/src/fields/StyleSetter/icons/align-items/SpaceAround.vue +34 -0
- package/src/fields/StyleSetter/icons/align-items/SpaceBetween.vue +34 -0
- package/src/fields/StyleSetter/icons/align-items/index.ts +5 -0
- package/src/fields/StyleSetter/icons/background-repeat/NoRepeat.vue +20 -4
- package/src/fields/StyleSetter/icons/background-repeat/Repeat.vue +10 -28
- package/src/fields/StyleSetter/icons/background-repeat/RepeatX.vue +4 -5
- package/src/fields/StyleSetter/icons/background-repeat/RepeatY.vue +4 -5
- package/src/fields/StyleSetter/icons/flex-direction/Column.vue +4 -3
- package/src/fields/StyleSetter/icons/flex-direction/ColumnReverse.vue +4 -3
- package/src/fields/StyleSetter/icons/flex-direction/Row.vue +4 -3
- package/src/fields/StyleSetter/icons/flex-direction/RowReverse.vue +4 -3
- package/src/fields/StyleSetter/icons/justify-content/Center.vue +5 -2
- package/src/fields/StyleSetter/icons/justify-content/FlexEnd.vue +15 -2
- package/src/fields/StyleSetter/icons/justify-content/FlexStart.vue +15 -2
- package/src/fields/StyleSetter/icons/justify-content/SpaceAround.vue +28 -3
- package/src/fields/StyleSetter/icons/justify-content/SpaceBetween.vue +28 -2
- package/src/fields/StyleSetter/pro/Background.vue +99 -55
- package/src/fields/StyleSetter/pro/Border.vue +9 -11
- package/src/fields/StyleSetter/pro/Font.vue +66 -64
- package/src/fields/StyleSetter/pro/Layout.vue +211 -139
- package/src/fields/StyleSetter/pro/Position.vue +69 -67
- package/src/fields/StyleSetter/pro/Transform.vue +23 -25
- package/src/fields/UISelect.vue +0 -12
- package/src/hooks/index.ts +1 -0
- package/src/hooks/use-code-block-edit.ts +4 -3
- package/src/hooks/use-compare-form.ts +187 -0
- package/src/hooks/use-data-source-edit.ts +2 -2
- package/src/hooks/use-stage.ts +5 -3
- package/src/icons/DatasourceIcon.vue +7 -0
- package/src/index.ts +12 -0
- package/src/initService.ts +26 -16
- package/src/layouts/CodeEditor.vue +34 -11
- package/src/layouts/Framework.vue +15 -8
- package/src/layouts/NavMenu.vue +3 -3
- package/src/layouts/history-list/Bucket.vue +33 -41
- package/src/layouts/history-list/BucketTab.vue +72 -0
- package/src/layouts/history-list/GroupRow.vue +190 -93
- package/src/layouts/history-list/HistoryDiffDialog.vue +169 -90
- package/src/layouts/history-list/HistoryListPanel.vue +191 -95
- package/src/layouts/history-list/InitialRow.vue +38 -8
- package/src/layouts/history-list/PageTab.vue +67 -43
- package/src/layouts/history-list/composables.ts +239 -125
- package/src/layouts/history-list/useHistoryList.ts +60 -0
- package/src/layouts/history-list/useHistoryRevert.ts +425 -0
- package/src/layouts/page-bar/PageBar.vue +4 -2
- package/src/layouts/props-panel/FormPanel.vue +72 -6
- package/src/layouts/props-panel/PropsPanel.vue +62 -18
- package/src/layouts/props-panel/use-style-panel.ts +4 -3
- package/src/layouts/sidebar/ComponentListPanel.vue +10 -6
- package/src/layouts/sidebar/Sidebar.vue +13 -6
- package/src/layouts/sidebar/code-block/CodeBlockList.vue +5 -5
- package/src/layouts/sidebar/code-block/CodeBlockListPanel.vue +5 -2
- package/src/layouts/sidebar/code-block/useContentMenu.ts +14 -2
- package/src/layouts/sidebar/data-source/DataSourceConfigPanel.vue +34 -2
- package/src/layouts/sidebar/data-source/DataSourceListPanel.vue +29 -4
- package/src/layouts/sidebar/data-source/useContentMenu.ts +14 -2
- package/src/layouts/sidebar/layer/LayerMenu.vue +21 -13
- package/src/layouts/sidebar/layer/LayerNodeContent.vue +57 -0
- package/src/layouts/sidebar/layer/LayerNodeTool.vue +7 -4
- package/src/layouts/sidebar/layer/LayerPanel.vue +4 -1
- package/src/layouts/sidebar/layer/use-click.ts +3 -3
- package/src/layouts/sidebar/layer/use-node-status.ts +2 -2
- package/src/layouts/workspace/viewer/NodeListMenu.vue +4 -1
- package/src/layouts/workspace/viewer/Stage.vue +1 -1
- package/src/layouts/workspace/viewer/ViewerMenu.vue +15 -15
- package/src/plugin.ts +6 -3
- package/src/services/codeBlock.ts +152 -47
- package/src/services/dataSource.ts +120 -41
- package/src/services/dep.ts +292 -47
- package/src/services/editor.ts +820 -224
- package/src/services/history.ts +449 -412
- package/src/services/keybinding.ts +6 -6
- package/src/services/ui.ts +33 -5
- package/src/theme/code-block.scss +37 -0
- package/src/theme/common/var.scss +1 -1
- package/src/theme/component-list-panel.scss +2 -2
- package/src/theme/data-source-field.scss +4 -0
- package/src/theme/display-conds.scss +11 -0
- package/src/theme/event.scss +70 -1
- package/src/theme/floating-box.scss +9 -1
- package/src/theme/framework.scss +4 -1
- package/src/theme/history-list-panel.scss +157 -23
- package/src/theme/layer-node-content.scss +14 -0
- package/src/theme/nav-menu.scss +5 -1
- package/src/theme/page-bar.scss +0 -4
- package/src/theme/props-panel.scss +5 -4
- package/src/theme/scroll-bar.scss +64 -0
- package/src/theme/style-setter/border.scss +17 -5
- package/src/theme/theme.scss +4 -0
- package/src/theme/themes/magic-admin/index.scss +214 -0
- package/src/theme/ui-select.scss +9 -0
- package/src/type.ts +668 -124
- package/src/utils/config.ts +9 -1
- package/src/utils/const.ts +3 -2
- package/src/utils/content-menu.ts +20 -11
- package/src/utils/data-source/index.ts +32 -12
- package/src/utils/dep/collect-worker-client.ts +149 -0
- package/src/utils/dep/idle-task.ts +72 -35
- package/src/utils/dep/worker.ts +113 -9
- package/src/utils/editor.ts +166 -60
- package/src/utils/event.ts +224 -0
- package/src/utils/history.ts +286 -0
- package/src/utils/index.ts +4 -0
- package/src/utils/indexed-db.ts +122 -0
- package/src/utils/monaco-editor.ts +27 -0
- package/src/utils/operator.ts +2 -2
- package/src/utils/props.ts +114 -11
- package/src/utils/type-match-rules.ts +684 -0
- package/src/utils/undo-redo.ts +88 -0
- package/types/index.d.ts +1979 -515
- package/dist/es/layouts/history-list/CodeBlockTab.js +0 -5
- package/dist/es/layouts/history-list/CodeBlockTab.vue_vue_type_script_setup_true_lang.js +0 -62
- package/dist/es/layouts/history-list/DataSourceTab.js +0 -5
- package/dist/es/layouts/history-list/DataSourceTab.vue_vue_type_script_setup_true_lang.js +0 -62
- package/src/layouts/history-list/CodeBlockTab.vue +0 -61
- package/src/layouts/history-list/DataSourceTab.vue +0 -61
|
@@ -1,46 +1,27 @@
|
|
|
1
1
|
import { Layout, canUsePluginMethods } from "../type.js";
|
|
2
2
|
import BaseService from "./BaseService.js";
|
|
3
3
|
import props_default from "./props.js";
|
|
4
|
+
import { getLastPushedHistoryIds } from "../utils/history.js";
|
|
4
5
|
import history_default from "./history.js";
|
|
5
6
|
import storage_default, { Protocol } from "./storage.js";
|
|
6
|
-
import { COPY_STORAGE_KEY, calcAlignCenterStyle, calcLayerTargetIndex, calcMoveStyle, classifyDragSources, collectRelatedNodes, editorNodeMergeCustomizer, fixNodePosition, getInitPositionStyle, getNodeIndex, getPageFragmentList, getPageList, moveItemsInContainer, resolveSelectedNode, setChildrenLayout, setLayout, toggleFixedPosition } from "../utils/editor.js";
|
|
7
|
+
import { COPY_STORAGE_KEY, calcAlignCenterStyle, calcLayerTargetIndex, calcMoveStyle, classifyDragSources, collectRelatedNodes, describeStepForRevert, editorNodeMergeCustomizer, fixNodePosition, getInitPositionStyle, getNodeIndex, getPageFragmentList, getPageList, moveItemsInContainer, resolveSelectedNode, setChildrenLayout, setLayout, toggleFixedPosition } from "../utils/editor.js";
|
|
7
8
|
import { beforePaste, getAddParent } from "../utils/operator.js";
|
|
8
9
|
import { isFixed } from "@tmagic/stage";
|
|
9
|
-
import { getNodeInfo, getNodePath, getValueByKeyPath, isPage, isPageFragment, setValueByKeyPath } from "@tmagic/utils";
|
|
10
|
+
import { getNodeInfo, getNodePath, getValueByKeyPath, guid, isPage, isPageFragment, isPageOrFragment, setValueByKeyPath, traverseNode } from "@tmagic/utils";
|
|
10
11
|
import { NodeType } from "@tmagic/core";
|
|
11
|
-
import { reactive, toRaw } from "vue";
|
|
12
|
-
import { cloneDeep as cloneDeep$1, isObject, mergeWith, uniq } from "lodash-es";
|
|
12
|
+
import { nextTick, reactive, toRaw } from "vue";
|
|
13
|
+
import { cloneDeep as cloneDeep$1, isEmpty, isEqual, isObject, mergeWith, uniq } from "lodash-es";
|
|
13
14
|
//#region packages/editor/src/services/editor.ts
|
|
14
15
|
/**
|
|
15
|
-
*
|
|
16
|
-
*
|
|
16
|
+
* 把「变更前后节点快照」列表归一成 update 类型的 {@link StepDiffItem} 列表,供 {@link StepValue.diff} 使用。
|
|
17
|
+
* `changeRecords` 来自 form 端的 propPath/value 列表,撤销/重做时只对这些 propPath 做局部更新;
|
|
18
|
+
* 缺省(未传 / 空数组)才退化为整节点替换。
|
|
17
19
|
*/
|
|
18
|
-
var
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
const label = node?.name || node?.type || (node?.id !== void 0 ? `${node.id}` : "");
|
|
24
|
-
return `撤回新增 ${count} 个节点${count === 1 && label ? `(${label})` : ""}`;
|
|
25
|
-
}
|
|
26
|
-
case "remove": {
|
|
27
|
-
const count = step.removedItems?.length ?? 0;
|
|
28
|
-
const node = step.removedItems?.[0]?.node;
|
|
29
|
-
const label = node?.name || node?.type || (node?.id !== void 0 ? `${node.id}` : "");
|
|
30
|
-
return `还原已删除的 ${count} 个节点${count === 1 && label ? `(${label})` : ""}`;
|
|
31
|
-
}
|
|
32
|
-
default: {
|
|
33
|
-
const items = step.updatedItems ?? [];
|
|
34
|
-
if (items.length === 1) {
|
|
35
|
-
const { newNode, oldNode, changeRecords } = items[0];
|
|
36
|
-
const target = newNode?.name || newNode?.type || oldNode?.name || oldNode?.type || `${newNode?.id ?? ""}`;
|
|
37
|
-
const propPath = changeRecords?.[0]?.propPath;
|
|
38
|
-
return propPath ? `还原 ${target} · ${propPath}` : `还原 ${target}`;
|
|
39
|
-
}
|
|
40
|
-
return `还原 ${items.length} 个节点的修改`;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
};
|
|
20
|
+
var buildUpdateDiff = (items) => items.map(({ oldNode, newNode, changeRecords }) => ({
|
|
21
|
+
oldSchema: oldNode,
|
|
22
|
+
newSchema: newNode,
|
|
23
|
+
...changeRecords?.length ? { changeRecords } : {}
|
|
24
|
+
}));
|
|
44
25
|
var Editor = class extends BaseService {
|
|
45
26
|
state = reactive({
|
|
46
27
|
root: null,
|
|
@@ -52,12 +33,24 @@ var Editor = class extends BaseService {
|
|
|
52
33
|
stageLoading: true,
|
|
53
34
|
highlightNode: null,
|
|
54
35
|
modifiedNodeIds: /* @__PURE__ */ new Map(),
|
|
36
|
+
invalidNodeIds: /* @__PURE__ */ new Map(),
|
|
55
37
|
pageLength: 0,
|
|
56
38
|
pageFragmentLength: 0,
|
|
57
39
|
disabledMultiSelect: false,
|
|
58
40
|
alwaysMultiSelect: false
|
|
59
41
|
});
|
|
60
42
|
selectionBeforeOp = null;
|
|
43
|
+
/**
|
|
44
|
+
* 操作前的节点校验错误快照,与 selectionBeforeOp 同时在 captureSelectionBeforeOp 中捕获,
|
|
45
|
+
* 供 pushOpHistory 写入 step.extra.invalidNodeIdsBefore,用于撤销时还原到「操作前」的错误状态。
|
|
46
|
+
*/
|
|
47
|
+
invalidNodeIdsBeforeOp = null;
|
|
48
|
+
/**
|
|
49
|
+
* 最近一次 pushOpHistory 写入的历史记录 uuid。
|
|
50
|
+
* 供 *AndGetHistoryId 系列方法在调用普通操作后取回本次产生的历史记录 id;
|
|
51
|
+
* 普通操作不会读取它,调用前由 *AndGetHistoryId 重置为 null。
|
|
52
|
+
*/
|
|
53
|
+
lastPushedHistoryId = null;
|
|
61
54
|
constructor() {
|
|
62
55
|
super(canUsePluginMethods.async.map((methodName) => ({
|
|
63
56
|
name: methodName,
|
|
@@ -70,10 +63,11 @@ var Editor = class extends BaseService {
|
|
|
70
63
|
}
|
|
71
64
|
/**
|
|
72
65
|
* 设置当前指点节点配置
|
|
73
|
-
* @param name 'root' | 'page' | 'parent' | 'node' | 'highlightNode' | 'nodes' | 'stage' | 'modifiedNodeIds' | 'pageLength' | 'pageFragmentLength
|
|
66
|
+
* @param name 'root' | 'page' | 'parent' | 'node' | 'highlightNode' | 'nodes' | 'stage' | 'modifiedNodeIds' | 'invalidNodeIds' | 'pageLength' | 'pageFragmentLength
|
|
74
67
|
* @param value MNode
|
|
68
|
+
* @param options.historySource 设置 root 时,本次变更写入历史记录的「操作来源」(仅 name === 'root' 时生效)
|
|
75
69
|
*/
|
|
76
|
-
set(name, value) {
|
|
70
|
+
set(name, value, options = {}) {
|
|
77
71
|
const preValue = this.state[name];
|
|
78
72
|
this.state[name] = value;
|
|
79
73
|
if (name === "nodes" && Array.isArray(value)) this.set("node", value[0]);
|
|
@@ -84,17 +78,25 @@ var Editor = class extends BaseService {
|
|
|
84
78
|
this.state.pageLength = getPageList(app).length || 0;
|
|
85
79
|
this.state.pageFragmentLength = getPageFragmentList(app).length || 0;
|
|
86
80
|
this.state.stageLoading = this.state.pageLength !== 0;
|
|
81
|
+
if (preValue && !isEmpty(preValue)) this.pushRootDiffHistory(preValue, app, options.historySource);
|
|
82
|
+
else app.items?.forEach((pageNode) => {
|
|
83
|
+
if (pageNode?.id !== void 0 && !history_default.getMarker("page", pageNode.id)) history_default.setMarker("page", pageNode.id, {
|
|
84
|
+
name: pageNode.name,
|
|
85
|
+
source: options.historySource
|
|
86
|
+
});
|
|
87
|
+
});
|
|
87
88
|
} else {
|
|
88
89
|
this.state.pageLength = 0;
|
|
89
90
|
this.state.pageFragmentLength = 0;
|
|
90
91
|
this.state.stageLoading = false;
|
|
91
92
|
}
|
|
92
|
-
this.emit("root-change", value, preValue);
|
|
93
|
+
this.emit("root-change", value, preValue, options);
|
|
94
|
+
this.pruneInvalidNodeIds();
|
|
93
95
|
}
|
|
94
96
|
}
|
|
95
97
|
/**
|
|
96
98
|
* 获取当前指点节点配置
|
|
97
|
-
* @param name 'root' | 'page' | 'parent' | 'node' | 'highlightNode' | 'nodes' | 'stage' | 'modifiedNodeIds' | 'pageLength' | 'pageFragmentLength'
|
|
99
|
+
* @param name 'root' | 'page' | 'parent' | 'node' | 'highlightNode' | 'nodes' | 'stage' | 'modifiedNodeIds' | 'invalidNodeIds' | 'pageLength' | 'pageFragmentLength'
|
|
98
100
|
* @returns MNode
|
|
99
101
|
*/
|
|
100
102
|
get(name) {
|
|
@@ -109,7 +111,25 @@ var Editor = class extends BaseService {
|
|
|
109
111
|
getNodeInfo(id, raw = true) {
|
|
110
112
|
let root = this.get("root");
|
|
111
113
|
if (raw) root = toRaw(root);
|
|
112
|
-
|
|
114
|
+
if (!root) return {
|
|
115
|
+
node: null,
|
|
116
|
+
parent: null,
|
|
117
|
+
page: null,
|
|
118
|
+
path: []
|
|
119
|
+
};
|
|
120
|
+
if (id === root.id) return {
|
|
121
|
+
node: root,
|
|
122
|
+
parent: null,
|
|
123
|
+
page: null,
|
|
124
|
+
path: []
|
|
125
|
+
};
|
|
126
|
+
const pageIdStr = `${this.get("page")?.id || ""}`;
|
|
127
|
+
const currentPageNode = root.items?.find((item) => `${item.id}` === pageIdStr);
|
|
128
|
+
if (currentPageNode && `${id}` !== pageIdStr) {
|
|
129
|
+
const info = getNodeInfo(id, currentPageNode);
|
|
130
|
+
if (info.node) return info;
|
|
131
|
+
}
|
|
132
|
+
return getNodeInfo(id, root, currentPageNode);
|
|
113
133
|
}
|
|
114
134
|
/**
|
|
115
135
|
* 根据ID获取指点节点配置
|
|
@@ -139,7 +159,7 @@ var Editor = class extends BaseService {
|
|
|
139
159
|
isOnDifferentPage(node) {
|
|
140
160
|
const currentPageId = this.get("page")?.id;
|
|
141
161
|
if (currentPageId === void 0 || currentPageId === null) return false;
|
|
142
|
-
if (
|
|
162
|
+
if (isPageOrFragment(node)) return `${node.id}` !== `${currentPageId}`;
|
|
143
163
|
const nodePage = this.getNodeInfo(node.id, false).page;
|
|
144
164
|
if (!nodePage) return false;
|
|
145
165
|
return `${nodePage.id}` !== `${currentPageId}`;
|
|
@@ -163,8 +183,6 @@ var Editor = class extends BaseService {
|
|
|
163
183
|
this.set("nodes", node ? [node] : []);
|
|
164
184
|
this.set("page", page);
|
|
165
185
|
this.set("parent", parent);
|
|
166
|
-
if (page) history_default.changePage(toRaw(page));
|
|
167
|
-
else history_default.resetState();
|
|
168
186
|
if (node?.id) this.get("stage")?.renderer?.runtime?.getApp?.()?.page?.emit("editor:select", {
|
|
169
187
|
node,
|
|
170
188
|
page,
|
|
@@ -234,8 +252,8 @@ var Editor = class extends BaseService {
|
|
|
234
252
|
const curNode = this.get("node");
|
|
235
253
|
const stage = this.get("stage");
|
|
236
254
|
if (!curNode) throw new Error("当前选中节点为空");
|
|
237
|
-
if ((parent.type === NodeType.ROOT || curNode?.type === NodeType.ROOT) && !(
|
|
238
|
-
if (parent.id !== curNode.id && !(
|
|
255
|
+
if ((parent.type === NodeType.ROOT || curNode?.type === NodeType.ROOT) && !isPageOrFragment(node)) throw new Error("app下不能添加组件");
|
|
256
|
+
if (parent.id !== curNode.id && !isPageOrFragment(node)) {
|
|
239
257
|
const index = parent.items.indexOf(curNode);
|
|
240
258
|
parent.items?.splice(index + 1, 0, node);
|
|
241
259
|
} else parent.items?.push(node);
|
|
@@ -269,7 +287,7 @@ var Editor = class extends BaseService {
|
|
|
269
287
|
* @param options.doNotPushHistory 是否不写入历史记录(默认 false)
|
|
270
288
|
* @returns 添加后的节点
|
|
271
289
|
*/
|
|
272
|
-
async add(addNode, parent, { doNotSelect = false, doNotSwitchPage = false, doNotPushHistory = false, historyDescription } = {}) {
|
|
290
|
+
async add(addNode, parent, { doNotSelect = false, doNotSwitchPage = false, doNotPushHistory = false, historyDescription, historySource } = {}) {
|
|
273
291
|
this.captureSelectionBeforeOp();
|
|
274
292
|
const stage = this.get("stage");
|
|
275
293
|
const addNodes = [];
|
|
@@ -280,7 +298,7 @@ var Editor = class extends BaseService {
|
|
|
280
298
|
} else addNodes.push(...addNode);
|
|
281
299
|
const newNodes = await Promise.all(addNodes.map((node) => {
|
|
282
300
|
const root = this.get("root");
|
|
283
|
-
if ((
|
|
301
|
+
if (isPageOrFragment(node) && root) return this.doAdd(node, root);
|
|
284
302
|
const parentNode = parent ?? getAddParent(node);
|
|
285
303
|
if (!parentNode) throw new Error("未找到父元素");
|
|
286
304
|
return this.doAdd(node, parentNode);
|
|
@@ -300,22 +318,44 @@ var Editor = class extends BaseService {
|
|
|
300
318
|
else if (isPageFragment(newNodes[0])) this.state.pageFragmentLength += 1;
|
|
301
319
|
else if (!skipSelect) stage?.select(newNodes[0].id);
|
|
302
320
|
}
|
|
303
|
-
if (!(
|
|
321
|
+
if (!isPageOrFragment(newNodes[0])) {
|
|
304
322
|
const pageForOp = this.getNodeInfo(newNodes[0].id, false).page;
|
|
305
|
-
if (!doNotPushHistory)
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
323
|
+
if (!doNotPushHistory) {
|
|
324
|
+
const parentId = (this.getParentById(newNodes[0].id, false) ?? this.get("root")).id;
|
|
325
|
+
this.pushOpHistory("add", {
|
|
326
|
+
diff: newNodes.map((n) => {
|
|
327
|
+
const p = this.getParentById(n.id, false);
|
|
328
|
+
const idx = p ? getNodeIndex(n.id, p) : -1;
|
|
329
|
+
return {
|
|
330
|
+
newSchema: cloneDeep$1(toRaw(n)),
|
|
331
|
+
parentId,
|
|
332
|
+
index: typeof idx === "number" ? idx : -1
|
|
333
|
+
};
|
|
334
|
+
}),
|
|
335
|
+
pageData: {
|
|
336
|
+
name: pageForOp?.name || "",
|
|
337
|
+
id: pageForOp.id
|
|
338
|
+
},
|
|
339
|
+
historyDescription,
|
|
340
|
+
source: historySource
|
|
341
|
+
});
|
|
342
|
+
} else this.selectionBeforeOp = null;
|
|
317
343
|
}
|
|
318
344
|
this.emit("add", newNodes);
|
|
345
|
+
this.emit("change", {
|
|
346
|
+
type: "add",
|
|
347
|
+
data: newNodes.map((node) => ({
|
|
348
|
+
node,
|
|
349
|
+
page: this.getPageOfNode(node.id)
|
|
350
|
+
})),
|
|
351
|
+
historySource,
|
|
352
|
+
doNotPushHistory
|
|
353
|
+
});
|
|
354
|
+
const addedPages = newNodes.filter((node) => isPageOrFragment(node));
|
|
355
|
+
if (addedPages.length) history_default.notifyPageStructureChange({
|
|
356
|
+
add: addedPages,
|
|
357
|
+
remove: []
|
|
358
|
+
});
|
|
319
359
|
return Array.isArray(addNode) ? newNodes : newNodes[0];
|
|
320
360
|
}
|
|
321
361
|
async doRemove(node, { doNotSelect = false, doNotSwitchPage = false } = {}) {
|
|
@@ -325,13 +365,10 @@ var Editor = class extends BaseService {
|
|
|
325
365
|
if (!parent || !curNode) throw new Error("找不要删除的节点");
|
|
326
366
|
const index = getNodeIndex(curNode.id, parent);
|
|
327
367
|
if (typeof index !== "number" || index === -1) throw new Error("找不要删除的节点");
|
|
328
|
-
parent.items?.splice(index, 1);
|
|
329
368
|
const stage = this.get("stage");
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
root: cloneDeep$1(root)
|
|
334
|
-
});
|
|
369
|
+
const currentPage = this.get("page");
|
|
370
|
+
const isDeletingCurrentPage = isPageOrFragment(node) && !!currentPage && `${currentPage.id}` === `${node.id}`;
|
|
371
|
+
parent.items?.splice(index, 1);
|
|
335
372
|
const selectedNodes = this.get("nodes");
|
|
336
373
|
const removedSelectedIndex = selectedNodes.findIndex((n) => `${n.id}` === `${node.id}`);
|
|
337
374
|
if (removedSelectedIndex !== -1) {
|
|
@@ -339,27 +376,29 @@ var Editor = class extends BaseService {
|
|
|
339
376
|
nextSelected.splice(removedSelectedIndex, 1);
|
|
340
377
|
this.set("nodes", nextSelected);
|
|
341
378
|
}
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
const selectDefault = async (pages) => {
|
|
347
|
-
if (pages[0]) {
|
|
348
|
-
await this.select(pages[0]);
|
|
349
|
-
stage?.select(pages[0].id);
|
|
350
|
-
} else {
|
|
351
|
-
this.selectRoot();
|
|
352
|
-
history_default.resetPage();
|
|
353
|
-
}
|
|
379
|
+
const removeData = {
|
|
380
|
+
id: node.id,
|
|
381
|
+
parentId: parent.id,
|
|
382
|
+
root: cloneDeep$1(root)
|
|
354
383
|
};
|
|
355
384
|
const rootItems = root.items || [];
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
this.state.pageFragmentLength -= 1;
|
|
361
|
-
if (
|
|
385
|
+
const shouldReselect = isDeletingCurrentPage && !doNotSelect && !doNotSwitchPage;
|
|
386
|
+
const shouldSwitchPage = shouldReselect && rootItems.length > 0;
|
|
387
|
+
if (isPageOrFragment(node)) {
|
|
388
|
+
if (isPage(node)) this.state.pageLength -= 1;
|
|
389
|
+
else this.state.pageFragmentLength -= 1;
|
|
390
|
+
if (shouldSwitchPage) {
|
|
391
|
+
await this.select(rootItems[0]);
|
|
392
|
+
stage?.select(rootItems[0].id);
|
|
393
|
+
await nextTick();
|
|
394
|
+
stage?.remove(removeData);
|
|
395
|
+
} else {
|
|
396
|
+
stage?.remove(removeData);
|
|
397
|
+
if (shouldReselect) this.selectRoot();
|
|
398
|
+
else if (isDeletingCurrentPage) this.set("page", null);
|
|
399
|
+
}
|
|
362
400
|
} else {
|
|
401
|
+
stage?.remove(removeData);
|
|
363
402
|
if (!doNotSelect) {
|
|
364
403
|
await this.select(parent);
|
|
365
404
|
stage?.select(parent.id);
|
|
@@ -379,12 +418,16 @@ var Editor = class extends BaseService {
|
|
|
379
418
|
* @param options.doNotSwitchPage 删除后是否不切换当前页面(默认 false;删除页面 / 页面片段时为 true 会跳过自动切换到首个剩余页面)
|
|
380
419
|
* @param options.doNotPushHistory 是否不写入历史记录(默认 false)
|
|
381
420
|
*/
|
|
382
|
-
async remove(nodeOrNodeList, { doNotSelect = false, doNotSwitchPage = false, doNotPushHistory = false, historyDescription } = {}) {
|
|
421
|
+
async remove(nodeOrNodeList, { doNotSelect = false, doNotSwitchPage = false, doNotPushHistory = false, historyDescription, historySource } = {}) {
|
|
383
422
|
this.captureSelectionBeforeOp();
|
|
384
423
|
const nodes = Array.isArray(nodeOrNodeList) ? nodeOrNodeList : [nodeOrNodeList];
|
|
424
|
+
const changeItems = nodes.map((node) => ({
|
|
425
|
+
node,
|
|
426
|
+
page: this.getPageOfNode(node.id)
|
|
427
|
+
}));
|
|
385
428
|
const removedItems = [];
|
|
386
429
|
let pageForOp = null;
|
|
387
|
-
if (!(
|
|
430
|
+
if (!isPageOrFragment(nodes[0])) for (const n of nodes) {
|
|
388
431
|
const { parent, node: curNode, page } = this.getNodeInfo(n.id, false);
|
|
389
432
|
if (parent && curNode) {
|
|
390
433
|
if (!pageForOp && page) pageForOp = {
|
|
@@ -393,7 +436,7 @@ var Editor = class extends BaseService {
|
|
|
393
436
|
};
|
|
394
437
|
const idx = getNodeIndex(curNode.id, parent);
|
|
395
438
|
removedItems.push({
|
|
396
|
-
|
|
439
|
+
oldSchema: cloneDeep$1(toRaw(curNode)),
|
|
397
440
|
parentId: parent.id,
|
|
398
441
|
index: typeof idx === "number" ? idx : -1
|
|
399
442
|
});
|
|
@@ -403,22 +446,38 @@ var Editor = class extends BaseService {
|
|
|
403
446
|
doNotSelect,
|
|
404
447
|
doNotSwitchPage
|
|
405
448
|
})));
|
|
406
|
-
|
|
449
|
+
this.removeInvalidNodesBySubtree(nodes);
|
|
450
|
+
if (removedItems.length > 0 && pageForOp) if (!doNotPushHistory) this.pushOpHistory("remove", {
|
|
451
|
+
diff: removedItems,
|
|
452
|
+
pageData: pageForOp,
|
|
453
|
+
historyDescription,
|
|
454
|
+
source: historySource
|
|
455
|
+
});
|
|
407
456
|
else this.selectionBeforeOp = null;
|
|
408
457
|
this.emit("remove", nodes);
|
|
458
|
+
this.emit("change", {
|
|
459
|
+
type: "remove",
|
|
460
|
+
data: changeItems,
|
|
461
|
+
historySource,
|
|
462
|
+
doNotPushHistory
|
|
463
|
+
});
|
|
464
|
+
const removedPages = nodes.filter((node) => isPageOrFragment(node));
|
|
465
|
+
if (removedPages.length) history_default.notifyPageStructureChange({
|
|
466
|
+
add: [],
|
|
467
|
+
remove: removedPages
|
|
468
|
+
});
|
|
409
469
|
}
|
|
410
|
-
async doUpdate(config, { changeRecords = [] } = {}) {
|
|
411
|
-
|
|
412
|
-
if (!root) throw new Error("root为空");
|
|
470
|
+
async doUpdate(config, { changeRecords = [], historySource } = {}) {
|
|
471
|
+
if (!this.get("root")) throw new Error("root为空");
|
|
413
472
|
if (!config?.id) throw new Error("没有配置或者配置缺少id值");
|
|
414
473
|
const info = this.getNodeInfo(config.id, false);
|
|
415
474
|
if (!info.node) throw new Error(`获取不到id为${config.id}的节点`);
|
|
416
475
|
const node = toRaw(info.node);
|
|
417
|
-
let newConfig = await toggleFixedPosition(toRaw(config), node,
|
|
476
|
+
let newConfig = await toggleFixedPosition(toRaw(config), node, info.path, this.getLayout);
|
|
418
477
|
newConfig = mergeWith(cloneDeep$1(node), newConfig, editorNodeMergeCustomizer);
|
|
419
478
|
if (!newConfig.type) throw new Error("配置缺少type值");
|
|
420
479
|
if (newConfig.type === NodeType.ROOT) {
|
|
421
|
-
this.set("root", newConfig);
|
|
480
|
+
this.set("root", newConfig, { historySource });
|
|
422
481
|
return {
|
|
423
482
|
oldNode: node,
|
|
424
483
|
newNode: newConfig,
|
|
@@ -440,7 +499,7 @@ var Editor = class extends BaseService {
|
|
|
440
499
|
selectedNodes.splice(targetIndex, 1, newConfig);
|
|
441
500
|
this.set("nodes", [...selectedNodes]);
|
|
442
501
|
}
|
|
443
|
-
if (
|
|
502
|
+
if (isPageOrFragment(newConfig)) {
|
|
444
503
|
const currentPage = this.get("page");
|
|
445
504
|
if (currentPage && `${currentPage.id}` === `${newConfig.id}`) this.set("page", newConfig);
|
|
446
505
|
}
|
|
@@ -464,26 +523,44 @@ var Editor = class extends BaseService {
|
|
|
464
523
|
*/
|
|
465
524
|
async update(config, data = {}) {
|
|
466
525
|
this.captureSelectionBeforeOp();
|
|
467
|
-
const { doNotPushHistory = false, changeRecordList, changeRecords, historyDescription } = data;
|
|
526
|
+
const { doNotPushHistory = false, changeRecordList, changeRecords, historyDescription, historySource, invalidInfo } = data;
|
|
468
527
|
const nodes = Array.isArray(config) ? config : [config];
|
|
469
528
|
const updateData = await Promise.all(nodes.map((node, index) => {
|
|
470
529
|
const recordsForNode = changeRecordList ? changeRecordList[index] ?? [] : changeRecords ?? [];
|
|
471
|
-
return this.doUpdate(node, {
|
|
530
|
+
return this.doUpdate(node, {
|
|
531
|
+
changeRecords: recordsForNode,
|
|
532
|
+
historySource
|
|
533
|
+
});
|
|
472
534
|
}));
|
|
535
|
+
this.applyInvalidInfo(config, invalidInfo);
|
|
473
536
|
if (updateData[0].oldNode?.type !== NodeType.ROOT) {
|
|
474
537
|
if (this.get("nodes").length) if (!doNotPushHistory) {
|
|
475
538
|
const pageForOp = this.getNodeInfo(nodes[0].id, false).page;
|
|
476
|
-
this.pushOpHistory("update", {
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
539
|
+
this.pushOpHistory("update", {
|
|
540
|
+
diff: buildUpdateDiff(updateData.map((d) => ({
|
|
541
|
+
oldNode: cloneDeep$1(d.oldNode),
|
|
542
|
+
newNode: cloneDeep$1(d.newNode),
|
|
543
|
+
changeRecords: d.changeRecords?.length ? cloneDeep$1(d.changeRecords) : void 0
|
|
544
|
+
}))),
|
|
545
|
+
pageData: {
|
|
546
|
+
name: pageForOp?.name || "",
|
|
547
|
+
id: pageForOp.id
|
|
548
|
+
},
|
|
549
|
+
historyDescription,
|
|
550
|
+
source: historySource
|
|
551
|
+
});
|
|
484
552
|
} else this.selectionBeforeOp = null;
|
|
485
553
|
}
|
|
486
554
|
this.emit("update", updateData);
|
|
555
|
+
this.emit("change", {
|
|
556
|
+
type: "update",
|
|
557
|
+
data: updateData.map((node) => ({
|
|
558
|
+
node,
|
|
559
|
+
page: this.getPageOfNode(node.newNode.id)
|
|
560
|
+
})),
|
|
561
|
+
historySource,
|
|
562
|
+
doNotPushHistory
|
|
563
|
+
});
|
|
487
564
|
return Array.isArray(config) ? updateData.map((item) => item.newNode) : updateData[0].newNode;
|
|
488
565
|
}
|
|
489
566
|
/**
|
|
@@ -496,7 +573,7 @@ var Editor = class extends BaseService {
|
|
|
496
573
|
* @param options.doNotPushHistory 是否不写入历史记录(默认 false)
|
|
497
574
|
* @returns void
|
|
498
575
|
*/
|
|
499
|
-
async sort(id1, id2, { doNotSelect = false, doNotPushHistory = false } = {}) {
|
|
576
|
+
async sort(id1, id2, { doNotSelect = false, doNotPushHistory = false, historySource } = {}) {
|
|
500
577
|
this.captureSelectionBeforeOp();
|
|
501
578
|
const root = this.get("root");
|
|
502
579
|
if (!root) throw new Error("root为空");
|
|
@@ -508,7 +585,10 @@ var Editor = class extends BaseService {
|
|
|
508
585
|
if (index2 < 0) return;
|
|
509
586
|
const index1 = parent.items.findIndex((node) => `${node.id}` === `${id1}`);
|
|
510
587
|
parent.items.splice(index2, 0, ...parent.items.splice(index1, 1));
|
|
511
|
-
await this.update(parent, {
|
|
588
|
+
await this.update(parent, {
|
|
589
|
+
doNotPushHistory,
|
|
590
|
+
historySource
|
|
591
|
+
});
|
|
512
592
|
if (!doNotSelect) await this.select(node);
|
|
513
593
|
this.get("stage")?.update({
|
|
514
594
|
config: cloneDeep$1(node),
|
|
@@ -544,7 +624,7 @@ var Editor = class extends BaseService {
|
|
|
544
624
|
* @param options.doNotPushHistory 是否不写入历史记录(默认 false)
|
|
545
625
|
* @returns 添加后的组件节点配置
|
|
546
626
|
*/
|
|
547
|
-
async paste(position = {}, collectorOptions, { doNotSelect = false, doNotSwitchPage = false, doNotPushHistory = false } = {}) {
|
|
627
|
+
async paste(position = {}, collectorOptions, { doNotSelect = false, doNotSwitchPage = false, doNotPushHistory = false, historyDescription, historySource } = {}) {
|
|
548
628
|
const config = storage_default.getItem(COPY_STORAGE_KEY);
|
|
549
629
|
if (!Array.isArray(config)) return;
|
|
550
630
|
const node = this.get("node");
|
|
@@ -558,7 +638,9 @@ var Editor = class extends BaseService {
|
|
|
558
638
|
return this.add(pasteConfigs, parent, {
|
|
559
639
|
doNotSelect,
|
|
560
640
|
doNotSwitchPage,
|
|
561
|
-
doNotPushHistory
|
|
641
|
+
doNotPushHistory,
|
|
642
|
+
historyDescription,
|
|
643
|
+
historySource
|
|
562
644
|
});
|
|
563
645
|
}
|
|
564
646
|
async doPaste(config, position = {}) {
|
|
@@ -586,11 +668,15 @@ var Editor = class extends BaseService {
|
|
|
586
668
|
* @param options.doNotPushHistory 是否不写入历史记录(默认 false)
|
|
587
669
|
* @returns 当前组件节点配置
|
|
588
670
|
*/
|
|
589
|
-
async alignCenter(config, { doNotSelect = false, doNotPushHistory = false } = {}) {
|
|
671
|
+
async alignCenter(config, { doNotSelect = false, doNotPushHistory = false, historyDescription, historySource } = {}) {
|
|
590
672
|
const nodes = Array.isArray(config) ? config : [config];
|
|
591
673
|
const stage = this.get("stage");
|
|
592
674
|
const newNodes = await Promise.all(nodes.map((node) => this.doAlignCenter(node)));
|
|
593
|
-
const newNode = await this.update(newNodes, {
|
|
675
|
+
const newNode = await this.update(newNodes, {
|
|
676
|
+
doNotPushHistory,
|
|
677
|
+
historyDescription,
|
|
678
|
+
historySource
|
|
679
|
+
});
|
|
594
680
|
if (!doNotSelect) if (newNodes.length > 1) await stage?.multiSelect(newNodes.map((node) => node.id));
|
|
595
681
|
else await stage?.select(newNodes[0].id);
|
|
596
682
|
return newNode;
|
|
@@ -601,7 +687,7 @@ var Editor = class extends BaseService {
|
|
|
601
687
|
* @param options 可选配置
|
|
602
688
|
* @param options.doNotPushHistory 是否不写入历史记录(默认 false)
|
|
603
689
|
*/
|
|
604
|
-
async moveLayer(offset, { doNotPushHistory = false } = {}) {
|
|
690
|
+
async moveLayer(offset, { doNotPushHistory = false, historyDescription, historySource } = {}) {
|
|
605
691
|
this.captureSelectionBeforeOp();
|
|
606
692
|
const root = this.get("root");
|
|
607
693
|
if (!root) throw new Error("root为空");
|
|
@@ -626,15 +712,30 @@ var Editor = class extends BaseService {
|
|
|
626
712
|
this.addModifiedNodeId(parent.id);
|
|
627
713
|
if (!doNotPushHistory) {
|
|
628
714
|
const pageForOp = this.getNodeInfo(node.id, false).page;
|
|
629
|
-
this.pushOpHistory("update", {
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
715
|
+
this.pushOpHistory("update", {
|
|
716
|
+
diff: buildUpdateDiff([{
|
|
717
|
+
oldNode: oldParent,
|
|
718
|
+
newNode: cloneDeep$1(toRaw(parent))
|
|
719
|
+
}]),
|
|
720
|
+
pageData: {
|
|
721
|
+
name: pageForOp?.name || "",
|
|
722
|
+
id: pageForOp.id
|
|
723
|
+
},
|
|
724
|
+
historyDescription,
|
|
725
|
+
source: historySource
|
|
635
726
|
});
|
|
636
727
|
} else this.selectionBeforeOp = null;
|
|
637
728
|
this.emit("move-layer", offset);
|
|
729
|
+
this.emit("change", {
|
|
730
|
+
type: "move-layer",
|
|
731
|
+
data: [{
|
|
732
|
+
node,
|
|
733
|
+
page: this.getPageOfNode(node.id)
|
|
734
|
+
}],
|
|
735
|
+
offset,
|
|
736
|
+
historySource,
|
|
737
|
+
doNotPushHistory
|
|
738
|
+
});
|
|
638
739
|
}
|
|
639
740
|
/**
|
|
640
741
|
* 移动一个或多个节点到指定容器中。
|
|
@@ -650,9 +751,9 @@ var Editor = class extends BaseService {
|
|
|
650
751
|
* @param options.doNotSwitchPage 移动后是否不切换当前页面(默认 false;目标容器位于其它页面时为 true 会跳过自动选中以避免页面切换)
|
|
651
752
|
* @param options.doNotPushHistory 是否不写入历史记录(默认 false)
|
|
652
753
|
*/
|
|
653
|
-
async moveToContainer(config, targetId, { doNotSelect = false, doNotSwitchPage = false, doNotPushHistory = false } = {}) {
|
|
754
|
+
async moveToContainer(config, targetId, { doNotSelect = false, doNotSwitchPage = false, doNotPushHistory = false, historyDescription, historySource } = {}) {
|
|
654
755
|
const isBatch = Array.isArray(config);
|
|
655
|
-
const configs = (isBatch ? config : [config]).filter((item) => !(
|
|
756
|
+
const configs = (isBatch ? config : [config]).filter((item) => !isPageOrFragment(item));
|
|
656
757
|
if (configs.length === 0) throw new Error("没有可移动的节点");
|
|
657
758
|
this.captureSelectionBeforeOp();
|
|
658
759
|
const target = this.getNodeById(targetId, false);
|
|
@@ -698,11 +799,16 @@ var Editor = class extends BaseService {
|
|
|
698
799
|
name: "",
|
|
699
800
|
id: target.id
|
|
700
801
|
};
|
|
701
|
-
this.pushOpHistory("update", {
|
|
802
|
+
this.pushOpHistory("update", {
|
|
803
|
+
diff: buildUpdateDiff(updatedItems),
|
|
804
|
+
pageData: historyPage,
|
|
805
|
+
historyDescription,
|
|
806
|
+
source: historySource
|
|
807
|
+
});
|
|
702
808
|
} else this.selectionBeforeOp = null;
|
|
703
809
|
return isBatch ? newConfigs : newConfigs[0];
|
|
704
810
|
}
|
|
705
|
-
async dragTo(config, targetParent, targetIndex, { doNotPushHistory = false } = {}) {
|
|
811
|
+
async dragTo(config, targetParent, targetIndex, { doNotPushHistory = false, historyDescription, historySource } = {}) {
|
|
706
812
|
this.captureSelectionBeforeOp();
|
|
707
813
|
if (!targetParent || !Array.isArray(targetParent.items)) return;
|
|
708
814
|
const configs = Array.isArray(config) ? config : [config];
|
|
@@ -744,9 +850,14 @@ var Editor = class extends BaseService {
|
|
|
744
850
|
}
|
|
745
851
|
if (!doNotPushHistory) {
|
|
746
852
|
const pageForOp = this.getNodeInfo(configs[0].id, false).page;
|
|
747
|
-
this.pushOpHistory("update", {
|
|
748
|
-
|
|
749
|
-
|
|
853
|
+
this.pushOpHistory("update", {
|
|
854
|
+
diff: buildUpdateDiff(updatedItems),
|
|
855
|
+
pageData: {
|
|
856
|
+
name: pageForOp?.name || "",
|
|
857
|
+
id: pageForOp.id
|
|
858
|
+
},
|
|
859
|
+
historyDescription,
|
|
860
|
+
source: historySource
|
|
750
861
|
});
|
|
751
862
|
} else this.selectionBeforeOp = null;
|
|
752
863
|
this.emit("drag-to", {
|
|
@@ -754,13 +865,84 @@ var Editor = class extends BaseService {
|
|
|
754
865
|
configs,
|
|
755
866
|
targetParent
|
|
756
867
|
});
|
|
868
|
+
this.emit("change", {
|
|
869
|
+
type: "drag-to",
|
|
870
|
+
data: configs.map((node) => ({
|
|
871
|
+
node,
|
|
872
|
+
page: this.getPageOfNode(node.id)
|
|
873
|
+
})),
|
|
874
|
+
targetIndex,
|
|
875
|
+
targetParent,
|
|
876
|
+
historySource,
|
|
877
|
+
doNotPushHistory
|
|
878
|
+
});
|
|
879
|
+
}
|
|
880
|
+
/**
|
|
881
|
+
* 下列 *AndGetHistoryId 方法与对应的普通操作(add / remove / update ...)行为完全一致,
|
|
882
|
+
* 返回值在 {@link DslOpWithHistoryIdsResult} 中同时包含原操作结果与本次写入历史栈的 uuid 列表({@link StepValue.uuid}),
|
|
883
|
+
* 可用于精确引用 / 定位该条历史记录(埋点、revert、跨端同步等)。
|
|
884
|
+
*
|
|
885
|
+
* 当本次操作未写入历史(doNotPushHistory 为 true、或操作无实际变更 / 提前返回)时 historyIds 为 `[]`。
|
|
886
|
+
*/
|
|
887
|
+
/** 等价于 {@link add},并额外返回本次写入历史记录的 uuid 列表(未入栈时 historyIds 为 `[]`)。 */
|
|
888
|
+
async addAndGetHistoryId(addNode, parent, options = {}) {
|
|
889
|
+
this.lastPushedHistoryId = null;
|
|
890
|
+
return {
|
|
891
|
+
result: await this.add(addNode, parent, options),
|
|
892
|
+
historyIds: getLastPushedHistoryIds(this.lastPushedHistoryId)
|
|
893
|
+
};
|
|
894
|
+
}
|
|
895
|
+
/** 等价于 {@link remove},并额外返回本次写入历史记录的 uuid 列表(未入栈时 historyIds 为 `[]`)。 */
|
|
896
|
+
async removeAndGetHistoryId(nodeOrNodeList, options = {}) {
|
|
897
|
+
this.lastPushedHistoryId = null;
|
|
898
|
+
await this.remove(nodeOrNodeList, options);
|
|
899
|
+
return {
|
|
900
|
+
result: void 0,
|
|
901
|
+
historyIds: getLastPushedHistoryIds(this.lastPushedHistoryId)
|
|
902
|
+
};
|
|
903
|
+
}
|
|
904
|
+
/** 等价于 {@link update},并额外返回本次写入历史记录的 uuid 列表(未入栈时 historyIds 为 `[]`)。 */
|
|
905
|
+
async updateAndGetHistoryId(config, data = {}) {
|
|
906
|
+
this.lastPushedHistoryId = null;
|
|
907
|
+
return {
|
|
908
|
+
result: await this.update(config, data),
|
|
909
|
+
historyIds: getLastPushedHistoryIds(this.lastPushedHistoryId)
|
|
910
|
+
};
|
|
911
|
+
}
|
|
912
|
+
/** 等价于 {@link moveLayer},并额外返回本次写入历史记录的 uuid 列表(未入栈时 historyIds 为 `[]`)。 */
|
|
913
|
+
async moveLayerAndGetHistoryId(offset, options = {}) {
|
|
914
|
+
this.lastPushedHistoryId = null;
|
|
915
|
+
await this.moveLayer(offset, options);
|
|
916
|
+
return {
|
|
917
|
+
result: void 0,
|
|
918
|
+
historyIds: getLastPushedHistoryIds(this.lastPushedHistoryId)
|
|
919
|
+
};
|
|
920
|
+
}
|
|
921
|
+
/** 等价于 {@link moveToContainer},并额外返回本次写入历史记录的 uuid 列表(未入栈时 historyIds 为 `[]`)。 */
|
|
922
|
+
async moveToContainerAndGetHistoryId(config, targetId, options = {}) {
|
|
923
|
+
this.lastPushedHistoryId = null;
|
|
924
|
+
return {
|
|
925
|
+
result: await this.moveToContainer(config, targetId, options),
|
|
926
|
+
historyIds: getLastPushedHistoryIds(this.lastPushedHistoryId)
|
|
927
|
+
};
|
|
928
|
+
}
|
|
929
|
+
/** 等价于 {@link dragTo},并额外返回本次写入历史记录的 uuid 列表(未入栈时 historyIds 为 `[]`)。 */
|
|
930
|
+
async dragToAndGetHistoryId(config, targetParent, targetIndex, options = {}) {
|
|
931
|
+
this.lastPushedHistoryId = null;
|
|
932
|
+
await this.dragTo(config, targetParent, targetIndex, options);
|
|
933
|
+
return {
|
|
934
|
+
result: void 0,
|
|
935
|
+
historyIds: getLastPushedHistoryIds(this.lastPushedHistoryId)
|
|
936
|
+
};
|
|
757
937
|
}
|
|
758
938
|
/**
|
|
759
939
|
* 撤销当前操作
|
|
760
940
|
* @returns 被撤销的操作
|
|
761
941
|
*/
|
|
762
942
|
async undo() {
|
|
763
|
-
const
|
|
943
|
+
const pageId = this.get("page")?.id;
|
|
944
|
+
if (pageId === void 0) return null;
|
|
945
|
+
const value = history_default.undo("page", pageId);
|
|
764
946
|
if (value) await this.applyHistoryOp(value, true);
|
|
765
947
|
return value;
|
|
766
948
|
}
|
|
@@ -769,7 +951,9 @@ var Editor = class extends BaseService {
|
|
|
769
951
|
* @returns 被恢复的操作
|
|
770
952
|
*/
|
|
771
953
|
async redo() {
|
|
772
|
-
const
|
|
954
|
+
const pageId = this.get("page")?.id;
|
|
955
|
+
if (pageId === void 0) return null;
|
|
956
|
+
const value = history_default.redo("page", pageId);
|
|
773
957
|
if (value) await this.applyHistoryOp(value, false);
|
|
774
958
|
return value;
|
|
775
959
|
}
|
|
@@ -790,12 +974,17 @@ var Editor = class extends BaseService {
|
|
|
790
974
|
* @returns 反向后产生的新 step;目标不存在 / 未应用 / 反向失败时返回 null
|
|
791
975
|
*/
|
|
792
976
|
async revertPageStep(index) {
|
|
793
|
-
const entry = history_default.
|
|
977
|
+
const entry = history_default.getStepList("page", this.get("page")?.id)[index];
|
|
794
978
|
if (!entry?.applied) return null;
|
|
795
979
|
const { step } = entry;
|
|
980
|
+
if (step.opType === "initial") return null;
|
|
796
981
|
if (!this.get("root")) return null;
|
|
982
|
+
if (step.opType === "update") {
|
|
983
|
+
const items = step.diff ?? [];
|
|
984
|
+
if (!items.length || !items.every((item) => item.changeRecords?.length)) return null;
|
|
985
|
+
}
|
|
797
986
|
let revertedStep = null;
|
|
798
|
-
const captureRevert = (s) => {
|
|
987
|
+
const captureRevert = (_pageId, s) => {
|
|
799
988
|
revertedStep = s;
|
|
800
989
|
};
|
|
801
990
|
history_default.once("change", captureRevert);
|
|
@@ -803,28 +992,31 @@ var Editor = class extends BaseService {
|
|
|
803
992
|
const opts = {
|
|
804
993
|
doNotSelect: true,
|
|
805
994
|
doNotSwitchPage: true,
|
|
806
|
-
historyDescription
|
|
995
|
+
historyDescription,
|
|
996
|
+
historySource: "rollback"
|
|
807
997
|
};
|
|
808
998
|
try {
|
|
809
999
|
switch (step.opType) {
|
|
810
|
-
case "add":
|
|
811
|
-
const
|
|
812
|
-
|
|
813
|
-
const existing = this.getNodeById(
|
|
1000
|
+
case "add":
|
|
1001
|
+
for (const { newSchema } of step.diff ?? []) {
|
|
1002
|
+
if (!newSchema) continue;
|
|
1003
|
+
const existing = this.getNodeById(newSchema.id, false);
|
|
814
1004
|
if (existing) await this.remove(existing, opts);
|
|
815
1005
|
}
|
|
816
1006
|
break;
|
|
817
|
-
}
|
|
818
1007
|
case "remove": {
|
|
819
|
-
const sorted = [...step.
|
|
820
|
-
for (const {
|
|
1008
|
+
const sorted = [...step.diff ?? []].sort((a, b) => (a.index ?? 0) - (b.index ?? 0));
|
|
1009
|
+
for (const { oldSchema, parentId } of sorted) {
|
|
1010
|
+
if (!oldSchema || parentId === void 0) continue;
|
|
821
1011
|
const parent = this.getNodeById(parentId, false);
|
|
822
|
-
if (parent) await this.add([cloneDeep$1(
|
|
1012
|
+
if (parent) await this.add([cloneDeep$1(oldSchema)], parent, opts);
|
|
823
1013
|
}
|
|
824
1014
|
break;
|
|
825
1015
|
}
|
|
826
1016
|
case "update": {
|
|
827
|
-
const configs = (step.
|
|
1017
|
+
const configs = (step.diff ?? []).filter((item) => item.oldSchema && item.newSchema).map(({ oldSchema, newSchema, changeRecords }) => {
|
|
1018
|
+
const oldNode = oldSchema;
|
|
1019
|
+
const newNode = newSchema;
|
|
828
1020
|
if (changeRecords?.length) {
|
|
829
1021
|
const patch = {
|
|
830
1022
|
id: newNode.id,
|
|
@@ -839,7 +1031,10 @@ var Editor = class extends BaseService {
|
|
|
839
1031
|
}
|
|
840
1032
|
return cloneDeep$1(oldNode);
|
|
841
1033
|
});
|
|
842
|
-
if (configs.length) await this.update(configs, {
|
|
1034
|
+
if (configs.length) await this.update(configs, {
|
|
1035
|
+
historyDescription,
|
|
1036
|
+
historySource: "rollback"
|
|
1037
|
+
});
|
|
843
1038
|
break;
|
|
844
1039
|
}
|
|
845
1040
|
}
|
|
@@ -851,6 +1046,22 @@ var Editor = class extends BaseService {
|
|
|
851
1046
|
return revertedStep;
|
|
852
1047
|
}
|
|
853
1048
|
/**
|
|
1049
|
+
* 通过历史记录 uuid 回滚当前页面的历史步骤,语义与 {@link revertPageStep} 完全一致,
|
|
1050
|
+
* 仅入参从 index 改为 uuid 列表({@link StepValue.uuid})。按数组顺序依次回滚,
|
|
1051
|
+
* 返回与入参同序的结果列表(某项失败时为 `null`)。
|
|
1052
|
+
*
|
|
1053
|
+
* @param uuids 目标历史记录的 uuid 列表,通常由 *AndGetHistoryId 方法返回的 `historyIds`
|
|
1054
|
+
*/
|
|
1055
|
+
async revertPageStepById(uuids) {
|
|
1056
|
+
const results = [];
|
|
1057
|
+
const pageId = this.get("page")?.id;
|
|
1058
|
+
for (const uuid of uuids) {
|
|
1059
|
+
const location = history_default.findStepLocationByUuid("page", uuid, pageId);
|
|
1060
|
+
results.push(!location ? null : await this.revertPageStep(location.index));
|
|
1061
|
+
}
|
|
1062
|
+
return results;
|
|
1063
|
+
}
|
|
1064
|
+
/**
|
|
854
1065
|
* 跳转当前页面历史栈到指定游标位置。
|
|
855
1066
|
*
|
|
856
1067
|
* `targetCursor` 与 `UndoRedo.getCursor()` 同义:表示"已应用步骤数量",
|
|
@@ -860,8 +1071,9 @@ var Editor = class extends BaseService {
|
|
|
860
1071
|
* @returns 实际移动到的最终游标位置
|
|
861
1072
|
*/
|
|
862
1073
|
async gotoPageStep(targetCursor) {
|
|
863
|
-
|
|
864
|
-
|
|
1074
|
+
const pageId = this.get("page")?.id;
|
|
1075
|
+
let cursor = history_default.getCursor("page", pageId);
|
|
1076
|
+
const { length } = history_default.getStepList("page", pageId);
|
|
865
1077
|
const target = Math.max(0, Math.min(targetCursor, length));
|
|
866
1078
|
while (cursor > target) {
|
|
867
1079
|
if (!await this.undo()) break;
|
|
@@ -873,7 +1085,7 @@ var Editor = class extends BaseService {
|
|
|
873
1085
|
}
|
|
874
1086
|
return cursor;
|
|
875
1087
|
}
|
|
876
|
-
async move(left, top, { doNotPushHistory = false } = {}) {
|
|
1088
|
+
async move(left, top, { doNotPushHistory = false, historyDescription, historySource } = {}) {
|
|
877
1089
|
const node = toRaw(this.get("node"));
|
|
878
1090
|
if (!node || isPage(node)) return;
|
|
879
1091
|
const newStyle = calcMoveStyle(node.style || {}, left, top);
|
|
@@ -882,7 +1094,11 @@ var Editor = class extends BaseService {
|
|
|
882
1094
|
id: node.id,
|
|
883
1095
|
type: node.type,
|
|
884
1096
|
style: newStyle
|
|
885
|
-
}, {
|
|
1097
|
+
}, {
|
|
1098
|
+
doNotPushHistory,
|
|
1099
|
+
historyDescription,
|
|
1100
|
+
historySource
|
|
1101
|
+
});
|
|
886
1102
|
}
|
|
887
1103
|
resetState() {
|
|
888
1104
|
this.set("root", null);
|
|
@@ -893,6 +1109,7 @@ var Editor = class extends BaseService {
|
|
|
893
1109
|
this.set("stage", null);
|
|
894
1110
|
this.set("highlightNode", null);
|
|
895
1111
|
this.set("modifiedNodeIds", /* @__PURE__ */ new Map());
|
|
1112
|
+
this.set("invalidNodeIds", /* @__PURE__ */ new Map());
|
|
896
1113
|
this.set("pageLength", 0);
|
|
897
1114
|
}
|
|
898
1115
|
destroy() {
|
|
@@ -903,6 +1120,51 @@ var Editor = class extends BaseService {
|
|
|
903
1120
|
resetModifiedNodeId() {
|
|
904
1121
|
this.get("modifiedNodeIds").clear();
|
|
905
1122
|
}
|
|
1123
|
+
/**
|
|
1124
|
+
* 记录(或覆盖)某个节点在指定来源(属性表单 / 样式表单)上的校验错误信息。
|
|
1125
|
+
* @param id 节点 id
|
|
1126
|
+
* @param source 错误来源:'props'(属性表单)| 'style'(样式表单)
|
|
1127
|
+
* @param message 错误文案(可能是包含 <br> 的 HTML)
|
|
1128
|
+
*/
|
|
1129
|
+
setInvalidNode(id, source, message) {
|
|
1130
|
+
const map = this.get("invalidNodeIds");
|
|
1131
|
+
const info = { ...map.get(id) || {} };
|
|
1132
|
+
info[source] = message;
|
|
1133
|
+
map.set(id, info);
|
|
1134
|
+
this.emit("invalid-node-change", map);
|
|
1135
|
+
}
|
|
1136
|
+
/**
|
|
1137
|
+
* 删除节点的校验错误记录。
|
|
1138
|
+
* @param id 节点 id
|
|
1139
|
+
* @param source 指定来源则仅删除该来源;不传则删除该节点全部来源的错误
|
|
1140
|
+
*/
|
|
1141
|
+
deleteInvalidNode(id, source) {
|
|
1142
|
+
const map = this.get("invalidNodeIds");
|
|
1143
|
+
if (!map.has(id)) return;
|
|
1144
|
+
if (!source) map.delete(id);
|
|
1145
|
+
else {
|
|
1146
|
+
const info = { ...map.get(id) || {} };
|
|
1147
|
+
delete info[source];
|
|
1148
|
+
if (info.props || info.style) map.set(id, info);
|
|
1149
|
+
else map.delete(id);
|
|
1150
|
+
}
|
|
1151
|
+
this.emit("invalid-node-change", map);
|
|
1152
|
+
}
|
|
1153
|
+
/** 获取当前存在校验错误的节点错误 Map(key 为节点 id) */
|
|
1154
|
+
getInvalidNodeIds() {
|
|
1155
|
+
return this.get("invalidNodeIds");
|
|
1156
|
+
}
|
|
1157
|
+
/** 获取指定节点的校验错误信息 */
|
|
1158
|
+
getInvalidNodeInfo(id) {
|
|
1159
|
+
return this.get("invalidNodeIds").get(id);
|
|
1160
|
+
}
|
|
1161
|
+
/** 清空全部校验错误记录 */
|
|
1162
|
+
resetInvalidNodeId() {
|
|
1163
|
+
const map = this.get("invalidNodeIds");
|
|
1164
|
+
if (map.size === 0) return;
|
|
1165
|
+
map.clear();
|
|
1166
|
+
this.emit("invalid-node-change", map);
|
|
1167
|
+
}
|
|
906
1168
|
usePlugin(options) {
|
|
907
1169
|
super.usePlugin(options);
|
|
908
1170
|
}
|
|
@@ -915,99 +1177,248 @@ var Editor = class extends BaseService {
|
|
|
915
1177
|
emit(eventName, ...args) {
|
|
916
1178
|
return super.emit(eventName, ...args);
|
|
917
1179
|
}
|
|
1180
|
+
/**
|
|
1181
|
+
* 应用一次属性面板提交携带的校验错误信息(在写入历史记录之前调用,使历史快照与本次变更对齐)。
|
|
1182
|
+
* - invalidInfo 为空(调用方未携带):认为本次更新对应的节点已无校验错误,清除其全部来源的错误;
|
|
1183
|
+
* - error 非空则记录错误,为空则清除对应来源的错误。
|
|
1184
|
+
*/
|
|
1185
|
+
applyInvalidInfo(config, invalidInfo) {
|
|
1186
|
+
if (!invalidInfo) {
|
|
1187
|
+
(Array.isArray(config) ? config : [config]).map((node) => node.id).filter((id) => id !== void 0).forEach((id) => this.deleteInvalidNode(id));
|
|
1188
|
+
return;
|
|
1189
|
+
}
|
|
1190
|
+
const { id, source, error } = invalidInfo;
|
|
1191
|
+
if (error) this.setInvalidNode(id, source, error);
|
|
1192
|
+
else this.deleteInvalidNode(id, source);
|
|
1193
|
+
}
|
|
1194
|
+
/** 删除被移除节点(含其子树)的校验错误记录,避免残留误报 */
|
|
1195
|
+
removeInvalidNodesBySubtree(nodes) {
|
|
1196
|
+
const map = this.get("invalidNodeIds");
|
|
1197
|
+
if (map.size === 0) return;
|
|
1198
|
+
let changed = false;
|
|
1199
|
+
nodes.forEach((node) => {
|
|
1200
|
+
traverseNode(node, (n) => {
|
|
1201
|
+
if (n.id !== void 0 && map.delete(n.id)) changed = true;
|
|
1202
|
+
});
|
|
1203
|
+
});
|
|
1204
|
+
if (changed) this.emit("invalid-node-change", map);
|
|
1205
|
+
}
|
|
1206
|
+
/** 清理不在当前 DSL 中的失效节点错误记录(用于整体替换 root 后) */
|
|
1207
|
+
pruneInvalidNodeIds() {
|
|
1208
|
+
const map = this.get("invalidNodeIds");
|
|
1209
|
+
if (map.size === 0) return;
|
|
1210
|
+
let changed = false;
|
|
1211
|
+
for (const id of [...map.keys()]) if (!this.getNodeById(id, false)) {
|
|
1212
|
+
map.delete(id);
|
|
1213
|
+
changed = true;
|
|
1214
|
+
}
|
|
1215
|
+
if (changed) this.emit("invalid-node-change", map);
|
|
1216
|
+
}
|
|
918
1217
|
addModifiedNodeId(id) {
|
|
919
1218
|
this.get("modifiedNodeIds").set(id, id);
|
|
920
1219
|
}
|
|
1220
|
+
/**
|
|
1221
|
+
* 获取指定节点所属的页面 / 页面片:
|
|
1222
|
+
* - 普通节点返回其所在的 page;
|
|
1223
|
+
* - 节点本身就是 page / pageFragment 时返回它自己;
|
|
1224
|
+
* - 找不到时返回 null。
|
|
1225
|
+
* 供 `change` 事件携带「变更节点对应的 page」(而非编辑器当前选中页)。
|
|
1226
|
+
*/
|
|
1227
|
+
getPageOfNode(id) {
|
|
1228
|
+
const { node, page } = this.getNodeInfo(id, false);
|
|
1229
|
+
if (page) return page;
|
|
1230
|
+
if (node && isPageOrFragment(node)) return node;
|
|
1231
|
+
return null;
|
|
1232
|
+
}
|
|
921
1233
|
captureSelectionBeforeOp() {
|
|
922
1234
|
if (this.selectionBeforeOp) return;
|
|
923
1235
|
this.selectionBeforeOp = this.get("nodes").map((n) => n.id);
|
|
1236
|
+
this.invalidNodeIdsBeforeOp = new Map(this.get("invalidNodeIds"));
|
|
924
1237
|
}
|
|
925
|
-
|
|
1238
|
+
/**
|
|
1239
|
+
* 比较「上一次 root」与「新 root」的页面 / 页面片,按页面粒度把整体替换拆成历史记录:
|
|
1240
|
+
* - 新旧都存在且内容变化的页面 → 一条 `update`(整页快照替换,无 changeRecords);
|
|
1241
|
+
* - 仅新 root 存在的页面 → 一条 `add`;
|
|
1242
|
+
* - 仅旧 root 存在的页面 → 一条 `remove`。
|
|
1243
|
+
*
|
|
1244
|
+
* 每条记录落到对应页面自己的历史栈(与普通节点操作一致),并标记来源 `source`。
|
|
1245
|
+
* 内容未变化的页面不产生记录,避免重复设置相同 DSL 时产生噪声。
|
|
1246
|
+
*/
|
|
1247
|
+
pushRootDiffHistory(preRoot, nextRoot, source) {
|
|
1248
|
+
const prevPages = preRoot?.items || [];
|
|
1249
|
+
const nextPages = nextRoot?.items || [];
|
|
1250
|
+
const prevMap = new Map(prevPages.map((p) => [`${p.id}`, p]));
|
|
1251
|
+
const nextMap = new Map(nextPages.map((p) => [`${p.id}`, p]));
|
|
1252
|
+
const indexInItems = (root, id) => (root.items ?? []).findIndex((item) => `${item.id}` === `${id}`);
|
|
1253
|
+
const addedPages = [];
|
|
1254
|
+
const removedPages = [];
|
|
1255
|
+
nextPages.forEach((nextPage) => {
|
|
1256
|
+
const prevPage = prevMap.get(`${nextPage.id}`);
|
|
1257
|
+
if (!prevPage) {
|
|
1258
|
+
this.pushPageDiffStep("add", nextPage, {
|
|
1259
|
+
newSchema: cloneDeep$1(toRaw(nextPage)),
|
|
1260
|
+
parentId: nextRoot.id,
|
|
1261
|
+
index: indexInItems(nextRoot, nextPage.id)
|
|
1262
|
+
}, source);
|
|
1263
|
+
addedPages.push(nextPage);
|
|
1264
|
+
} else if (!isEqual(toRaw(prevPage), toRaw(nextPage))) this.pushPageDiffStep("update", nextPage, {
|
|
1265
|
+
oldSchema: cloneDeep$1(toRaw(prevPage)),
|
|
1266
|
+
newSchema: cloneDeep$1(toRaw(nextPage))
|
|
1267
|
+
}, source);
|
|
1268
|
+
});
|
|
1269
|
+
prevPages.forEach((prevPage) => {
|
|
1270
|
+
if (!nextMap.has(`${prevPage.id}`)) {
|
|
1271
|
+
this.pushPageDiffStep("remove", prevPage, {
|
|
1272
|
+
oldSchema: cloneDeep$1(toRaw(prevPage)),
|
|
1273
|
+
parentId: preRoot.id,
|
|
1274
|
+
index: indexInItems(preRoot, prevPage.id)
|
|
1275
|
+
}, source);
|
|
1276
|
+
removedPages.push(prevPage);
|
|
1277
|
+
}
|
|
1278
|
+
});
|
|
1279
|
+
if (addedPages.length || removedPages.length) history_default.notifyPageStructureChange({
|
|
1280
|
+
add: addedPages,
|
|
1281
|
+
remove: removedPages
|
|
1282
|
+
});
|
|
1283
|
+
}
|
|
1284
|
+
/**
|
|
1285
|
+
* 构造一条页面级「set root」历史记录(不携带选区 / modifiedNodeIds 上下文)并落到该页面自己的栈。
|
|
1286
|
+
*
|
|
1287
|
+
* 连续 set root 替换:若该页栈最新一条已是**同来源**的 set root 记录({@link StepValue.rootStep} 且 `source` 相同),
|
|
1288
|
+
* 则用本次记录**替换**它而非新增,避免源码反复保存 / 外部重设 DSL 时堆积多条 root 记录;
|
|
1289
|
+
* 来源不同则照常新增(initial 基线不是 rootStep,不在此列)。
|
|
1290
|
+
*/
|
|
1291
|
+
pushPageDiffStep(opType, page, diffItem, source) {
|
|
926
1292
|
const step = {
|
|
1293
|
+
uuid: guid(),
|
|
1294
|
+
data: {
|
|
1295
|
+
name: page.name || "",
|
|
1296
|
+
id: page.id
|
|
1297
|
+
},
|
|
1298
|
+
opType,
|
|
1299
|
+
extra: {
|
|
1300
|
+
selectedBefore: [],
|
|
1301
|
+
selectedAfter: [],
|
|
1302
|
+
modifiedNodeIds: /* @__PURE__ */ new Map()
|
|
1303
|
+
},
|
|
1304
|
+
diff: [diffItem],
|
|
1305
|
+
rootStep: true
|
|
1306
|
+
};
|
|
1307
|
+
if (source) step.source = source;
|
|
1308
|
+
const top = history_default.getCurrentPageStep(page.id);
|
|
1309
|
+
if (top?.rootStep && top.source === source) history_default.replaceCurrentStep("page", step, page.id);
|
|
1310
|
+
else history_default.push("page", step, page.id);
|
|
1311
|
+
}
|
|
1312
|
+
pushOpHistory(opType, { diff, pageData, historyDescription, source }) {
|
|
1313
|
+
const step = {
|
|
1314
|
+
uuid: guid(),
|
|
927
1315
|
data: pageData,
|
|
928
1316
|
opType,
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
1317
|
+
extra: {
|
|
1318
|
+
selectedBefore: this.selectionBeforeOp ?? [],
|
|
1319
|
+
selectedAfter: this.get("nodes").map((n) => n.id),
|
|
1320
|
+
modifiedNodeIds: new Map(this.get("modifiedNodeIds")),
|
|
1321
|
+
invalidNodeIdsBefore: new Map(this.invalidNodeIdsBeforeOp ?? this.get("invalidNodeIds")),
|
|
1322
|
+
invalidNodeIdsAfter: new Map(this.get("invalidNodeIds"))
|
|
1323
|
+
},
|
|
1324
|
+
diff
|
|
933
1325
|
};
|
|
934
1326
|
if (historyDescription) step.historyDescription = historyDescription;
|
|
935
|
-
|
|
1327
|
+
if (source) step.source = source;
|
|
1328
|
+
const historyId = history_default.push("page", step, pageData.id) ? step.uuid : null;
|
|
1329
|
+
this.lastPushedHistoryId = historyId;
|
|
936
1330
|
this.selectionBeforeOp = null;
|
|
1331
|
+
this.invalidNodeIdsBeforeOp = null;
|
|
1332
|
+
return historyId;
|
|
937
1333
|
}
|
|
938
1334
|
/**
|
|
939
1335
|
* 应用历史操作(撤销 / 重做)
|
|
940
1336
|
*
|
|
941
|
-
*
|
|
942
|
-
* `doNotSelect / doNotSwitchPage`
|
|
1337
|
+
* 删除 / 更新类修改走 `editor.remove / update`,并通过 `doNotPushHistory` 阻止再次入栈、
|
|
1338
|
+
* `doNotSelect / doNotSwitchPage` 让选区由方法末尾的统一逻辑兜底;
|
|
1339
|
+
* 「重新插回节点」(撤销 remove / 重做 add)需按 step 记录的 parentId / index 精确还原,
|
|
1340
|
+
* 不走 this.add,由手工 splice + stage.add 完成后补发等价的 add / change 事件(见 emitHistoryInsertEvents)。
|
|
943
1341
|
*
|
|
944
|
-
*
|
|
1342
|
+
* 注意:这些路径都会发出 add / remove / update / change 事件,业务侧若需要区分"用户操作"与"撤销重做触发",
|
|
945
1343
|
* 请监听 `history-change` 事件配合判断。
|
|
946
1344
|
*
|
|
947
1345
|
* @param step 操作记录
|
|
948
1346
|
* @param reverse true = 撤销,false = 重做
|
|
949
1347
|
*/
|
|
950
1348
|
async applyHistoryOp(step, reverse) {
|
|
1349
|
+
if (step.opType === "initial") return;
|
|
951
1350
|
const root = this.get("root");
|
|
952
1351
|
const stage = this.get("stage");
|
|
953
1352
|
if (!root) return;
|
|
954
1353
|
const commonOpts = {
|
|
955
1354
|
doNotSelect: true,
|
|
956
1355
|
doNotSwitchPage: true,
|
|
957
|
-
doNotPushHistory: true
|
|
1356
|
+
doNotPushHistory: true,
|
|
1357
|
+
historySource: step.source
|
|
958
1358
|
};
|
|
959
1359
|
switch (step.opType) {
|
|
960
1360
|
case "add": {
|
|
961
|
-
const
|
|
962
|
-
if (reverse) for (const
|
|
963
|
-
|
|
1361
|
+
const items = step.diff ?? [];
|
|
1362
|
+
if (reverse) for (const { newSchema } of items) {
|
|
1363
|
+
if (!newSchema) continue;
|
|
1364
|
+
const existing = this.getNodeById(newSchema.id, false);
|
|
964
1365
|
if (existing) await this.remove(existing, commonOpts);
|
|
965
1366
|
}
|
|
966
1367
|
else {
|
|
967
|
-
const
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
1368
|
+
const sorted = [...items].sort((a, b) => (a.index ?? 0) - (b.index ?? 0));
|
|
1369
|
+
const addedNodes = [];
|
|
1370
|
+
for (const { newSchema, parentId, index } of sorted) {
|
|
1371
|
+
if (!newSchema || parentId === void 0) continue;
|
|
1372
|
+
const parent = this.getNodeById(parentId, false);
|
|
1373
|
+
if (parent?.items) {
|
|
1374
|
+
const addedNode = cloneDeep$1(newSchema);
|
|
1375
|
+
if (typeof index === "number" && index >= 0 && index < parent.items.length) parent.items.splice(index, 0, addedNode);
|
|
1376
|
+
else parent.items.push(addedNode);
|
|
1377
|
+
addedNodes.push(addedNode);
|
|
1378
|
+
await stage?.add({
|
|
1379
|
+
config: cloneDeep$1(newSchema),
|
|
1380
|
+
parent: cloneDeep$1(parent),
|
|
1381
|
+
parentId: parent.id,
|
|
1382
|
+
root: cloneDeep$1(root)
|
|
1383
|
+
});
|
|
982
1384
|
}
|
|
983
1385
|
}
|
|
1386
|
+
this.emitHistoryInsertEvents(addedNodes, step.source);
|
|
984
1387
|
}
|
|
985
1388
|
break;
|
|
986
1389
|
}
|
|
987
1390
|
case "remove": {
|
|
988
|
-
const items = step.
|
|
1391
|
+
const items = step.diff ?? [];
|
|
989
1392
|
if (reverse) {
|
|
990
|
-
const sorted = [...items].sort((a, b) => a.index - b.index);
|
|
991
|
-
|
|
1393
|
+
const sorted = [...items].sort((a, b) => (a.index ?? 0) - (b.index ?? 0));
|
|
1394
|
+
const addedNodes = [];
|
|
1395
|
+
for (const { oldSchema, parentId, index } of sorted) {
|
|
1396
|
+
if (!oldSchema || parentId === void 0) continue;
|
|
992
1397
|
const parent = this.getNodeById(parentId, false);
|
|
993
1398
|
if (parent?.items) {
|
|
994
|
-
|
|
1399
|
+
const addedNode = cloneDeep$1(oldSchema);
|
|
1400
|
+
parent.items.splice(index ?? parent.items.length, 0, addedNode);
|
|
1401
|
+
addedNodes.push(addedNode);
|
|
995
1402
|
await stage?.add({
|
|
996
|
-
config: cloneDeep$1(
|
|
1403
|
+
config: cloneDeep$1(oldSchema),
|
|
997
1404
|
parent: cloneDeep$1(parent),
|
|
998
1405
|
parentId,
|
|
999
1406
|
root: cloneDeep$1(root)
|
|
1000
1407
|
});
|
|
1001
1408
|
}
|
|
1002
1409
|
}
|
|
1003
|
-
|
|
1004
|
-
|
|
1410
|
+
this.emitHistoryInsertEvents(addedNodes, step.source);
|
|
1411
|
+
} else for (const { oldSchema } of items) {
|
|
1412
|
+
if (!oldSchema) continue;
|
|
1413
|
+
const existing = this.getNodeById(oldSchema.id, false);
|
|
1005
1414
|
if (existing) await this.remove(existing, commonOpts);
|
|
1006
1415
|
}
|
|
1007
1416
|
break;
|
|
1008
1417
|
}
|
|
1009
1418
|
case "update": {
|
|
1010
|
-
const configs = (step.
|
|
1419
|
+
const configs = (step.diff ?? []).filter((item) => item.oldSchema && item.newSchema).map(({ oldSchema, newSchema, changeRecords }) => {
|
|
1420
|
+
const oldNode = oldSchema;
|
|
1421
|
+
const newNode = newSchema;
|
|
1011
1422
|
if (changeRecords?.length) {
|
|
1012
1423
|
const sourceForValues = reverse ? oldNode : newNode;
|
|
1013
1424
|
const patch = {
|
|
@@ -1023,14 +1434,20 @@ var Editor = class extends BaseService {
|
|
|
1023
1434
|
}
|
|
1024
1435
|
return cloneDeep$1(reverse ? oldNode : newNode);
|
|
1025
1436
|
});
|
|
1026
|
-
if (configs.length) await this.update(configs, {
|
|
1437
|
+
if (configs.length) await this.update(configs, {
|
|
1438
|
+
doNotPushHistory: true,
|
|
1439
|
+
historySource: step.source
|
|
1440
|
+
});
|
|
1027
1441
|
break;
|
|
1028
1442
|
}
|
|
1029
1443
|
}
|
|
1030
|
-
this.set("modifiedNodeIds", step.modifiedNodeIds);
|
|
1444
|
+
this.set("modifiedNodeIds", step.extra?.modifiedNodeIds ?? /* @__PURE__ */ new Map());
|
|
1445
|
+
const invalidToRestore = (reverse ? step.extra?.invalidNodeIdsBefore : step.extra?.invalidNodeIdsAfter) ?? /* @__PURE__ */ new Map();
|
|
1446
|
+
this.set("invalidNodeIds", new Map(invalidToRestore));
|
|
1447
|
+
this.emit("invalid-node-change", this.get("invalidNodeIds"));
|
|
1031
1448
|
const page = toRaw(this.get("page"));
|
|
1032
1449
|
if (page) {
|
|
1033
|
-
const selectIds = reverse ? step.selectedBefore : step.selectedAfter;
|
|
1450
|
+
const selectIds = (reverse ? step.extra?.selectedBefore : step.extra?.selectedAfter) ?? [];
|
|
1034
1451
|
setTimeout(() => {
|
|
1035
1452
|
if (!selectIds.length) return;
|
|
1036
1453
|
if (selectIds.length > 1) {
|
|
@@ -1044,6 +1461,23 @@ var Editor = class extends BaseService {
|
|
|
1044
1461
|
selectedConfigExceptionHandler(config) {
|
|
1045
1462
|
return resolveSelectedNode(config, (id) => this.getNodeInfo(id), this.state.root?.id);
|
|
1046
1463
|
}
|
|
1464
|
+
/**
|
|
1465
|
+
* 撤销 remove / 重做 add 通过手工 splice 按 step 记录的 parentId / index 精确还原节点(不走 this.add,原因见调用处注释),
|
|
1466
|
+
* 这里补齐与 this.add 等价的 add / change 事件,保证撤销/重做路径的事件行为与正向操作一致。
|
|
1467
|
+
*/
|
|
1468
|
+
emitHistoryInsertEvents(nodes, source) {
|
|
1469
|
+
if (!nodes.length) return;
|
|
1470
|
+
this.emit("add", nodes);
|
|
1471
|
+
this.emit("change", {
|
|
1472
|
+
type: "add",
|
|
1473
|
+
data: nodes.map((node) => ({
|
|
1474
|
+
node,
|
|
1475
|
+
page: this.getPageOfNode(node.id)
|
|
1476
|
+
})),
|
|
1477
|
+
historySource: source,
|
|
1478
|
+
doNotPushHistory: true
|
|
1479
|
+
});
|
|
1480
|
+
}
|
|
1047
1481
|
};
|
|
1048
1482
|
var editor_default = new Editor();
|
|
1049
1483
|
//#endregion
|