@atlaskit/editor-plugin-block-menu 1.0.3 → 1.0.5
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 +20 -0
- package/dist/cjs/editor-commands/formatNode.js +1 -1
- package/dist/cjs/editor-commands/transforms/layout-transforms.js +30 -0
- package/dist/cjs/editor-commands/transforms/list/transformBetweenListTypes.js +65 -63
- package/dist/cjs/editor-commands/transforms/list-transforms.js +97 -30
- package/dist/cjs/editor-commands/transforms/transformNodeToTargetType.js +4 -0
- package/dist/cjs/editor-commands/transforms/utils.js +23 -2
- package/dist/cjs/ui/block-menu-components.js +2 -1
- package/dist/es2019/editor-commands/formatNode.js +1 -1
- package/dist/es2019/editor-commands/transforms/layout-transforms.js +25 -0
- package/dist/es2019/editor-commands/transforms/list/transformBetweenListTypes.js +67 -62
- package/dist/es2019/editor-commands/transforms/list-transforms.js +97 -27
- package/dist/es2019/editor-commands/transforms/transformNodeToTargetType.js +5 -1
- package/dist/es2019/editor-commands/transforms/utils.js +22 -1
- package/dist/es2019/ui/block-menu-components.js +2 -1
- package/dist/esm/editor-commands/formatNode.js +1 -1
- package/dist/esm/editor-commands/transforms/layout-transforms.js +24 -0
- package/dist/esm/editor-commands/transforms/list/transformBetweenListTypes.js +66 -63
- package/dist/esm/editor-commands/transforms/list-transforms.js +92 -26
- package/dist/esm/editor-commands/transforms/transformNodeToTargetType.js +5 -1
- package/dist/esm/editor-commands/transforms/utils.js +22 -1
- package/dist/esm/ui/block-menu-components.js +2 -1
- package/dist/types/editor-commands/transforms/layout-transforms.d.ts +2 -0
- package/dist/types/editor-commands/transforms/list/transformBetweenListTypes.d.ts +3 -7
- package/dist/types/editor-commands/transforms/list-transforms.d.ts +5 -1
- package/dist/types/editor-commands/transforms/transformNodeToTargetType.d.ts +1 -1
- package/dist/types/editor-commands/transforms/types.d.ts +2 -2
- package/dist/types/editor-commands/transforms/utils.d.ts +5 -0
- package/dist/types-ts4.5/editor-commands/transforms/layout-transforms.d.ts +2 -0
- package/dist/types-ts4.5/editor-commands/transforms/list/transformBetweenListTypes.d.ts +3 -7
- package/dist/types-ts4.5/editor-commands/transforms/list-transforms.d.ts +5 -1
- package/dist/types-ts4.5/editor-commands/transforms/transformNodeToTargetType.d.ts +1 -1
- package/dist/types-ts4.5/editor-commands/transforms/types.d.ts +2 -2
- package/dist/types-ts4.5/editor-commands/transforms/utils.d.ts +5 -0
- package/package.json +6 -6
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { getSupportedListTypesSet, isBulletOrOrderedList, isTaskList } from '../utils';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* Convert a block node to inline content suitable for task items
|
|
3
5
|
*/
|
|
@@ -6,89 +8,92 @@ const convertBlockToInlineContent = (node, schema) => {
|
|
|
6
8
|
paragraph
|
|
7
9
|
} = schema.nodes;
|
|
8
10
|
if (node.type === paragraph) {
|
|
9
|
-
// Extract inline content from paragraphs
|
|
10
11
|
return [...node.content.content];
|
|
11
|
-
}
|
|
12
|
-
|
|
12
|
+
}
|
|
13
|
+
if (node.isBlock) {
|
|
13
14
|
const textContent = node.textContent;
|
|
14
|
-
|
|
15
|
-
const textNode = schema.text(textContent);
|
|
16
|
-
return [textNode];
|
|
17
|
-
}
|
|
18
|
-
} else {
|
|
19
|
-
// Already inline content, add directly
|
|
20
|
-
return [node];
|
|
15
|
+
return textContent ? [schema.text(textContent)] : [];
|
|
21
16
|
}
|
|
22
|
-
return [];
|
|
17
|
+
return [node];
|
|
23
18
|
};
|
|
24
19
|
|
|
25
20
|
/**
|
|
26
|
-
* Transform list structure
|
|
21
|
+
* Transform list structure between different list types
|
|
27
22
|
*/
|
|
28
|
-
export const transformListStructure =
|
|
23
|
+
export const transformListStructure = context => {
|
|
24
|
+
const {
|
|
25
|
+
tr,
|
|
26
|
+
sourceNode,
|
|
27
|
+
sourcePos,
|
|
28
|
+
targetNodeType
|
|
29
|
+
} = context;
|
|
30
|
+
const nodes = tr.doc.type.schema.nodes;
|
|
29
31
|
try {
|
|
32
|
+
const listNode = {
|
|
33
|
+
node: sourceNode,
|
|
34
|
+
pos: sourcePos
|
|
35
|
+
};
|
|
30
36
|
const {
|
|
31
37
|
node: sourceList,
|
|
32
38
|
pos: listPos
|
|
33
39
|
} = listNode;
|
|
34
40
|
const {
|
|
35
|
-
bulletList,
|
|
36
|
-
orderedList,
|
|
37
41
|
taskList,
|
|
38
42
|
listItem,
|
|
39
43
|
taskItem,
|
|
40
44
|
paragraph
|
|
41
45
|
} = nodes;
|
|
42
|
-
const isSourceBulletOrOrdered = sourceList.type
|
|
43
|
-
const isTargetTask = targetNodeType
|
|
44
|
-
const isSourceTask = sourceList.type
|
|
45
|
-
const
|
|
46
|
-
const
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
inlineContent.
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
newListItems.push(newItem);
|
|
46
|
+
const isSourceBulletOrOrdered = isBulletOrOrderedList(sourceList.type);
|
|
47
|
+
const isTargetTask = isTaskList(targetNodeType);
|
|
48
|
+
const isSourceTask = isTaskList(sourceList.type);
|
|
49
|
+
const isTargetBulletOrOrdered = isBulletOrOrderedList(targetNodeType);
|
|
50
|
+
const supportedListTypes = getSupportedListTypesSet(nodes);
|
|
51
|
+
const transformListRecursively = listNode => {
|
|
52
|
+
const transformedItems = [];
|
|
53
|
+
listNode.forEach(child => {
|
|
54
|
+
if (isSourceBulletOrOrdered && isTargetTask) {
|
|
55
|
+
// Convert bullet/ordered => task
|
|
56
|
+
if (child.type === listItem) {
|
|
57
|
+
const inlineContent = [];
|
|
58
|
+
const nestedTaskLists = [];
|
|
59
|
+
child.forEach(grandChild => {
|
|
60
|
+
if (supportedListTypes.has(grandChild.type) && grandChild.type !== taskList) {
|
|
61
|
+
nestedTaskLists.push(transformListRecursively(grandChild));
|
|
62
|
+
} else {
|
|
63
|
+
inlineContent.push(...convertBlockToInlineContent(grandChild, tr.doc.type.schema));
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
if (inlineContent.length > 0) {
|
|
67
|
+
transformedItems.push(taskItem.create(null, inlineContent));
|
|
68
|
+
}
|
|
69
|
+
transformedItems.push(...nestedTaskLists);
|
|
67
70
|
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
71
|
+
} else if (isSourceTask && isTargetBulletOrOrdered) {
|
|
72
|
+
// Convert task => bullet/ordered
|
|
73
|
+
if (child.type === taskItem) {
|
|
74
|
+
const inlineContent = [...child.content.content];
|
|
75
|
+
if (inlineContent.length > 0) {
|
|
76
|
+
const paragraphNode = paragraph.create(null, inlineContent);
|
|
77
|
+
transformedItems.push(listItem.create(null, [paragraphNode]));
|
|
78
|
+
}
|
|
79
|
+
} else if (child.type === taskList) {
|
|
80
|
+
const transformedNestedList = transformListRecursively(child);
|
|
81
|
+
const lastItem = transformedItems[transformedItems.length - 1];
|
|
82
|
+
if ((lastItem === null || lastItem === void 0 ? void 0 : lastItem.type) === listItem) {
|
|
83
|
+
// Attach nested list to previous item
|
|
84
|
+
const updatedContent = [...lastItem.content.content, transformedNestedList];
|
|
85
|
+
transformedItems[transformedItems.length - 1] = listItem.create(lastItem.attrs, updatedContent);
|
|
86
|
+
} else {
|
|
87
|
+
// No previous item, flatten nested items
|
|
88
|
+
transformedItems.push(...transformedNestedList.content.content);
|
|
89
|
+
}
|
|
78
90
|
}
|
|
79
91
|
}
|
|
80
|
-
}
|
|
81
|
-
return
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// Create new list with transformed items
|
|
88
|
-
const newList = targetNodeType.create(null, newListItems);
|
|
89
|
-
|
|
90
|
-
// Replace the entire list
|
|
91
|
-
tr.replaceWith(listStart, listEnd, newList);
|
|
92
|
+
});
|
|
93
|
+
return targetNodeType.create(null, transformedItems);
|
|
94
|
+
};
|
|
95
|
+
const newList = transformListRecursively(sourceList);
|
|
96
|
+
tr.replaceWith(listPos, listPos + sourceList.nodeSize, newList);
|
|
92
97
|
return tr;
|
|
93
98
|
} catch {
|
|
94
99
|
return tr;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
import { Fragment } from '@atlaskit/editor-prosemirror/model';
|
|
1
2
|
import { findWrapping } from '@atlaskit/editor-prosemirror/transform';
|
|
2
|
-
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
6
|
import { transformToTaskList } from './list/transformToTaskList';
|
|
7
|
-
import { isBlockNodeType, isContainerNodeType, isListNodeType } from './utils';
|
|
7
|
+
import { getSupportedListTypesSet, isBulletOrOrderedList, isBlockNodeType, isContainerNodeType, isListNodeType, isTaskList } from './utils';
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Transform selection to list type
|
|
@@ -27,7 +27,7 @@ export const transformBlockToList = context => {
|
|
|
27
27
|
const {
|
|
28
28
|
nodes
|
|
29
29
|
} = tr.doc.type.schema;
|
|
30
|
-
const isTargetTask = targetNodeType
|
|
30
|
+
const isTargetTask = isTaskList(targetNodeType);
|
|
31
31
|
|
|
32
32
|
// Handle task lists differently due to their structure
|
|
33
33
|
if (isTargetTask) {
|
|
@@ -65,6 +65,65 @@ export const transformListToBlockNodes = context => {
|
|
|
65
65
|
}
|
|
66
66
|
};
|
|
67
67
|
|
|
68
|
+
/**
|
|
69
|
+
* Wraps bulletList, orderedList or taskList in node of container type
|
|
70
|
+
*/
|
|
71
|
+
export const transformListToContainer = context => {
|
|
72
|
+
const {
|
|
73
|
+
tr,
|
|
74
|
+
sourceNode,
|
|
75
|
+
sourcePos,
|
|
76
|
+
targetNodeType,
|
|
77
|
+
targetAttrs
|
|
78
|
+
} = context;
|
|
79
|
+
if (sourcePos === null) {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
const {
|
|
83
|
+
schema
|
|
84
|
+
} = tr.doc.type;
|
|
85
|
+
const {
|
|
86
|
+
blockquote,
|
|
87
|
+
taskList,
|
|
88
|
+
taskItem,
|
|
89
|
+
paragraph
|
|
90
|
+
} = schema.nodes;
|
|
91
|
+
|
|
92
|
+
// Special case: Task list -> Blockquote
|
|
93
|
+
// Flattens the task list before wrapping by blockquote
|
|
94
|
+
if (sourceNode.type === taskList && targetNodeType === blockquote) {
|
|
95
|
+
const extractParagraphsFromTaskList = node => {
|
|
96
|
+
const paragraphs = [];
|
|
97
|
+
node.forEach(child => {
|
|
98
|
+
if (child.type === taskItem) {
|
|
99
|
+
if (child.content.size > 0) {
|
|
100
|
+
const paragraphNode = paragraph.createChecked({}, child.content.content);
|
|
101
|
+
paragraphs.push(paragraphNode);
|
|
102
|
+
}
|
|
103
|
+
} else if (child.type === taskList) {
|
|
104
|
+
paragraphs.push(...extractParagraphsFromTaskList(child));
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
return paragraphs;
|
|
108
|
+
};
|
|
109
|
+
const liftedParagraphs = extractParagraphsFromTaskList(sourceNode);
|
|
110
|
+
const containerNode = targetNodeType.createAndFill(targetAttrs, Fragment.from(liftedParagraphs));
|
|
111
|
+
if (!containerNode) {
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
tr.replaceWith(sourcePos, sourcePos + sourceNode.nodeSize, containerNode);
|
|
115
|
+
return tr;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Default case
|
|
119
|
+
const containerNode = targetNodeType.createAndFill(targetAttrs, [sourceNode]);
|
|
120
|
+
if (!containerNode) {
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
tr.replaceWith(sourcePos, sourcePos + sourceNode.nodeSize, containerNode);
|
|
124
|
+
return tr;
|
|
125
|
+
};
|
|
126
|
+
|
|
68
127
|
/**
|
|
69
128
|
* Transform list nodes
|
|
70
129
|
*/
|
|
@@ -80,8 +139,8 @@ export const transformListNode = context => {
|
|
|
80
139
|
|
|
81
140
|
// Transform list to container type
|
|
82
141
|
if (isContainerNodeType(targetNodeType)) {
|
|
83
|
-
//
|
|
84
|
-
return
|
|
142
|
+
// Wrap list items into container type, where possible
|
|
143
|
+
return transformListToContainer(context);
|
|
85
144
|
}
|
|
86
145
|
|
|
87
146
|
// Transform between list types
|
|
@@ -102,41 +161,52 @@ export const liftListToBlockType = () => {
|
|
|
102
161
|
/**
|
|
103
162
|
* Transform between different list types
|
|
104
163
|
*/
|
|
105
|
-
export const transformBetweenListTypes =
|
|
106
|
-
tr,
|
|
107
|
-
targetNodeType
|
|
108
|
-
}) => {
|
|
164
|
+
export const transformBetweenListTypes = context => {
|
|
109
165
|
const {
|
|
110
|
-
|
|
111
|
-
|
|
166
|
+
tr,
|
|
167
|
+
sourceNode,
|
|
168
|
+
sourcePos,
|
|
169
|
+
targetNodeType
|
|
170
|
+
} = context;
|
|
112
171
|
const {
|
|
113
172
|
nodes
|
|
114
173
|
} = tr.doc.type.schema;
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
const
|
|
118
|
-
|
|
119
|
-
const
|
|
120
|
-
if (!listNode) {
|
|
121
|
-
return null;
|
|
122
|
-
}
|
|
123
|
-
const sourceListType = listNode.node.type;
|
|
124
|
-
const isSourceBulletOrOrdered = sourceListType === nodes.bulletList || sourceListType === nodes.orderedList;
|
|
125
|
-
const isTargetTask = targetNodeType === nodes.taskList;
|
|
126
|
-
const isSourceTask = sourceListType === nodes.taskList;
|
|
127
|
-
const isTargetBulletOrOrdered = targetNodeType === nodes.bulletList || targetNodeType === nodes.orderedList;
|
|
174
|
+
const sourceListType = sourceNode.type;
|
|
175
|
+
const isSourceBulletOrOrdered = isBulletOrOrderedList(sourceListType);
|
|
176
|
+
const isTargetTask = isTaskList(targetNodeType);
|
|
177
|
+
const isSourceTask = isTaskList(sourceListType);
|
|
178
|
+
const isTargetBulletOrOrdered = isBulletOrOrderedList(targetNodeType);
|
|
128
179
|
|
|
129
180
|
// Check if we need structure transformation
|
|
130
181
|
const needsStructureTransform = isSourceBulletOrOrdered && isTargetTask || isSourceTask && isTargetBulletOrOrdered;
|
|
131
182
|
try {
|
|
132
183
|
if (!needsStructureTransform) {
|
|
133
184
|
// Simple type change for same structure lists (bullet <-> ordered)
|
|
134
|
-
|
|
185
|
+
// Apply to the main list
|
|
186
|
+
tr.setNodeMarkup(sourcePos, targetNodeType);
|
|
187
|
+
|
|
188
|
+
// Apply to nested lists
|
|
189
|
+
const listStart = sourcePos;
|
|
190
|
+
const listEnd = sourcePos + sourceNode.nodeSize;
|
|
191
|
+
const supportedListTypesSet = getSupportedListTypesSet(nodes);
|
|
192
|
+
tr.doc.nodesBetween(listStart, listEnd, (node, pos, parent) => {
|
|
193
|
+
// Only process nested lists (not the root list we already handled)
|
|
194
|
+
if (supportedListTypesSet.has(node.type) && pos !== sourcePos) {
|
|
195
|
+
const isNestedList = parent && (supportedListTypesSet.has(parent.type) || parent.type === nodes.listItem);
|
|
196
|
+
if (isNestedList) {
|
|
197
|
+
const shouldTransformNode = node.type === sourceListType || isBulletOrOrderedList(node.type) && isTargetBulletOrOrdered;
|
|
198
|
+
if (shouldTransformNode) {
|
|
199
|
+
tr.setNodeMarkup(pos, targetNodeType);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
return true; // Continue traversing
|
|
204
|
+
});
|
|
205
|
+
return tr;
|
|
135
206
|
} else {
|
|
136
|
-
|
|
207
|
+
return transformListStructure(context);
|
|
137
208
|
}
|
|
138
209
|
} catch {
|
|
139
210
|
return null;
|
|
140
211
|
}
|
|
141
|
-
return tr;
|
|
142
212
|
};
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { transformBlockNode } from './block-transforms';
|
|
2
2
|
import { transformContainerNode } from './container-transforms';
|
|
3
|
+
import { convertToLayout } from './layout-transforms';
|
|
3
4
|
import { transformListNode } from './list-transforms';
|
|
4
|
-
import { getTargetNodeInfo, isBlockNode, isListNode, isContainerNode } from './utils';
|
|
5
|
+
import { getTargetNodeInfo, isBlockNode, isListNode, isContainerNode, isLayoutNodeType } from './utils';
|
|
5
6
|
export function transformNodeToTargetType(tr, sourceNode, sourcePos, targetType) {
|
|
6
7
|
const {
|
|
7
8
|
nodes
|
|
@@ -41,6 +42,9 @@ export function transformNodeToTargetType(tr, sourceNode, sourcePos, targetType)
|
|
|
41
42
|
|
|
42
43
|
// Route to appropriate transformation strategy based on source node type
|
|
43
44
|
try {
|
|
45
|
+
if (isLayoutNodeType(targetNodeType)) {
|
|
46
|
+
return convertToLayout(transformationContext);
|
|
47
|
+
}
|
|
44
48
|
if (isBlockNode(sourceNode)) {
|
|
45
49
|
return transformBlockNode(transformationContext);
|
|
46
50
|
}
|
|
@@ -77,6 +77,10 @@ export const getTargetNodeInfo = (targetType, nodes) => {
|
|
|
77
77
|
return {
|
|
78
78
|
nodeType: nodes.taskList
|
|
79
79
|
};
|
|
80
|
+
case 'layoutSection':
|
|
81
|
+
return {
|
|
82
|
+
nodeType: nodes.layoutSection
|
|
83
|
+
};
|
|
80
84
|
default:
|
|
81
85
|
return null;
|
|
82
86
|
}
|
|
@@ -87,7 +91,7 @@ export const isBlockNode = node => {
|
|
|
87
91
|
return ['paragraph', 'heading', 'codeBlock'].includes(node.type.name);
|
|
88
92
|
};
|
|
89
93
|
export const isListNode = node => {
|
|
90
|
-
return ['bulletList', 'orderedList', 'taskList'
|
|
94
|
+
return ['bulletList', 'orderedList', 'taskList'].includes(node.type.name);
|
|
91
95
|
};
|
|
92
96
|
export const isContainerNode = node => {
|
|
93
97
|
return ['panel', 'expand', 'blockquote'].includes(node.type.name);
|
|
@@ -100,4 +104,21 @@ export const isListNodeType = nodeType => {
|
|
|
100
104
|
};
|
|
101
105
|
export const isContainerNodeType = nodeType => {
|
|
102
106
|
return ['panel', 'expand', 'blockquote'].includes(nodeType.name);
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
// List type utilities
|
|
110
|
+
export const isBulletOrOrderedList = nodeType => {
|
|
111
|
+
return nodeType.name === 'bulletList' || nodeType.name === 'orderedList';
|
|
112
|
+
};
|
|
113
|
+
export const isTaskList = nodeType => {
|
|
114
|
+
return nodeType.name === 'taskList';
|
|
115
|
+
};
|
|
116
|
+
export const getSupportedListTypes = nodes => {
|
|
117
|
+
return [nodes.bulletList, nodes.orderedList, nodes.taskList].filter(Boolean);
|
|
118
|
+
};
|
|
119
|
+
export const getSupportedListTypesSet = nodes => {
|
|
120
|
+
return new Set(getSupportedListTypes(nodes));
|
|
121
|
+
};
|
|
122
|
+
export const isLayoutNodeType = nodeType => {
|
|
123
|
+
return nodeType.name === 'layoutSection';
|
|
103
124
|
};
|
|
@@ -12,7 +12,7 @@ export var formatNode = function formatNode(targetType) {
|
|
|
12
12
|
|
|
13
13
|
// Find the node to format from the current selection
|
|
14
14
|
var nodeToFormat;
|
|
15
|
-
var nodePos =
|
|
15
|
+
var nodePos = selection.from;
|
|
16
16
|
|
|
17
17
|
// Try to find the current node from selection
|
|
18
18
|
var selectedNode = findSelectedNodeOfType([nodes.paragraph, nodes.heading, nodes.blockquote, nodes.panel, nodes.expand, nodes.codeBlock, nodes.bulletList, nodes.orderedList, nodes.taskList, nodes.layoutSection])(selection);
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { DEFAULT_TWO_COLUMN_LAYOUT_COLUMN_WIDTH } from '@atlaskit/editor-common/styles';
|
|
2
|
+
import { Fragment } from '@atlaskit/editor-prosemirror/model';
|
|
3
|
+
export var convertToLayout = function convertToLayout(context) {
|
|
4
|
+
var tr = context.tr,
|
|
5
|
+
sourceNode = context.sourceNode,
|
|
6
|
+
sourcePos = context.sourcePos;
|
|
7
|
+
var _ref = tr.doc.type.schema.nodes || {},
|
|
8
|
+
layoutSection = _ref.layoutSection,
|
|
9
|
+
layoutColumn = _ref.layoutColumn,
|
|
10
|
+
paragraph = _ref.paragraph;
|
|
11
|
+
var content = sourceNode.mark(sourceNode.marks.filter(function (mark) {
|
|
12
|
+
return mark.type.name !== 'breakout';
|
|
13
|
+
}));
|
|
14
|
+
var layoutContent = Fragment.fromArray([layoutColumn.createChecked({
|
|
15
|
+
width: DEFAULT_TWO_COLUMN_LAYOUT_COLUMN_WIDTH
|
|
16
|
+
}, content), layoutColumn.create({
|
|
17
|
+
width: DEFAULT_TWO_COLUMN_LAYOUT_COLUMN_WIDTH
|
|
18
|
+
}, paragraph.createAndFill())]);
|
|
19
|
+
var layoutSectionNode = layoutSection.createChecked(undefined, layoutContent);
|
|
20
|
+
|
|
21
|
+
// Replace the original node with the new layout node
|
|
22
|
+
tr.replaceRangeWith(sourcePos || 0, (sourcePos || 0) + sourceNode.nodeSize, layoutSectionNode);
|
|
23
|
+
return tr;
|
|
24
|
+
};
|
|
@@ -1,89 +1,92 @@
|
|
|
1
1
|
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
|
|
2
|
+
import { getSupportedListTypesSet, isBulletOrOrderedList, isTaskList } from '../utils';
|
|
3
|
+
|
|
2
4
|
/**
|
|
3
5
|
* Convert a block node to inline content suitable for task items
|
|
4
6
|
*/
|
|
5
7
|
var convertBlockToInlineContent = function convertBlockToInlineContent(node, schema) {
|
|
6
8
|
var paragraph = schema.nodes.paragraph;
|
|
7
9
|
if (node.type === paragraph) {
|
|
8
|
-
// Extract inline content from paragraphs
|
|
9
10
|
return _toConsumableArray(node.content.content);
|
|
10
|
-
}
|
|
11
|
-
|
|
11
|
+
}
|
|
12
|
+
if (node.isBlock) {
|
|
12
13
|
var textContent = node.textContent;
|
|
13
|
-
|
|
14
|
-
var textNode = schema.text(textContent);
|
|
15
|
-
return [textNode];
|
|
16
|
-
}
|
|
17
|
-
} else {
|
|
18
|
-
// Already inline content, add directly
|
|
19
|
-
return [node];
|
|
14
|
+
return textContent ? [schema.text(textContent)] : [];
|
|
20
15
|
}
|
|
21
|
-
return [];
|
|
16
|
+
return [node];
|
|
22
17
|
};
|
|
23
18
|
|
|
24
19
|
/**
|
|
25
|
-
* Transform list structure
|
|
20
|
+
* Transform list structure between different list types
|
|
26
21
|
*/
|
|
27
|
-
export var transformListStructure = function transformListStructure(
|
|
22
|
+
export var transformListStructure = function transformListStructure(context) {
|
|
23
|
+
var tr = context.tr,
|
|
24
|
+
sourceNode = context.sourceNode,
|
|
25
|
+
sourcePos = context.sourcePos,
|
|
26
|
+
targetNodeType = context.targetNodeType;
|
|
27
|
+
var nodes = tr.doc.type.schema.nodes;
|
|
28
28
|
try {
|
|
29
|
+
var listNode = {
|
|
30
|
+
node: sourceNode,
|
|
31
|
+
pos: sourcePos
|
|
32
|
+
};
|
|
29
33
|
var sourceList = listNode.node,
|
|
30
34
|
listPos = listNode.pos;
|
|
31
|
-
var
|
|
32
|
-
orderedList = nodes.orderedList,
|
|
33
|
-
taskList = nodes.taskList,
|
|
35
|
+
var taskList = nodes.taskList,
|
|
34
36
|
listItem = nodes.listItem,
|
|
35
37
|
taskItem = nodes.taskItem,
|
|
36
38
|
paragraph = nodes.paragraph;
|
|
37
|
-
var isSourceBulletOrOrdered = sourceList.type
|
|
38
|
-
var isTargetTask = targetNodeType
|
|
39
|
-
var isSourceTask = sourceList.type
|
|
40
|
-
var
|
|
41
|
-
var
|
|
42
|
-
var
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
inlineContent.
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
newListItems.push(newItem);
|
|
39
|
+
var isSourceBulletOrOrdered = isBulletOrOrderedList(sourceList.type);
|
|
40
|
+
var isTargetTask = isTaskList(targetNodeType);
|
|
41
|
+
var isSourceTask = isTaskList(sourceList.type);
|
|
42
|
+
var isTargetBulletOrOrdered = isBulletOrOrderedList(targetNodeType);
|
|
43
|
+
var supportedListTypes = getSupportedListTypesSet(nodes);
|
|
44
|
+
var _transformListRecursively = function transformListRecursively(listNode) {
|
|
45
|
+
var transformedItems = [];
|
|
46
|
+
listNode.forEach(function (child) {
|
|
47
|
+
if (isSourceBulletOrOrdered && isTargetTask) {
|
|
48
|
+
// Convert bullet/ordered => task
|
|
49
|
+
if (child.type === listItem) {
|
|
50
|
+
var inlineContent = [];
|
|
51
|
+
var nestedTaskLists = [];
|
|
52
|
+
child.forEach(function (grandChild) {
|
|
53
|
+
if (supportedListTypes.has(grandChild.type) && grandChild.type !== taskList) {
|
|
54
|
+
nestedTaskLists.push(_transformListRecursively(grandChild));
|
|
55
|
+
} else {
|
|
56
|
+
inlineContent.push.apply(inlineContent, _toConsumableArray(convertBlockToInlineContent(grandChild, tr.doc.type.schema)));
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
if (inlineContent.length > 0) {
|
|
60
|
+
transformedItems.push(taskItem.create(null, inlineContent));
|
|
61
|
+
}
|
|
62
|
+
transformedItems.push.apply(transformedItems, nestedTaskLists);
|
|
62
63
|
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
64
|
+
} else if (isSourceTask && isTargetBulletOrOrdered) {
|
|
65
|
+
// Convert task => bullet/ordered
|
|
66
|
+
if (child.type === taskItem) {
|
|
67
|
+
var _inlineContent = _toConsumableArray(child.content.content);
|
|
68
|
+
if (_inlineContent.length > 0) {
|
|
69
|
+
var paragraphNode = paragraph.create(null, _inlineContent);
|
|
70
|
+
transformedItems.push(listItem.create(null, [paragraphNode]));
|
|
71
|
+
}
|
|
72
|
+
} else if (child.type === taskList) {
|
|
73
|
+
var transformedNestedList = _transformListRecursively(child);
|
|
74
|
+
var lastItem = transformedItems[transformedItems.length - 1];
|
|
75
|
+
if ((lastItem === null || lastItem === void 0 ? void 0 : lastItem.type) === listItem) {
|
|
76
|
+
// Attach nested list to previous item
|
|
77
|
+
var updatedContent = [].concat(_toConsumableArray(lastItem.content.content), [transformedNestedList]);
|
|
78
|
+
transformedItems[transformedItems.length - 1] = listItem.create(lastItem.attrs, updatedContent);
|
|
79
|
+
} else {
|
|
80
|
+
// No previous item, flatten nested items
|
|
81
|
+
transformedItems.push.apply(transformedItems, _toConsumableArray(transformedNestedList.content.content));
|
|
82
|
+
}
|
|
73
83
|
}
|
|
74
84
|
}
|
|
75
|
-
}
|
|
76
|
-
return
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
// Create new list with transformed items
|
|
83
|
-
var newList = targetNodeType.create(null, newListItems);
|
|
84
|
-
|
|
85
|
-
// Replace the entire list
|
|
86
|
-
tr.replaceWith(listStart, listEnd, newList);
|
|
85
|
+
});
|
|
86
|
+
return targetNodeType.create(null, transformedItems);
|
|
87
|
+
};
|
|
88
|
+
var newList = _transformListRecursively(sourceList);
|
|
89
|
+
tr.replaceWith(listPos, listPos + sourceList.nodeSize, newList);
|
|
87
90
|
return tr;
|
|
88
91
|
} catch (_unused) {
|
|
89
92
|
return tr;
|