@atlaskit/editor-plugin-block-menu 1.0.7 → 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 +8 -0
- package/dist/cjs/editor-commands/transforms/container-transforms.js +86 -3
- package/dist/cjs/editor-commands/transforms/utils.js +48 -1
- package/dist/es2019/editor-commands/transforms/container-transforms.js +88 -3
- package/dist/es2019/editor-commands/transforms/utils.js +47 -0
- package/dist/esm/editor-commands/transforms/container-transforms.js +86 -3
- package/dist/esm/editor-commands/transforms/utils.js +47 -0
- package/dist/types/editor-commands/transforms/container-transforms.d.ts +1 -0
- package/dist/types/editor-commands/transforms/utils.d.ts +14 -1
- package/dist/types-ts4.5/editor-commands/transforms/container-transforms.d.ts +1 -0
- 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,13 @@
|
|
|
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
|
+
|
|
3
11
|
## 1.0.7
|
|
4
12
|
|
|
5
13
|
### 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
|
};
|
|
@@ -241,4 +246,82 @@ var unwrapAndConvertToList = exports.unwrapAndConvertToList = function unwrapAnd
|
|
|
241
246
|
}
|
|
242
247
|
createListAndAddToContent();
|
|
243
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);
|
|
293
|
+
}
|
|
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;
|
|
244
327
|
};
|
|
@@ -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
|
};
|
|
@@ -238,4 +243,84 @@ export const unwrapAndConvertToList = ({
|
|
|
238
243
|
}
|
|
239
244
|
createListAndAddToContent();
|
|
240
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);
|
|
292
|
+
}
|
|
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;
|
|
241
326
|
};
|
|
@@ -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
|
};
|
|
@@ -234,4 +239,82 @@ export var unwrapAndConvertToList = function unwrapAndConvertToList(_ref3) {
|
|
|
234
239
|
}
|
|
235
240
|
createListAndAddToContent();
|
|
236
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);
|
|
286
|
+
}
|
|
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;
|
|
237
320
|
};
|
|
@@ -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
|
};
|
|
@@ -15,3 +15,4 @@ export declare const unwrapAndConvertToBlockType: (context: TransformContext) =>
|
|
|
15
15
|
* Unwrap container node and convert content to list
|
|
16
16
|
*/
|
|
17
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[];
|
|
@@ -15,3 +15,4 @@ export declare const unwrapAndConvertToBlockType: (context: TransformContext) =>
|
|
|
15
15
|
* Unwrap container node and convert content to list
|
|
16
16
|
*/
|
|
17
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": {
|