@atlaskit/editor-plugin-block-menu 1.0.6 → 1.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 +16 -0
- package/dist/cjs/editor-commands/transforms/container-transforms.js +131 -24
- package/dist/cjs/editor-commands/transforms/transformNodeToTargetType.js +5 -0
- package/dist/cjs/editor-commands/transforms/utils.js +48 -1
- package/dist/es2019/editor-commands/transforms/container-transforms.js +131 -24
- package/dist/es2019/editor-commands/transforms/transformNodeToTargetType.js +7 -2
- package/dist/es2019/editor-commands/transforms/utils.js +47 -0
- package/dist/esm/editor-commands/transforms/container-transforms.js +131 -24
- package/dist/esm/editor-commands/transforms/transformNodeToTargetType.js +7 -2
- package/dist/esm/editor-commands/transforms/utils.js +47 -0
- package/dist/types/editor-commands/transforms/container-transforms.d.ts +2 -1
- package/dist/types/editor-commands/transforms/utils.d.ts +14 -1
- package/dist/types-ts4.5/editor-commands/transforms/container-transforms.d.ts +2 -1
- package/dist/types-ts4.5/editor-commands/transforms/utils.d.ts +14 -1
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-block-menu
|
|
2
2
|
|
|
3
|
+
## 1.0.8
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`b3e1332c170a6`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/b3e1332c170a6) -
|
|
8
|
+
Container to container transform with unsupportted content
|
|
9
|
+
- Updated dependencies
|
|
10
|
+
|
|
11
|
+
## 1.0.7
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- [`34871606f04ba`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/34871606f04ba) -
|
|
16
|
+
[ux] Updates unwrapAndConvertToList to support codeBlock to list case and cases where contnent is
|
|
17
|
+
not textblock.
|
|
18
|
+
|
|
3
19
|
## 1.0.6
|
|
4
20
|
|
|
5
21
|
### Patch Changes
|
|
@@ -4,7 +4,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
|
|
|
4
4
|
Object.defineProperty(exports, "__esModule", {
|
|
5
5
|
value: true
|
|
6
6
|
});
|
|
7
|
-
exports.unwrapAndConvertToList = exports.unwrapAndConvertToBlockType = exports.transformToContainer = exports.transformContainerNode = void 0;
|
|
7
|
+
exports.unwrapAndConvertToList = exports.unwrapAndConvertToBlockType = exports.transformToContainer = exports.transformContainerNode = exports.transformBetweenContainerTypes = void 0;
|
|
8
8
|
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
|
|
9
9
|
var _model = require("@atlaskit/editor-prosemirror/model");
|
|
10
10
|
var _utils = require("./utils");
|
|
@@ -84,8 +84,13 @@ var transformContainerNode = exports.transformContainerNode = function transform
|
|
|
84
84
|
|
|
85
85
|
// Transform between container types
|
|
86
86
|
if ((0, _utils.isContainerNodeType)(targetNodeType)) {
|
|
87
|
-
|
|
88
|
-
|
|
87
|
+
return transformBetweenContainerTypes({
|
|
88
|
+
tr: tr,
|
|
89
|
+
sourceNode: sourceNode,
|
|
90
|
+
sourcePos: sourcePos,
|
|
91
|
+
targetNodeType: targetNodeType,
|
|
92
|
+
targetAttrs: targetAttrs
|
|
93
|
+
});
|
|
89
94
|
}
|
|
90
95
|
return null;
|
|
91
96
|
};
|
|
@@ -171,18 +176,16 @@ var unwrapAndConvertToList = exports.unwrapAndConvertToList = function unwrapAnd
|
|
|
171
176
|
sourcePos = _ref3.sourcePos,
|
|
172
177
|
targetNodeType = _ref3.targetNodeType,
|
|
173
178
|
targetAttrs = _ref3.targetAttrs;
|
|
174
|
-
if (sourcePos === null) {
|
|
175
|
-
return tr;
|
|
176
|
-
}
|
|
177
179
|
var schema = tr.doc.type.schema;
|
|
178
180
|
var _schema$nodes2 = schema.nodes,
|
|
179
181
|
listItem = _schema$nodes2.listItem,
|
|
180
182
|
paragraph = _schema$nodes2.paragraph,
|
|
181
183
|
taskList = _schema$nodes2.taskList,
|
|
182
|
-
taskItem = _schema$nodes2.taskItem
|
|
184
|
+
taskItem = _schema$nodes2.taskItem,
|
|
185
|
+
heading = _schema$nodes2.heading;
|
|
183
186
|
var isTargetTaskList = targetNodeType === taskList;
|
|
184
|
-
var createListItemFromInline = function createListItemFromInline(
|
|
185
|
-
return isTargetTaskList ? taskItem.create(null,
|
|
187
|
+
var createListItemFromInline = function createListItemFromInline(content) {
|
|
188
|
+
return isTargetTaskList ? taskItem.create(null, content) : listItem.create(null, paragraph.create(null, content));
|
|
186
189
|
};
|
|
187
190
|
var getInlineContent = function getInlineContent(textblock) {
|
|
188
191
|
var inlineContent = [];
|
|
@@ -191,30 +194,134 @@ var unwrapAndConvertToList = exports.unwrapAndConvertToList = function unwrapAnd
|
|
|
191
194
|
});
|
|
192
195
|
return inlineContent;
|
|
193
196
|
};
|
|
194
|
-
var
|
|
195
|
-
|
|
197
|
+
var resultContent = [];
|
|
198
|
+
var currentListItems = [];
|
|
199
|
+
var targetListItemType = isTargetTaskList ? taskItem : listItem;
|
|
196
200
|
// Expand's title should become the first item of the list
|
|
197
201
|
if (sourceNode.type.name === 'expand') {
|
|
198
202
|
var _sourceNode$attrs2;
|
|
199
203
|
var title = (_sourceNode$attrs2 = sourceNode.attrs) === null || _sourceNode$attrs2 === void 0 ? void 0 : _sourceNode$attrs2.title;
|
|
200
204
|
if (title) {
|
|
201
205
|
var titleContent = schema.text(title);
|
|
202
|
-
|
|
206
|
+
currentListItems.push(createListItemFromInline(titleContent));
|
|
203
207
|
}
|
|
204
208
|
}
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
return tr;
|
|
209
|
+
var createListAndAddToContent = function createListAndAddToContent() {
|
|
210
|
+
if (currentListItems.length) {
|
|
211
|
+
var currentList = targetNodeType.create(targetAttrs || null, _model.Fragment.from(currentListItems));
|
|
212
|
+
currentListItems = [];
|
|
213
|
+
resultContent.push(currentList);
|
|
211
214
|
}
|
|
212
|
-
|
|
213
|
-
|
|
215
|
+
};
|
|
216
|
+
if (sourceNode.type.name === 'codeBlock') {
|
|
217
|
+
var codeText = sourceNode.textContent;
|
|
218
|
+
if (codeText) {
|
|
219
|
+
var lines = codeText.split('\n');
|
|
220
|
+
// Remove empty lines
|
|
221
|
+
var nonEmptyLines = lines.filter(function (line) {
|
|
222
|
+
return line.trim().length > 0;
|
|
223
|
+
});
|
|
224
|
+
nonEmptyLines.forEach(function (line) {
|
|
225
|
+
var lineText = schema.text(line);
|
|
226
|
+
currentListItems.push(createListItemFromInline(lineText));
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
} else {
|
|
230
|
+
sourceNode.forEach(function (child) {
|
|
231
|
+
if (targetListItemType.validContent(_model.Fragment.from(child))) {
|
|
232
|
+
currentListItems.push(targetListItemType.create(null, child));
|
|
233
|
+
} else if (heading === child.type || isTargetTaskList && paragraph === child.type) {
|
|
234
|
+
var inline = _model.Fragment.from(getInlineContent(child));
|
|
235
|
+
currentListItems.push(createListItemFromInline(inline));
|
|
236
|
+
} else {
|
|
237
|
+
// Create list and add list first
|
|
238
|
+
createListAndAddToContent();
|
|
239
|
+
// Then add content that can't be converted into listItem
|
|
240
|
+
resultContent.push(child);
|
|
241
|
+
}
|
|
242
|
+
});
|
|
214
243
|
}
|
|
215
|
-
if (!
|
|
216
|
-
return
|
|
244
|
+
if (!resultContent.length && !currentListItems.length) {
|
|
245
|
+
return null;
|
|
246
|
+
}
|
|
247
|
+
createListAndAddToContent();
|
|
248
|
+
return tr.replaceWith(sourcePos, sourcePos + sourceNode.nodeSize, _model.Fragment.from(resultContent));
|
|
249
|
+
};
|
|
250
|
+
var transformBetweenContainerTypes = exports.transformBetweenContainerTypes = function transformBetweenContainerTypes(context) {
|
|
251
|
+
var tr = context.tr,
|
|
252
|
+
sourceNode = context.sourceNode,
|
|
253
|
+
sourcePos = context.sourcePos,
|
|
254
|
+
targetNodeType = context.targetNodeType,
|
|
255
|
+
targetAttrs = context.targetAttrs;
|
|
256
|
+
|
|
257
|
+
// Get content validation for target container type
|
|
258
|
+
var isContentSupported = (0, _utils.getContentSupportChecker)(targetNodeType);
|
|
259
|
+
|
|
260
|
+
// Process content and collect splits
|
|
261
|
+
var contentSplits = splitContentAroundUnsupportedBlocks(sourceNode, isContentSupported, targetNodeType, targetAttrs, tr.doc.type.schema);
|
|
262
|
+
|
|
263
|
+
// Replace the original node with the first split
|
|
264
|
+
var insertPos = sourcePos;
|
|
265
|
+
contentSplits.forEach(function (splitNode, index) {
|
|
266
|
+
if (index === 0) {
|
|
267
|
+
// Replace the original node with the first split
|
|
268
|
+
tr.replaceWith(sourcePos, sourcePos + sourceNode.nodeSize, splitNode);
|
|
269
|
+
insertPos = sourcePos + splitNode.nodeSize;
|
|
270
|
+
} else {
|
|
271
|
+
// Insert additional splits after
|
|
272
|
+
tr.insert(insertPos, splitNode);
|
|
273
|
+
insertPos += splitNode.nodeSize;
|
|
274
|
+
}
|
|
275
|
+
});
|
|
276
|
+
return tr;
|
|
277
|
+
};
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Split content around unsupported block nodes, creating separate containers
|
|
281
|
+
* for content before and after each unsupported block
|
|
282
|
+
*/
|
|
283
|
+
var splitContentAroundUnsupportedBlocks = function splitContentAroundUnsupportedBlocks(sourceNode, isContentSupported, targetNodeType, targetAttrs, schema) {
|
|
284
|
+
var _sourceNode$attrs3;
|
|
285
|
+
var splits = [];
|
|
286
|
+
var children = sourceNode.content.content;
|
|
287
|
+
var currentContainerContent = [];
|
|
288
|
+
|
|
289
|
+
// Handle expand title - add as first paragraph if source is expand with title
|
|
290
|
+
if (sourceNode.type.name === 'expand' && (_sourceNode$attrs3 = sourceNode.attrs) !== null && _sourceNode$attrs3 !== void 0 && _sourceNode$attrs3.title) {
|
|
291
|
+
var titleParagraph = schema.nodes.paragraph.create({}, schema.text(sourceNode.attrs.title));
|
|
292
|
+
currentContainerContent.push(titleParagraph);
|
|
217
293
|
}
|
|
218
|
-
var
|
|
219
|
-
|
|
294
|
+
var flushCurrentContainer = function flushCurrentContainer() {
|
|
295
|
+
if (currentContainerContent.length > 0) {
|
|
296
|
+
var containerNode = targetNodeType.create(targetAttrs, _model.Fragment.fromArray(currentContainerContent));
|
|
297
|
+
splits.push(containerNode);
|
|
298
|
+
currentContainerContent = [];
|
|
299
|
+
}
|
|
300
|
+
};
|
|
301
|
+
children.forEach(function (childNode) {
|
|
302
|
+
if (isContentSupported(childNode)) {
|
|
303
|
+
// Supported content - add to current container
|
|
304
|
+
currentContainerContent.push(childNode);
|
|
305
|
+
} else if ((0, _utils.isBlockNodeForExtraction)(childNode)) {
|
|
306
|
+
// Unsupported block node - flush current container, add block, continue
|
|
307
|
+
flushCurrentContainer();
|
|
308
|
+
splits.push(childNode);
|
|
309
|
+
} else if (childNode.type.name === targetNodeType.name) {
|
|
310
|
+
// Same type of container merge contents
|
|
311
|
+
childNode.content.forEach(function (child) {
|
|
312
|
+
currentContainerContent.push(child);
|
|
313
|
+
});
|
|
314
|
+
} else {
|
|
315
|
+
// Unsupported inline content - convert to paragraph and add to container
|
|
316
|
+
var inlineContent = (0, _utils.convertNodeToInlineContent)(childNode, schema);
|
|
317
|
+
if (inlineContent.length > 0) {
|
|
318
|
+
var paragraph = schema.nodes.paragraph.create({}, _model.Fragment.fromArray(inlineContent));
|
|
319
|
+
currentContainerContent.push(paragraph);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
// Flush any remaining container content
|
|
325
|
+
flushCurrentContainer();
|
|
326
|
+
return splits;
|
|
220
327
|
};
|
|
@@ -47,6 +47,11 @@ function transformNodeToTargetType(tr, sourceNode, sourcePos, targetType) {
|
|
|
47
47
|
if ((0, _utils.isLayoutNodeType)(targetNodeType)) {
|
|
48
48
|
return (0, _layoutTransforms.convertToLayout)(transformationContext);
|
|
49
49
|
}
|
|
50
|
+
|
|
51
|
+
// special case codeblock to listType
|
|
52
|
+
if (sourceNode.type.name === 'codeBlock' && (0, _utils.isListNodeType)(targetNodeType)) {
|
|
53
|
+
return (0, _containerTransforms.unwrapAndConvertToList)(transformationContext);
|
|
54
|
+
}
|
|
50
55
|
if ((0, _utils.isBlockNode)(sourceNode)) {
|
|
51
56
|
return (0, _blockTransforms.transformBlockNode)(transformationContext);
|
|
52
57
|
}
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.isTaskList = exports.isListNodeType = exports.isListNode = exports.isLayoutNodeType = exports.isContainerNodeType = exports.isContainerNode = exports.isBulletOrOrderedList = exports.isBlockNodeType = exports.isBlockNode = exports.getTargetNodeInfo = exports.getSupportedListTypesSet = exports.getSupportedListTypes = void 0;
|
|
6
|
+
exports.isTaskList = exports.isListNodeType = exports.isListNode = exports.isLayoutNodeType = exports.isContainerNodeType = exports.isContainerNode = exports.isBulletOrOrderedList = exports.isBlockNodeType = exports.isBlockNodeForExtraction = exports.isBlockNode = exports.getTargetNodeInfo = exports.getSupportedListTypesSet = exports.getSupportedListTypes = exports.getContentSupportChecker = exports.convertNodeToInlineContent = void 0;
|
|
7
|
+
var _model = require("@atlaskit/editor-prosemirror/model");
|
|
7
8
|
var getTargetNodeInfo = exports.getTargetNodeInfo = function getTargetNodeInfo(targetType, nodes) {
|
|
8
9
|
switch (targetType) {
|
|
9
10
|
case 'heading1':
|
|
@@ -127,4 +128,50 @@ var getSupportedListTypesSet = exports.getSupportedListTypesSet = function getSu
|
|
|
127
128
|
};
|
|
128
129
|
var isLayoutNodeType = exports.isLayoutNodeType = function isLayoutNodeType(nodeType) {
|
|
129
130
|
return nodeType.name === 'layoutSection';
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Check if a node should be extracted as a standalone block node
|
|
135
|
+
* rather than converted to inline content
|
|
136
|
+
*/
|
|
137
|
+
var isBlockNodeForExtraction = exports.isBlockNodeForExtraction = function isBlockNodeForExtraction(node) {
|
|
138
|
+
var blockNodesForExtraction = ['table', 'mediaSingle', 'extension', 'bodiedExtension', 'blockCard', 'embedCard'];
|
|
139
|
+
return blockNodesForExtraction.includes(node.type.name);
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Get a function that checks if content is supported in the target container type
|
|
144
|
+
*/
|
|
145
|
+
var getContentSupportChecker = exports.getContentSupportChecker = function getContentSupportChecker(targetNodeType) {
|
|
146
|
+
return function (node) {
|
|
147
|
+
// Check if the target container type can contain this node
|
|
148
|
+
try {
|
|
149
|
+
return targetNodeType.validContent(_model.Fragment.from(node));
|
|
150
|
+
} catch (_unused) {
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Convert a node to inline content that can be placed in a paragraph
|
|
158
|
+
*/
|
|
159
|
+
var convertNodeToInlineContent = exports.convertNodeToInlineContent = function convertNodeToInlineContent(node, schema) {
|
|
160
|
+
// Extract text and inline nodes from any complex node
|
|
161
|
+
var inlineNodes = [];
|
|
162
|
+
node.descendants(function (childNode) {
|
|
163
|
+
if (childNode.isText) {
|
|
164
|
+
inlineNodes.push(childNode);
|
|
165
|
+
} else if (childNode.isInline) {
|
|
166
|
+
inlineNodes.push(childNode);
|
|
167
|
+
}
|
|
168
|
+
return true; // Continue traversing
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
// If no inline content was found but the node has text content,
|
|
172
|
+
// create a text node with the full text content
|
|
173
|
+
if (inlineNodes.length === 0 && node.textContent) {
|
|
174
|
+
return [schema.text(node.textContent)];
|
|
175
|
+
}
|
|
176
|
+
return inlineNodes;
|
|
130
177
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Fragment, Slice } from '@atlaskit/editor-prosemirror/model';
|
|
2
|
-
import { isBlockNodeType, isListNodeType, isContainerNodeType } from './utils';
|
|
2
|
+
import { isBlockNodeType, isListNodeType, isContainerNodeType, isBlockNodeForExtraction, convertNodeToInlineContent, getContentSupportChecker } from './utils';
|
|
3
3
|
const convertInvalidNodeToValidNodeType = (sourceContent, sourceNodeType, validNodeType, withMarks) => {
|
|
4
4
|
const validTransformedContent = [];
|
|
5
5
|
// Headings are not valid inside headings so convert heading nodes to paragraphs
|
|
@@ -78,8 +78,13 @@ export const transformContainerNode = ({
|
|
|
78
78
|
|
|
79
79
|
// Transform between container types
|
|
80
80
|
if (isContainerNodeType(targetNodeType)) {
|
|
81
|
-
|
|
82
|
-
|
|
81
|
+
return transformBetweenContainerTypes({
|
|
82
|
+
tr,
|
|
83
|
+
sourceNode,
|
|
84
|
+
sourcePos,
|
|
85
|
+
targetNodeType,
|
|
86
|
+
targetAttrs
|
|
87
|
+
});
|
|
83
88
|
}
|
|
84
89
|
return null;
|
|
85
90
|
};
|
|
@@ -167,9 +172,6 @@ export const unwrapAndConvertToList = ({
|
|
|
167
172
|
targetNodeType,
|
|
168
173
|
targetAttrs
|
|
169
174
|
}) => {
|
|
170
|
-
if (sourcePos === null) {
|
|
171
|
-
return tr;
|
|
172
|
-
}
|
|
173
175
|
const {
|
|
174
176
|
schema
|
|
175
177
|
} = tr.doc.type;
|
|
@@ -177,11 +179,12 @@ export const unwrapAndConvertToList = ({
|
|
|
177
179
|
listItem,
|
|
178
180
|
paragraph,
|
|
179
181
|
taskList,
|
|
180
|
-
taskItem
|
|
182
|
+
taskItem,
|
|
183
|
+
heading
|
|
181
184
|
} = schema.nodes;
|
|
182
185
|
const isTargetTaskList = targetNodeType === taskList;
|
|
183
|
-
const createListItemFromInline =
|
|
184
|
-
return isTargetTaskList ? taskItem.create(null,
|
|
186
|
+
const createListItemFromInline = content => {
|
|
187
|
+
return isTargetTaskList ? taskItem.create(null, content) : listItem.create(null, paragraph.create(null, content));
|
|
185
188
|
};
|
|
186
189
|
const getInlineContent = textblock => {
|
|
187
190
|
const inlineContent = [];
|
|
@@ -190,30 +193,134 @@ export const unwrapAndConvertToList = ({
|
|
|
190
193
|
});
|
|
191
194
|
return inlineContent;
|
|
192
195
|
};
|
|
193
|
-
const
|
|
194
|
-
|
|
196
|
+
const resultContent = [];
|
|
197
|
+
let currentListItems = [];
|
|
198
|
+
const targetListItemType = isTargetTaskList ? taskItem : listItem;
|
|
195
199
|
// Expand's title should become the first item of the list
|
|
196
200
|
if (sourceNode.type.name === 'expand') {
|
|
197
201
|
var _sourceNode$attrs2;
|
|
198
202
|
const title = (_sourceNode$attrs2 = sourceNode.attrs) === null || _sourceNode$attrs2 === void 0 ? void 0 : _sourceNode$attrs2.title;
|
|
199
203
|
if (title) {
|
|
200
204
|
const titleContent = schema.text(title);
|
|
201
|
-
|
|
205
|
+
currentListItems.push(createListItemFromInline(titleContent));
|
|
202
206
|
}
|
|
203
207
|
}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
return tr;
|
|
208
|
+
const createListAndAddToContent = () => {
|
|
209
|
+
if (currentListItems.length) {
|
|
210
|
+
const currentList = targetNodeType.create(targetAttrs || null, Fragment.from(currentListItems));
|
|
211
|
+
currentListItems = [];
|
|
212
|
+
resultContent.push(currentList);
|
|
210
213
|
}
|
|
211
|
-
|
|
212
|
-
|
|
214
|
+
};
|
|
215
|
+
if (sourceNode.type.name === 'codeBlock') {
|
|
216
|
+
const codeText = sourceNode.textContent;
|
|
217
|
+
if (codeText) {
|
|
218
|
+
const lines = codeText.split('\n');
|
|
219
|
+
// Remove empty lines
|
|
220
|
+
const nonEmptyLines = lines.filter(line => line.trim().length > 0);
|
|
221
|
+
nonEmptyLines.forEach(line => {
|
|
222
|
+
const lineText = schema.text(line);
|
|
223
|
+
currentListItems.push(createListItemFromInline(lineText));
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
} else {
|
|
227
|
+
sourceNode.forEach(child => {
|
|
228
|
+
if (targetListItemType.validContent(Fragment.from(child))) {
|
|
229
|
+
currentListItems.push(targetListItemType.create(null, child));
|
|
230
|
+
} else if (heading === child.type || isTargetTaskList && paragraph === child.type) {
|
|
231
|
+
const inline = Fragment.from(getInlineContent(child));
|
|
232
|
+
currentListItems.push(createListItemFromInline(inline));
|
|
233
|
+
} else {
|
|
234
|
+
// Create list and add list first
|
|
235
|
+
createListAndAddToContent();
|
|
236
|
+
// Then add content that can't be converted into listItem
|
|
237
|
+
resultContent.push(child);
|
|
238
|
+
}
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
if (!resultContent.length && !currentListItems.length) {
|
|
242
|
+
return null;
|
|
213
243
|
}
|
|
214
|
-
|
|
215
|
-
|
|
244
|
+
createListAndAddToContent();
|
|
245
|
+
return tr.replaceWith(sourcePos, sourcePos + sourceNode.nodeSize, Fragment.from(resultContent));
|
|
246
|
+
};
|
|
247
|
+
export const transformBetweenContainerTypes = context => {
|
|
248
|
+
const {
|
|
249
|
+
tr,
|
|
250
|
+
sourceNode,
|
|
251
|
+
sourcePos,
|
|
252
|
+
targetNodeType,
|
|
253
|
+
targetAttrs
|
|
254
|
+
} = context;
|
|
255
|
+
|
|
256
|
+
// Get content validation for target container type
|
|
257
|
+
const isContentSupported = getContentSupportChecker(targetNodeType);
|
|
258
|
+
|
|
259
|
+
// Process content and collect splits
|
|
260
|
+
const contentSplits = splitContentAroundUnsupportedBlocks(sourceNode, isContentSupported, targetNodeType, targetAttrs, tr.doc.type.schema);
|
|
261
|
+
|
|
262
|
+
// Replace the original node with the first split
|
|
263
|
+
let insertPos = sourcePos;
|
|
264
|
+
contentSplits.forEach((splitNode, index) => {
|
|
265
|
+
if (index === 0) {
|
|
266
|
+
// Replace the original node with the first split
|
|
267
|
+
tr.replaceWith(sourcePos, sourcePos + sourceNode.nodeSize, splitNode);
|
|
268
|
+
insertPos = sourcePos + splitNode.nodeSize;
|
|
269
|
+
} else {
|
|
270
|
+
// Insert additional splits after
|
|
271
|
+
tr.insert(insertPos, splitNode);
|
|
272
|
+
insertPos += splitNode.nodeSize;
|
|
273
|
+
}
|
|
274
|
+
});
|
|
275
|
+
return tr;
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Split content around unsupported block nodes, creating separate containers
|
|
280
|
+
* for content before and after each unsupported block
|
|
281
|
+
*/
|
|
282
|
+
const splitContentAroundUnsupportedBlocks = (sourceNode, isContentSupported, targetNodeType, targetAttrs, schema) => {
|
|
283
|
+
var _sourceNode$attrs3;
|
|
284
|
+
const splits = [];
|
|
285
|
+
const children = sourceNode.content.content;
|
|
286
|
+
let currentContainerContent = [];
|
|
287
|
+
|
|
288
|
+
// Handle expand title - add as first paragraph if source is expand with title
|
|
289
|
+
if (sourceNode.type.name === 'expand' && (_sourceNode$attrs3 = sourceNode.attrs) !== null && _sourceNode$attrs3 !== void 0 && _sourceNode$attrs3.title) {
|
|
290
|
+
const titleParagraph = schema.nodes.paragraph.create({}, schema.text(sourceNode.attrs.title));
|
|
291
|
+
currentContainerContent.push(titleParagraph);
|
|
216
292
|
}
|
|
217
|
-
const
|
|
218
|
-
|
|
293
|
+
const flushCurrentContainer = () => {
|
|
294
|
+
if (currentContainerContent.length > 0) {
|
|
295
|
+
const containerNode = targetNodeType.create(targetAttrs, Fragment.fromArray(currentContainerContent));
|
|
296
|
+
splits.push(containerNode);
|
|
297
|
+
currentContainerContent = [];
|
|
298
|
+
}
|
|
299
|
+
};
|
|
300
|
+
children.forEach(childNode => {
|
|
301
|
+
if (isContentSupported(childNode)) {
|
|
302
|
+
// Supported content - add to current container
|
|
303
|
+
currentContainerContent.push(childNode);
|
|
304
|
+
} else if (isBlockNodeForExtraction(childNode)) {
|
|
305
|
+
// Unsupported block node - flush current container, add block, continue
|
|
306
|
+
flushCurrentContainer();
|
|
307
|
+
splits.push(childNode);
|
|
308
|
+
} else if (childNode.type.name === targetNodeType.name) {
|
|
309
|
+
// Same type of container merge contents
|
|
310
|
+
childNode.content.forEach(child => {
|
|
311
|
+
currentContainerContent.push(child);
|
|
312
|
+
});
|
|
313
|
+
} else {
|
|
314
|
+
// Unsupported inline content - convert to paragraph and add to container
|
|
315
|
+
const inlineContent = convertNodeToInlineContent(childNode, schema);
|
|
316
|
+
if (inlineContent.length > 0) {
|
|
317
|
+
const paragraph = schema.nodes.paragraph.create({}, Fragment.fromArray(inlineContent));
|
|
318
|
+
currentContainerContent.push(paragraph);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
// Flush any remaining container content
|
|
324
|
+
flushCurrentContainer();
|
|
325
|
+
return splits;
|
|
219
326
|
};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { transformBlockNode } from './block-transforms';
|
|
2
|
-
import { transformContainerNode } from './container-transforms';
|
|
2
|
+
import { transformContainerNode, unwrapAndConvertToList } from './container-transforms';
|
|
3
3
|
import { convertToLayout } from './layout-transforms';
|
|
4
4
|
import { transformListNode } from './list-transforms';
|
|
5
|
-
import { getTargetNodeInfo, isBlockNode, isListNode, isContainerNode, isLayoutNodeType } from './utils';
|
|
5
|
+
import { getTargetNodeInfo, isBlockNode, isListNode, isListNodeType, isContainerNode, isLayoutNodeType } from './utils';
|
|
6
6
|
export function transformNodeToTargetType(tr, sourceNode, sourcePos, targetType) {
|
|
7
7
|
const {
|
|
8
8
|
nodes
|
|
@@ -45,6 +45,11 @@ export function transformNodeToTargetType(tr, sourceNode, sourcePos, targetType)
|
|
|
45
45
|
if (isLayoutNodeType(targetNodeType)) {
|
|
46
46
|
return convertToLayout(transformationContext);
|
|
47
47
|
}
|
|
48
|
+
|
|
49
|
+
// special case codeblock to listType
|
|
50
|
+
if (sourceNode.type.name === 'codeBlock' && isListNodeType(targetNodeType)) {
|
|
51
|
+
return unwrapAndConvertToList(transformationContext);
|
|
52
|
+
}
|
|
48
53
|
if (isBlockNode(sourceNode)) {
|
|
49
54
|
return transformBlockNode(transformationContext);
|
|
50
55
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Fragment } from '@atlaskit/editor-prosemirror/model';
|
|
1
2
|
export const getTargetNodeInfo = (targetType, nodes) => {
|
|
2
3
|
switch (targetType) {
|
|
3
4
|
case 'heading1':
|
|
@@ -121,4 +122,50 @@ export const getSupportedListTypesSet = nodes => {
|
|
|
121
122
|
};
|
|
122
123
|
export const isLayoutNodeType = nodeType => {
|
|
123
124
|
return nodeType.name === 'layoutSection';
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Check if a node should be extracted as a standalone block node
|
|
129
|
+
* rather than converted to inline content
|
|
130
|
+
*/
|
|
131
|
+
export const isBlockNodeForExtraction = node => {
|
|
132
|
+
const blockNodesForExtraction = ['table', 'mediaSingle', 'extension', 'bodiedExtension', 'blockCard', 'embedCard'];
|
|
133
|
+
return blockNodesForExtraction.includes(node.type.name);
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Get a function that checks if content is supported in the target container type
|
|
138
|
+
*/
|
|
139
|
+
export const getContentSupportChecker = targetNodeType => {
|
|
140
|
+
return node => {
|
|
141
|
+
// Check if the target container type can contain this node
|
|
142
|
+
try {
|
|
143
|
+
return targetNodeType.validContent(Fragment.from(node));
|
|
144
|
+
} catch {
|
|
145
|
+
return false;
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Convert a node to inline content that can be placed in a paragraph
|
|
152
|
+
*/
|
|
153
|
+
export const convertNodeToInlineContent = (node, schema) => {
|
|
154
|
+
// Extract text and inline nodes from any complex node
|
|
155
|
+
const inlineNodes = [];
|
|
156
|
+
node.descendants(childNode => {
|
|
157
|
+
if (childNode.isText) {
|
|
158
|
+
inlineNodes.push(childNode);
|
|
159
|
+
} else if (childNode.isInline) {
|
|
160
|
+
inlineNodes.push(childNode);
|
|
161
|
+
}
|
|
162
|
+
return true; // Continue traversing
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
// If no inline content was found but the node has text content,
|
|
166
|
+
// create a text node with the full text content
|
|
167
|
+
if (inlineNodes.length === 0 && node.textContent) {
|
|
168
|
+
return [schema.text(node.textContent)];
|
|
169
|
+
}
|
|
170
|
+
return inlineNodes;
|
|
124
171
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
|
|
2
2
|
import { Fragment, Slice } from '@atlaskit/editor-prosemirror/model';
|
|
3
|
-
import { isBlockNodeType, isListNodeType, isContainerNodeType } from './utils';
|
|
3
|
+
import { isBlockNodeType, isListNodeType, isContainerNodeType, isBlockNodeForExtraction, convertNodeToInlineContent, getContentSupportChecker } from './utils';
|
|
4
4
|
var convertInvalidNodeToValidNodeType = function convertInvalidNodeToValidNodeType(sourceContent, sourceNodeType, validNodeType, withMarks) {
|
|
5
5
|
var validTransformedContent = [];
|
|
6
6
|
// Headings are not valid inside headings so convert heading nodes to paragraphs
|
|
@@ -77,8 +77,13 @@ export var transformContainerNode = function transformContainerNode(_ref2) {
|
|
|
77
77
|
|
|
78
78
|
// Transform between container types
|
|
79
79
|
if (isContainerNodeType(targetNodeType)) {
|
|
80
|
-
|
|
81
|
-
|
|
80
|
+
return transformBetweenContainerTypes({
|
|
81
|
+
tr: tr,
|
|
82
|
+
sourceNode: sourceNode,
|
|
83
|
+
sourcePos: sourcePos,
|
|
84
|
+
targetNodeType: targetNodeType,
|
|
85
|
+
targetAttrs: targetAttrs
|
|
86
|
+
});
|
|
82
87
|
}
|
|
83
88
|
return null;
|
|
84
89
|
};
|
|
@@ -164,18 +169,16 @@ export var unwrapAndConvertToList = function unwrapAndConvertToList(_ref3) {
|
|
|
164
169
|
sourcePos = _ref3.sourcePos,
|
|
165
170
|
targetNodeType = _ref3.targetNodeType,
|
|
166
171
|
targetAttrs = _ref3.targetAttrs;
|
|
167
|
-
if (sourcePos === null) {
|
|
168
|
-
return tr;
|
|
169
|
-
}
|
|
170
172
|
var schema = tr.doc.type.schema;
|
|
171
173
|
var _schema$nodes2 = schema.nodes,
|
|
172
174
|
listItem = _schema$nodes2.listItem,
|
|
173
175
|
paragraph = _schema$nodes2.paragraph,
|
|
174
176
|
taskList = _schema$nodes2.taskList,
|
|
175
|
-
taskItem = _schema$nodes2.taskItem
|
|
177
|
+
taskItem = _schema$nodes2.taskItem,
|
|
178
|
+
heading = _schema$nodes2.heading;
|
|
176
179
|
var isTargetTaskList = targetNodeType === taskList;
|
|
177
|
-
var createListItemFromInline = function createListItemFromInline(
|
|
178
|
-
return isTargetTaskList ? taskItem.create(null,
|
|
180
|
+
var createListItemFromInline = function createListItemFromInline(content) {
|
|
181
|
+
return isTargetTaskList ? taskItem.create(null, content) : listItem.create(null, paragraph.create(null, content));
|
|
179
182
|
};
|
|
180
183
|
var getInlineContent = function getInlineContent(textblock) {
|
|
181
184
|
var inlineContent = [];
|
|
@@ -184,30 +187,134 @@ export var unwrapAndConvertToList = function unwrapAndConvertToList(_ref3) {
|
|
|
184
187
|
});
|
|
185
188
|
return inlineContent;
|
|
186
189
|
};
|
|
187
|
-
var
|
|
188
|
-
|
|
190
|
+
var resultContent = [];
|
|
191
|
+
var currentListItems = [];
|
|
192
|
+
var targetListItemType = isTargetTaskList ? taskItem : listItem;
|
|
189
193
|
// Expand's title should become the first item of the list
|
|
190
194
|
if (sourceNode.type.name === 'expand') {
|
|
191
195
|
var _sourceNode$attrs2;
|
|
192
196
|
var title = (_sourceNode$attrs2 = sourceNode.attrs) === null || _sourceNode$attrs2 === void 0 ? void 0 : _sourceNode$attrs2.title;
|
|
193
197
|
if (title) {
|
|
194
198
|
var titleContent = schema.text(title);
|
|
195
|
-
|
|
199
|
+
currentListItems.push(createListItemFromInline(titleContent));
|
|
196
200
|
}
|
|
197
201
|
}
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
return tr;
|
|
202
|
+
var createListAndAddToContent = function createListAndAddToContent() {
|
|
203
|
+
if (currentListItems.length) {
|
|
204
|
+
var currentList = targetNodeType.create(targetAttrs || null, Fragment.from(currentListItems));
|
|
205
|
+
currentListItems = [];
|
|
206
|
+
resultContent.push(currentList);
|
|
204
207
|
}
|
|
205
|
-
|
|
206
|
-
|
|
208
|
+
};
|
|
209
|
+
if (sourceNode.type.name === 'codeBlock') {
|
|
210
|
+
var codeText = sourceNode.textContent;
|
|
211
|
+
if (codeText) {
|
|
212
|
+
var lines = codeText.split('\n');
|
|
213
|
+
// Remove empty lines
|
|
214
|
+
var nonEmptyLines = lines.filter(function (line) {
|
|
215
|
+
return line.trim().length > 0;
|
|
216
|
+
});
|
|
217
|
+
nonEmptyLines.forEach(function (line) {
|
|
218
|
+
var lineText = schema.text(line);
|
|
219
|
+
currentListItems.push(createListItemFromInline(lineText));
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
} else {
|
|
223
|
+
sourceNode.forEach(function (child) {
|
|
224
|
+
if (targetListItemType.validContent(Fragment.from(child))) {
|
|
225
|
+
currentListItems.push(targetListItemType.create(null, child));
|
|
226
|
+
} else if (heading === child.type || isTargetTaskList && paragraph === child.type) {
|
|
227
|
+
var inline = Fragment.from(getInlineContent(child));
|
|
228
|
+
currentListItems.push(createListItemFromInline(inline));
|
|
229
|
+
} else {
|
|
230
|
+
// Create list and add list first
|
|
231
|
+
createListAndAddToContent();
|
|
232
|
+
// Then add content that can't be converted into listItem
|
|
233
|
+
resultContent.push(child);
|
|
234
|
+
}
|
|
235
|
+
});
|
|
207
236
|
}
|
|
208
|
-
if (!
|
|
209
|
-
return
|
|
237
|
+
if (!resultContent.length && !currentListItems.length) {
|
|
238
|
+
return null;
|
|
239
|
+
}
|
|
240
|
+
createListAndAddToContent();
|
|
241
|
+
return tr.replaceWith(sourcePos, sourcePos + sourceNode.nodeSize, Fragment.from(resultContent));
|
|
242
|
+
};
|
|
243
|
+
export var transformBetweenContainerTypes = function transformBetweenContainerTypes(context) {
|
|
244
|
+
var tr = context.tr,
|
|
245
|
+
sourceNode = context.sourceNode,
|
|
246
|
+
sourcePos = context.sourcePos,
|
|
247
|
+
targetNodeType = context.targetNodeType,
|
|
248
|
+
targetAttrs = context.targetAttrs;
|
|
249
|
+
|
|
250
|
+
// Get content validation for target container type
|
|
251
|
+
var isContentSupported = getContentSupportChecker(targetNodeType);
|
|
252
|
+
|
|
253
|
+
// Process content and collect splits
|
|
254
|
+
var contentSplits = splitContentAroundUnsupportedBlocks(sourceNode, isContentSupported, targetNodeType, targetAttrs, tr.doc.type.schema);
|
|
255
|
+
|
|
256
|
+
// Replace the original node with the first split
|
|
257
|
+
var insertPos = sourcePos;
|
|
258
|
+
contentSplits.forEach(function (splitNode, index) {
|
|
259
|
+
if (index === 0) {
|
|
260
|
+
// Replace the original node with the first split
|
|
261
|
+
tr.replaceWith(sourcePos, sourcePos + sourceNode.nodeSize, splitNode);
|
|
262
|
+
insertPos = sourcePos + splitNode.nodeSize;
|
|
263
|
+
} else {
|
|
264
|
+
// Insert additional splits after
|
|
265
|
+
tr.insert(insertPos, splitNode);
|
|
266
|
+
insertPos += splitNode.nodeSize;
|
|
267
|
+
}
|
|
268
|
+
});
|
|
269
|
+
return tr;
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Split content around unsupported block nodes, creating separate containers
|
|
274
|
+
* for content before and after each unsupported block
|
|
275
|
+
*/
|
|
276
|
+
var splitContentAroundUnsupportedBlocks = function splitContentAroundUnsupportedBlocks(sourceNode, isContentSupported, targetNodeType, targetAttrs, schema) {
|
|
277
|
+
var _sourceNode$attrs3;
|
|
278
|
+
var splits = [];
|
|
279
|
+
var children = sourceNode.content.content;
|
|
280
|
+
var currentContainerContent = [];
|
|
281
|
+
|
|
282
|
+
// Handle expand title - add as first paragraph if source is expand with title
|
|
283
|
+
if (sourceNode.type.name === 'expand' && (_sourceNode$attrs3 = sourceNode.attrs) !== null && _sourceNode$attrs3 !== void 0 && _sourceNode$attrs3.title) {
|
|
284
|
+
var titleParagraph = schema.nodes.paragraph.create({}, schema.text(sourceNode.attrs.title));
|
|
285
|
+
currentContainerContent.push(titleParagraph);
|
|
210
286
|
}
|
|
211
|
-
var
|
|
212
|
-
|
|
287
|
+
var flushCurrentContainer = function flushCurrentContainer() {
|
|
288
|
+
if (currentContainerContent.length > 0) {
|
|
289
|
+
var containerNode = targetNodeType.create(targetAttrs, Fragment.fromArray(currentContainerContent));
|
|
290
|
+
splits.push(containerNode);
|
|
291
|
+
currentContainerContent = [];
|
|
292
|
+
}
|
|
293
|
+
};
|
|
294
|
+
children.forEach(function (childNode) {
|
|
295
|
+
if (isContentSupported(childNode)) {
|
|
296
|
+
// Supported content - add to current container
|
|
297
|
+
currentContainerContent.push(childNode);
|
|
298
|
+
} else if (isBlockNodeForExtraction(childNode)) {
|
|
299
|
+
// Unsupported block node - flush current container, add block, continue
|
|
300
|
+
flushCurrentContainer();
|
|
301
|
+
splits.push(childNode);
|
|
302
|
+
} else if (childNode.type.name === targetNodeType.name) {
|
|
303
|
+
// Same type of container merge contents
|
|
304
|
+
childNode.content.forEach(function (child) {
|
|
305
|
+
currentContainerContent.push(child);
|
|
306
|
+
});
|
|
307
|
+
} else {
|
|
308
|
+
// Unsupported inline content - convert to paragraph and add to container
|
|
309
|
+
var inlineContent = convertNodeToInlineContent(childNode, schema);
|
|
310
|
+
if (inlineContent.length > 0) {
|
|
311
|
+
var paragraph = schema.nodes.paragraph.create({}, Fragment.fromArray(inlineContent));
|
|
312
|
+
currentContainerContent.push(paragraph);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
// Flush any remaining container content
|
|
318
|
+
flushCurrentContainer();
|
|
319
|
+
return splits;
|
|
213
320
|
};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { transformBlockNode } from './block-transforms';
|
|
2
|
-
import { transformContainerNode } from './container-transforms';
|
|
2
|
+
import { transformContainerNode, unwrapAndConvertToList } from './container-transforms';
|
|
3
3
|
import { convertToLayout } from './layout-transforms';
|
|
4
4
|
import { transformListNode } from './list-transforms';
|
|
5
|
-
import { getTargetNodeInfo, isBlockNode, isListNode, isContainerNode, isLayoutNodeType } from './utils';
|
|
5
|
+
import { getTargetNodeInfo, isBlockNode, isListNode, isListNodeType, isContainerNode, isLayoutNodeType } from './utils';
|
|
6
6
|
export function transformNodeToTargetType(tr, sourceNode, sourcePos, targetType) {
|
|
7
7
|
var nodes = tr.doc.type.schema.nodes;
|
|
8
8
|
var targetNodeInfo = getTargetNodeInfo(targetType, nodes);
|
|
@@ -41,6 +41,11 @@ export function transformNodeToTargetType(tr, sourceNode, sourcePos, targetType)
|
|
|
41
41
|
if (isLayoutNodeType(targetNodeType)) {
|
|
42
42
|
return convertToLayout(transformationContext);
|
|
43
43
|
}
|
|
44
|
+
|
|
45
|
+
// special case codeblock to listType
|
|
46
|
+
if (sourceNode.type.name === 'codeBlock' && isListNodeType(targetNodeType)) {
|
|
47
|
+
return unwrapAndConvertToList(transformationContext);
|
|
48
|
+
}
|
|
44
49
|
if (isBlockNode(sourceNode)) {
|
|
45
50
|
return transformBlockNode(transformationContext);
|
|
46
51
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Fragment } from '@atlaskit/editor-prosemirror/model';
|
|
1
2
|
export var getTargetNodeInfo = function getTargetNodeInfo(targetType, nodes) {
|
|
2
3
|
switch (targetType) {
|
|
3
4
|
case 'heading1':
|
|
@@ -121,4 +122,50 @@ export var getSupportedListTypesSet = function getSupportedListTypesSet(nodes) {
|
|
|
121
122
|
};
|
|
122
123
|
export var isLayoutNodeType = function isLayoutNodeType(nodeType) {
|
|
123
124
|
return nodeType.name === 'layoutSection';
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Check if a node should be extracted as a standalone block node
|
|
129
|
+
* rather than converted to inline content
|
|
130
|
+
*/
|
|
131
|
+
export var isBlockNodeForExtraction = function isBlockNodeForExtraction(node) {
|
|
132
|
+
var blockNodesForExtraction = ['table', 'mediaSingle', 'extension', 'bodiedExtension', 'blockCard', 'embedCard'];
|
|
133
|
+
return blockNodesForExtraction.includes(node.type.name);
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Get a function that checks if content is supported in the target container type
|
|
138
|
+
*/
|
|
139
|
+
export var getContentSupportChecker = function getContentSupportChecker(targetNodeType) {
|
|
140
|
+
return function (node) {
|
|
141
|
+
// Check if the target container type can contain this node
|
|
142
|
+
try {
|
|
143
|
+
return targetNodeType.validContent(Fragment.from(node));
|
|
144
|
+
} catch (_unused) {
|
|
145
|
+
return false;
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Convert a node to inline content that can be placed in a paragraph
|
|
152
|
+
*/
|
|
153
|
+
export var convertNodeToInlineContent = function convertNodeToInlineContent(node, schema) {
|
|
154
|
+
// Extract text and inline nodes from any complex node
|
|
155
|
+
var inlineNodes = [];
|
|
156
|
+
node.descendants(function (childNode) {
|
|
157
|
+
if (childNode.isText) {
|
|
158
|
+
inlineNodes.push(childNode);
|
|
159
|
+
} else if (childNode.isInline) {
|
|
160
|
+
inlineNodes.push(childNode);
|
|
161
|
+
}
|
|
162
|
+
return true; // Continue traversing
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
// If no inline content was found but the node has text content,
|
|
166
|
+
// create a text node with the full text content
|
|
167
|
+
if (inlineNodes.length === 0 && node.textContent) {
|
|
168
|
+
return [schema.text(node.textContent)];
|
|
169
|
+
}
|
|
170
|
+
return inlineNodes;
|
|
124
171
|
};
|
|
@@ -14,4 +14,5 @@ export declare const unwrapAndConvertToBlockType: (context: TransformContext) =>
|
|
|
14
14
|
/**
|
|
15
15
|
* Unwrap container node and convert content to list
|
|
16
16
|
*/
|
|
17
|
-
export declare const unwrapAndConvertToList: ({ tr, sourceNode, sourcePos, targetNodeType, targetAttrs, }: TransformContext) => import("prosemirror-state").Transaction;
|
|
17
|
+
export declare const unwrapAndConvertToList: ({ tr, sourceNode, sourcePos, targetNodeType, targetAttrs, }: TransformContext) => import("prosemirror-state").Transaction | null;
|
|
18
|
+
export declare const transformBetweenContainerTypes: (context: TransformContext) => import("prosemirror-state").Transaction;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Node as PMNode, NodeType } from '@atlaskit/editor-prosemirror/model';
|
|
1
|
+
import type { Node as PMNode, NodeType, Schema } from '@atlaskit/editor-prosemirror/model';
|
|
2
2
|
import type { FormatNodeTargetType } from './types';
|
|
3
3
|
export declare const getTargetNodeInfo: (targetType: FormatNodeTargetType, nodes: Record<string, NodeType>) => {
|
|
4
4
|
attrs?: Record<string, unknown>;
|
|
@@ -15,3 +15,16 @@ export declare const isTaskList: (nodeType: NodeType) => boolean;
|
|
|
15
15
|
export declare const getSupportedListTypes: (nodes: Record<string, NodeType>) => NodeType[];
|
|
16
16
|
export declare const getSupportedListTypesSet: (nodes: Record<string, NodeType>) => Set<NodeType>;
|
|
17
17
|
export declare const isLayoutNodeType: (nodeType: NodeType) => boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Check if a node should be extracted as a standalone block node
|
|
20
|
+
* rather than converted to inline content
|
|
21
|
+
*/
|
|
22
|
+
export declare const isBlockNodeForExtraction: (node: PMNode) => boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Get a function that checks if content is supported in the target container type
|
|
25
|
+
*/
|
|
26
|
+
export declare const getContentSupportChecker: (targetNodeType: NodeType) => ((node: PMNode) => boolean);
|
|
27
|
+
/**
|
|
28
|
+
* Convert a node to inline content that can be placed in a paragraph
|
|
29
|
+
*/
|
|
30
|
+
export declare const convertNodeToInlineContent: (node: PMNode, schema: Schema) => PMNode[];
|
|
@@ -14,4 +14,5 @@ export declare const unwrapAndConvertToBlockType: (context: TransformContext) =>
|
|
|
14
14
|
/**
|
|
15
15
|
* Unwrap container node and convert content to list
|
|
16
16
|
*/
|
|
17
|
-
export declare const unwrapAndConvertToList: ({ tr, sourceNode, sourcePos, targetNodeType, targetAttrs, }: TransformContext) => import("prosemirror-state").Transaction;
|
|
17
|
+
export declare const unwrapAndConvertToList: ({ tr, sourceNode, sourcePos, targetNodeType, targetAttrs, }: TransformContext) => import("prosemirror-state").Transaction | null;
|
|
18
|
+
export declare const transformBetweenContainerTypes: (context: TransformContext) => import("prosemirror-state").Transaction;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Node as PMNode, NodeType } from '@atlaskit/editor-prosemirror/model';
|
|
1
|
+
import type { Node as PMNode, NodeType, Schema } from '@atlaskit/editor-prosemirror/model';
|
|
2
2
|
import type { FormatNodeTargetType } from './types';
|
|
3
3
|
export declare const getTargetNodeInfo: (targetType: FormatNodeTargetType, nodes: Record<string, NodeType>) => {
|
|
4
4
|
attrs?: Record<string, unknown>;
|
|
@@ -15,3 +15,16 @@ export declare const isTaskList: (nodeType: NodeType) => boolean;
|
|
|
15
15
|
export declare const getSupportedListTypes: (nodes: Record<string, NodeType>) => NodeType[];
|
|
16
16
|
export declare const getSupportedListTypesSet: (nodes: Record<string, NodeType>) => Set<NodeType>;
|
|
17
17
|
export declare const isLayoutNodeType: (nodeType: NodeType) => boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Check if a node should be extracted as a standalone block node
|
|
20
|
+
* rather than converted to inline content
|
|
21
|
+
*/
|
|
22
|
+
export declare const isBlockNodeForExtraction: (node: PMNode) => boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Get a function that checks if content is supported in the target container type
|
|
25
|
+
*/
|
|
26
|
+
export declare const getContentSupportChecker: (targetNodeType: NodeType) => ((node: PMNode) => boolean);
|
|
27
|
+
/**
|
|
28
|
+
* Convert a node to inline content that can be placed in a paragraph
|
|
29
|
+
*/
|
|
30
|
+
export declare const convertNodeToInlineContent: (node: PMNode, schema: Schema) => PMNode[];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-block-menu",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.8",
|
|
4
4
|
"description": "BlockMenu plugin for @atlaskit/editor-core",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"sideEffects": false,
|
|
29
29
|
"atlaskit:src": "src/index.ts",
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@atlaskit/css": "^0.
|
|
31
|
+
"@atlaskit/css": "^0.14.0",
|
|
32
32
|
"@atlaskit/dropdown-menu": "^16.3.0",
|
|
33
33
|
"@atlaskit/editor-plugin-block-controls": "^5.0.0",
|
|
34
34
|
"@atlaskit/editor-plugin-decorations": "^4.0.0",
|
|
@@ -41,8 +41,8 @@
|
|
|
41
41
|
"@atlaskit/icon": "^28.1.0",
|
|
42
42
|
"@atlaskit/icon-lab": "^5.7.0",
|
|
43
43
|
"@atlaskit/platform-feature-flags": "^1.1.0",
|
|
44
|
-
"@atlaskit/primitives": "^14.
|
|
45
|
-
"@atlaskit/tokens": "^6.
|
|
44
|
+
"@atlaskit/primitives": "^14.14.0",
|
|
45
|
+
"@atlaskit/tokens": "^6.3.0",
|
|
46
46
|
"@babel/runtime": "^7.0.0"
|
|
47
47
|
},
|
|
48
48
|
"peerDependencies": {
|