@atlaskit/editor-plugin-block-menu 6.0.7 → 6.0.8
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 +12 -0
- package/dist/cjs/editor-commands/transform-node-utils/flattenStep.js +0 -10
- package/dist/cjs/editor-commands/transform-node-utils/steps/applyTargetTextTypeStep.js +22 -18
- package/dist/cjs/editor-commands/transform-node-utils/steps/wrapMixedContentStep.js +79 -45
- package/dist/cjs/editor-commands/transform-node-utils/transform.js +13 -15
- package/dist/cjs/editor-commands/transformNode.js +8 -2
- package/dist/es2019/editor-commands/transform-node-utils/flattenStep.js +0 -8
- package/dist/es2019/editor-commands/transform-node-utils/steps/applyTargetTextTypeStep.js +22 -18
- package/dist/es2019/editor-commands/transform-node-utils/steps/wrapMixedContentStep.js +79 -45
- package/dist/es2019/editor-commands/transform-node-utils/transform.js +13 -15
- package/dist/es2019/editor-commands/transformNode.js +8 -2
- package/dist/esm/editor-commands/transform-node-utils/flattenStep.js +0 -10
- package/dist/esm/editor-commands/transform-node-utils/steps/applyTargetTextTypeStep.js +22 -18
- package/dist/esm/editor-commands/transform-node-utils/steps/wrapMixedContentStep.js +80 -46
- package/dist/esm/editor-commands/transform-node-utils/transform.js +13 -15
- package/dist/esm/editor-commands/transformNode.js +8 -2
- package/dist/types/editor-commands/transform-node-utils/steps/applyTargetTextTypeStep.d.ts +10 -7
- package/dist/types/editor-commands/transform-node-utils/steps/wrapMixedContentStep.d.ts +3 -0
- package/dist/types-ts4.5/editor-commands/transform-node-utils/steps/applyTargetTextTypeStep.d.ts +10 -7
- package/dist/types-ts4.5/editor-commands/transform-node-utils/steps/wrapMixedContentStep.d.ts +3 -0
- package/package.json +2 -2
- package/dist/cjs/editor-commands/transform-node-utils/steps/wrapTextToCodeblock.js +0 -21
- package/dist/es2019/editor-commands/transform-node-utils/steps/wrapTextToCodeblock.js +0 -18
- package/dist/esm/editor-commands/transform-node-utils/steps/wrapTextToCodeblock.js +0 -16
- package/dist/types/editor-commands/transform-node-utils/steps/wrapTextToCodeblock.d.ts +0 -9
- package/dist/types-ts4.5/editor-commands/transform-node-utils/steps/wrapTextToCodeblock.d.ts +0 -9
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-block-menu
|
|
2
2
|
|
|
3
|
+
## 6.0.8
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`bdcaf574d7d2d`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/bdcaf574d7d2d) -
|
|
8
|
+
Fix transformation of multiple headings and paragraphs to codeblocks
|
|
9
|
+
- [`68ebba7ccdc1b`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/68ebba7ccdc1b) -
|
|
10
|
+
[EDITOR-4157] Fix editor freeze when transforming mediaSingle at bottom of document
|
|
11
|
+
- [`fef9134c6feb5`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/fef9134c6feb5) -
|
|
12
|
+
[ux] Implement multiselect transformations for text (heading, paragraph) nodes
|
|
13
|
+
- Updated dependencies
|
|
14
|
+
|
|
3
15
|
## 6.0.7
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
|
@@ -12,16 +12,6 @@ var flattenStep = exports.flattenStep = function flattenStep(nodes, context) {
|
|
|
12
12
|
if (!targetNodeType || !paragraph) {
|
|
13
13
|
return nodes;
|
|
14
14
|
}
|
|
15
|
-
|
|
16
|
-
// TODO: EDITOR-2920 - Implement flattening logic.
|
|
17
|
-
var isTargetCodeBlock = targetNodeTypeName === 'codeBlock';
|
|
18
|
-
if (isTargetCodeBlock) {
|
|
19
|
-
// This strips explicitly text nodes
|
|
20
|
-
var codeBlockContent = nodes.map(function (node) {
|
|
21
|
-
return node.content.textBetween(0, node.content.size, '\n');
|
|
22
|
-
}).join('\n');
|
|
23
|
-
return [schema.nodes.codeBlock.create({}, schema.text(codeBlockContent))];
|
|
24
|
-
}
|
|
25
15
|
return nodes.map(function (node) {
|
|
26
16
|
var isValidWithin = targetNodeType.validContent(node.content);
|
|
27
17
|
if (!isValidWithin) {
|
|
@@ -5,18 +5,21 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.applyTargetTextTypeStep = void 0;
|
|
7
7
|
/**
|
|
8
|
-
* Applies target text type conversion.
|
|
9
|
-
* (
|
|
10
|
-
* Non-textblock nodes are always left unchanged.
|
|
8
|
+
* Applies target text type conversion. Converts textblock nodes to the target text type
|
|
9
|
+
* (paragraph or heading). Non-textblock nodes are left unchanged.
|
|
11
10
|
*
|
|
12
11
|
* @example
|
|
13
12
|
* Input:
|
|
14
|
-
* - paragraph "
|
|
15
|
-
* - paragraph "
|
|
13
|
+
* - paragraph "Text 1"
|
|
14
|
+
* - paragraph "Text 2"
|
|
16
15
|
*
|
|
17
16
|
* Output (with target: heading, level: 2):
|
|
18
|
-
* - heading (level: 2) "
|
|
19
|
-
* - heading (level: 2) "
|
|
17
|
+
* - heading (level: 2) "Text 1"
|
|
18
|
+
* - heading (level: 2) "Text 2"
|
|
19
|
+
*
|
|
20
|
+
* Output (with target: paragraph):
|
|
21
|
+
* - paragraph "Text 1"
|
|
22
|
+
* - paragraph "Text 2"
|
|
20
23
|
*
|
|
21
24
|
* @param nodes
|
|
22
25
|
* @param context
|
|
@@ -26,23 +29,24 @@ var applyTargetTextTypeStep = exports.applyTargetTextTypeStep = function applyTa
|
|
|
26
29
|
var schema = context.schema,
|
|
27
30
|
targetNodeTypeName = context.targetNodeTypeName,
|
|
28
31
|
targetAttrs = context.targetAttrs;
|
|
29
|
-
if (targetNodeTypeName !== 'heading') {
|
|
32
|
+
if (targetNodeTypeName !== 'heading' && targetNodeTypeName !== 'paragraph') {
|
|
30
33
|
return nodes;
|
|
31
34
|
}
|
|
32
|
-
var
|
|
33
|
-
if (!
|
|
35
|
+
var targetType = schema.nodes[targetNodeTypeName];
|
|
36
|
+
if (!targetType) {
|
|
34
37
|
return nodes;
|
|
35
38
|
}
|
|
36
|
-
|
|
37
|
-
// Default to level 1 if no level is specified
|
|
38
|
-
// The level should ideally come from targetAttrs, but if not available, use default
|
|
39
|
-
var headingLevel = typeof (targetAttrs === null || targetAttrs === void 0 ? void 0 : targetAttrs.level) === 'number' ? targetAttrs.level : 1;
|
|
40
39
|
return nodes.map(function (node) {
|
|
41
40
|
if (node.isTextblock) {
|
|
42
|
-
// Convert textblock nodes
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
41
|
+
// Convert textblock nodes to the target type with content preserved
|
|
42
|
+
var attrs = {};
|
|
43
|
+
if (targetNodeTypeName === 'heading') {
|
|
44
|
+
var level = typeof (targetAttrs === null || targetAttrs === void 0 ? void 0 : targetAttrs.level) === 'number' ? targetAttrs.level : 1;
|
|
45
|
+
attrs = {
|
|
46
|
+
level: level
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
return targetType.create(attrs, node.content, node.marks);
|
|
46
50
|
}
|
|
47
51
|
// Non-textblock nodes are left unchanged
|
|
48
52
|
return node;
|
|
@@ -10,6 +10,34 @@ var _model = require("@atlaskit/editor-prosemirror/model");
|
|
|
10
10
|
var _marks = require("../marks");
|
|
11
11
|
var _types = require("../types");
|
|
12
12
|
var _utils = require("../utils");
|
|
13
|
+
/**
|
|
14
|
+
* Creates a layout section with two columns, where the first column contains the provided content.
|
|
15
|
+
*/
|
|
16
|
+
var createLayoutSection = function createLayoutSection(content, layoutSection, layoutColumn) {
|
|
17
|
+
var columnOne = layoutColumn.createAndFill({}, (0, _marks.removeDisallowedMarks)(content, layoutColumn));
|
|
18
|
+
var columnTwo = layoutColumn.createAndFill();
|
|
19
|
+
if (!columnOne || !columnTwo) {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
return layoutSection.createAndFill({}, [columnOne, columnTwo]);
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Creates a container with text content (for codeblocks).
|
|
27
|
+
*/
|
|
28
|
+
var createTextContentContainer = function createTextContentContainer(textContentArray, targetNodeType, schema) {
|
|
29
|
+
var textContent = textContentArray.join('\n');
|
|
30
|
+
var textNode = textContent ? schema.text(textContent) : null;
|
|
31
|
+
return targetNodeType.createAndFill({}, textNode);
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Creates a regular container with node content.
|
|
36
|
+
*/
|
|
37
|
+
var createNodeContentContainer = function createNodeContentContainer(nodeContent, targetNodeType) {
|
|
38
|
+
return targetNodeType.createAndFill({}, nodeContent);
|
|
39
|
+
};
|
|
40
|
+
|
|
13
41
|
/**
|
|
14
42
|
* Handles the edge case where transforming from a container to another container results in
|
|
15
43
|
* all content breaking out (no valid children for the target). In this case, creates an empty
|
|
@@ -34,12 +62,16 @@ var handleEmptyContainerEdgeCase = function handleEmptyContainerEdgeCase(result,
|
|
|
34
62
|
// (meaning there were no valid children that could be wrapped)
|
|
35
63
|
var allContentBrokeOut = !hasCreatedContainer && result.length > 0;
|
|
36
64
|
var shouldCreateEmptyTarget = isFromContainer && isTargetContainer && allContentBrokeOut;
|
|
37
|
-
if (shouldCreateEmptyTarget) {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
65
|
+
if (!shouldCreateEmptyTarget) {
|
|
66
|
+
return result;
|
|
67
|
+
}
|
|
68
|
+
if (targetNodeTypeName === schema.nodes.codeBlock.name) {
|
|
69
|
+
var emptyCodeBlock = createTextContentContainer([], schema.nodes.codeBlock, schema);
|
|
70
|
+
return emptyCodeBlock ? [emptyCodeBlock].concat((0, _toConsumableArray2.default)(result)) : result;
|
|
41
71
|
}
|
|
42
|
-
|
|
72
|
+
var emptyParagraph = schema.nodes.paragraph.create();
|
|
73
|
+
var emptyContainer = targetNodeType.create({}, emptyParagraph);
|
|
74
|
+
return [emptyContainer].concat((0, _toConsumableArray2.default)(result));
|
|
43
75
|
};
|
|
44
76
|
|
|
45
77
|
/**
|
|
@@ -57,6 +89,9 @@ var handleEmptyContainerEdgeCase = function handleEmptyContainerEdgeCase(result,
|
|
|
57
89
|
* - Layouts always require layoutColumns as children (never paragraphs directly)
|
|
58
90
|
* - Layout columns can contain most block content including headings, paragraphs, lists, etc.
|
|
59
91
|
*
|
|
92
|
+
* Special handling for codeblocks:
|
|
93
|
+
* - Text nodes are converted to plain text and added to the codeblock
|
|
94
|
+
*
|
|
60
95
|
* Edge case handling:
|
|
61
96
|
* - For regular containers: If all content breaks out (container → container transform with no
|
|
62
97
|
* valid children), an empty container with a paragraph is created to ensure the target type exists
|
|
@@ -85,6 +120,7 @@ var wrapMixedContentStep = exports.wrapMixedContentStep = function wrapMixedCont
|
|
|
85
120
|
return nodes;
|
|
86
121
|
}
|
|
87
122
|
var isLayout = targetNodeTypeName === 'layoutSection';
|
|
123
|
+
var isCodeblock = targetNodeTypeName === 'codeBlock';
|
|
88
124
|
var _schema$nodes = schema.nodes,
|
|
89
125
|
layoutSection = _schema$nodes.layoutSection,
|
|
90
126
|
layoutColumn = _schema$nodes.layoutColumn;
|
|
@@ -95,64 +131,62 @@ var wrapMixedContentStep = exports.wrapMixedContentStep = function wrapMixedCont
|
|
|
95
131
|
if (currentContainerContent.length === 0) {
|
|
96
132
|
return;
|
|
97
133
|
}
|
|
134
|
+
var container = null;
|
|
98
135
|
if (isLayout) {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
return;
|
|
105
|
-
}
|
|
106
|
-
var layout = layoutSection.createAndFill({}, [columnOne, columnTwo]);
|
|
107
|
-
if (layout) {
|
|
108
|
-
result.push(layout);
|
|
109
|
-
hasCreatedContainer = true;
|
|
110
|
-
}
|
|
111
|
-
currentContainerContent = [];
|
|
112
|
-
return;
|
|
136
|
+
container = createLayoutSection(currentContainerContent, layoutSection, layoutColumn);
|
|
137
|
+
} else if (isCodeblock) {
|
|
138
|
+
container = createTextContentContainer(currentContainerContent, targetNodeType, schema);
|
|
139
|
+
} else {
|
|
140
|
+
container = createNodeContentContainer(currentContainerContent, targetNodeType);
|
|
113
141
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
var containerNode = targetNodeType.createAndFill({}, currentContainerContent);
|
|
117
|
-
if (containerNode) {
|
|
118
|
-
result.push(containerNode);
|
|
142
|
+
if (container) {
|
|
143
|
+
result.push(container);
|
|
119
144
|
hasCreatedContainer = true;
|
|
120
145
|
}
|
|
121
146
|
currentContainerContent = [];
|
|
122
147
|
};
|
|
123
|
-
var
|
|
148
|
+
var canNodeBeWrapped = function canNodeBeWrapped(node) {
|
|
124
149
|
var validationType = isLayout ? layoutColumn : targetNodeType;
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
150
|
+
return validationType.validContent(_model.Fragment.from((0, _marks.removeDisallowedMarks)([node], validationType)));
|
|
151
|
+
};
|
|
152
|
+
var handleWrappableNode = function handleWrappableNode(node) {
|
|
153
|
+
var _currentContainerCont;
|
|
154
|
+
var validationType = isLayout ? layoutColumn : targetNodeType;
|
|
155
|
+
(_currentContainerCont = currentContainerContent).push.apply(_currentContainerCont, (0, _toConsumableArray2.default)((0, _marks.removeDisallowedMarks)([node], validationType)));
|
|
156
|
+
};
|
|
157
|
+
var handleCodeblockTextNode = function handleCodeblockTextNode(node) {
|
|
158
|
+
currentContainerContent.push((0, _utils.createTextContent)(node));
|
|
159
|
+
};
|
|
160
|
+
var handleConvertibleTextNode = function handleConvertibleTextNode(node) {
|
|
161
|
+
var paragraph = (0, _utils.convertTextNodeToParagraph)(node, schema);
|
|
162
|
+
if (paragraph) {
|
|
163
|
+
currentContainerContent.push(paragraph);
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
var handleUnsupportedNode = function handleUnsupportedNode(node) {
|
|
167
|
+
flushCurrentContainer();
|
|
168
|
+
result.push(node);
|
|
169
|
+
};
|
|
170
|
+
var processNode = function processNode(node) {
|
|
171
|
+
if (canNodeBeWrapped(node)) {
|
|
172
|
+
handleWrappableNode(node);
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
if ((0, _utils.isTextNode)(node) && isCodeblock) {
|
|
176
|
+
handleCodeblockTextNode(node);
|
|
132
177
|
return;
|
|
133
178
|
}
|
|
134
|
-
|
|
135
|
-
// Text node (heading, paragraph) that can't be wrapped - convert to paragraph
|
|
136
|
-
// Example: heading can't go in blockquote, so convert to paragraph with same content
|
|
137
179
|
if ((0, _utils.isTextNode)(node)) {
|
|
138
|
-
|
|
139
|
-
if (paragraph) {
|
|
140
|
-
currentContainerContent.push(paragraph);
|
|
141
|
-
}
|
|
180
|
+
handleConvertibleTextNode(node);
|
|
142
181
|
return;
|
|
143
182
|
}
|
|
144
183
|
|
|
145
184
|
// All other nodes that cannot be wrapped in the target node - break out
|
|
146
185
|
// Examples: same-type containers, tables in panels, layoutSections in layouts
|
|
147
|
-
|
|
148
|
-
result.push(node);
|
|
186
|
+
handleUnsupportedNode(node);
|
|
149
187
|
};
|
|
150
188
|
nodes.forEach(processNode);
|
|
151
|
-
|
|
152
|
-
// Flush any remaining content into a container
|
|
153
189
|
flushCurrentContainer();
|
|
154
|
-
|
|
155
|
-
// Skip edge case handling for layouts since layouts always have columns
|
|
156
190
|
if (isLayout) {
|
|
157
191
|
return result.length > 0 ? result : nodes;
|
|
158
192
|
}
|
|
@@ -17,7 +17,6 @@ var _unwrapLayoutStep = require("./steps/unwrapLayoutStep");
|
|
|
17
17
|
var _unwrapListStep = require("./steps/unwrapListStep");
|
|
18
18
|
var _wrapBlockquoteToDecisionListStep = require("./steps/wrapBlockquoteToDecisionListStep");
|
|
19
19
|
var _wrapMixedContentStep = require("./steps/wrapMixedContentStep");
|
|
20
|
-
var _wrapTextToCodeblock = require("./steps/wrapTextToCodeblock");
|
|
21
20
|
var _types = require("./types");
|
|
22
21
|
var _unwrapExpandStep = require("./unwrapExpandStep");
|
|
23
22
|
var _unwrapStep = require("./unwrapStep");
|
|
@@ -36,7 +35,7 @@ var TRANSFORM_STEPS = {
|
|
|
36
35
|
atomic: undefined,
|
|
37
36
|
container: [_unwrapStep.unwrapStep, _wrapStep.wrapStep],
|
|
38
37
|
list: undefined,
|
|
39
|
-
text: [_unwrapStep.unwrapStep
|
|
38
|
+
text: [_unwrapStep.unwrapStep],
|
|
40
39
|
multi: undefined
|
|
41
40
|
},
|
|
42
41
|
list: {
|
|
@@ -67,18 +66,13 @@ var TRANSFORM_STEPS = {
|
|
|
67
66
|
// Use 'null' to indicate unavailable transfrorm for a case where TRANSFORM_STEPS are not undefined.
|
|
68
67
|
var TRANSFORM_STEPS_OVERRIDE = {
|
|
69
68
|
paragraph: {
|
|
70
|
-
paragraph: null
|
|
71
|
-
codeBlock: [_wrapTextToCodeblock.wrapTextToCodeblockStep],
|
|
72
|
-
layoutSection: [_wrapMixedContentStep.wrapMixedContentStep]
|
|
73
|
-
},
|
|
74
|
-
heading: {
|
|
75
|
-
codeBlock: [_wrapTextToCodeblock.wrapTextToCodeblockStep],
|
|
76
|
-
layoutSection: [_wrapMixedContentStep.wrapMixedContentStep]
|
|
69
|
+
paragraph: null
|
|
77
70
|
},
|
|
71
|
+
heading: {},
|
|
78
72
|
panel: {
|
|
79
73
|
panel: null,
|
|
80
74
|
layoutSection: [_unwrapStep.unwrapStep, _wrapMixedContentStep.wrapMixedContentStep],
|
|
81
|
-
codeBlock: [_unwrapStep.unwrapStep,
|
|
75
|
+
codeBlock: [_unwrapStep.unwrapStep, _wrapMixedContentStep.wrapMixedContentStep],
|
|
82
76
|
blockquote: [_unwrapStep.unwrapStep, _wrapMixedContentStep.wrapMixedContentStep],
|
|
83
77
|
taskList: null,
|
|
84
78
|
bulletList: null,
|
|
@@ -109,7 +103,9 @@ var TRANSFORM_STEPS_OVERRIDE = {
|
|
|
109
103
|
nestedExpand: [_wrapStep.wrapStep],
|
|
110
104
|
layoutSection: [_wrapMixedContentStep.wrapMixedContentStep],
|
|
111
105
|
codeBlock: null,
|
|
112
|
-
decisionList: [_unwrapStep.unwrapStep, _wrapBlockquoteToDecisionListStep.wrapBlockquoteToDecisionListStep]
|
|
106
|
+
decisionList: [_unwrapStep.unwrapStep, _wrapBlockquoteToDecisionListStep.wrapBlockquoteToDecisionListStep],
|
|
107
|
+
paragraph: [_unwrapStep.unwrapStep],
|
|
108
|
+
heading: [_unwrapStep.unwrapStep, _applyTargetTextTypeStep.applyTargetTextTypeStep]
|
|
113
109
|
},
|
|
114
110
|
layoutSection: {
|
|
115
111
|
layoutSection: null,
|
|
@@ -127,6 +123,7 @@ var TRANSFORM_STEPS_OVERRIDE = {
|
|
|
127
123
|
nestedExpand: [_wrapStep.wrapStep],
|
|
128
124
|
layoutSection: [_wrapMixedContentStep.wrapMixedContentStep],
|
|
129
125
|
panel: [_wrapStep.wrapStep],
|
|
126
|
+
paragraph: [_applyTargetTextTypeStep.applyTargetTextTypeStep],
|
|
130
127
|
heading: null
|
|
131
128
|
},
|
|
132
129
|
bulletList: {
|
|
@@ -221,10 +218,11 @@ var TRANSFORM_STEPS_OVERRIDE = {
|
|
|
221
218
|
decisionList: null
|
|
222
219
|
},
|
|
223
220
|
multi: {
|
|
224
|
-
|
|
225
|
-
heading
|
|
226
|
-
//
|
|
227
|
-
|
|
221
|
+
heading: [_applyTargetTextTypeStep.applyTargetTextTypeStep]
|
|
222
|
+
// Similar to heading, all structures are kept as is
|
|
223
|
+
// EG: transformed: other lists, paragarph, headings
|
|
224
|
+
// eg: not-transformed: quotes, codeblocks ... all typeof 'containers'
|
|
225
|
+
// decisionList: [],
|
|
228
226
|
}
|
|
229
227
|
};
|
|
230
228
|
var getTransformStepsForNodeTypes = function getTransformStepsForNodeTypes(selectedNodeTypeName, targetNodeTypeName) {
|
|
@@ -51,8 +51,14 @@ var transformNode = exports.transformNode = function transformNode(api) {
|
|
|
51
51
|
});
|
|
52
52
|
var content = resultNodes.length > 0 ? resultNodes : slice.content;
|
|
53
53
|
if (preservedSelection instanceof _state.NodeSelection && preservedSelection.node.type === nodes.mediaSingle) {
|
|
54
|
-
tr.
|
|
55
|
-
|
|
54
|
+
// when node is media single, use tr.replaceWith freeze editor, if modify position, tr.replaceWith creates duplicats
|
|
55
|
+
var deleteFrom = $from.pos;
|
|
56
|
+
var deleteTo = $to.pos;
|
|
57
|
+
tr.delete(deleteFrom, deleteTo);
|
|
58
|
+
// After deletion, recalculate the insertion position to ensure it's valid
|
|
59
|
+
// especially when mediaSingle with caption is at the bottom of the document
|
|
60
|
+
var insertPos = Math.min(deleteFrom, tr.doc.content.size);
|
|
61
|
+
tr.insert(insertPos, content);
|
|
56
62
|
} else {
|
|
57
63
|
tr.replaceWith(sliceStart, $to.pos, content);
|
|
58
64
|
}
|
|
@@ -10,14 +10,6 @@ export const flattenStep = (nodes, context) => {
|
|
|
10
10
|
if (!targetNodeType || !paragraph) {
|
|
11
11
|
return nodes;
|
|
12
12
|
}
|
|
13
|
-
|
|
14
|
-
// TODO: EDITOR-2920 - Implement flattening logic.
|
|
15
|
-
const isTargetCodeBlock = targetNodeTypeName === 'codeBlock';
|
|
16
|
-
if (isTargetCodeBlock) {
|
|
17
|
-
// This strips explicitly text nodes
|
|
18
|
-
const codeBlockContent = nodes.map(node => node.content.textBetween(0, node.content.size, '\n')).join('\n');
|
|
19
|
-
return [schema.nodes.codeBlock.create({}, schema.text(codeBlockContent))];
|
|
20
|
-
}
|
|
21
13
|
return nodes.map(node => {
|
|
22
14
|
const isValidWithin = targetNodeType.validContent(node.content);
|
|
23
15
|
if (!isValidWithin) {
|
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Applies target text type conversion.
|
|
3
|
-
* (
|
|
4
|
-
* Non-textblock nodes are always left unchanged.
|
|
2
|
+
* Applies target text type conversion. Converts textblock nodes to the target text type
|
|
3
|
+
* (paragraph or heading). Non-textblock nodes are left unchanged.
|
|
5
4
|
*
|
|
6
5
|
* @example
|
|
7
6
|
* Input:
|
|
8
|
-
* - paragraph "
|
|
9
|
-
* - paragraph "
|
|
7
|
+
* - paragraph "Text 1"
|
|
8
|
+
* - paragraph "Text 2"
|
|
10
9
|
*
|
|
11
10
|
* Output (with target: heading, level: 2):
|
|
12
|
-
* - heading (level: 2) "
|
|
13
|
-
* - heading (level: 2) "
|
|
11
|
+
* - heading (level: 2) "Text 1"
|
|
12
|
+
* - heading (level: 2) "Text 2"
|
|
13
|
+
*
|
|
14
|
+
* Output (with target: paragraph):
|
|
15
|
+
* - paragraph "Text 1"
|
|
16
|
+
* - paragraph "Text 2"
|
|
14
17
|
*
|
|
15
18
|
* @param nodes
|
|
16
19
|
* @param context
|
|
@@ -22,23 +25,24 @@ export const applyTargetTextTypeStep = (nodes, context) => {
|
|
|
22
25
|
targetNodeTypeName,
|
|
23
26
|
targetAttrs
|
|
24
27
|
} = context;
|
|
25
|
-
if (targetNodeTypeName !== 'heading') {
|
|
28
|
+
if (targetNodeTypeName !== 'heading' && targetNodeTypeName !== 'paragraph') {
|
|
26
29
|
return nodes;
|
|
27
30
|
}
|
|
28
|
-
const
|
|
29
|
-
if (!
|
|
31
|
+
const targetType = schema.nodes[targetNodeTypeName];
|
|
32
|
+
if (!targetType) {
|
|
30
33
|
return nodes;
|
|
31
34
|
}
|
|
32
|
-
|
|
33
|
-
// Default to level 1 if no level is specified
|
|
34
|
-
// The level should ideally come from targetAttrs, but if not available, use default
|
|
35
|
-
const headingLevel = typeof (targetAttrs === null || targetAttrs === void 0 ? void 0 : targetAttrs.level) === 'number' ? targetAttrs.level : 1;
|
|
36
35
|
return nodes.map(node => {
|
|
37
36
|
if (node.isTextblock) {
|
|
38
|
-
// Convert textblock nodes
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
37
|
+
// Convert textblock nodes to the target type with content preserved
|
|
38
|
+
let attrs = {};
|
|
39
|
+
if (targetNodeTypeName === 'heading') {
|
|
40
|
+
const level = typeof (targetAttrs === null || targetAttrs === void 0 ? void 0 : targetAttrs.level) === 'number' ? targetAttrs.level : 1;
|
|
41
|
+
attrs = {
|
|
42
|
+
level
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
return targetType.create(attrs, node.content, node.marks);
|
|
42
46
|
}
|
|
43
47
|
// Non-textblock nodes are left unchanged
|
|
44
48
|
return node;
|
|
@@ -1,7 +1,35 @@
|
|
|
1
1
|
import { Fragment } from '@atlaskit/editor-prosemirror/model';
|
|
2
2
|
import { removeDisallowedMarks } from '../marks';
|
|
3
3
|
import { NODE_CATEGORY_BY_TYPE } from '../types';
|
|
4
|
-
import { convertTextNodeToParagraph, isTextNode } from '../utils';
|
|
4
|
+
import { convertTextNodeToParagraph, createTextContent, isTextNode } from '../utils';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Creates a layout section with two columns, where the first column contains the provided content.
|
|
8
|
+
*/
|
|
9
|
+
const createLayoutSection = (content, layoutSection, layoutColumn) => {
|
|
10
|
+
const columnOne = layoutColumn.createAndFill({}, removeDisallowedMarks(content, layoutColumn));
|
|
11
|
+
const columnTwo = layoutColumn.createAndFill();
|
|
12
|
+
if (!columnOne || !columnTwo) {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
return layoutSection.createAndFill({}, [columnOne, columnTwo]);
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Creates a container with text content (for codeblocks).
|
|
20
|
+
*/
|
|
21
|
+
const createTextContentContainer = (textContentArray, targetNodeType, schema) => {
|
|
22
|
+
const textContent = textContentArray.join('\n');
|
|
23
|
+
const textNode = textContent ? schema.text(textContent) : null;
|
|
24
|
+
return targetNodeType.createAndFill({}, textNode);
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Creates a regular container with node content.
|
|
29
|
+
*/
|
|
30
|
+
const createNodeContentContainer = (nodeContent, targetNodeType) => {
|
|
31
|
+
return targetNodeType.createAndFill({}, nodeContent);
|
|
32
|
+
};
|
|
5
33
|
|
|
6
34
|
/**
|
|
7
35
|
* Handles the edge case where transforming from a container to another container results in
|
|
@@ -27,12 +55,16 @@ const handleEmptyContainerEdgeCase = (result, hasCreatedContainer, fromNode, tar
|
|
|
27
55
|
// (meaning there were no valid children that could be wrapped)
|
|
28
56
|
const allContentBrokeOut = !hasCreatedContainer && result.length > 0;
|
|
29
57
|
const shouldCreateEmptyTarget = isFromContainer && isTargetContainer && allContentBrokeOut;
|
|
30
|
-
if (shouldCreateEmptyTarget) {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
58
|
+
if (!shouldCreateEmptyTarget) {
|
|
59
|
+
return result;
|
|
60
|
+
}
|
|
61
|
+
if (targetNodeTypeName === schema.nodes.codeBlock.name) {
|
|
62
|
+
const emptyCodeBlock = createTextContentContainer([], schema.nodes.codeBlock, schema);
|
|
63
|
+
return emptyCodeBlock ? [emptyCodeBlock, ...result] : result;
|
|
34
64
|
}
|
|
35
|
-
|
|
65
|
+
const emptyParagraph = schema.nodes.paragraph.create();
|
|
66
|
+
const emptyContainer = targetNodeType.create({}, emptyParagraph);
|
|
67
|
+
return [emptyContainer, ...result];
|
|
36
68
|
};
|
|
37
69
|
|
|
38
70
|
/**
|
|
@@ -50,6 +82,9 @@ const handleEmptyContainerEdgeCase = (result, hasCreatedContainer, fromNode, tar
|
|
|
50
82
|
* - Layouts always require layoutColumns as children (never paragraphs directly)
|
|
51
83
|
* - Layout columns can contain most block content including headings, paragraphs, lists, etc.
|
|
52
84
|
*
|
|
85
|
+
* Special handling for codeblocks:
|
|
86
|
+
* - Text nodes are converted to plain text and added to the codeblock
|
|
87
|
+
*
|
|
53
88
|
* Edge case handling:
|
|
54
89
|
* - For regular containers: If all content breaks out (container → container transform with no
|
|
55
90
|
* valid children), an empty container with a paragraph is created to ensure the target type exists
|
|
@@ -80,6 +115,7 @@ export const wrapMixedContentStep = (nodes, context) => {
|
|
|
80
115
|
return nodes;
|
|
81
116
|
}
|
|
82
117
|
const isLayout = targetNodeTypeName === 'layoutSection';
|
|
118
|
+
const isCodeblock = targetNodeTypeName === 'codeBlock';
|
|
83
119
|
const {
|
|
84
120
|
layoutSection,
|
|
85
121
|
layoutColumn
|
|
@@ -91,63 +127,61 @@ export const wrapMixedContentStep = (nodes, context) => {
|
|
|
91
127
|
if (currentContainerContent.length === 0) {
|
|
92
128
|
return;
|
|
93
129
|
}
|
|
130
|
+
let container = null;
|
|
94
131
|
if (isLayout) {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
return;
|
|
101
|
-
}
|
|
102
|
-
const layout = layoutSection.createAndFill({}, [columnOne, columnTwo]);
|
|
103
|
-
if (layout) {
|
|
104
|
-
result.push(layout);
|
|
105
|
-
hasCreatedContainer = true;
|
|
106
|
-
}
|
|
107
|
-
currentContainerContent = [];
|
|
108
|
-
return;
|
|
132
|
+
container = createLayoutSection(currentContainerContent, layoutSection, layoutColumn);
|
|
133
|
+
} else if (isCodeblock) {
|
|
134
|
+
container = createTextContentContainer(currentContainerContent, targetNodeType, schema);
|
|
135
|
+
} else {
|
|
136
|
+
container = createNodeContentContainer(currentContainerContent, targetNodeType);
|
|
109
137
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
const containerNode = targetNodeType.createAndFill({}, currentContainerContent);
|
|
113
|
-
if (containerNode) {
|
|
114
|
-
result.push(containerNode);
|
|
138
|
+
if (container) {
|
|
139
|
+
result.push(container);
|
|
115
140
|
hasCreatedContainer = true;
|
|
116
141
|
}
|
|
117
142
|
currentContainerContent = [];
|
|
118
143
|
};
|
|
119
|
-
const
|
|
144
|
+
const canNodeBeWrapped = node => {
|
|
120
145
|
const validationType = isLayout ? layoutColumn : targetNodeType;
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
146
|
+
return validationType.validContent(Fragment.from(removeDisallowedMarks([node], validationType)));
|
|
147
|
+
};
|
|
148
|
+
const handleWrappableNode = node => {
|
|
149
|
+
const validationType = isLayout ? layoutColumn : targetNodeType;
|
|
150
|
+
currentContainerContent.push(...removeDisallowedMarks([node], validationType));
|
|
151
|
+
};
|
|
152
|
+
const handleCodeblockTextNode = node => {
|
|
153
|
+
currentContainerContent.push(createTextContent(node));
|
|
154
|
+
};
|
|
155
|
+
const handleConvertibleTextNode = node => {
|
|
156
|
+
const paragraph = convertTextNodeToParagraph(node, schema);
|
|
157
|
+
if (paragraph) {
|
|
158
|
+
currentContainerContent.push(paragraph);
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
const handleUnsupportedNode = node => {
|
|
162
|
+
flushCurrentContainer();
|
|
163
|
+
result.push(node);
|
|
164
|
+
};
|
|
165
|
+
const processNode = node => {
|
|
166
|
+
if (canNodeBeWrapped(node)) {
|
|
167
|
+
handleWrappableNode(node);
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
if (isTextNode(node) && isCodeblock) {
|
|
171
|
+
handleCodeblockTextNode(node);
|
|
127
172
|
return;
|
|
128
173
|
}
|
|
129
|
-
|
|
130
|
-
// Text node (heading, paragraph) that can't be wrapped - convert to paragraph
|
|
131
|
-
// Example: heading can't go in blockquote, so convert to paragraph with same content
|
|
132
174
|
if (isTextNode(node)) {
|
|
133
|
-
|
|
134
|
-
if (paragraph) {
|
|
135
|
-
currentContainerContent.push(paragraph);
|
|
136
|
-
}
|
|
175
|
+
handleConvertibleTextNode(node);
|
|
137
176
|
return;
|
|
138
177
|
}
|
|
139
178
|
|
|
140
179
|
// All other nodes that cannot be wrapped in the target node - break out
|
|
141
180
|
// Examples: same-type containers, tables in panels, layoutSections in layouts
|
|
142
|
-
|
|
143
|
-
result.push(node);
|
|
181
|
+
handleUnsupportedNode(node);
|
|
144
182
|
};
|
|
145
183
|
nodes.forEach(processNode);
|
|
146
|
-
|
|
147
|
-
// Flush any remaining content into a container
|
|
148
184
|
flushCurrentContainer();
|
|
149
|
-
|
|
150
|
-
// Skip edge case handling for layouts since layouts always have columns
|
|
151
185
|
if (isLayout) {
|
|
152
186
|
return result.length > 0 ? result : nodes;
|
|
153
187
|
}
|
|
@@ -11,7 +11,6 @@ import { unwrapLayoutStep } from './steps/unwrapLayoutStep';
|
|
|
11
11
|
import { unwrapListStep } from './steps/unwrapListStep';
|
|
12
12
|
import { wrapBlockquoteToDecisionListStep } from './steps/wrapBlockquoteToDecisionListStep';
|
|
13
13
|
import { wrapMixedContentStep } from './steps/wrapMixedContentStep';
|
|
14
|
-
import { wrapTextToCodeblockStep } from './steps/wrapTextToCodeblock';
|
|
15
14
|
import { getNodeName, NODE_CATEGORY_BY_TYPE, toNodeTypeValue } from './types';
|
|
16
15
|
import { unwrapExpandStep } from './unwrapExpandStep';
|
|
17
16
|
import { unwrapStep } from './unwrapStep';
|
|
@@ -31,7 +30,7 @@ const TRANSFORM_STEPS = {
|
|
|
31
30
|
atomic: undefined,
|
|
32
31
|
container: [unwrapStep, wrapStep],
|
|
33
32
|
list: undefined,
|
|
34
|
-
text: [unwrapStep
|
|
33
|
+
text: [unwrapStep],
|
|
35
34
|
multi: undefined
|
|
36
35
|
},
|
|
37
36
|
list: {
|
|
@@ -62,18 +61,13 @@ const TRANSFORM_STEPS = {
|
|
|
62
61
|
// Use 'null' to indicate unavailable transfrorm for a case where TRANSFORM_STEPS are not undefined.
|
|
63
62
|
const TRANSFORM_STEPS_OVERRIDE = {
|
|
64
63
|
paragraph: {
|
|
65
|
-
paragraph: null
|
|
66
|
-
codeBlock: [wrapTextToCodeblockStep],
|
|
67
|
-
layoutSection: [wrapMixedContentStep]
|
|
68
|
-
},
|
|
69
|
-
heading: {
|
|
70
|
-
codeBlock: [wrapTextToCodeblockStep],
|
|
71
|
-
layoutSection: [wrapMixedContentStep]
|
|
64
|
+
paragraph: null
|
|
72
65
|
},
|
|
66
|
+
heading: {},
|
|
73
67
|
panel: {
|
|
74
68
|
panel: null,
|
|
75
69
|
layoutSection: [unwrapStep, wrapMixedContentStep],
|
|
76
|
-
codeBlock: [unwrapStep,
|
|
70
|
+
codeBlock: [unwrapStep, wrapMixedContentStep],
|
|
77
71
|
blockquote: [unwrapStep, wrapMixedContentStep],
|
|
78
72
|
taskList: null,
|
|
79
73
|
bulletList: null,
|
|
@@ -104,7 +98,9 @@ const TRANSFORM_STEPS_OVERRIDE = {
|
|
|
104
98
|
nestedExpand: [wrapStep],
|
|
105
99
|
layoutSection: [wrapMixedContentStep],
|
|
106
100
|
codeBlock: null,
|
|
107
|
-
decisionList: [unwrapStep, wrapBlockquoteToDecisionListStep]
|
|
101
|
+
decisionList: [unwrapStep, wrapBlockquoteToDecisionListStep],
|
|
102
|
+
paragraph: [unwrapStep],
|
|
103
|
+
heading: [unwrapStep, applyTargetTextTypeStep]
|
|
108
104
|
},
|
|
109
105
|
layoutSection: {
|
|
110
106
|
layoutSection: null,
|
|
@@ -122,6 +118,7 @@ const TRANSFORM_STEPS_OVERRIDE = {
|
|
|
122
118
|
nestedExpand: [wrapStep],
|
|
123
119
|
layoutSection: [wrapMixedContentStep],
|
|
124
120
|
panel: [wrapStep],
|
|
121
|
+
paragraph: [applyTargetTextTypeStep],
|
|
125
122
|
heading: null
|
|
126
123
|
},
|
|
127
124
|
bulletList: {
|
|
@@ -216,10 +213,11 @@ const TRANSFORM_STEPS_OVERRIDE = {
|
|
|
216
213
|
decisionList: null
|
|
217
214
|
},
|
|
218
215
|
multi: {
|
|
219
|
-
|
|
220
|
-
heading
|
|
221
|
-
//
|
|
222
|
-
|
|
216
|
+
heading: [applyTargetTextTypeStep]
|
|
217
|
+
// Similar to heading, all structures are kept as is
|
|
218
|
+
// EG: transformed: other lists, paragarph, headings
|
|
219
|
+
// eg: not-transformed: quotes, codeblocks ... all typeof 'containers'
|
|
220
|
+
// decisionList: [],
|
|
223
221
|
}
|
|
224
222
|
};
|
|
225
223
|
const getTransformStepsForNodeTypes = (selectedNodeTypeName, targetNodeTypeName) => {
|
|
@@ -45,8 +45,14 @@ export const transformNode = api => (targetType, metadata) => ({
|
|
|
45
45
|
});
|
|
46
46
|
const content = resultNodes.length > 0 ? resultNodes : slice.content;
|
|
47
47
|
if (preservedSelection instanceof NodeSelection && preservedSelection.node.type === nodes.mediaSingle) {
|
|
48
|
-
tr.
|
|
49
|
-
|
|
48
|
+
// when node is media single, use tr.replaceWith freeze editor, if modify position, tr.replaceWith creates duplicats
|
|
49
|
+
const deleteFrom = $from.pos;
|
|
50
|
+
const deleteTo = $to.pos;
|
|
51
|
+
tr.delete(deleteFrom, deleteTo);
|
|
52
|
+
// After deletion, recalculate the insertion position to ensure it's valid
|
|
53
|
+
// especially when mediaSingle with caption is at the bottom of the document
|
|
54
|
+
const insertPos = Math.min(deleteFrom, tr.doc.content.size);
|
|
55
|
+
tr.insert(insertPos, content);
|
|
50
56
|
} else {
|
|
51
57
|
tr.replaceWith(sliceStart, $to.pos, content);
|
|
52
58
|
}
|
|
@@ -6,16 +6,6 @@ export var flattenStep = function flattenStep(nodes, context) {
|
|
|
6
6
|
if (!targetNodeType || !paragraph) {
|
|
7
7
|
return nodes;
|
|
8
8
|
}
|
|
9
|
-
|
|
10
|
-
// TODO: EDITOR-2920 - Implement flattening logic.
|
|
11
|
-
var isTargetCodeBlock = targetNodeTypeName === 'codeBlock';
|
|
12
|
-
if (isTargetCodeBlock) {
|
|
13
|
-
// This strips explicitly text nodes
|
|
14
|
-
var codeBlockContent = nodes.map(function (node) {
|
|
15
|
-
return node.content.textBetween(0, node.content.size, '\n');
|
|
16
|
-
}).join('\n');
|
|
17
|
-
return [schema.nodes.codeBlock.create({}, schema.text(codeBlockContent))];
|
|
18
|
-
}
|
|
19
9
|
return nodes.map(function (node) {
|
|
20
10
|
var isValidWithin = targetNodeType.validContent(node.content);
|
|
21
11
|
if (!isValidWithin) {
|
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Applies target text type conversion.
|
|
3
|
-
* (
|
|
4
|
-
* Non-textblock nodes are always left unchanged.
|
|
2
|
+
* Applies target text type conversion. Converts textblock nodes to the target text type
|
|
3
|
+
* (paragraph or heading). Non-textblock nodes are left unchanged.
|
|
5
4
|
*
|
|
6
5
|
* @example
|
|
7
6
|
* Input:
|
|
8
|
-
* - paragraph "
|
|
9
|
-
* - paragraph "
|
|
7
|
+
* - paragraph "Text 1"
|
|
8
|
+
* - paragraph "Text 2"
|
|
10
9
|
*
|
|
11
10
|
* Output (with target: heading, level: 2):
|
|
12
|
-
* - heading (level: 2) "
|
|
13
|
-
* - heading (level: 2) "
|
|
11
|
+
* - heading (level: 2) "Text 1"
|
|
12
|
+
* - heading (level: 2) "Text 2"
|
|
13
|
+
*
|
|
14
|
+
* Output (with target: paragraph):
|
|
15
|
+
* - paragraph "Text 1"
|
|
16
|
+
* - paragraph "Text 2"
|
|
14
17
|
*
|
|
15
18
|
* @param nodes
|
|
16
19
|
* @param context
|
|
@@ -20,23 +23,24 @@ export var applyTargetTextTypeStep = function applyTargetTextTypeStep(nodes, con
|
|
|
20
23
|
var schema = context.schema,
|
|
21
24
|
targetNodeTypeName = context.targetNodeTypeName,
|
|
22
25
|
targetAttrs = context.targetAttrs;
|
|
23
|
-
if (targetNodeTypeName !== 'heading') {
|
|
26
|
+
if (targetNodeTypeName !== 'heading' && targetNodeTypeName !== 'paragraph') {
|
|
24
27
|
return nodes;
|
|
25
28
|
}
|
|
26
|
-
var
|
|
27
|
-
if (!
|
|
29
|
+
var targetType = schema.nodes[targetNodeTypeName];
|
|
30
|
+
if (!targetType) {
|
|
28
31
|
return nodes;
|
|
29
32
|
}
|
|
30
|
-
|
|
31
|
-
// Default to level 1 if no level is specified
|
|
32
|
-
// The level should ideally come from targetAttrs, but if not available, use default
|
|
33
|
-
var headingLevel = typeof (targetAttrs === null || targetAttrs === void 0 ? void 0 : targetAttrs.level) === 'number' ? targetAttrs.level : 1;
|
|
34
33
|
return nodes.map(function (node) {
|
|
35
34
|
if (node.isTextblock) {
|
|
36
|
-
// Convert textblock nodes
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
35
|
+
// Convert textblock nodes to the target type with content preserved
|
|
36
|
+
var attrs = {};
|
|
37
|
+
if (targetNodeTypeName === 'heading') {
|
|
38
|
+
var level = typeof (targetAttrs === null || targetAttrs === void 0 ? void 0 : targetAttrs.level) === 'number' ? targetAttrs.level : 1;
|
|
39
|
+
attrs = {
|
|
40
|
+
level: level
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
return targetType.create(attrs, node.content, node.marks);
|
|
40
44
|
}
|
|
41
45
|
// Non-textblock nodes are left unchanged
|
|
42
46
|
return node;
|
|
@@ -2,7 +2,35 @@ import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
|
|
|
2
2
|
import { Fragment } from '@atlaskit/editor-prosemirror/model';
|
|
3
3
|
import { removeDisallowedMarks } from '../marks';
|
|
4
4
|
import { NODE_CATEGORY_BY_TYPE } from '../types';
|
|
5
|
-
import { convertTextNodeToParagraph, isTextNode } from '../utils';
|
|
5
|
+
import { convertTextNodeToParagraph, createTextContent, isTextNode } from '../utils';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Creates a layout section with two columns, where the first column contains the provided content.
|
|
9
|
+
*/
|
|
10
|
+
var createLayoutSection = function createLayoutSection(content, layoutSection, layoutColumn) {
|
|
11
|
+
var columnOne = layoutColumn.createAndFill({}, removeDisallowedMarks(content, layoutColumn));
|
|
12
|
+
var columnTwo = layoutColumn.createAndFill();
|
|
13
|
+
if (!columnOne || !columnTwo) {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
return layoutSection.createAndFill({}, [columnOne, columnTwo]);
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Creates a container with text content (for codeblocks).
|
|
21
|
+
*/
|
|
22
|
+
var createTextContentContainer = function createTextContentContainer(textContentArray, targetNodeType, schema) {
|
|
23
|
+
var textContent = textContentArray.join('\n');
|
|
24
|
+
var textNode = textContent ? schema.text(textContent) : null;
|
|
25
|
+
return targetNodeType.createAndFill({}, textNode);
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Creates a regular container with node content.
|
|
30
|
+
*/
|
|
31
|
+
var createNodeContentContainer = function createNodeContentContainer(nodeContent, targetNodeType) {
|
|
32
|
+
return targetNodeType.createAndFill({}, nodeContent);
|
|
33
|
+
};
|
|
6
34
|
|
|
7
35
|
/**
|
|
8
36
|
* Handles the edge case where transforming from a container to another container results in
|
|
@@ -28,12 +56,16 @@ var handleEmptyContainerEdgeCase = function handleEmptyContainerEdgeCase(result,
|
|
|
28
56
|
// (meaning there were no valid children that could be wrapped)
|
|
29
57
|
var allContentBrokeOut = !hasCreatedContainer && result.length > 0;
|
|
30
58
|
var shouldCreateEmptyTarget = isFromContainer && isTargetContainer && allContentBrokeOut;
|
|
31
|
-
if (shouldCreateEmptyTarget) {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
59
|
+
if (!shouldCreateEmptyTarget) {
|
|
60
|
+
return result;
|
|
61
|
+
}
|
|
62
|
+
if (targetNodeTypeName === schema.nodes.codeBlock.name) {
|
|
63
|
+
var emptyCodeBlock = createTextContentContainer([], schema.nodes.codeBlock, schema);
|
|
64
|
+
return emptyCodeBlock ? [emptyCodeBlock].concat(_toConsumableArray(result)) : result;
|
|
35
65
|
}
|
|
36
|
-
|
|
66
|
+
var emptyParagraph = schema.nodes.paragraph.create();
|
|
67
|
+
var emptyContainer = targetNodeType.create({}, emptyParagraph);
|
|
68
|
+
return [emptyContainer].concat(_toConsumableArray(result));
|
|
37
69
|
};
|
|
38
70
|
|
|
39
71
|
/**
|
|
@@ -51,6 +83,9 @@ var handleEmptyContainerEdgeCase = function handleEmptyContainerEdgeCase(result,
|
|
|
51
83
|
* - Layouts always require layoutColumns as children (never paragraphs directly)
|
|
52
84
|
* - Layout columns can contain most block content including headings, paragraphs, lists, etc.
|
|
53
85
|
*
|
|
86
|
+
* Special handling for codeblocks:
|
|
87
|
+
* - Text nodes are converted to plain text and added to the codeblock
|
|
88
|
+
*
|
|
54
89
|
* Edge case handling:
|
|
55
90
|
* - For regular containers: If all content breaks out (container → container transform with no
|
|
56
91
|
* valid children), an empty container with a paragraph is created to ensure the target type exists
|
|
@@ -79,6 +114,7 @@ export var wrapMixedContentStep = function wrapMixedContentStep(nodes, context)
|
|
|
79
114
|
return nodes;
|
|
80
115
|
}
|
|
81
116
|
var isLayout = targetNodeTypeName === 'layoutSection';
|
|
117
|
+
var isCodeblock = targetNodeTypeName === 'codeBlock';
|
|
82
118
|
var _schema$nodes = schema.nodes,
|
|
83
119
|
layoutSection = _schema$nodes.layoutSection,
|
|
84
120
|
layoutColumn = _schema$nodes.layoutColumn;
|
|
@@ -89,64 +125,62 @@ export var wrapMixedContentStep = function wrapMixedContentStep(nodes, context)
|
|
|
89
125
|
if (currentContainerContent.length === 0) {
|
|
90
126
|
return;
|
|
91
127
|
}
|
|
128
|
+
var container = null;
|
|
92
129
|
if (isLayout) {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
return;
|
|
99
|
-
}
|
|
100
|
-
var layout = layoutSection.createAndFill({}, [columnOne, columnTwo]);
|
|
101
|
-
if (layout) {
|
|
102
|
-
result.push(layout);
|
|
103
|
-
hasCreatedContainer = true;
|
|
104
|
-
}
|
|
105
|
-
currentContainerContent = [];
|
|
106
|
-
return;
|
|
130
|
+
container = createLayoutSection(currentContainerContent, layoutSection, layoutColumn);
|
|
131
|
+
} else if (isCodeblock) {
|
|
132
|
+
container = createTextContentContainer(currentContainerContent, targetNodeType, schema);
|
|
133
|
+
} else {
|
|
134
|
+
container = createNodeContentContainer(currentContainerContent, targetNodeType);
|
|
107
135
|
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
var containerNode = targetNodeType.createAndFill({}, currentContainerContent);
|
|
111
|
-
if (containerNode) {
|
|
112
|
-
result.push(containerNode);
|
|
136
|
+
if (container) {
|
|
137
|
+
result.push(container);
|
|
113
138
|
hasCreatedContainer = true;
|
|
114
139
|
}
|
|
115
140
|
currentContainerContent = [];
|
|
116
141
|
};
|
|
117
|
-
var
|
|
142
|
+
var canNodeBeWrapped = function canNodeBeWrapped(node) {
|
|
118
143
|
var validationType = isLayout ? layoutColumn : targetNodeType;
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
144
|
+
return validationType.validContent(Fragment.from(removeDisallowedMarks([node], validationType)));
|
|
145
|
+
};
|
|
146
|
+
var handleWrappableNode = function handleWrappableNode(node) {
|
|
147
|
+
var _currentContainerCont;
|
|
148
|
+
var validationType = isLayout ? layoutColumn : targetNodeType;
|
|
149
|
+
(_currentContainerCont = currentContainerContent).push.apply(_currentContainerCont, _toConsumableArray(removeDisallowedMarks([node], validationType)));
|
|
150
|
+
};
|
|
151
|
+
var handleCodeblockTextNode = function handleCodeblockTextNode(node) {
|
|
152
|
+
currentContainerContent.push(createTextContent(node));
|
|
153
|
+
};
|
|
154
|
+
var handleConvertibleTextNode = function handleConvertibleTextNode(node) {
|
|
155
|
+
var paragraph = convertTextNodeToParagraph(node, schema);
|
|
156
|
+
if (paragraph) {
|
|
157
|
+
currentContainerContent.push(paragraph);
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
var handleUnsupportedNode = function handleUnsupportedNode(node) {
|
|
161
|
+
flushCurrentContainer();
|
|
162
|
+
result.push(node);
|
|
163
|
+
};
|
|
164
|
+
var processNode = function processNode(node) {
|
|
165
|
+
if (canNodeBeWrapped(node)) {
|
|
166
|
+
handleWrappableNode(node);
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
if (isTextNode(node) && isCodeblock) {
|
|
170
|
+
handleCodeblockTextNode(node);
|
|
126
171
|
return;
|
|
127
172
|
}
|
|
128
|
-
|
|
129
|
-
// Text node (heading, paragraph) that can't be wrapped - convert to paragraph
|
|
130
|
-
// Example: heading can't go in blockquote, so convert to paragraph with same content
|
|
131
173
|
if (isTextNode(node)) {
|
|
132
|
-
|
|
133
|
-
if (paragraph) {
|
|
134
|
-
currentContainerContent.push(paragraph);
|
|
135
|
-
}
|
|
174
|
+
handleConvertibleTextNode(node);
|
|
136
175
|
return;
|
|
137
176
|
}
|
|
138
177
|
|
|
139
178
|
// All other nodes that cannot be wrapped in the target node - break out
|
|
140
179
|
// Examples: same-type containers, tables in panels, layoutSections in layouts
|
|
141
|
-
|
|
142
|
-
result.push(node);
|
|
180
|
+
handleUnsupportedNode(node);
|
|
143
181
|
};
|
|
144
182
|
nodes.forEach(processNode);
|
|
145
|
-
|
|
146
|
-
// Flush any remaining content into a container
|
|
147
183
|
flushCurrentContainer();
|
|
148
|
-
|
|
149
|
-
// Skip edge case handling for layouts since layouts always have columns
|
|
150
184
|
if (isLayout) {
|
|
151
185
|
return result.length > 0 ? result : nodes;
|
|
152
186
|
}
|
|
@@ -11,7 +11,6 @@ import { unwrapLayoutStep } from './steps/unwrapLayoutStep';
|
|
|
11
11
|
import { unwrapListStep } from './steps/unwrapListStep';
|
|
12
12
|
import { wrapBlockquoteToDecisionListStep } from './steps/wrapBlockquoteToDecisionListStep';
|
|
13
13
|
import { wrapMixedContentStep } from './steps/wrapMixedContentStep';
|
|
14
|
-
import { wrapTextToCodeblockStep } from './steps/wrapTextToCodeblock';
|
|
15
14
|
import { getNodeName, NODE_CATEGORY_BY_TYPE, toNodeTypeValue } from './types';
|
|
16
15
|
import { unwrapExpandStep } from './unwrapExpandStep';
|
|
17
16
|
import { unwrapStep } from './unwrapStep';
|
|
@@ -31,7 +30,7 @@ var TRANSFORM_STEPS = {
|
|
|
31
30
|
atomic: undefined,
|
|
32
31
|
container: [unwrapStep, wrapStep],
|
|
33
32
|
list: undefined,
|
|
34
|
-
text: [unwrapStep
|
|
33
|
+
text: [unwrapStep],
|
|
35
34
|
multi: undefined
|
|
36
35
|
},
|
|
37
36
|
list: {
|
|
@@ -62,18 +61,13 @@ var TRANSFORM_STEPS = {
|
|
|
62
61
|
// Use 'null' to indicate unavailable transfrorm for a case where TRANSFORM_STEPS are not undefined.
|
|
63
62
|
var TRANSFORM_STEPS_OVERRIDE = {
|
|
64
63
|
paragraph: {
|
|
65
|
-
paragraph: null
|
|
66
|
-
codeBlock: [wrapTextToCodeblockStep],
|
|
67
|
-
layoutSection: [wrapMixedContentStep]
|
|
68
|
-
},
|
|
69
|
-
heading: {
|
|
70
|
-
codeBlock: [wrapTextToCodeblockStep],
|
|
71
|
-
layoutSection: [wrapMixedContentStep]
|
|
64
|
+
paragraph: null
|
|
72
65
|
},
|
|
66
|
+
heading: {},
|
|
73
67
|
panel: {
|
|
74
68
|
panel: null,
|
|
75
69
|
layoutSection: [unwrapStep, wrapMixedContentStep],
|
|
76
|
-
codeBlock: [unwrapStep,
|
|
70
|
+
codeBlock: [unwrapStep, wrapMixedContentStep],
|
|
77
71
|
blockquote: [unwrapStep, wrapMixedContentStep],
|
|
78
72
|
taskList: null,
|
|
79
73
|
bulletList: null,
|
|
@@ -104,7 +98,9 @@ var TRANSFORM_STEPS_OVERRIDE = {
|
|
|
104
98
|
nestedExpand: [wrapStep],
|
|
105
99
|
layoutSection: [wrapMixedContentStep],
|
|
106
100
|
codeBlock: null,
|
|
107
|
-
decisionList: [unwrapStep, wrapBlockquoteToDecisionListStep]
|
|
101
|
+
decisionList: [unwrapStep, wrapBlockquoteToDecisionListStep],
|
|
102
|
+
paragraph: [unwrapStep],
|
|
103
|
+
heading: [unwrapStep, applyTargetTextTypeStep]
|
|
108
104
|
},
|
|
109
105
|
layoutSection: {
|
|
110
106
|
layoutSection: null,
|
|
@@ -122,6 +118,7 @@ var TRANSFORM_STEPS_OVERRIDE = {
|
|
|
122
118
|
nestedExpand: [wrapStep],
|
|
123
119
|
layoutSection: [wrapMixedContentStep],
|
|
124
120
|
panel: [wrapStep],
|
|
121
|
+
paragraph: [applyTargetTextTypeStep],
|
|
125
122
|
heading: null
|
|
126
123
|
},
|
|
127
124
|
bulletList: {
|
|
@@ -216,10 +213,11 @@ var TRANSFORM_STEPS_OVERRIDE = {
|
|
|
216
213
|
decisionList: null
|
|
217
214
|
},
|
|
218
215
|
multi: {
|
|
219
|
-
|
|
220
|
-
heading
|
|
221
|
-
//
|
|
222
|
-
|
|
216
|
+
heading: [applyTargetTextTypeStep]
|
|
217
|
+
// Similar to heading, all structures are kept as is
|
|
218
|
+
// EG: transformed: other lists, paragarph, headings
|
|
219
|
+
// eg: not-transformed: quotes, codeblocks ... all typeof 'containers'
|
|
220
|
+
// decisionList: [],
|
|
223
221
|
}
|
|
224
222
|
};
|
|
225
223
|
var getTransformStepsForNodeTypes = function getTransformStepsForNodeTypes(selectedNodeTypeName, targetNodeTypeName) {
|
|
@@ -44,8 +44,14 @@ export var transformNode = function transformNode(api) {
|
|
|
44
44
|
});
|
|
45
45
|
var content = resultNodes.length > 0 ? resultNodes : slice.content;
|
|
46
46
|
if (preservedSelection instanceof NodeSelection && preservedSelection.node.type === nodes.mediaSingle) {
|
|
47
|
-
tr.
|
|
48
|
-
|
|
47
|
+
// when node is media single, use tr.replaceWith freeze editor, if modify position, tr.replaceWith creates duplicats
|
|
48
|
+
var deleteFrom = $from.pos;
|
|
49
|
+
var deleteTo = $to.pos;
|
|
50
|
+
tr.delete(deleteFrom, deleteTo);
|
|
51
|
+
// After deletion, recalculate the insertion position to ensure it's valid
|
|
52
|
+
// especially when mediaSingle with caption is at the bottom of the document
|
|
53
|
+
var insertPos = Math.min(deleteFrom, tr.doc.content.size);
|
|
54
|
+
tr.insert(insertPos, content);
|
|
49
55
|
} else {
|
|
50
56
|
tr.replaceWith(sliceStart, $to.pos, content);
|
|
51
57
|
}
|
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
import type { TransformStep } from '../types';
|
|
2
2
|
/**
|
|
3
|
-
* Applies target text type conversion.
|
|
4
|
-
* (
|
|
5
|
-
* Non-textblock nodes are always left unchanged.
|
|
3
|
+
* Applies target text type conversion. Converts textblock nodes to the target text type
|
|
4
|
+
* (paragraph or heading). Non-textblock nodes are left unchanged.
|
|
6
5
|
*
|
|
7
6
|
* @example
|
|
8
7
|
* Input:
|
|
9
|
-
* - paragraph "
|
|
10
|
-
* - paragraph "
|
|
8
|
+
* - paragraph "Text 1"
|
|
9
|
+
* - paragraph "Text 2"
|
|
11
10
|
*
|
|
12
11
|
* Output (with target: heading, level: 2):
|
|
13
|
-
* - heading (level: 2) "
|
|
14
|
-
* - heading (level: 2) "
|
|
12
|
+
* - heading (level: 2) "Text 1"
|
|
13
|
+
* - heading (level: 2) "Text 2"
|
|
14
|
+
*
|
|
15
|
+
* Output (with target: paragraph):
|
|
16
|
+
* - paragraph "Text 1"
|
|
17
|
+
* - paragraph "Text 2"
|
|
15
18
|
*
|
|
16
19
|
* @param nodes
|
|
17
20
|
* @param context
|
|
@@ -14,6 +14,9 @@ import type { TransformStep } from '../types';
|
|
|
14
14
|
* - Layouts always require layoutColumns as children (never paragraphs directly)
|
|
15
15
|
* - Layout columns can contain most block content including headings, paragraphs, lists, etc.
|
|
16
16
|
*
|
|
17
|
+
* Special handling for codeblocks:
|
|
18
|
+
* - Text nodes are converted to plain text and added to the codeblock
|
|
19
|
+
*
|
|
17
20
|
* Edge case handling:
|
|
18
21
|
* - For regular containers: If all content breaks out (container → container transform with no
|
|
19
22
|
* valid children), an empty container with a paragraph is created to ensure the target type exists
|
package/dist/types-ts4.5/editor-commands/transform-node-utils/steps/applyTargetTextTypeStep.d.ts
CHANGED
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
import type { TransformStep } from '../types';
|
|
2
2
|
/**
|
|
3
|
-
* Applies target text type conversion.
|
|
4
|
-
* (
|
|
5
|
-
* Non-textblock nodes are always left unchanged.
|
|
3
|
+
* Applies target text type conversion. Converts textblock nodes to the target text type
|
|
4
|
+
* (paragraph or heading). Non-textblock nodes are left unchanged.
|
|
6
5
|
*
|
|
7
6
|
* @example
|
|
8
7
|
* Input:
|
|
9
|
-
* - paragraph "
|
|
10
|
-
* - paragraph "
|
|
8
|
+
* - paragraph "Text 1"
|
|
9
|
+
* - paragraph "Text 2"
|
|
11
10
|
*
|
|
12
11
|
* Output (with target: heading, level: 2):
|
|
13
|
-
* - heading (level: 2) "
|
|
14
|
-
* - heading (level: 2) "
|
|
12
|
+
* - heading (level: 2) "Text 1"
|
|
13
|
+
* - heading (level: 2) "Text 2"
|
|
14
|
+
*
|
|
15
|
+
* Output (with target: paragraph):
|
|
16
|
+
* - paragraph "Text 1"
|
|
17
|
+
* - paragraph "Text 2"
|
|
15
18
|
*
|
|
16
19
|
* @param nodes
|
|
17
20
|
* @param context
|
package/dist/types-ts4.5/editor-commands/transform-node-utils/steps/wrapMixedContentStep.d.ts
CHANGED
|
@@ -14,6 +14,9 @@ import type { TransformStep } from '../types';
|
|
|
14
14
|
* - Layouts always require layoutColumns as children (never paragraphs directly)
|
|
15
15
|
* - Layout columns can contain most block content including headings, paragraphs, lists, etc.
|
|
16
16
|
*
|
|
17
|
+
* Special handling for codeblocks:
|
|
18
|
+
* - Text nodes are converted to plain text and added to the codeblock
|
|
19
|
+
*
|
|
17
20
|
* Edge case handling:
|
|
18
21
|
* - For regular containers: If all content breaks out (container → container transform with no
|
|
19
22
|
* valid children), an empty container with a paragraph is created to ensure the target type exists
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-block-menu",
|
|
3
|
-
"version": "6.0.
|
|
3
|
+
"version": "6.0.8",
|
|
4
4
|
"description": "BlockMenu plugin for @atlaskit/editor-core",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"@atlaskit/platform-feature-flags-react": "^0.4.0",
|
|
46
46
|
"@atlaskit/primitives": "^17.0.0",
|
|
47
47
|
"@atlaskit/tmp-editor-statsig": "^16.4.0",
|
|
48
|
-
"@atlaskit/tokens": "^9.
|
|
48
|
+
"@atlaskit/tokens": "^9.1.0",
|
|
49
49
|
"@babel/runtime": "^7.0.0"
|
|
50
50
|
},
|
|
51
51
|
"peerDependencies": {
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.wrapTextToCodeblockStep = void 0;
|
|
7
|
-
var _utils = require("../utils");
|
|
8
|
-
/**
|
|
9
|
-
* Transforms a paragraph (or heading) into a codeBlock by extracting its text content.
|
|
10
|
-
* This step handles the conversion of inline content (including marks) to plain text,
|
|
11
|
-
* which is required because codeBlocks can only contain plain text nodes.
|
|
12
|
-
*
|
|
13
|
-
* Example: paragraph with bold/italic/status → codeBlock with plain text
|
|
14
|
-
*/
|
|
15
|
-
var wrapTextToCodeblockStep = exports.wrapTextToCodeblockStep = function wrapTextToCodeblockStep(nodes, context) {
|
|
16
|
-
var schema = context.schema;
|
|
17
|
-
return nodes.map(function (node) {
|
|
18
|
-
var codeBlockNode = schema.nodes.codeBlock.createAndFill({}, schema.text((0, _utils.createTextContent)(node)));
|
|
19
|
-
return codeBlockNode !== null && codeBlockNode !== void 0 ? codeBlockNode : node;
|
|
20
|
-
});
|
|
21
|
-
};
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { createTextContent } from '../utils';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Transforms a paragraph (or heading) into a codeBlock by extracting its text content.
|
|
5
|
-
* This step handles the conversion of inline content (including marks) to plain text,
|
|
6
|
-
* which is required because codeBlocks can only contain plain text nodes.
|
|
7
|
-
*
|
|
8
|
-
* Example: paragraph with bold/italic/status → codeBlock with plain text
|
|
9
|
-
*/
|
|
10
|
-
export const wrapTextToCodeblockStep = (nodes, context) => {
|
|
11
|
-
const {
|
|
12
|
-
schema
|
|
13
|
-
} = context;
|
|
14
|
-
return nodes.map(node => {
|
|
15
|
-
const codeBlockNode = schema.nodes.codeBlock.createAndFill({}, schema.text(createTextContent(node)));
|
|
16
|
-
return codeBlockNode !== null && codeBlockNode !== void 0 ? codeBlockNode : node;
|
|
17
|
-
});
|
|
18
|
-
};
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { createTextContent } from '../utils';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Transforms a paragraph (or heading) into a codeBlock by extracting its text content.
|
|
5
|
-
* This step handles the conversion of inline content (including marks) to plain text,
|
|
6
|
-
* which is required because codeBlocks can only contain plain text nodes.
|
|
7
|
-
*
|
|
8
|
-
* Example: paragraph with bold/italic/status → codeBlock with plain text
|
|
9
|
-
*/
|
|
10
|
-
export var wrapTextToCodeblockStep = function wrapTextToCodeblockStep(nodes, context) {
|
|
11
|
-
var schema = context.schema;
|
|
12
|
-
return nodes.map(function (node) {
|
|
13
|
-
var codeBlockNode = schema.nodes.codeBlock.createAndFill({}, schema.text(createTextContent(node)));
|
|
14
|
-
return codeBlockNode !== null && codeBlockNode !== void 0 ? codeBlockNode : node;
|
|
15
|
-
});
|
|
16
|
-
};
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import type { TransformStep } from '../types';
|
|
2
|
-
/**
|
|
3
|
-
* Transforms a paragraph (or heading) into a codeBlock by extracting its text content.
|
|
4
|
-
* This step handles the conversion of inline content (including marks) to plain text,
|
|
5
|
-
* which is required because codeBlocks can only contain plain text nodes.
|
|
6
|
-
*
|
|
7
|
-
* Example: paragraph with bold/italic/status → codeBlock with plain text
|
|
8
|
-
*/
|
|
9
|
-
export declare const wrapTextToCodeblockStep: TransformStep;
|
package/dist/types-ts4.5/editor-commands/transform-node-utils/steps/wrapTextToCodeblock.d.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import type { TransformStep } from '../types';
|
|
2
|
-
/**
|
|
3
|
-
* Transforms a paragraph (or heading) into a codeBlock by extracting its text content.
|
|
4
|
-
* This step handles the conversion of inline content (including marks) to plain text,
|
|
5
|
-
* which is required because codeBlocks can only contain plain text nodes.
|
|
6
|
-
*
|
|
7
|
-
* Example: paragraph with bold/italic/status → codeBlock with plain text
|
|
8
|
-
*/
|
|
9
|
-
export declare const wrapTextToCodeblockStep: TransformStep;
|