@atlaskit/editor-plugin-block-menu 1.0.2 → 1.0.3
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/formatNode.js +1 -1
- package/dist/cjs/editor-commands/transforms/container-transforms.js +60 -4
- package/dist/cjs/editor-commands/transforms/list/transformBetweenListTypes.js +22 -26
- package/dist/cjs/editor-commands/transforms/list/transformToTaskList.js +44 -0
- package/dist/cjs/editor-commands/transforms/list-transforms.js +3 -3
- package/dist/es2019/editor-commands/formatNode.js +1 -1
- package/dist/es2019/editor-commands/transforms/container-transforms.js +64 -4
- package/dist/es2019/editor-commands/transforms/list/transformBetweenListTypes.js +24 -26
- package/dist/es2019/editor-commands/transforms/list/transformToTaskList.js +38 -0
- package/dist/es2019/editor-commands/transforms/list-transforms.js +3 -3
- package/dist/esm/editor-commands/formatNode.js +1 -1
- package/dist/esm/editor-commands/transforms/container-transforms.js +60 -4
- package/dist/esm/editor-commands/transforms/list/transformBetweenListTypes.js +22 -26
- package/dist/esm/editor-commands/transforms/list/transformToTaskList.js +37 -0
- package/dist/esm/editor-commands/transforms/list-transforms.js +3 -3
- package/dist/types/editor-commands/transforms/container-transforms.d.ts +1 -1
- package/dist/types/editor-commands/transforms/list/transformToTaskList.d.ts +10 -0
- package/dist/types-ts4.5/editor-commands/transforms/container-transforms.d.ts +1 -1
- package/dist/types-ts4.5/editor-commands/transforms/list/transformToTaskList.d.ts +10 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-block-menu
|
|
2
2
|
|
|
3
|
+
## 1.0.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`3db18eece6c2f`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/3db18eece6c2f) -
|
|
8
|
+
[ux] Adds basic conversion from expand, panel, blockquote to bulled, numbered or task list.
|
|
9
|
+
- Updated dependencies
|
|
10
|
+
|
|
3
11
|
## 1.0.2
|
|
4
12
|
|
|
5
13
|
### Patch Changes
|
|
@@ -40,7 +40,7 @@ var formatNode = exports.formatNode = function formatNode(targetType) {
|
|
|
40
40
|
nodeToFormat = listParent.node;
|
|
41
41
|
nodePos = listParent.pos;
|
|
42
42
|
}
|
|
43
|
-
} else if (paragraphOrHeadingNode) {
|
|
43
|
+
} else if (parentNode.node.type !== nodes.blockquote && paragraphOrHeadingNode) {
|
|
44
44
|
nodeToFormat = paragraphOrHeadingNode.node;
|
|
45
45
|
nodePos = paragraphOrHeadingNode.pos;
|
|
46
46
|
}
|
|
@@ -50,6 +50,7 @@ var transformToContainer = exports.transformToContainer = function transformToCo
|
|
|
50
50
|
*/
|
|
51
51
|
var transformContainerNode = exports.transformContainerNode = function transformContainerNode(_ref2) {
|
|
52
52
|
var tr = _ref2.tr,
|
|
53
|
+
sourceNode = _ref2.sourceNode,
|
|
53
54
|
sourcePos = _ref2.sourcePos,
|
|
54
55
|
targetNodeType = _ref2.targetNodeType,
|
|
55
56
|
targetAttrs = _ref2.targetAttrs;
|
|
@@ -64,7 +65,13 @@ var transformContainerNode = exports.transformContainerNode = function transform
|
|
|
64
65
|
|
|
65
66
|
// Transform container to list type
|
|
66
67
|
if ((0, _utils.isListNodeType)(targetNodeType)) {
|
|
67
|
-
return unwrapAndConvertToList(
|
|
68
|
+
return unwrapAndConvertToList({
|
|
69
|
+
tr: tr,
|
|
70
|
+
sourceNode: sourceNode,
|
|
71
|
+
sourcePos: sourcePos,
|
|
72
|
+
targetNodeType: targetNodeType,
|
|
73
|
+
targetAttrs: targetAttrs
|
|
74
|
+
});
|
|
68
75
|
}
|
|
69
76
|
|
|
70
77
|
// Transform between container types
|
|
@@ -86,7 +93,56 @@ var unwrapAndConvertToBlockType = exports.unwrapAndConvertToBlockType = function
|
|
|
86
93
|
/**
|
|
87
94
|
* Unwrap container node and convert content to list
|
|
88
95
|
*/
|
|
89
|
-
var unwrapAndConvertToList = exports.unwrapAndConvertToList = function unwrapAndConvertToList() {
|
|
90
|
-
|
|
91
|
-
|
|
96
|
+
var unwrapAndConvertToList = exports.unwrapAndConvertToList = function unwrapAndConvertToList(_ref3) {
|
|
97
|
+
var tr = _ref3.tr,
|
|
98
|
+
sourceNode = _ref3.sourceNode,
|
|
99
|
+
sourcePos = _ref3.sourcePos,
|
|
100
|
+
targetNodeType = _ref3.targetNodeType,
|
|
101
|
+
targetAttrs = _ref3.targetAttrs;
|
|
102
|
+
if (sourcePos === null) {
|
|
103
|
+
return tr;
|
|
104
|
+
}
|
|
105
|
+
var schema = tr.doc.type.schema;
|
|
106
|
+
var _schema$nodes = schema.nodes,
|
|
107
|
+
listItem = _schema$nodes.listItem,
|
|
108
|
+
paragraph = _schema$nodes.paragraph,
|
|
109
|
+
taskList = _schema$nodes.taskList,
|
|
110
|
+
taskItem = _schema$nodes.taskItem;
|
|
111
|
+
var isTargetTaskList = targetNodeType === taskList;
|
|
112
|
+
var createListItemFromInline = function createListItemFromInline(inlineFrag) {
|
|
113
|
+
return isTargetTaskList ? taskItem.create(null, inlineFrag) : listItem.create(null, paragraph.create(null, inlineFrag));
|
|
114
|
+
};
|
|
115
|
+
var getInlineContent = function getInlineContent(textblock) {
|
|
116
|
+
var inlineContent = [];
|
|
117
|
+
textblock.forEach(function (inline) {
|
|
118
|
+
inlineContent.push(inline);
|
|
119
|
+
});
|
|
120
|
+
return inlineContent;
|
|
121
|
+
};
|
|
122
|
+
var items = [];
|
|
123
|
+
|
|
124
|
+
// Expand's title should become the first item of the list
|
|
125
|
+
if (sourceNode.type.name === 'expand') {
|
|
126
|
+
var _sourceNode$attrs;
|
|
127
|
+
var title = (_sourceNode$attrs = sourceNode.attrs) === null || _sourceNode$attrs === void 0 ? void 0 : _sourceNode$attrs.title;
|
|
128
|
+
if (title) {
|
|
129
|
+
var titleContent = schema.text(title);
|
|
130
|
+
items.push(isTargetTaskList ? taskItem.create(null, titleContent) : listItem.create(null, paragraph.create(null, titleContent)));
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
for (var i = 0; i < sourceNode.childCount; i++) {
|
|
134
|
+
var node = sourceNode.child(i);
|
|
135
|
+
|
|
136
|
+
// Abort early if unsupported content (e.g. table) encounted inside of the container
|
|
137
|
+
if (!node.isTextblock) {
|
|
138
|
+
return tr;
|
|
139
|
+
}
|
|
140
|
+
var inline = _model.Fragment.from(getInlineContent(node));
|
|
141
|
+
items.push(createListItemFromInline(inline));
|
|
142
|
+
}
|
|
143
|
+
if (!items.length) {
|
|
144
|
+
return tr;
|
|
145
|
+
}
|
|
146
|
+
var list = targetNodeType.create(targetAttrs || null, _model.Fragment.from(items));
|
|
147
|
+
return tr.replaceWith(sourcePos, sourcePos + sourceNode.nodeSize, list);
|
|
92
148
|
};
|
|
@@ -7,14 +7,25 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
7
7
|
exports.transformListStructure = void 0;
|
|
8
8
|
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
|
|
9
9
|
/**
|
|
10
|
-
*
|
|
10
|
+
* Convert a block node to inline content suitable for task items
|
|
11
11
|
*/
|
|
12
|
-
var
|
|
13
|
-
var
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
var convertBlockToInlineContent = function convertBlockToInlineContent(node, schema) {
|
|
13
|
+
var paragraph = schema.nodes.paragraph;
|
|
14
|
+
if (node.type === paragraph) {
|
|
15
|
+
// Extract inline content from paragraphs
|
|
16
|
+
return (0, _toConsumableArray2.default)(node.content.content);
|
|
17
|
+
} else if (node.isBlock) {
|
|
18
|
+
// For other block content types eg. codeBlock, extract their text content and create text nodes
|
|
19
|
+
var textContent = node.textContent;
|
|
20
|
+
if (textContent) {
|
|
21
|
+
var textNode = schema.text(textContent);
|
|
22
|
+
return [textNode];
|
|
23
|
+
}
|
|
24
|
+
} else {
|
|
25
|
+
// Already inline content, add directly
|
|
26
|
+
return [node];
|
|
16
27
|
}
|
|
17
|
-
return
|
|
28
|
+
return [];
|
|
18
29
|
};
|
|
19
30
|
|
|
20
31
|
/**
|
|
@@ -48,25 +59,10 @@ var transformListStructure = exports.transformListStructure = function transform
|
|
|
48
59
|
// Extract inline content from all children within listItem
|
|
49
60
|
if (node.type === listItem) {
|
|
50
61
|
var inlineContent = [];
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
if (child.type === paragraph) {
|
|
56
|
-
// Extract inline content from paragraphs
|
|
57
|
-
inlineContent.push.apply(inlineContent, (0, _toConsumableArray2.default)(extractInlineContent(child)));
|
|
58
|
-
} else if (child.isBlock) {
|
|
59
|
-
// For other block content types eg. codeBlock, extract their text content and create text nodes
|
|
60
|
-
var textContent = child.textContent;
|
|
61
|
-
if (textContent) {
|
|
62
|
-
var textNode = tr.doc.type.schema.text(textContent);
|
|
63
|
-
inlineContent.push(textNode);
|
|
64
|
-
}
|
|
65
|
-
} else {
|
|
66
|
-
// Already inline content, add directly
|
|
67
|
-
inlineContent.push(child);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
62
|
+
// Extract inline content from all child nodes
|
|
63
|
+
node.forEach(function (child) {
|
|
64
|
+
inlineContent.push.apply(inlineContent, (0, _toConsumableArray2.default)(convertBlockToInlineContent(child, tr.doc.type.schema)));
|
|
65
|
+
});
|
|
70
66
|
if (inlineContent.length > 0) {
|
|
71
67
|
var newItem = taskItem.create(null, inlineContent);
|
|
72
68
|
newListItems.push(newItem);
|
|
@@ -76,7 +72,7 @@ var transformListStructure = exports.transformListStructure = function transform
|
|
|
76
72
|
// Converting from task list to bullet/ordered list
|
|
77
73
|
// Structure: taskItem > inline content -> listItem > paragraph > inline content
|
|
78
74
|
if (node.type === taskItem) {
|
|
79
|
-
var _inlineContent =
|
|
75
|
+
var _inlineContent = (0, _toConsumableArray2.default)(node.content.content);
|
|
80
76
|
if (_inlineContent.length > 0) {
|
|
81
77
|
var paragraphNode = paragraph.create(null, _inlineContent);
|
|
82
78
|
var newListItem = listItem.create(null, paragraphNode);
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.transformToTaskList = void 0;
|
|
8
|
+
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
|
|
9
|
+
/**
|
|
10
|
+
* Transform selection to task list
|
|
11
|
+
* Handles the special structure where taskItem contains text directly (no paragraph wrapper)
|
|
12
|
+
*/
|
|
13
|
+
var transformToTaskList = exports.transformToTaskList = function transformToTaskList(tr, range, targetNodeType, targetAttrs, nodes) {
|
|
14
|
+
try {
|
|
15
|
+
var taskItem = nodes.taskItem;
|
|
16
|
+
var listItems = [];
|
|
17
|
+
|
|
18
|
+
// Process each block in the range
|
|
19
|
+
tr.doc.nodesBetween(range.start, range.end, function (node) {
|
|
20
|
+
if (node.isBlock) {
|
|
21
|
+
// For block nodes like paragraphs, directly use their inline content
|
|
22
|
+
var inlineContent = (0, _toConsumableArray2.default)(node.content.content);
|
|
23
|
+
if (inlineContent.length > 0) {
|
|
24
|
+
// Create task item with inline content directly
|
|
25
|
+
var listItem = taskItem.create(targetAttrs, inlineContent);
|
|
26
|
+
listItems.push(listItem);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return false; // Don't traverse into children
|
|
30
|
+
});
|
|
31
|
+
if (listItems.length === 0) {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Create the new task list
|
|
36
|
+
var newList = targetNodeType.create(targetAttrs, listItems);
|
|
37
|
+
|
|
38
|
+
// Replace the range with the new list
|
|
39
|
+
tr.replaceWith(range.start, range.end, newList);
|
|
40
|
+
return tr;
|
|
41
|
+
} catch (_unused) {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
};
|
|
@@ -9,12 +9,14 @@ var _utils = require("@atlaskit/editor-prosemirror/utils");
|
|
|
9
9
|
var _transformBetweenListTypes = require("./list/transformBetweenListTypes");
|
|
10
10
|
var _transformOrderedUnorderedListToBlockNodes = require("./list/transformOrderedUnorderedListToBlockNodes");
|
|
11
11
|
var _transformTaskListToBlockNodes = require("./list/transformTaskListToBlockNodes");
|
|
12
|
+
var _transformToTaskList = require("./list/transformToTaskList");
|
|
12
13
|
var _utils2 = require("./utils");
|
|
13
14
|
/**
|
|
14
15
|
* Transform selection to list type
|
|
15
16
|
*/
|
|
16
17
|
var transformBlockToList = exports.transformBlockToList = function transformBlockToList(context) {
|
|
17
18
|
var tr = context.tr,
|
|
19
|
+
sourceNode = context.sourceNode,
|
|
18
20
|
targetNodeType = context.targetNodeType,
|
|
19
21
|
targetAttrs = context.targetAttrs;
|
|
20
22
|
var _tr$selection = tr.selection,
|
|
@@ -28,13 +30,11 @@ var transformBlockToList = exports.transformBlockToList = function transformBloc
|
|
|
28
30
|
var isTargetTask = targetNodeType === nodes.taskList;
|
|
29
31
|
|
|
30
32
|
// Handle task lists differently due to their structure
|
|
31
|
-
// TODO: ED-29152 - Implement task list transformation
|
|
32
33
|
if (isTargetTask) {
|
|
33
|
-
return
|
|
34
|
+
return (0, _transformToTaskList.transformToTaskList)(tr, range, targetNodeType, targetAttrs, nodes);
|
|
34
35
|
}
|
|
35
36
|
|
|
36
37
|
// For headings, convert to paragraph first since headings cannot be direct children of list items
|
|
37
|
-
var sourceNode = tr.doc.nodeAt(range.start);
|
|
38
38
|
if (sourceNode && sourceNode.type.name.startsWith('heading')) {
|
|
39
39
|
tr.setBlockType(range.start, range.end, nodes.paragraph);
|
|
40
40
|
}
|
|
@@ -39,7 +39,7 @@ export const formatNode = targetType => {
|
|
|
39
39
|
nodeToFormat = listParent.node;
|
|
40
40
|
nodePos = listParent.pos;
|
|
41
41
|
}
|
|
42
|
-
} else if (paragraphOrHeadingNode) {
|
|
42
|
+
} else if (parentNode.node.type !== nodes.blockquote && paragraphOrHeadingNode) {
|
|
43
43
|
nodeToFormat = paragraphOrHeadingNode.node;
|
|
44
44
|
nodePos = paragraphOrHeadingNode.pos;
|
|
45
45
|
}
|
|
@@ -45,6 +45,7 @@ export const transformToContainer = ({
|
|
|
45
45
|
*/
|
|
46
46
|
export const transformContainerNode = ({
|
|
47
47
|
tr,
|
|
48
|
+
sourceNode,
|
|
48
49
|
sourcePos,
|
|
49
50
|
targetNodeType,
|
|
50
51
|
targetAttrs
|
|
@@ -60,7 +61,13 @@ export const transformContainerNode = ({
|
|
|
60
61
|
|
|
61
62
|
// Transform container to list type
|
|
62
63
|
if (isListNodeType(targetNodeType)) {
|
|
63
|
-
return unwrapAndConvertToList(
|
|
64
|
+
return unwrapAndConvertToList({
|
|
65
|
+
tr,
|
|
66
|
+
sourceNode,
|
|
67
|
+
sourcePos,
|
|
68
|
+
targetNodeType,
|
|
69
|
+
targetAttrs
|
|
70
|
+
});
|
|
64
71
|
}
|
|
65
72
|
|
|
66
73
|
// Transform between container types
|
|
@@ -82,7 +89,60 @@ export const unwrapAndConvertToBlockType = () => {
|
|
|
82
89
|
/**
|
|
83
90
|
* Unwrap container node and convert content to list
|
|
84
91
|
*/
|
|
85
|
-
export const unwrapAndConvertToList = (
|
|
86
|
-
|
|
87
|
-
|
|
92
|
+
export const unwrapAndConvertToList = ({
|
|
93
|
+
tr,
|
|
94
|
+
sourceNode,
|
|
95
|
+
sourcePos,
|
|
96
|
+
targetNodeType,
|
|
97
|
+
targetAttrs
|
|
98
|
+
}) => {
|
|
99
|
+
if (sourcePos === null) {
|
|
100
|
+
return tr;
|
|
101
|
+
}
|
|
102
|
+
const {
|
|
103
|
+
schema
|
|
104
|
+
} = tr.doc.type;
|
|
105
|
+
const {
|
|
106
|
+
listItem,
|
|
107
|
+
paragraph,
|
|
108
|
+
taskList,
|
|
109
|
+
taskItem
|
|
110
|
+
} = schema.nodes;
|
|
111
|
+
const isTargetTaskList = targetNodeType === taskList;
|
|
112
|
+
const createListItemFromInline = inlineFrag => {
|
|
113
|
+
return isTargetTaskList ? taskItem.create(null, inlineFrag) : listItem.create(null, paragraph.create(null, inlineFrag));
|
|
114
|
+
};
|
|
115
|
+
const getInlineContent = textblock => {
|
|
116
|
+
const inlineContent = [];
|
|
117
|
+
textblock.forEach(inline => {
|
|
118
|
+
inlineContent.push(inline);
|
|
119
|
+
});
|
|
120
|
+
return inlineContent;
|
|
121
|
+
};
|
|
122
|
+
const items = [];
|
|
123
|
+
|
|
124
|
+
// Expand's title should become the first item of the list
|
|
125
|
+
if (sourceNode.type.name === 'expand') {
|
|
126
|
+
var _sourceNode$attrs;
|
|
127
|
+
const title = (_sourceNode$attrs = sourceNode.attrs) === null || _sourceNode$attrs === void 0 ? void 0 : _sourceNode$attrs.title;
|
|
128
|
+
if (title) {
|
|
129
|
+
const titleContent = schema.text(title);
|
|
130
|
+
items.push(isTargetTaskList ? taskItem.create(null, titleContent) : listItem.create(null, paragraph.create(null, titleContent)));
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
for (let i = 0; i < sourceNode.childCount; i++) {
|
|
134
|
+
const node = sourceNode.child(i);
|
|
135
|
+
|
|
136
|
+
// Abort early if unsupported content (e.g. table) encounted inside of the container
|
|
137
|
+
if (!node.isTextblock) {
|
|
138
|
+
return tr;
|
|
139
|
+
}
|
|
140
|
+
const inline = Fragment.from(getInlineContent(node));
|
|
141
|
+
items.push(createListItemFromInline(inline));
|
|
142
|
+
}
|
|
143
|
+
if (!items.length) {
|
|
144
|
+
return tr;
|
|
145
|
+
}
|
|
146
|
+
const list = targetNodeType.create(targetAttrs || null, Fragment.from(items));
|
|
147
|
+
return tr.replaceWith(sourcePos, sourcePos + sourceNode.nodeSize, list);
|
|
88
148
|
};
|
|
@@ -1,12 +1,25 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Convert a block node to inline content suitable for task items
|
|
3
3
|
*/
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
const convertBlockToInlineContent = (node, schema) => {
|
|
5
|
+
const {
|
|
6
|
+
paragraph
|
|
7
|
+
} = schema.nodes;
|
|
8
|
+
if (node.type === paragraph) {
|
|
9
|
+
// Extract inline content from paragraphs
|
|
10
|
+
return [...node.content.content];
|
|
11
|
+
} else if (node.isBlock) {
|
|
12
|
+
// For other block content types eg. codeBlock, extract their text content and create text nodes
|
|
13
|
+
const textContent = node.textContent;
|
|
14
|
+
if (textContent) {
|
|
15
|
+
const textNode = schema.text(textContent);
|
|
16
|
+
return [textNode];
|
|
17
|
+
}
|
|
18
|
+
} else {
|
|
19
|
+
// Already inline content, add directly
|
|
20
|
+
return [node];
|
|
8
21
|
}
|
|
9
|
-
return
|
|
22
|
+
return [];
|
|
10
23
|
};
|
|
11
24
|
|
|
12
25
|
/**
|
|
@@ -44,25 +57,10 @@ export const transformListStructure = (tr, listNode, targetNodeType, nodes) => {
|
|
|
44
57
|
// Extract inline content from all children within listItem
|
|
45
58
|
if (node.type === listItem) {
|
|
46
59
|
const inlineContent = [];
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
if (child.type === paragraph) {
|
|
52
|
-
// Extract inline content from paragraphs
|
|
53
|
-
inlineContent.push(...extractInlineContent(child));
|
|
54
|
-
} else if (child.isBlock) {
|
|
55
|
-
// For other block content types eg. codeBlock, extract their text content and create text nodes
|
|
56
|
-
const textContent = child.textContent;
|
|
57
|
-
if (textContent) {
|
|
58
|
-
const textNode = tr.doc.type.schema.text(textContent);
|
|
59
|
-
inlineContent.push(textNode);
|
|
60
|
-
}
|
|
61
|
-
} else {
|
|
62
|
-
// Already inline content, add directly
|
|
63
|
-
inlineContent.push(child);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
60
|
+
// Extract inline content from all child nodes
|
|
61
|
+
node.forEach(child => {
|
|
62
|
+
inlineContent.push(...convertBlockToInlineContent(child, tr.doc.type.schema));
|
|
63
|
+
});
|
|
66
64
|
if (inlineContent.length > 0) {
|
|
67
65
|
const newItem = taskItem.create(null, inlineContent);
|
|
68
66
|
newListItems.push(newItem);
|
|
@@ -72,7 +70,7 @@ export const transformListStructure = (tr, listNode, targetNodeType, nodes) => {
|
|
|
72
70
|
// Converting from task list to bullet/ordered list
|
|
73
71
|
// Structure: taskItem > inline content -> listItem > paragraph > inline content
|
|
74
72
|
if (node.type === taskItem) {
|
|
75
|
-
const inlineContent =
|
|
73
|
+
const inlineContent = [...node.content.content];
|
|
76
74
|
if (inlineContent.length > 0) {
|
|
77
75
|
const paragraphNode = paragraph.create(null, inlineContent);
|
|
78
76
|
const newListItem = listItem.create(null, paragraphNode);
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transform selection to task list
|
|
3
|
+
* Handles the special structure where taskItem contains text directly (no paragraph wrapper)
|
|
4
|
+
*/
|
|
5
|
+
export const transformToTaskList = (tr, range, targetNodeType, targetAttrs, nodes) => {
|
|
6
|
+
try {
|
|
7
|
+
const {
|
|
8
|
+
taskItem
|
|
9
|
+
} = nodes;
|
|
10
|
+
const listItems = [];
|
|
11
|
+
|
|
12
|
+
// Process each block in the range
|
|
13
|
+
tr.doc.nodesBetween(range.start, range.end, node => {
|
|
14
|
+
if (node.isBlock) {
|
|
15
|
+
// For block nodes like paragraphs, directly use their inline content
|
|
16
|
+
const inlineContent = [...node.content.content];
|
|
17
|
+
if (inlineContent.length > 0) {
|
|
18
|
+
// Create task item with inline content directly
|
|
19
|
+
const listItem = taskItem.create(targetAttrs, inlineContent);
|
|
20
|
+
listItems.push(listItem);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return false; // Don't traverse into children
|
|
24
|
+
});
|
|
25
|
+
if (listItems.length === 0) {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Create the new task list
|
|
30
|
+
const newList = targetNodeType.create(targetAttrs, listItems);
|
|
31
|
+
|
|
32
|
+
// Replace the range with the new list
|
|
33
|
+
tr.replaceWith(range.start, range.end, newList);
|
|
34
|
+
return tr;
|
|
35
|
+
} catch {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
};
|
|
@@ -3,6 +3,7 @@ import { findParentNodeOfType } from '@atlaskit/editor-prosemirror/utils';
|
|
|
3
3
|
import { transformListStructure } from './list/transformBetweenListTypes';
|
|
4
4
|
import { transformOrderedUnorderedListToBlockNodes } from './list/transformOrderedUnorderedListToBlockNodes';
|
|
5
5
|
import { transformTaskListToBlockNodes } from './list/transformTaskListToBlockNodes';
|
|
6
|
+
import { transformToTaskList } from './list/transformToTaskList';
|
|
6
7
|
import { isBlockNodeType, isContainerNodeType, isListNodeType } from './utils';
|
|
7
8
|
|
|
8
9
|
/**
|
|
@@ -11,6 +12,7 @@ import { isBlockNodeType, isContainerNodeType, isListNodeType } from './utils';
|
|
|
11
12
|
export const transformBlockToList = context => {
|
|
12
13
|
const {
|
|
13
14
|
tr,
|
|
15
|
+
sourceNode,
|
|
14
16
|
targetNodeType,
|
|
15
17
|
targetAttrs
|
|
16
18
|
} = context;
|
|
@@ -28,13 +30,11 @@ export const transformBlockToList = context => {
|
|
|
28
30
|
const isTargetTask = targetNodeType === nodes.taskList;
|
|
29
31
|
|
|
30
32
|
// Handle task lists differently due to their structure
|
|
31
|
-
// TODO: ED-29152 - Implement task list transformation
|
|
32
33
|
if (isTargetTask) {
|
|
33
|
-
return
|
|
34
|
+
return transformToTaskList(tr, range, targetNodeType, targetAttrs, nodes);
|
|
34
35
|
}
|
|
35
36
|
|
|
36
37
|
// For headings, convert to paragraph first since headings cannot be direct children of list items
|
|
37
|
-
const sourceNode = tr.doc.nodeAt(range.start);
|
|
38
38
|
if (sourceNode && sourceNode.type.name.startsWith('heading')) {
|
|
39
39
|
tr.setBlockType(range.start, range.end, nodes.paragraph);
|
|
40
40
|
}
|
|
@@ -34,7 +34,7 @@ export var formatNode = function formatNode(targetType) {
|
|
|
34
34
|
nodeToFormat = listParent.node;
|
|
35
35
|
nodePos = listParent.pos;
|
|
36
36
|
}
|
|
37
|
-
} else if (paragraphOrHeadingNode) {
|
|
37
|
+
} else if (parentNode.node.type !== nodes.blockquote && paragraphOrHeadingNode) {
|
|
38
38
|
nodeToFormat = paragraphOrHeadingNode.node;
|
|
39
39
|
nodePos = paragraphOrHeadingNode.pos;
|
|
40
40
|
}
|
|
@@ -44,6 +44,7 @@ export var transformToContainer = function transformToContainer(_ref) {
|
|
|
44
44
|
*/
|
|
45
45
|
export var transformContainerNode = function transformContainerNode(_ref2) {
|
|
46
46
|
var tr = _ref2.tr,
|
|
47
|
+
sourceNode = _ref2.sourceNode,
|
|
47
48
|
sourcePos = _ref2.sourcePos,
|
|
48
49
|
targetNodeType = _ref2.targetNodeType,
|
|
49
50
|
targetAttrs = _ref2.targetAttrs;
|
|
@@ -58,7 +59,13 @@ export var transformContainerNode = function transformContainerNode(_ref2) {
|
|
|
58
59
|
|
|
59
60
|
// Transform container to list type
|
|
60
61
|
if (isListNodeType(targetNodeType)) {
|
|
61
|
-
return unwrapAndConvertToList(
|
|
62
|
+
return unwrapAndConvertToList({
|
|
63
|
+
tr: tr,
|
|
64
|
+
sourceNode: sourceNode,
|
|
65
|
+
sourcePos: sourcePos,
|
|
66
|
+
targetNodeType: targetNodeType,
|
|
67
|
+
targetAttrs: targetAttrs
|
|
68
|
+
});
|
|
62
69
|
}
|
|
63
70
|
|
|
64
71
|
// Transform between container types
|
|
@@ -80,7 +87,56 @@ export var unwrapAndConvertToBlockType = function unwrapAndConvertToBlockType()
|
|
|
80
87
|
/**
|
|
81
88
|
* Unwrap container node and convert content to list
|
|
82
89
|
*/
|
|
83
|
-
export var unwrapAndConvertToList = function unwrapAndConvertToList() {
|
|
84
|
-
|
|
85
|
-
|
|
90
|
+
export var unwrapAndConvertToList = function unwrapAndConvertToList(_ref3) {
|
|
91
|
+
var tr = _ref3.tr,
|
|
92
|
+
sourceNode = _ref3.sourceNode,
|
|
93
|
+
sourcePos = _ref3.sourcePos,
|
|
94
|
+
targetNodeType = _ref3.targetNodeType,
|
|
95
|
+
targetAttrs = _ref3.targetAttrs;
|
|
96
|
+
if (sourcePos === null) {
|
|
97
|
+
return tr;
|
|
98
|
+
}
|
|
99
|
+
var schema = tr.doc.type.schema;
|
|
100
|
+
var _schema$nodes = schema.nodes,
|
|
101
|
+
listItem = _schema$nodes.listItem,
|
|
102
|
+
paragraph = _schema$nodes.paragraph,
|
|
103
|
+
taskList = _schema$nodes.taskList,
|
|
104
|
+
taskItem = _schema$nodes.taskItem;
|
|
105
|
+
var isTargetTaskList = targetNodeType === taskList;
|
|
106
|
+
var createListItemFromInline = function createListItemFromInline(inlineFrag) {
|
|
107
|
+
return isTargetTaskList ? taskItem.create(null, inlineFrag) : listItem.create(null, paragraph.create(null, inlineFrag));
|
|
108
|
+
};
|
|
109
|
+
var getInlineContent = function getInlineContent(textblock) {
|
|
110
|
+
var inlineContent = [];
|
|
111
|
+
textblock.forEach(function (inline) {
|
|
112
|
+
inlineContent.push(inline);
|
|
113
|
+
});
|
|
114
|
+
return inlineContent;
|
|
115
|
+
};
|
|
116
|
+
var items = [];
|
|
117
|
+
|
|
118
|
+
// Expand's title should become the first item of the list
|
|
119
|
+
if (sourceNode.type.name === 'expand') {
|
|
120
|
+
var _sourceNode$attrs;
|
|
121
|
+
var title = (_sourceNode$attrs = sourceNode.attrs) === null || _sourceNode$attrs === void 0 ? void 0 : _sourceNode$attrs.title;
|
|
122
|
+
if (title) {
|
|
123
|
+
var titleContent = schema.text(title);
|
|
124
|
+
items.push(isTargetTaskList ? taskItem.create(null, titleContent) : listItem.create(null, paragraph.create(null, titleContent)));
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
for (var i = 0; i < sourceNode.childCount; i++) {
|
|
128
|
+
var node = sourceNode.child(i);
|
|
129
|
+
|
|
130
|
+
// Abort early if unsupported content (e.g. table) encounted inside of the container
|
|
131
|
+
if (!node.isTextblock) {
|
|
132
|
+
return tr;
|
|
133
|
+
}
|
|
134
|
+
var inline = Fragment.from(getInlineContent(node));
|
|
135
|
+
items.push(createListItemFromInline(inline));
|
|
136
|
+
}
|
|
137
|
+
if (!items.length) {
|
|
138
|
+
return tr;
|
|
139
|
+
}
|
|
140
|
+
var list = targetNodeType.create(targetAttrs || null, Fragment.from(items));
|
|
141
|
+
return tr.replaceWith(sourcePos, sourcePos + sourceNode.nodeSize, list);
|
|
86
142
|
};
|
|
@@ -1,13 +1,24 @@
|
|
|
1
1
|
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* Convert a block node to inline content suitable for task items
|
|
4
4
|
*/
|
|
5
|
-
var
|
|
6
|
-
var
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
var convertBlockToInlineContent = function convertBlockToInlineContent(node, schema) {
|
|
6
|
+
var paragraph = schema.nodes.paragraph;
|
|
7
|
+
if (node.type === paragraph) {
|
|
8
|
+
// Extract inline content from paragraphs
|
|
9
|
+
return _toConsumableArray(node.content.content);
|
|
10
|
+
} else if (node.isBlock) {
|
|
11
|
+
// For other block content types eg. codeBlock, extract their text content and create text nodes
|
|
12
|
+
var textContent = node.textContent;
|
|
13
|
+
if (textContent) {
|
|
14
|
+
var textNode = schema.text(textContent);
|
|
15
|
+
return [textNode];
|
|
16
|
+
}
|
|
17
|
+
} else {
|
|
18
|
+
// Already inline content, add directly
|
|
19
|
+
return [node];
|
|
9
20
|
}
|
|
10
|
-
return
|
|
21
|
+
return [];
|
|
11
22
|
};
|
|
12
23
|
|
|
13
24
|
/**
|
|
@@ -41,25 +52,10 @@ export var transformListStructure = function transformListStructure(tr, listNode
|
|
|
41
52
|
// Extract inline content from all children within listItem
|
|
42
53
|
if (node.type === listItem) {
|
|
43
54
|
var inlineContent = [];
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
if (child.type === paragraph) {
|
|
49
|
-
// Extract inline content from paragraphs
|
|
50
|
-
inlineContent.push.apply(inlineContent, _toConsumableArray(extractInlineContent(child)));
|
|
51
|
-
} else if (child.isBlock) {
|
|
52
|
-
// For other block content types eg. codeBlock, extract their text content and create text nodes
|
|
53
|
-
var textContent = child.textContent;
|
|
54
|
-
if (textContent) {
|
|
55
|
-
var textNode = tr.doc.type.schema.text(textContent);
|
|
56
|
-
inlineContent.push(textNode);
|
|
57
|
-
}
|
|
58
|
-
} else {
|
|
59
|
-
// Already inline content, add directly
|
|
60
|
-
inlineContent.push(child);
|
|
61
|
-
}
|
|
62
|
-
}
|
|
55
|
+
// Extract inline content from all child nodes
|
|
56
|
+
node.forEach(function (child) {
|
|
57
|
+
inlineContent.push.apply(inlineContent, _toConsumableArray(convertBlockToInlineContent(child, tr.doc.type.schema)));
|
|
58
|
+
});
|
|
63
59
|
if (inlineContent.length > 0) {
|
|
64
60
|
var newItem = taskItem.create(null, inlineContent);
|
|
65
61
|
newListItems.push(newItem);
|
|
@@ -69,7 +65,7 @@ export var transformListStructure = function transformListStructure(tr, listNode
|
|
|
69
65
|
// Converting from task list to bullet/ordered list
|
|
70
66
|
// Structure: taskItem > inline content -> listItem > paragraph > inline content
|
|
71
67
|
if (node.type === taskItem) {
|
|
72
|
-
var _inlineContent =
|
|
68
|
+
var _inlineContent = _toConsumableArray(node.content.content);
|
|
73
69
|
if (_inlineContent.length > 0) {
|
|
74
70
|
var paragraphNode = paragraph.create(null, _inlineContent);
|
|
75
71
|
var newListItem = listItem.create(null, paragraphNode);
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
|
|
2
|
+
/**
|
|
3
|
+
* Transform selection to task list
|
|
4
|
+
* Handles the special structure where taskItem contains text directly (no paragraph wrapper)
|
|
5
|
+
*/
|
|
6
|
+
export var transformToTaskList = function transformToTaskList(tr, range, targetNodeType, targetAttrs, nodes) {
|
|
7
|
+
try {
|
|
8
|
+
var taskItem = nodes.taskItem;
|
|
9
|
+
var listItems = [];
|
|
10
|
+
|
|
11
|
+
// Process each block in the range
|
|
12
|
+
tr.doc.nodesBetween(range.start, range.end, function (node) {
|
|
13
|
+
if (node.isBlock) {
|
|
14
|
+
// For block nodes like paragraphs, directly use their inline content
|
|
15
|
+
var inlineContent = _toConsumableArray(node.content.content);
|
|
16
|
+
if (inlineContent.length > 0) {
|
|
17
|
+
// Create task item with inline content directly
|
|
18
|
+
var listItem = taskItem.create(targetAttrs, inlineContent);
|
|
19
|
+
listItems.push(listItem);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return false; // Don't traverse into children
|
|
23
|
+
});
|
|
24
|
+
if (listItems.length === 0) {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Create the new task list
|
|
29
|
+
var newList = targetNodeType.create(targetAttrs, listItems);
|
|
30
|
+
|
|
31
|
+
// Replace the range with the new list
|
|
32
|
+
tr.replaceWith(range.start, range.end, newList);
|
|
33
|
+
return tr;
|
|
34
|
+
} catch (_unused) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
};
|
|
@@ -3,6 +3,7 @@ import { findParentNodeOfType } from '@atlaskit/editor-prosemirror/utils';
|
|
|
3
3
|
import { transformListStructure } from './list/transformBetweenListTypes';
|
|
4
4
|
import { transformOrderedUnorderedListToBlockNodes } from './list/transformOrderedUnorderedListToBlockNodes';
|
|
5
5
|
import { transformTaskListToBlockNodes } from './list/transformTaskListToBlockNodes';
|
|
6
|
+
import { transformToTaskList } from './list/transformToTaskList';
|
|
6
7
|
import { isBlockNodeType, isContainerNodeType, isListNodeType } from './utils';
|
|
7
8
|
|
|
8
9
|
/**
|
|
@@ -10,6 +11,7 @@ import { isBlockNodeType, isContainerNodeType, isListNodeType } from './utils';
|
|
|
10
11
|
*/
|
|
11
12
|
export var transformBlockToList = function transformBlockToList(context) {
|
|
12
13
|
var tr = context.tr,
|
|
14
|
+
sourceNode = context.sourceNode,
|
|
13
15
|
targetNodeType = context.targetNodeType,
|
|
14
16
|
targetAttrs = context.targetAttrs;
|
|
15
17
|
var _tr$selection = tr.selection,
|
|
@@ -23,13 +25,11 @@ export var transformBlockToList = function transformBlockToList(context) {
|
|
|
23
25
|
var isTargetTask = targetNodeType === nodes.taskList;
|
|
24
26
|
|
|
25
27
|
// Handle task lists differently due to their structure
|
|
26
|
-
// TODO: ED-29152 - Implement task list transformation
|
|
27
28
|
if (isTargetTask) {
|
|
28
|
-
return
|
|
29
|
+
return transformToTaskList(tr, range, targetNodeType, targetAttrs, nodes);
|
|
29
30
|
}
|
|
30
31
|
|
|
31
32
|
// For headings, convert to paragraph first since headings cannot be direct children of list items
|
|
32
|
-
var sourceNode = tr.doc.nodeAt(range.start);
|
|
33
33
|
if (sourceNode && sourceNode.type.name.startsWith('heading')) {
|
|
34
34
|
tr.setBlockType(range.start, range.end, nodes.paragraph);
|
|
35
35
|
}
|
|
@@ -14,4 +14,4 @@ export declare const unwrapAndConvertToBlockType: () => null;
|
|
|
14
14
|
/**
|
|
15
15
|
* Unwrap container node and convert content to list
|
|
16
16
|
*/
|
|
17
|
-
export declare const unwrapAndConvertToList: () =>
|
|
17
|
+
export declare const unwrapAndConvertToList: ({ tr, sourceNode, sourcePos, targetNodeType, targetAttrs, }: TransformContext) => import("prosemirror-state").Transaction;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { NodeType } from '@atlaskit/editor-prosemirror/model';
|
|
2
|
+
import type { Transaction } from '@atlaskit/editor-prosemirror/state';
|
|
3
|
+
/**
|
|
4
|
+
* Transform selection to task list
|
|
5
|
+
* Handles the special structure where taskItem contains text directly (no paragraph wrapper)
|
|
6
|
+
*/
|
|
7
|
+
export declare const transformToTaskList: (tr: Transaction, range: {
|
|
8
|
+
end: number;
|
|
9
|
+
start: number;
|
|
10
|
+
}, targetNodeType: NodeType, targetAttrs: Record<string, unknown> | undefined, nodes: Record<string, NodeType>) => Transaction | null;
|
|
@@ -14,4 +14,4 @@ export declare const unwrapAndConvertToBlockType: () => null;
|
|
|
14
14
|
/**
|
|
15
15
|
* Unwrap container node and convert content to list
|
|
16
16
|
*/
|
|
17
|
-
export declare const unwrapAndConvertToList: () =>
|
|
17
|
+
export declare const unwrapAndConvertToList: ({ tr, sourceNode, sourcePos, targetNodeType, targetAttrs, }: TransformContext) => import("prosemirror-state").Transaction;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { NodeType } from '@atlaskit/editor-prosemirror/model';
|
|
2
|
+
import type { Transaction } from '@atlaskit/editor-prosemirror/state';
|
|
3
|
+
/**
|
|
4
|
+
* Transform selection to task list
|
|
5
|
+
* Handles the special structure where taskItem contains text directly (no paragraph wrapper)
|
|
6
|
+
*/
|
|
7
|
+
export declare const transformToTaskList: (tr: Transaction, range: {
|
|
8
|
+
end: number;
|
|
9
|
+
start: number;
|
|
10
|
+
}, targetNodeType: NodeType, targetAttrs: Record<string, unknown> | undefined, nodes: Record<string, NodeType>) => Transaction | null;
|