@atlaskit/editor-plugin-block-menu 5.2.19 → 5.2.21
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/CHANGELOG.md +16 -0
- package/dist/cjs/blockMenuPlugin.js +17 -2
- package/dist/cjs/editor-actions/isTrasformToTargetDisabled.js +114 -0
- package/dist/cjs/editor-commands/transform-node-utils/steps/listToDecisionListStep.js +1 -1
- package/dist/cjs/editor-commands/transform-node-utils/steps/wrapMixedContentStep.js +2 -16
- package/dist/cjs/editor-commands/transform-node-utils/transform.js +99 -29
- package/dist/cjs/editor-commands/transform-node-utils/utils.js +16 -1
- package/dist/cjs/editor-commands/transform-node-utils/wrapIntoListStep.js +10 -2
- package/dist/es2019/blockMenuPlugin.js +17 -2
- package/dist/es2019/editor-actions/isTrasformToTargetDisabled.js +110 -0
- package/dist/es2019/editor-commands/transform-node-utils/steps/listToDecisionListStep.js +1 -1
- package/dist/es2019/editor-commands/transform-node-utils/steps/wrapMixedContentStep.js +1 -15
- package/dist/es2019/editor-commands/transform-node-utils/transform.js +98 -28
- package/dist/es2019/editor-commands/transform-node-utils/utils.js +15 -0
- package/dist/es2019/editor-commands/transform-node-utils/wrapIntoListStep.js +6 -2
- package/dist/esm/blockMenuPlugin.js +17 -2
- package/dist/esm/editor-actions/isTrasformToTargetDisabled.js +108 -0
- package/dist/esm/editor-commands/transform-node-utils/steps/listToDecisionListStep.js +1 -1
- package/dist/esm/editor-commands/transform-node-utils/steps/wrapMixedContentStep.js +1 -15
- package/dist/esm/editor-commands/transform-node-utils/transform.js +98 -28
- package/dist/esm/editor-commands/transform-node-utils/utils.js +15 -0
- package/dist/esm/editor-commands/transform-node-utils/wrapIntoListStep.js +10 -2
- package/dist/types/blockMenuPluginType.d.ts +1 -0
- package/dist/types/editor-actions/isTrasformToTargetDisabled.d.ts +11 -0
- package/dist/types/editor-commands/transform-node-utils/transform.d.ts +2 -0
- package/dist/types/editor-commands/transform-node-utils/utils.d.ts +6 -0
- package/dist/types-ts4.5/blockMenuPluginType.d.ts +1 -0
- package/dist/types-ts4.5/editor-actions/isTrasformToTargetDisabled.d.ts +11 -0
- package/dist/types-ts4.5/editor-commands/transform-node-utils/transform.d.ts +2 -0
- package/dist/types-ts4.5/editor-commands/transform-node-utils/utils.d.ts +6 -0
- package/package.json +4 -4
- package/dist/cjs/editor-commands/transform-node-utils/stubStep.js +0 -9
- package/dist/es2019/editor-commands/transform-node-utils/stubStep.js +0 -3
- package/dist/esm/editor-commands/transform-node-utils/stubStep.js +0 -3
- package/dist/types/editor-commands/transform-node-utils/stubStep.d.ts +0 -2
- package/dist/types-ts4.5/editor-commands/transform-node-utils/stubStep.d.ts +0 -2
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { expandSelectionToBlockRange } from '@atlaskit/editor-common/selection';
|
|
2
|
+
import { Fragment } from '@atlaskit/editor-prosemirror/model';
|
|
3
|
+
import { isTransformDisabledBasedOnStepsConfig } from '../editor-commands/transform-node-utils/transform';
|
|
4
|
+
import { toNodeTypeValue } from '../editor-commands/transform-node-utils/types';
|
|
5
|
+
import { getBlockNodesInRange, getTargetNodeTypeNameInContext } from '../editor-commands/transform-node-utils/utils';
|
|
6
|
+
export const canParentContainNodeType = (schema, parentNode, nodeTypeName, nodeTypeAttrs) => {
|
|
7
|
+
const adjustedNodeTypeName = getTargetNodeTypeNameInContext(nodeTypeName, true);
|
|
8
|
+
if (!adjustedNodeTypeName) {
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
const nodeType = schema.nodes[adjustedNodeTypeName];
|
|
12
|
+
return parentNode.type.validContent(Fragment.from(nodeType.createAndFill(nodeTypeAttrs)));
|
|
13
|
+
};
|
|
14
|
+
const isHeadingToHeadingTransformEnabled = (selectedNode, targetNodeTypeAttrs) => {
|
|
15
|
+
var _selectedNode$attrs;
|
|
16
|
+
const selectedLevel = (_selectedNode$attrs = selectedNode.attrs) === null || _selectedNode$attrs === void 0 ? void 0 : _selectedNode$attrs.level;
|
|
17
|
+
const targetLevel = targetNodeTypeAttrs === null || targetNodeTypeAttrs === void 0 ? void 0 : targetNodeTypeAttrs.level;
|
|
18
|
+
if (selectedLevel === undefined || targetLevel === undefined) {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
return selectedLevel !== targetLevel;
|
|
22
|
+
};
|
|
23
|
+
const isTransformEnabledForNode = (node, targetNodeTypeName, targetNodeTypeAttrs, isNested, parent, schema) => {
|
|
24
|
+
const selectedNodeTypeName = toNodeTypeValue(node.type.name);
|
|
25
|
+
if (!selectedNodeTypeName) {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
const isDisabledByStepsConfig = isTransformDisabledBasedOnStepsConfig(selectedNodeTypeName, targetNodeTypeName);
|
|
29
|
+
if (isDisabledByStepsConfig) {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
if (selectedNodeTypeName === 'heading' && targetNodeTypeName === 'heading') {
|
|
33
|
+
return isHeadingToHeadingTransformEnabled(node, targetNodeTypeAttrs);
|
|
34
|
+
}
|
|
35
|
+
if (isNested && !canParentContainNodeType(schema, parent, targetNodeTypeName, targetNodeTypeAttrs)) {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
return true;
|
|
39
|
+
};
|
|
40
|
+
export const isTrasformToTargetDisabled = ({
|
|
41
|
+
selection,
|
|
42
|
+
targetNodeTypeName,
|
|
43
|
+
targetNodeTypeAttrs
|
|
44
|
+
}) => {
|
|
45
|
+
const {
|
|
46
|
+
range
|
|
47
|
+
} = expandSelectionToBlockRange(selection);
|
|
48
|
+
if (!range) {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
const selectedNodes = getBlockNodesInRange(range);
|
|
52
|
+
const parent = range.parent;
|
|
53
|
+
const isNested = range.depth >= 1;
|
|
54
|
+
const {
|
|
55
|
+
schema
|
|
56
|
+
} = selection.$from.doc.type;
|
|
57
|
+
const supportedTargetNodeTypeName = toNodeTypeValue(targetNodeTypeName);
|
|
58
|
+
if (!supportedTargetNodeTypeName) {
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
const isEnabledForAnyNode = selectedNodes.some(node => isTransformEnabledForNode(node, supportedTargetNodeTypeName, targetNodeTypeAttrs, isNested, parent, schema));
|
|
62
|
+
return !isEnabledForAnyNode;
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
// export const isTrasformToTargetDisabled = ({
|
|
66
|
+
// selection,
|
|
67
|
+
// targetNodeTypeName,
|
|
68
|
+
// targetNodeTypeAttrs,
|
|
69
|
+
// }: TransformDisabledArgs) => {
|
|
70
|
+
// const { range } = expandSelectionToBlockRange(selection);
|
|
71
|
+
// if (!range) {
|
|
72
|
+
// return false;
|
|
73
|
+
// }
|
|
74
|
+
|
|
75
|
+
// const selectedNodes = getBlockNodesInRange(range);
|
|
76
|
+
// const parent = range.parent;
|
|
77
|
+
// const isNested = range.depth >= 1;
|
|
78
|
+
|
|
79
|
+
// const { schema } = selection.$from.doc.type;
|
|
80
|
+
|
|
81
|
+
// const isTransformEnabledForAnySelectedNode = selectedNodes.some((node) => {
|
|
82
|
+
// const selectedNodeTypeName = toNodeTypeValue(node.type.name);
|
|
83
|
+
// const supportedTargetNodeTypeName = toNodeTypeValue(targetNodeTypeName);
|
|
84
|
+
// if (!selectedNodeTypeName || !supportedTargetNodeTypeName) {
|
|
85
|
+
// return false;
|
|
86
|
+
// }
|
|
87
|
+
|
|
88
|
+
// if (isTransformDisabledBasedOnStepsConfig(selectedNodeTypeName, supportedTargetNodeTypeName)) {
|
|
89
|
+
// if (selectedNodeTypeName === 'heading' && supportedTargetNodeTypeName === 'heading') {
|
|
90
|
+
// return isHeadingToHeadingTransformDisabled(node, targetNodeTypeAttrs);
|
|
91
|
+
// }
|
|
92
|
+
// return false;
|
|
93
|
+
// }
|
|
94
|
+
|
|
95
|
+
// if (
|
|
96
|
+
// isNested &&
|
|
97
|
+
// !canParentContainNodeType(schema, parent, supportedTargetNodeTypeName, targetNodeTypeAttrs)
|
|
98
|
+
// ) {
|
|
99
|
+
// return false;
|
|
100
|
+
// }
|
|
101
|
+
|
|
102
|
+
// return true;
|
|
103
|
+
// });
|
|
104
|
+
|
|
105
|
+
// if (isTransformEnabledForAnySelectedNode) {
|
|
106
|
+
// return false;
|
|
107
|
+
// }
|
|
108
|
+
|
|
109
|
+
// return true;
|
|
110
|
+
// };
|
|
@@ -39,7 +39,7 @@ export const listToDecisionListStep = (nodes, context) => {
|
|
|
39
39
|
if (child.type === paragraphType) {
|
|
40
40
|
// paragraph may contain hard breaks etc.
|
|
41
41
|
itemContent.push(...child.children);
|
|
42
|
-
} else if (child.isText) {
|
|
42
|
+
} else if (child.isText || child.isInline) {
|
|
43
43
|
itemContent.push(child);
|
|
44
44
|
} else if (!isListWithIndentation(child.type.name, schema)) {
|
|
45
45
|
unsupportedContent.push(child);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Fragment } from '@atlaskit/editor-prosemirror/model';
|
|
2
2
|
import { NODE_CATEGORY_BY_TYPE } from '../types';
|
|
3
|
+
import { convertTextNodeToParagraph } from '../utils';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Determines if a node is a text node (heading or paragraph).
|
|
@@ -10,21 +11,6 @@ const isTextNode = node => {
|
|
|
10
11
|
return category === 'text';
|
|
11
12
|
};
|
|
12
13
|
|
|
13
|
-
/**
|
|
14
|
-
* Converts a text node (heading, paragraph) to a paragraph preserving its inline content.
|
|
15
|
-
* This is used when a text node can't be wrapped directly in the target container
|
|
16
|
-
* (e.g., heading can't go in blockquote, so it becomes a paragraph).
|
|
17
|
-
*/
|
|
18
|
-
const convertTextNodeToParagraph = (node, schema) => {
|
|
19
|
-
var _schema$nodes$paragra;
|
|
20
|
-
// If it's already a paragraph, return as-is
|
|
21
|
-
if (node.type.name === 'paragraph') {
|
|
22
|
-
return node;
|
|
23
|
-
}
|
|
24
|
-
// Convert heading (or other text node) to paragraph with same inline content
|
|
25
|
-
return (_schema$nodes$paragra = schema.nodes.paragraph.createAndFill({}, node.content)) !== null && _schema$nodes$paragra !== void 0 ? _schema$nodes$paragra : null;
|
|
26
|
-
};
|
|
27
|
-
|
|
28
14
|
/**
|
|
29
15
|
* Determines if a node can be wrapped in the target container type.
|
|
30
16
|
* Uses the schema's validContent to check if the target container can hold this node.
|
|
@@ -10,7 +10,6 @@ import { unwrapListStep } from './steps/unwrapListStep';
|
|
|
10
10
|
import { wrapBlockquoteToDecisionListStep } from './steps/wrapBlockquoteToDecisionListStep';
|
|
11
11
|
import { wrapMixedContentStep } from './steps/wrapMixedContentStep';
|
|
12
12
|
import { wrapTextToCodeblockStep } from './steps/wrapTextToCodeblock';
|
|
13
|
-
import { stubStep } from './stubStep';
|
|
14
13
|
import { NODE_CATEGORY_BY_TYPE, toNodeTypeValue } from './types';
|
|
15
14
|
import { unwrapExpandStep } from './unwrapExpandStep';
|
|
16
15
|
import { unwrapStep } from './unwrapStep';
|
|
@@ -40,7 +39,7 @@ const TRANSFORM_STEPS = {
|
|
|
40
39
|
},
|
|
41
40
|
text: {
|
|
42
41
|
atomic: undefined,
|
|
43
|
-
container: [
|
|
42
|
+
container: [wrapMixedContentStep],
|
|
44
43
|
list: [wrapIntoListStep],
|
|
45
44
|
text: [flattenStep, applyTargetTextTypeStep]
|
|
46
45
|
}
|
|
@@ -48,102 +47,166 @@ const TRANSFORM_STEPS = {
|
|
|
48
47
|
|
|
49
48
|
// Transform steps for specific pairs of node types that cannot be processed
|
|
50
49
|
// using generic rules/steps from TRANSFORM_STEPS.
|
|
50
|
+
// Use 'null' to indicate unavailable transfrorm for a case where TRANSFORM_STEPS are not undefined.
|
|
51
51
|
const TRANSFORM_STEPS_OVERRIDE = {
|
|
52
52
|
paragraph: {
|
|
53
|
+
paragraph: null,
|
|
54
|
+
codeBlock: [wrapTextToCodeblockStep],
|
|
55
|
+
layoutSection: [wrapIntoLayoutStep]
|
|
56
|
+
},
|
|
57
|
+
heading: {
|
|
53
58
|
codeBlock: [wrapTextToCodeblockStep],
|
|
54
59
|
layoutSection: [wrapIntoLayoutStep]
|
|
55
60
|
},
|
|
56
61
|
panel: {
|
|
62
|
+
panel: null,
|
|
57
63
|
layoutSection: [unwrapStep, wrapIntoLayoutStep],
|
|
58
64
|
codeBlock: [unwrapStep, flattenStep, wrapStep],
|
|
59
|
-
blockquote: [unwrapStep, wrapMixedContentStep]
|
|
65
|
+
blockquote: [unwrapStep, wrapMixedContentStep],
|
|
66
|
+
taskList: null,
|
|
67
|
+
bulletList: null,
|
|
68
|
+
orderedList: null,
|
|
69
|
+
heading: null
|
|
60
70
|
},
|
|
61
71
|
expand: {
|
|
72
|
+
expand: null,
|
|
62
73
|
panel: [unwrapExpandStep, wrapMixedContentStep],
|
|
63
74
|
blockquote: [unwrapExpandStep, wrapMixedContentStep],
|
|
64
75
|
layoutSection: [unwrapExpandStep, wrapIntoLayoutStep],
|
|
65
76
|
paragraph: [unwrapExpandStep],
|
|
66
|
-
codeBlock:
|
|
77
|
+
codeBlock: null,
|
|
78
|
+
heading: null
|
|
67
79
|
},
|
|
68
80
|
nestedExpand: {
|
|
81
|
+
expand: null,
|
|
82
|
+
nestedExpand: null,
|
|
69
83
|
panel: [unwrapExpandStep, wrapMixedContentStep],
|
|
70
84
|
blockquote: [unwrapExpandStep, wrapMixedContentStep],
|
|
71
85
|
paragraph: [unwrapExpandStep],
|
|
72
|
-
codeBlock:
|
|
86
|
+
codeBlock: null,
|
|
87
|
+
heading: null
|
|
73
88
|
},
|
|
74
89
|
blockquote: {
|
|
90
|
+
blockquote: null,
|
|
75
91
|
expand: [wrapStep],
|
|
76
92
|
nestedExpand: [wrapStep],
|
|
77
93
|
layoutSection: [wrapIntoLayoutStep],
|
|
78
|
-
codeBlock:
|
|
94
|
+
codeBlock: null,
|
|
79
95
|
decisionList: [unwrapStep, wrapBlockquoteToDecisionListStep]
|
|
80
96
|
},
|
|
81
97
|
layoutSection: {
|
|
98
|
+
layoutSection: null,
|
|
82
99
|
blockquote: [unwrapLayoutStep, wrapMixedContentStep],
|
|
83
100
|
expand: [unwrapLayoutStep, wrapStep],
|
|
84
101
|
panel: [unwrapLayoutStep, wrapMixedContentStep],
|
|
85
|
-
codeBlock:
|
|
86
|
-
paragraph: [unwrapLayoutStep]
|
|
102
|
+
codeBlock: null,
|
|
103
|
+
paragraph: [unwrapLayoutStep],
|
|
104
|
+
heading: null
|
|
87
105
|
},
|
|
88
106
|
codeBlock: {
|
|
107
|
+
codeBlock: null,
|
|
89
108
|
blockquote: [wrapStep],
|
|
90
109
|
expand: [wrapStep],
|
|
91
110
|
nestedExpand: [wrapStep],
|
|
92
111
|
layoutSection: [wrapIntoLayoutStep],
|
|
93
|
-
panel: [wrapStep]
|
|
112
|
+
panel: [wrapStep],
|
|
113
|
+
heading: null
|
|
94
114
|
},
|
|
95
115
|
bulletList: {
|
|
96
|
-
|
|
97
|
-
codeBlock:
|
|
116
|
+
bulletList: null,
|
|
117
|
+
codeBlock: null,
|
|
98
118
|
layoutSection: [wrapIntoLayoutStep],
|
|
99
|
-
decisionList: [flattenListStep, listToDecisionListStep]
|
|
119
|
+
decisionList: [flattenListStep, listToDecisionListStep],
|
|
120
|
+
heading: null
|
|
100
121
|
},
|
|
101
122
|
orderedList: {
|
|
102
|
-
|
|
103
|
-
codeBlock:
|
|
123
|
+
orderedList: null,
|
|
124
|
+
codeBlock: null,
|
|
104
125
|
layoutSection: [wrapIntoLayoutStep],
|
|
105
|
-
decisionList: [flattenListStep, listToDecisionListStep]
|
|
126
|
+
decisionList: [flattenListStep, listToDecisionListStep],
|
|
127
|
+
heading: null
|
|
106
128
|
},
|
|
107
129
|
taskList: {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
codeBlock: [stubStep],
|
|
130
|
+
blockquote: null,
|
|
131
|
+
codeBlock: null,
|
|
111
132
|
layoutSection: [wrapIntoLayoutStep],
|
|
112
|
-
decisionList: [flattenListStep, listToDecisionListStep]
|
|
133
|
+
decisionList: [flattenListStep, listToDecisionListStep],
|
|
134
|
+
heading: null,
|
|
135
|
+
taskList: null
|
|
113
136
|
},
|
|
114
137
|
table: {
|
|
115
|
-
layoutSection: [wrapIntoLayoutStep]
|
|
138
|
+
layoutSection: [wrapIntoLayoutStep],
|
|
139
|
+
blockquote: null,
|
|
140
|
+
panel: null,
|
|
141
|
+
codeBlock: null,
|
|
142
|
+
orderedList: null,
|
|
143
|
+
bulletList: null,
|
|
144
|
+
taskList: null,
|
|
145
|
+
decisionList: null
|
|
116
146
|
},
|
|
117
147
|
mediaSingle: {
|
|
118
|
-
layoutSection: [wrapIntoLayoutStep]
|
|
148
|
+
layoutSection: [wrapIntoLayoutStep],
|
|
149
|
+
codeBlock: null,
|
|
150
|
+
decisionList: null,
|
|
151
|
+
taskList: null
|
|
119
152
|
},
|
|
120
153
|
mediaGroup: {
|
|
121
|
-
layoutSection: [wrapIntoLayoutStep]
|
|
154
|
+
layoutSection: [wrapIntoLayoutStep],
|
|
155
|
+
codeBlock: null
|
|
122
156
|
},
|
|
123
157
|
decisionList: {
|
|
158
|
+
decisionList: null,
|
|
124
159
|
bulletList: [decisionListToListStep],
|
|
125
160
|
orderedList: [decisionListToListStep],
|
|
126
161
|
taskList: [decisionListToListStep],
|
|
127
162
|
layoutSection: [wrapIntoLayoutStep]
|
|
128
163
|
},
|
|
129
164
|
blockCard: {
|
|
130
|
-
layoutSection: [wrapIntoLayoutStep]
|
|
165
|
+
layoutSection: [wrapIntoLayoutStep],
|
|
166
|
+
blockquote: null,
|
|
167
|
+
codeBlock: null,
|
|
168
|
+
orderedList: null,
|
|
169
|
+
bulletList: null,
|
|
170
|
+
taskList: null,
|
|
171
|
+
decisionList: null
|
|
131
172
|
},
|
|
132
173
|
embedCard: {
|
|
133
|
-
layoutSection: [wrapIntoLayoutStep]
|
|
174
|
+
layoutSection: [wrapIntoLayoutStep],
|
|
175
|
+
blockquote: null,
|
|
176
|
+
panel: null,
|
|
177
|
+
codeBlock: null,
|
|
178
|
+
orderedList: null,
|
|
179
|
+
bulletList: null,
|
|
180
|
+
taskList: null,
|
|
181
|
+
decisionList: null
|
|
134
182
|
},
|
|
135
183
|
extension: {
|
|
136
|
-
layoutSection: [wrapIntoLayoutStep]
|
|
184
|
+
layoutSection: [wrapIntoLayoutStep],
|
|
185
|
+
codeBlock: null,
|
|
186
|
+
decisionList: null,
|
|
187
|
+
taskList: null
|
|
137
188
|
},
|
|
138
189
|
bodiedExtension: {
|
|
139
|
-
layoutSection: [wrapIntoLayoutStep]
|
|
190
|
+
layoutSection: [wrapIntoLayoutStep],
|
|
191
|
+
blockquote: null,
|
|
192
|
+
expand: null,
|
|
193
|
+
panel: null,
|
|
194
|
+
codeBlock: null,
|
|
195
|
+
orderedList: null,
|
|
196
|
+
bulletList: null,
|
|
197
|
+
taskList: null,
|
|
198
|
+
decisionList: null
|
|
140
199
|
}
|
|
141
200
|
};
|
|
142
201
|
const getTransformStepsForNodeTypes = (selectedNodeTypeName, targetNodeTypeName) => {
|
|
143
|
-
var _TRANSFORM_STEPS_OVER
|
|
202
|
+
var _TRANSFORM_STEPS_OVER;
|
|
144
203
|
const fromCategory = NODE_CATEGORY_BY_TYPE[selectedNodeTypeName];
|
|
145
204
|
const toCategory = NODE_CATEGORY_BY_TYPE[targetNodeTypeName];
|
|
146
|
-
const
|
|
205
|
+
const overrideSteps = (_TRANSFORM_STEPS_OVER = TRANSFORM_STEPS_OVERRIDE[selectedNodeTypeName]) === null || _TRANSFORM_STEPS_OVER === void 0 ? void 0 : _TRANSFORM_STEPS_OVER[targetNodeTypeName];
|
|
206
|
+
if (overrideSteps === null) {
|
|
207
|
+
return null;
|
|
208
|
+
}
|
|
209
|
+
const steps = overrideSteps !== null && overrideSteps !== void 0 ? overrideSteps : TRANSFORM_STEPS[fromCategory][toCategory];
|
|
147
210
|
return steps;
|
|
148
211
|
};
|
|
149
212
|
// Note: Currently works only for single node in the selection
|
|
@@ -175,4 +238,11 @@ export const getOutputNodes = ({
|
|
|
175
238
|
return steps.reduce((nodes, step) => {
|
|
176
239
|
return step(nodes, context);
|
|
177
240
|
}, nodesToReplace);
|
|
241
|
+
};
|
|
242
|
+
export const isTransformDisabledBasedOnStepsConfig = (selectedNodeType, targetNodeType) => {
|
|
243
|
+
const steps = getTransformStepsForNodeTypes(selectedNodeType, targetNodeType);
|
|
244
|
+
if (!steps || steps.length === 0) {
|
|
245
|
+
return true;
|
|
246
|
+
}
|
|
247
|
+
return false;
|
|
178
248
|
};
|
|
@@ -82,6 +82,21 @@ export const convertExpandToNestedExpand = (node, schema) => {
|
|
|
82
82
|
title: ((_node$attrs2 = node.attrs) === null || _node$attrs2 === void 0 ? void 0 : _node$attrs2.title) || ''
|
|
83
83
|
}, node.content);
|
|
84
84
|
};
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Converts a text node (heading, paragraph) to a paragraph preserving its inline content.
|
|
88
|
+
* This is used when a text node can't be wrapped directly in the target container
|
|
89
|
+
* (e.g., heading can't go in blockquote, so it becomes a paragraph).
|
|
90
|
+
*/
|
|
91
|
+
export const convertTextNodeToParagraph = (node, schema) => {
|
|
92
|
+
var _schema$nodes$paragra;
|
|
93
|
+
// If it's already a paragraph, return as-is
|
|
94
|
+
if (node.type.name === 'paragraph') {
|
|
95
|
+
return node;
|
|
96
|
+
}
|
|
97
|
+
// Convert heading (or other text node) to paragraph with same inline content
|
|
98
|
+
return (_schema$nodes$paragra = schema.nodes.paragraph.createAndFill({}, node.content)) !== null && _schema$nodes$paragra !== void 0 ? _schema$nodes$paragra : null;
|
|
99
|
+
};
|
|
85
100
|
export const getBlockNodesInRange = range => {
|
|
86
101
|
if (range.startIndex === range.endIndex) {
|
|
87
102
|
return [];
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { isListWithTextContentOnly } from './nodeChecks';
|
|
2
|
+
import { convertTextNodeToParagraph } from './utils';
|
|
2
3
|
const wrapIntoTaskOrDecisionList = (nodes, targetNodeTypeName, schema) => {
|
|
3
4
|
const itemNodeType = targetNodeTypeName === 'taskList' ? schema.nodes.taskItem : schema.nodes.decisionItem;
|
|
4
5
|
const inlineContent = nodes.flatMap(node => {
|
|
@@ -14,8 +15,11 @@ const wrapIntoTaskOrDecisionList = (nodes, targetNodeTypeName, schema) => {
|
|
|
14
15
|
return outputNode ? [outputNode] : nodes;
|
|
15
16
|
};
|
|
16
17
|
const wrapIntoBulletOrOrderedList = (nodes, targetNodeTypeName, schema) => {
|
|
17
|
-
const
|
|
18
|
-
|
|
18
|
+
const listItemNodes = nodes.map(node => schema.nodes.listItem.createAndFill({}, node.isTextblock ? convertTextNodeToParagraph(node, schema) : node)).filter(node => node !== null);
|
|
19
|
+
if (listItemNodes.length === 0) {
|
|
20
|
+
return nodes;
|
|
21
|
+
}
|
|
22
|
+
const outputNode = schema.nodes[targetNodeTypeName].createAndFill({}, listItemNodes);
|
|
19
23
|
return outputNode ? [outputNode] : nodes;
|
|
20
24
|
};
|
|
21
25
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { createBlockMenuRegistry } from './editor-actions';
|
|
3
|
+
import { isTrasformToTargetDisabled } from './editor-actions/isTrasformToTargetDisabled';
|
|
3
4
|
import { formatNode as _formatNode } from './editor-commands/formatNode';
|
|
4
5
|
import { transformNode as _transformNode } from './editor-commands/transformNode';
|
|
5
6
|
import { blockMenuPluginKey, createPlugin } from './pm-plugins/main';
|
|
@@ -29,6 +30,20 @@ export var blockMenuPlugin = function blockMenuPlugin(_ref) {
|
|
|
29
30
|
},
|
|
30
31
|
getBlockMenuComponents: function getBlockMenuComponents() {
|
|
31
32
|
return registry.components;
|
|
33
|
+
},
|
|
34
|
+
isTransformOptionDisabled: function isTransformOptionDisabled(optionNodeTypeName, optionNodeTypeAttrs) {
|
|
35
|
+
var _api$blockControls, _api$selection;
|
|
36
|
+
var preservedSelection = api === null || api === void 0 || (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 || (_api$blockControls = _api$blockControls.sharedState.currentState()) === null || _api$blockControls === void 0 ? void 0 : _api$blockControls.preservedSelection;
|
|
37
|
+
var selection = api === null || api === void 0 || (_api$selection = api.selection) === null || _api$selection === void 0 || (_api$selection = _api$selection.sharedState) === null || _api$selection === void 0 || (_api$selection = _api$selection.currentState()) === null || _api$selection === void 0 ? void 0 : _api$selection.selection;
|
|
38
|
+
var currentSelection = preservedSelection || selection;
|
|
39
|
+
if (!currentSelection) {
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
return isTrasformToTargetDisabled({
|
|
43
|
+
selection: currentSelection,
|
|
44
|
+
targetNodeTypeName: optionNodeTypeName,
|
|
45
|
+
targetNodeTypeAttrs: optionNodeTypeAttrs
|
|
46
|
+
});
|
|
32
47
|
}
|
|
33
48
|
},
|
|
34
49
|
commands: {
|
|
@@ -40,7 +55,7 @@ export var blockMenuPlugin = function blockMenuPlugin(_ref) {
|
|
|
40
55
|
}
|
|
41
56
|
},
|
|
42
57
|
getSharedState: function getSharedState(editorState) {
|
|
43
|
-
var _api$
|
|
58
|
+
var _api$blockControls2, _pluginState$showFlag;
|
|
44
59
|
if (!editorState) {
|
|
45
60
|
return {
|
|
46
61
|
currentSelectedNodeName: undefined,
|
|
@@ -49,7 +64,7 @@ export var blockMenuPlugin = function blockMenuPlugin(_ref) {
|
|
|
49
64
|
}
|
|
50
65
|
|
|
51
66
|
// Get the menuTriggerBy from blockControls plugin if available
|
|
52
|
-
var currentSelectedNodeName = api === null || api === void 0 || (_api$
|
|
67
|
+
var currentSelectedNodeName = api === null || api === void 0 || (_api$blockControls2 = api.blockControls) === null || _api$blockControls2 === void 0 || (_api$blockControls2 = _api$blockControls2.sharedState.currentState()) === null || _api$blockControls2 === void 0 ? void 0 : _api$blockControls2.menuTriggerBy;
|
|
53
68
|
|
|
54
69
|
// Get the showFlag from plugin state
|
|
55
70
|
var pluginState = blockMenuPluginKey.getState(editorState);
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { expandSelectionToBlockRange } from '@atlaskit/editor-common/selection';
|
|
2
|
+
import { Fragment } from '@atlaskit/editor-prosemirror/model';
|
|
3
|
+
import { isTransformDisabledBasedOnStepsConfig } from '../editor-commands/transform-node-utils/transform';
|
|
4
|
+
import { toNodeTypeValue } from '../editor-commands/transform-node-utils/types';
|
|
5
|
+
import { getBlockNodesInRange, getTargetNodeTypeNameInContext } from '../editor-commands/transform-node-utils/utils';
|
|
6
|
+
export var canParentContainNodeType = function canParentContainNodeType(schema, parentNode, nodeTypeName, nodeTypeAttrs) {
|
|
7
|
+
var adjustedNodeTypeName = getTargetNodeTypeNameInContext(nodeTypeName, true);
|
|
8
|
+
if (!adjustedNodeTypeName) {
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
var nodeType = schema.nodes[adjustedNodeTypeName];
|
|
12
|
+
return parentNode.type.validContent(Fragment.from(nodeType.createAndFill(nodeTypeAttrs)));
|
|
13
|
+
};
|
|
14
|
+
var isHeadingToHeadingTransformEnabled = function isHeadingToHeadingTransformEnabled(selectedNode, targetNodeTypeAttrs) {
|
|
15
|
+
var _selectedNode$attrs;
|
|
16
|
+
var selectedLevel = (_selectedNode$attrs = selectedNode.attrs) === null || _selectedNode$attrs === void 0 ? void 0 : _selectedNode$attrs.level;
|
|
17
|
+
var targetLevel = targetNodeTypeAttrs === null || targetNodeTypeAttrs === void 0 ? void 0 : targetNodeTypeAttrs.level;
|
|
18
|
+
if (selectedLevel === undefined || targetLevel === undefined) {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
return selectedLevel !== targetLevel;
|
|
22
|
+
};
|
|
23
|
+
var isTransformEnabledForNode = function isTransformEnabledForNode(node, targetNodeTypeName, targetNodeTypeAttrs, isNested, parent, schema) {
|
|
24
|
+
var selectedNodeTypeName = toNodeTypeValue(node.type.name);
|
|
25
|
+
if (!selectedNodeTypeName) {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
var isDisabledByStepsConfig = isTransformDisabledBasedOnStepsConfig(selectedNodeTypeName, targetNodeTypeName);
|
|
29
|
+
if (isDisabledByStepsConfig) {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
if (selectedNodeTypeName === 'heading' && targetNodeTypeName === 'heading') {
|
|
33
|
+
return isHeadingToHeadingTransformEnabled(node, targetNodeTypeAttrs);
|
|
34
|
+
}
|
|
35
|
+
if (isNested && !canParentContainNodeType(schema, parent, targetNodeTypeName, targetNodeTypeAttrs)) {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
return true;
|
|
39
|
+
};
|
|
40
|
+
export var isTrasformToTargetDisabled = function isTrasformToTargetDisabled(_ref) {
|
|
41
|
+
var selection = _ref.selection,
|
|
42
|
+
targetNodeTypeName = _ref.targetNodeTypeName,
|
|
43
|
+
targetNodeTypeAttrs = _ref.targetNodeTypeAttrs;
|
|
44
|
+
var _expandSelectionToBlo = expandSelectionToBlockRange(selection),
|
|
45
|
+
range = _expandSelectionToBlo.range;
|
|
46
|
+
if (!range) {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
var selectedNodes = getBlockNodesInRange(range);
|
|
50
|
+
var parent = range.parent;
|
|
51
|
+
var isNested = range.depth >= 1;
|
|
52
|
+
var schema = selection.$from.doc.type.schema;
|
|
53
|
+
var supportedTargetNodeTypeName = toNodeTypeValue(targetNodeTypeName);
|
|
54
|
+
if (!supportedTargetNodeTypeName) {
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
var isEnabledForAnyNode = selectedNodes.some(function (node) {
|
|
58
|
+
return isTransformEnabledForNode(node, supportedTargetNodeTypeName, targetNodeTypeAttrs, isNested, parent, schema);
|
|
59
|
+
});
|
|
60
|
+
return !isEnabledForAnyNode;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
// export const isTrasformToTargetDisabled = ({
|
|
64
|
+
// selection,
|
|
65
|
+
// targetNodeTypeName,
|
|
66
|
+
// targetNodeTypeAttrs,
|
|
67
|
+
// }: TransformDisabledArgs) => {
|
|
68
|
+
// const { range } = expandSelectionToBlockRange(selection);
|
|
69
|
+
// if (!range) {
|
|
70
|
+
// return false;
|
|
71
|
+
// }
|
|
72
|
+
|
|
73
|
+
// const selectedNodes = getBlockNodesInRange(range);
|
|
74
|
+
// const parent = range.parent;
|
|
75
|
+
// const isNested = range.depth >= 1;
|
|
76
|
+
|
|
77
|
+
// const { schema } = selection.$from.doc.type;
|
|
78
|
+
|
|
79
|
+
// const isTransformEnabledForAnySelectedNode = selectedNodes.some((node) => {
|
|
80
|
+
// const selectedNodeTypeName = toNodeTypeValue(node.type.name);
|
|
81
|
+
// const supportedTargetNodeTypeName = toNodeTypeValue(targetNodeTypeName);
|
|
82
|
+
// if (!selectedNodeTypeName || !supportedTargetNodeTypeName) {
|
|
83
|
+
// return false;
|
|
84
|
+
// }
|
|
85
|
+
|
|
86
|
+
// if (isTransformDisabledBasedOnStepsConfig(selectedNodeTypeName, supportedTargetNodeTypeName)) {
|
|
87
|
+
// if (selectedNodeTypeName === 'heading' && supportedTargetNodeTypeName === 'heading') {
|
|
88
|
+
// return isHeadingToHeadingTransformDisabled(node, targetNodeTypeAttrs);
|
|
89
|
+
// }
|
|
90
|
+
// return false;
|
|
91
|
+
// }
|
|
92
|
+
|
|
93
|
+
// if (
|
|
94
|
+
// isNested &&
|
|
95
|
+
// !canParentContainNodeType(schema, parent, supportedTargetNodeTypeName, targetNodeTypeAttrs)
|
|
96
|
+
// ) {
|
|
97
|
+
// return false;
|
|
98
|
+
// }
|
|
99
|
+
|
|
100
|
+
// return true;
|
|
101
|
+
// });
|
|
102
|
+
|
|
103
|
+
// if (isTransformEnabledForAnySelectedNode) {
|
|
104
|
+
// return false;
|
|
105
|
+
// }
|
|
106
|
+
|
|
107
|
+
// return true;
|
|
108
|
+
// };
|
|
@@ -38,7 +38,7 @@ export var listToDecisionListStep = function listToDecisionListStep(nodes, conte
|
|
|
38
38
|
if (child.type === paragraphType) {
|
|
39
39
|
// paragraph may contain hard breaks etc.
|
|
40
40
|
itemContent.push.apply(itemContent, _toConsumableArray(child.children));
|
|
41
|
-
} else if (child.isText) {
|
|
41
|
+
} else if (child.isText || child.isInline) {
|
|
42
42
|
itemContent.push(child);
|
|
43
43
|
} else if (!isListWithIndentation(child.type.name, schema)) {
|
|
44
44
|
unsupportedContent.push(child);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
|
|
2
2
|
import { Fragment } from '@atlaskit/editor-prosemirror/model';
|
|
3
3
|
import { NODE_CATEGORY_BY_TYPE } from '../types';
|
|
4
|
+
import { convertTextNodeToParagraph } from '../utils';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Determines if a node is a text node (heading or paragraph).
|
|
@@ -11,21 +12,6 @@ var isTextNode = function isTextNode(node) {
|
|
|
11
12
|
return category === 'text';
|
|
12
13
|
};
|
|
13
14
|
|
|
14
|
-
/**
|
|
15
|
-
* Converts a text node (heading, paragraph) to a paragraph preserving its inline content.
|
|
16
|
-
* This is used when a text node can't be wrapped directly in the target container
|
|
17
|
-
* (e.g., heading can't go in blockquote, so it becomes a paragraph).
|
|
18
|
-
*/
|
|
19
|
-
var convertTextNodeToParagraph = function convertTextNodeToParagraph(node, schema) {
|
|
20
|
-
var _schema$nodes$paragra;
|
|
21
|
-
// If it's already a paragraph, return as-is
|
|
22
|
-
if (node.type.name === 'paragraph') {
|
|
23
|
-
return node;
|
|
24
|
-
}
|
|
25
|
-
// Convert heading (or other text node) to paragraph with same inline content
|
|
26
|
-
return (_schema$nodes$paragra = schema.nodes.paragraph.createAndFill({}, node.content)) !== null && _schema$nodes$paragra !== void 0 ? _schema$nodes$paragra : null;
|
|
27
|
-
};
|
|
28
|
-
|
|
29
15
|
/**
|
|
30
16
|
* Determines if a node can be wrapped in the target container type.
|
|
31
17
|
* Uses the schema's validContent to check if the target container can hold this node.
|