@atlaskit/editor-plugin-block-menu 1.0.3 → 1.0.4
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 +10 -0
- package/dist/cjs/editor-commands/formatNode.js +1 -1
- package/dist/cjs/editor-commands/transforms/list/transformBetweenListTypes.js +65 -63
- package/dist/cjs/editor-commands/transforms/list-transforms.js +37 -27
- package/dist/cjs/editor-commands/transforms/utils.js +16 -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/list/transformBetweenListTypes.js +67 -62
- package/dist/es2019/editor-commands/transforms/list-transforms.js +35 -25
- package/dist/es2019/editor-commands/transforms/utils.js +15 -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/list/transformBetweenListTypes.js +66 -63
- package/dist/esm/editor-commands/transforms/list-transforms.js +34 -24
- package/dist/esm/editor-commands/transforms/utils.js +15 -1
- package/dist/esm/ui/block-menu-components.js +2 -1
- package/dist/types/editor-commands/transforms/list/transformBetweenListTypes.d.ts +3 -7
- package/dist/types/editor-commands/transforms/list-transforms.d.ts +1 -1
- package/dist/types/editor-commands/transforms/transformNodeToTargetType.d.ts +1 -1
- package/dist/types/editor-commands/transforms/types.d.ts +1 -1
- package/dist/types/editor-commands/transforms/utils.d.ts +4 -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 +1 -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 +1 -1
- package/dist/types-ts4.5/editor-commands/transforms/utils.d.ts +4 -0
- package/package.json +6 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-block-menu
|
|
2
2
|
|
|
3
|
+
## 1.0.4
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`30454d0f4baf2`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/30454d0f4baf2) -
|
|
8
|
+
Support multiple levels list to list transform
|
|
9
|
+
- [`cb4decb701766`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/cb4decb701766) -
|
|
10
|
+
[ux] Enable max height on block menu flyout menu
|
|
11
|
+
- Updated dependencies
|
|
12
|
+
|
|
3
13
|
## 1.0.3
|
|
4
14
|
|
|
5
15
|
### Patch Changes
|
|
@@ -18,7 +18,7 @@ var formatNode = exports.formatNode = function formatNode(targetType) {
|
|
|
18
18
|
|
|
19
19
|
// Find the node to format from the current selection
|
|
20
20
|
var nodeToFormat;
|
|
21
|
-
var nodePos =
|
|
21
|
+
var nodePos = selection.from;
|
|
22
22
|
|
|
23
23
|
// Try to find the current node from selection
|
|
24
24
|
var selectedNode = (0, _utils.findSelectedNodeOfType)([nodes.paragraph, nodes.heading, nodes.blockquote, nodes.panel, nodes.expand, nodes.codeBlock, nodes.bulletList, nodes.orderedList, nodes.taskList, nodes.layoutSection])(selection);
|
|
@@ -6,91 +6,93 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
});
|
|
7
7
|
exports.transformListStructure = void 0;
|
|
8
8
|
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
|
|
9
|
+
var _utils = require("../utils");
|
|
9
10
|
/**
|
|
10
11
|
* Convert a block node to inline content suitable for task items
|
|
11
12
|
*/
|
|
12
13
|
var convertBlockToInlineContent = function convertBlockToInlineContent(node, schema) {
|
|
13
14
|
var paragraph = schema.nodes.paragraph;
|
|
14
15
|
if (node.type === paragraph) {
|
|
15
|
-
// Extract inline content from paragraphs
|
|
16
16
|
return (0, _toConsumableArray2.default)(node.content.content);
|
|
17
|
-
}
|
|
18
|
-
|
|
17
|
+
}
|
|
18
|
+
if (node.isBlock) {
|
|
19
19
|
var textContent = node.textContent;
|
|
20
|
-
|
|
21
|
-
var textNode = schema.text(textContent);
|
|
22
|
-
return [textNode];
|
|
23
|
-
}
|
|
24
|
-
} else {
|
|
25
|
-
// Already inline content, add directly
|
|
26
|
-
return [node];
|
|
20
|
+
return textContent ? [schema.text(textContent)] : [];
|
|
27
21
|
}
|
|
28
|
-
return [];
|
|
22
|
+
return [node];
|
|
29
23
|
};
|
|
30
24
|
|
|
31
25
|
/**
|
|
32
|
-
* Transform list structure
|
|
26
|
+
* Transform list structure between different list types
|
|
33
27
|
*/
|
|
34
|
-
var transformListStructure = exports.transformListStructure = function transformListStructure(
|
|
28
|
+
var transformListStructure = exports.transformListStructure = function transformListStructure(context) {
|
|
29
|
+
var tr = context.tr,
|
|
30
|
+
sourceNode = context.sourceNode,
|
|
31
|
+
sourcePos = context.sourcePos,
|
|
32
|
+
targetNodeType = context.targetNodeType;
|
|
33
|
+
var nodes = tr.doc.type.schema.nodes;
|
|
35
34
|
try {
|
|
35
|
+
var listNode = {
|
|
36
|
+
node: sourceNode,
|
|
37
|
+
pos: sourcePos
|
|
38
|
+
};
|
|
36
39
|
var sourceList = listNode.node,
|
|
37
40
|
listPos = listNode.pos;
|
|
38
|
-
var
|
|
39
|
-
orderedList = nodes.orderedList,
|
|
40
|
-
taskList = nodes.taskList,
|
|
41
|
+
var taskList = nodes.taskList,
|
|
41
42
|
listItem = nodes.listItem,
|
|
42
43
|
taskItem = nodes.taskItem,
|
|
43
44
|
paragraph = nodes.paragraph;
|
|
44
|
-
var isSourceBulletOrOrdered =
|
|
45
|
-
var isTargetTask = targetNodeType
|
|
46
|
-
var isSourceTask = sourceList.type
|
|
47
|
-
var
|
|
48
|
-
var
|
|
49
|
-
var
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
inlineContent.
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
newListItems.push(newItem);
|
|
45
|
+
var isSourceBulletOrOrdered = (0, _utils.isBulletOrOrderedList)(sourceList.type);
|
|
46
|
+
var isTargetTask = (0, _utils.isTaskList)(targetNodeType);
|
|
47
|
+
var isSourceTask = (0, _utils.isTaskList)(sourceList.type);
|
|
48
|
+
var isTargetBulletOrOrdered = (0, _utils.isBulletOrOrderedList)(targetNodeType);
|
|
49
|
+
var supportedListTypes = (0, _utils.getSupportedListTypesSet)(nodes);
|
|
50
|
+
var _transformListRecursively = function transformListRecursively(listNode) {
|
|
51
|
+
var transformedItems = [];
|
|
52
|
+
listNode.forEach(function (child) {
|
|
53
|
+
if (isSourceBulletOrOrdered && isTargetTask) {
|
|
54
|
+
// Convert bullet/ordered => task
|
|
55
|
+
if (child.type === listItem) {
|
|
56
|
+
var inlineContent = [];
|
|
57
|
+
var nestedTaskLists = [];
|
|
58
|
+
child.forEach(function (grandChild) {
|
|
59
|
+
if (supportedListTypes.has(grandChild.type) && grandChild.type !== taskList) {
|
|
60
|
+
nestedTaskLists.push(_transformListRecursively(grandChild));
|
|
61
|
+
} else {
|
|
62
|
+
inlineContent.push.apply(inlineContent, (0, _toConsumableArray2.default)(convertBlockToInlineContent(grandChild, tr.doc.type.schema)));
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
if (inlineContent.length > 0) {
|
|
66
|
+
transformedItems.push(taskItem.create(null, inlineContent));
|
|
67
|
+
}
|
|
68
|
+
transformedItems.push.apply(transformedItems, nestedTaskLists);
|
|
69
69
|
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
70
|
+
} else if (isSourceTask && isTargetBulletOrOrdered) {
|
|
71
|
+
// Convert task => bullet/ordered
|
|
72
|
+
if (child.type === taskItem) {
|
|
73
|
+
var _inlineContent = (0, _toConsumableArray2.default)(child.content.content);
|
|
74
|
+
if (_inlineContent.length > 0) {
|
|
75
|
+
var paragraphNode = paragraph.create(null, _inlineContent);
|
|
76
|
+
transformedItems.push(listItem.create(null, [paragraphNode]));
|
|
77
|
+
}
|
|
78
|
+
} else if (child.type === taskList) {
|
|
79
|
+
var transformedNestedList = _transformListRecursively(child);
|
|
80
|
+
var lastItem = transformedItems[transformedItems.length - 1];
|
|
81
|
+
if ((lastItem === null || lastItem === void 0 ? void 0 : lastItem.type) === listItem) {
|
|
82
|
+
// Attach nested list to previous item
|
|
83
|
+
var updatedContent = [].concat((0, _toConsumableArray2.default)(lastItem.content.content), [transformedNestedList]);
|
|
84
|
+
transformedItems[transformedItems.length - 1] = listItem.create(lastItem.attrs, updatedContent);
|
|
85
|
+
} else {
|
|
86
|
+
// No previous item, flatten nested items
|
|
87
|
+
transformedItems.push.apply(transformedItems, (0, _toConsumableArray2.default)(transformedNestedList.content.content));
|
|
88
|
+
}
|
|
80
89
|
}
|
|
81
90
|
}
|
|
82
|
-
}
|
|
83
|
-
return
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// Create new list with transformed items
|
|
90
|
-
var newList = targetNodeType.create(null, newListItems);
|
|
91
|
-
|
|
92
|
-
// Replace the entire list
|
|
93
|
-
tr.replaceWith(listStart, listEnd, newList);
|
|
91
|
+
});
|
|
92
|
+
return targetNodeType.create(null, transformedItems);
|
|
93
|
+
};
|
|
94
|
+
var newList = _transformListRecursively(sourceList);
|
|
95
|
+
tr.replaceWith(listPos, listPos + sourceList.nodeSize, newList);
|
|
94
96
|
return tr;
|
|
95
97
|
} catch (_unused) {
|
|
96
98
|
return tr;
|
|
@@ -5,12 +5,11 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.transformListToBlockNodes = exports.transformListNode = exports.transformBlockToList = exports.transformBetweenListTypes = exports.liftListToBlockType = void 0;
|
|
7
7
|
var _transform = require("@atlaskit/editor-prosemirror/transform");
|
|
8
|
-
var _utils = require("@atlaskit/editor-prosemirror/utils");
|
|
9
8
|
var _transformBetweenListTypes = require("./list/transformBetweenListTypes");
|
|
10
9
|
var _transformOrderedUnorderedListToBlockNodes = require("./list/transformOrderedUnorderedListToBlockNodes");
|
|
11
10
|
var _transformTaskListToBlockNodes = require("./list/transformTaskListToBlockNodes");
|
|
12
11
|
var _transformToTaskList = require("./list/transformToTaskList");
|
|
13
|
-
var
|
|
12
|
+
var _utils = require("./utils");
|
|
14
13
|
/**
|
|
15
14
|
* Transform selection to list type
|
|
16
15
|
*/
|
|
@@ -27,7 +26,7 @@ var transformBlockToList = exports.transformBlockToList = function transformBloc
|
|
|
27
26
|
return null;
|
|
28
27
|
}
|
|
29
28
|
var nodes = tr.doc.type.schema.nodes;
|
|
30
|
-
var isTargetTask =
|
|
29
|
+
var isTargetTask = (0, _utils.isTaskList)(targetNodeType);
|
|
31
30
|
|
|
32
31
|
// Handle task lists differently due to their structure
|
|
33
32
|
if (isTargetTask) {
|
|
@@ -69,19 +68,19 @@ var transformListToBlockNodes = exports.transformListToBlockNodes = function tra
|
|
|
69
68
|
var transformListNode = exports.transformListNode = function transformListNode(context) {
|
|
70
69
|
var targetNodeType = context.targetNodeType;
|
|
71
70
|
// Transform list to block type
|
|
72
|
-
if ((0,
|
|
71
|
+
if ((0, _utils.isBlockNodeType)(targetNodeType)) {
|
|
73
72
|
// Lift list items out of the list and convert to target block type
|
|
74
73
|
return transformListToBlockNodes(context);
|
|
75
74
|
}
|
|
76
75
|
|
|
77
76
|
// Transform list to container type
|
|
78
|
-
if ((0,
|
|
77
|
+
if ((0, _utils.isContainerNodeType)(targetNodeType)) {
|
|
79
78
|
// Lift list items out of the list and convert to container type
|
|
80
79
|
return null;
|
|
81
80
|
}
|
|
82
81
|
|
|
83
82
|
// Transform between list types
|
|
84
|
-
if ((0,
|
|
83
|
+
if ((0, _utils.isListNodeType)(targetNodeType)) {
|
|
85
84
|
return transformBetweenListTypes(context);
|
|
86
85
|
}
|
|
87
86
|
return null;
|
|
@@ -98,37 +97,48 @@ var liftListToBlockType = exports.liftListToBlockType = function liftListToBlock
|
|
|
98
97
|
/**
|
|
99
98
|
* Transform between different list types
|
|
100
99
|
*/
|
|
101
|
-
var transformBetweenListTypes = exports.transformBetweenListTypes = function transformBetweenListTypes(
|
|
102
|
-
var tr =
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
100
|
+
var transformBetweenListTypes = exports.transformBetweenListTypes = function transformBetweenListTypes(context) {
|
|
101
|
+
var tr = context.tr,
|
|
102
|
+
sourceNode = context.sourceNode,
|
|
103
|
+
sourcePos = context.sourcePos,
|
|
104
|
+
targetNodeType = context.targetNodeType;
|
|
106
105
|
var nodes = tr.doc.type.schema.nodes;
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
var
|
|
110
|
-
|
|
111
|
-
var
|
|
112
|
-
if (!listNode) {
|
|
113
|
-
return null;
|
|
114
|
-
}
|
|
115
|
-
var sourceListType = listNode.node.type;
|
|
116
|
-
var isSourceBulletOrOrdered = sourceListType === nodes.bulletList || sourceListType === nodes.orderedList;
|
|
117
|
-
var isTargetTask = targetNodeType === nodes.taskList;
|
|
118
|
-
var isSourceTask = sourceListType === nodes.taskList;
|
|
119
|
-
var isTargetBulletOrOrdered = targetNodeType === nodes.bulletList || targetNodeType === nodes.orderedList;
|
|
106
|
+
var sourceListType = sourceNode.type;
|
|
107
|
+
var isSourceBulletOrOrdered = (0, _utils.isBulletOrOrderedList)(sourceListType);
|
|
108
|
+
var isTargetTask = (0, _utils.isTaskList)(targetNodeType);
|
|
109
|
+
var isSourceTask = (0, _utils.isTaskList)(sourceListType);
|
|
110
|
+
var isTargetBulletOrOrdered = (0, _utils.isBulletOrOrderedList)(targetNodeType);
|
|
120
111
|
|
|
121
112
|
// Check if we need structure transformation
|
|
122
113
|
var needsStructureTransform = isSourceBulletOrOrdered && isTargetTask || isSourceTask && isTargetBulletOrOrdered;
|
|
123
114
|
try {
|
|
124
115
|
if (!needsStructureTransform) {
|
|
125
116
|
// Simple type change for same structure lists (bullet <-> ordered)
|
|
126
|
-
|
|
117
|
+
// Apply to the main list
|
|
118
|
+
tr.setNodeMarkup(sourcePos, targetNodeType);
|
|
119
|
+
|
|
120
|
+
// Apply to nested lists
|
|
121
|
+
var listStart = sourcePos;
|
|
122
|
+
var listEnd = sourcePos + sourceNode.nodeSize;
|
|
123
|
+
var supportedListTypesSet = (0, _utils.getSupportedListTypesSet)(nodes);
|
|
124
|
+
tr.doc.nodesBetween(listStart, listEnd, function (node, pos, parent) {
|
|
125
|
+
// Only process nested lists (not the root list we already handled)
|
|
126
|
+
if (supportedListTypesSet.has(node.type) && pos !== sourcePos) {
|
|
127
|
+
var isNestedList = parent && (supportedListTypesSet.has(parent.type) || parent.type === nodes.listItem);
|
|
128
|
+
if (isNestedList) {
|
|
129
|
+
var shouldTransformNode = node.type === sourceListType || (0, _utils.isBulletOrOrderedList)(node.type) && isTargetBulletOrOrdered;
|
|
130
|
+
if (shouldTransformNode) {
|
|
131
|
+
tr.setNodeMarkup(pos, targetNodeType);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return true; // Continue traversing
|
|
136
|
+
});
|
|
137
|
+
return tr;
|
|
127
138
|
} else {
|
|
128
|
-
|
|
139
|
+
return (0, _transformBetweenListTypes.transformListStructure)(context);
|
|
129
140
|
}
|
|
130
141
|
} catch (_unused) {
|
|
131
142
|
return null;
|
|
132
143
|
}
|
|
133
|
-
return tr;
|
|
134
144
|
};
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.isListNodeType = exports.isListNode = exports.isContainerNodeType = exports.isContainerNode = exports.isBlockNodeType = exports.isBlockNode = exports.getTargetNodeInfo = void 0;
|
|
6
|
+
exports.isTaskList = exports.isListNodeType = exports.isListNode = exports.isContainerNodeType = exports.isContainerNode = exports.isBulletOrOrderedList = exports.isBlockNodeType = exports.isBlockNode = exports.getTargetNodeInfo = exports.getSupportedListTypesSet = exports.getSupportedListTypes = void 0;
|
|
7
7
|
var getTargetNodeInfo = exports.getTargetNodeInfo = function getTargetNodeInfo(targetType, nodes) {
|
|
8
8
|
switch (targetType) {
|
|
9
9
|
case 'heading1':
|
|
@@ -93,7 +93,7 @@ var isBlockNode = exports.isBlockNode = function isBlockNode(node) {
|
|
|
93
93
|
return ['paragraph', 'heading', 'codeBlock'].includes(node.type.name);
|
|
94
94
|
};
|
|
95
95
|
var isListNode = exports.isListNode = function isListNode(node) {
|
|
96
|
-
return ['bulletList', 'orderedList', 'taskList'
|
|
96
|
+
return ['bulletList', 'orderedList', 'taskList'].includes(node.type.name);
|
|
97
97
|
};
|
|
98
98
|
var isContainerNode = exports.isContainerNode = function isContainerNode(node) {
|
|
99
99
|
return ['panel', 'expand', 'blockquote'].includes(node.type.name);
|
|
@@ -106,4 +106,18 @@ var isListNodeType = exports.isListNodeType = function isListNodeType(nodeType)
|
|
|
106
106
|
};
|
|
107
107
|
var isContainerNodeType = exports.isContainerNodeType = function isContainerNodeType(nodeType) {
|
|
108
108
|
return ['panel', 'expand', 'blockquote'].includes(nodeType.name);
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
// List type utilities
|
|
112
|
+
var isBulletOrOrderedList = exports.isBulletOrOrderedList = function isBulletOrOrderedList(nodeType) {
|
|
113
|
+
return nodeType.name === 'bulletList' || nodeType.name === 'orderedList';
|
|
114
|
+
};
|
|
115
|
+
var isTaskList = exports.isTaskList = function isTaskList(nodeType) {
|
|
116
|
+
return nodeType.name === 'taskList';
|
|
117
|
+
};
|
|
118
|
+
var getSupportedListTypes = exports.getSupportedListTypes = function getSupportedListTypes(nodes) {
|
|
119
|
+
return [nodes.bulletList, nodes.orderedList, nodes.taskList].filter(Boolean);
|
|
120
|
+
};
|
|
121
|
+
var getSupportedListTypesSet = exports.getSupportedListTypesSet = function getSupportedListTypesSet(nodes) {
|
|
122
|
+
return new Set(getSupportedListTypes(nodes));
|
|
109
123
|
};
|
|
@@ -17,7 +17,7 @@ export const formatNode = targetType => {
|
|
|
17
17
|
|
|
18
18
|
// Find the node to format from the current selection
|
|
19
19
|
let nodeToFormat;
|
|
20
|
-
let nodePos =
|
|
20
|
+
let nodePos = selection.from;
|
|
21
21
|
|
|
22
22
|
// Try to find the current node from selection
|
|
23
23
|
const selectedNode = findSelectedNodeOfType([nodes.paragraph, nodes.heading, nodes.blockquote, nodes.panel, nodes.expand, nodes.codeBlock, nodes.bulletList, nodes.orderedList, nodes.taskList, nodes.layoutSection])(selection);
|
|
@@ -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,9 @@
|
|
|
1
1
|
import { findWrapping } from '@atlaskit/editor-prosemirror/transform';
|
|
2
|
-
import { findParentNodeOfType } from '@atlaskit/editor-prosemirror/utils';
|
|
3
2
|
import { transformListStructure } from './list/transformBetweenListTypes';
|
|
4
3
|
import { transformOrderedUnorderedListToBlockNodes } from './list/transformOrderedUnorderedListToBlockNodes';
|
|
5
4
|
import { transformTaskListToBlockNodes } from './list/transformTaskListToBlockNodes';
|
|
6
5
|
import { transformToTaskList } from './list/transformToTaskList';
|
|
7
|
-
import { isBlockNodeType, isContainerNodeType, isListNodeType } from './utils';
|
|
6
|
+
import { getSupportedListTypesSet, isBulletOrOrderedList, isBlockNodeType, isContainerNodeType, isListNodeType, isTaskList } from './utils';
|
|
8
7
|
|
|
9
8
|
/**
|
|
10
9
|
* Transform selection to list type
|
|
@@ -27,7 +26,7 @@ export const transformBlockToList = context => {
|
|
|
27
26
|
const {
|
|
28
27
|
nodes
|
|
29
28
|
} = tr.doc.type.schema;
|
|
30
|
-
const isTargetTask = targetNodeType
|
|
29
|
+
const isTargetTask = isTaskList(targetNodeType);
|
|
31
30
|
|
|
32
31
|
// Handle task lists differently due to their structure
|
|
33
32
|
if (isTargetTask) {
|
|
@@ -102,41 +101,52 @@ export const liftListToBlockType = () => {
|
|
|
102
101
|
/**
|
|
103
102
|
* Transform between different list types
|
|
104
103
|
*/
|
|
105
|
-
export const transformBetweenListTypes =
|
|
106
|
-
tr,
|
|
107
|
-
targetNodeType
|
|
108
|
-
}) => {
|
|
104
|
+
export const transformBetweenListTypes = context => {
|
|
109
105
|
const {
|
|
110
|
-
|
|
111
|
-
|
|
106
|
+
tr,
|
|
107
|
+
sourceNode,
|
|
108
|
+
sourcePos,
|
|
109
|
+
targetNodeType
|
|
110
|
+
} = context;
|
|
112
111
|
const {
|
|
113
112
|
nodes
|
|
114
113
|
} = 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;
|
|
114
|
+
const sourceListType = sourceNode.type;
|
|
115
|
+
const isSourceBulletOrOrdered = isBulletOrOrderedList(sourceListType);
|
|
116
|
+
const isTargetTask = isTaskList(targetNodeType);
|
|
117
|
+
const isSourceTask = isTaskList(sourceListType);
|
|
118
|
+
const isTargetBulletOrOrdered = isBulletOrOrderedList(targetNodeType);
|
|
128
119
|
|
|
129
120
|
// Check if we need structure transformation
|
|
130
121
|
const needsStructureTransform = isSourceBulletOrOrdered && isTargetTask || isSourceTask && isTargetBulletOrOrdered;
|
|
131
122
|
try {
|
|
132
123
|
if (!needsStructureTransform) {
|
|
133
124
|
// Simple type change for same structure lists (bullet <-> ordered)
|
|
134
|
-
|
|
125
|
+
// Apply to the main list
|
|
126
|
+
tr.setNodeMarkup(sourcePos, targetNodeType);
|
|
127
|
+
|
|
128
|
+
// Apply to nested lists
|
|
129
|
+
const listStart = sourcePos;
|
|
130
|
+
const listEnd = sourcePos + sourceNode.nodeSize;
|
|
131
|
+
const supportedListTypesSet = getSupportedListTypesSet(nodes);
|
|
132
|
+
tr.doc.nodesBetween(listStart, listEnd, (node, pos, parent) => {
|
|
133
|
+
// Only process nested lists (not the root list we already handled)
|
|
134
|
+
if (supportedListTypesSet.has(node.type) && pos !== sourcePos) {
|
|
135
|
+
const isNestedList = parent && (supportedListTypesSet.has(parent.type) || parent.type === nodes.listItem);
|
|
136
|
+
if (isNestedList) {
|
|
137
|
+
const shouldTransformNode = node.type === sourceListType || isBulletOrOrderedList(node.type) && isTargetBulletOrOrdered;
|
|
138
|
+
if (shouldTransformNode) {
|
|
139
|
+
tr.setNodeMarkup(pos, targetNodeType);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return true; // Continue traversing
|
|
144
|
+
});
|
|
145
|
+
return tr;
|
|
135
146
|
} else {
|
|
136
|
-
|
|
147
|
+
return transformListStructure(context);
|
|
137
148
|
}
|
|
138
149
|
} catch {
|
|
139
150
|
return null;
|
|
140
151
|
}
|
|
141
|
-
return tr;
|
|
142
152
|
};
|
|
@@ -87,7 +87,7 @@ export const isBlockNode = node => {
|
|
|
87
87
|
return ['paragraph', 'heading', 'codeBlock'].includes(node.type.name);
|
|
88
88
|
};
|
|
89
89
|
export const isListNode = node => {
|
|
90
|
-
return ['bulletList', 'orderedList', 'taskList'
|
|
90
|
+
return ['bulletList', 'orderedList', 'taskList'].includes(node.type.name);
|
|
91
91
|
};
|
|
92
92
|
export const isContainerNode = node => {
|
|
93
93
|
return ['panel', 'expand', 'blockquote'].includes(node.type.name);
|
|
@@ -100,4 +100,18 @@ export const isListNodeType = nodeType => {
|
|
|
100
100
|
};
|
|
101
101
|
export const isContainerNodeType = nodeType => {
|
|
102
102
|
return ['panel', 'expand', 'blockquote'].includes(nodeType.name);
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
// List type utilities
|
|
106
|
+
export const isBulletOrOrderedList = nodeType => {
|
|
107
|
+
return nodeType.name === 'bulletList' || nodeType.name === 'orderedList';
|
|
108
|
+
};
|
|
109
|
+
export const isTaskList = nodeType => {
|
|
110
|
+
return nodeType.name === 'taskList';
|
|
111
|
+
};
|
|
112
|
+
export const getSupportedListTypes = nodes => {
|
|
113
|
+
return [nodes.bulletList, nodes.orderedList, nodes.taskList].filter(Boolean);
|
|
114
|
+
};
|
|
115
|
+
export const getSupportedListTypesSet = nodes => {
|
|
116
|
+
return new Set(getSupportedListTypes(nodes));
|
|
103
117
|
};
|
|
@@ -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);
|
|
@@ -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;
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { findWrapping } from '@atlaskit/editor-prosemirror/transform';
|
|
2
|
-
import { findParentNodeOfType } from '@atlaskit/editor-prosemirror/utils';
|
|
3
2
|
import { transformListStructure } from './list/transformBetweenListTypes';
|
|
4
3
|
import { transformOrderedUnorderedListToBlockNodes } from './list/transformOrderedUnorderedListToBlockNodes';
|
|
5
4
|
import { transformTaskListToBlockNodes } from './list/transformTaskListToBlockNodes';
|
|
6
5
|
import { transformToTaskList } from './list/transformToTaskList';
|
|
7
|
-
import { isBlockNodeType, isContainerNodeType, isListNodeType } from './utils';
|
|
6
|
+
import { getSupportedListTypesSet, isBulletOrOrderedList, isBlockNodeType, isContainerNodeType, isListNodeType, isTaskList } from './utils';
|
|
8
7
|
|
|
9
8
|
/**
|
|
10
9
|
* Transform selection to list type
|
|
@@ -22,7 +21,7 @@ export var transformBlockToList = function transformBlockToList(context) {
|
|
|
22
21
|
return null;
|
|
23
22
|
}
|
|
24
23
|
var nodes = tr.doc.type.schema.nodes;
|
|
25
|
-
var isTargetTask = targetNodeType
|
|
24
|
+
var isTargetTask = isTaskList(targetNodeType);
|
|
26
25
|
|
|
27
26
|
// Handle task lists differently due to their structure
|
|
28
27
|
if (isTargetTask) {
|
|
@@ -93,37 +92,48 @@ export var liftListToBlockType = function liftListToBlockType() {
|
|
|
93
92
|
/**
|
|
94
93
|
* Transform between different list types
|
|
95
94
|
*/
|
|
96
|
-
export var transformBetweenListTypes = function transformBetweenListTypes(
|
|
97
|
-
var tr =
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
95
|
+
export var transformBetweenListTypes = function transformBetweenListTypes(context) {
|
|
96
|
+
var tr = context.tr,
|
|
97
|
+
sourceNode = context.sourceNode,
|
|
98
|
+
sourcePos = context.sourcePos,
|
|
99
|
+
targetNodeType = context.targetNodeType;
|
|
101
100
|
var nodes = tr.doc.type.schema.nodes;
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
var
|
|
105
|
-
|
|
106
|
-
var
|
|
107
|
-
if (!listNode) {
|
|
108
|
-
return null;
|
|
109
|
-
}
|
|
110
|
-
var sourceListType = listNode.node.type;
|
|
111
|
-
var isSourceBulletOrOrdered = sourceListType === nodes.bulletList || sourceListType === nodes.orderedList;
|
|
112
|
-
var isTargetTask = targetNodeType === nodes.taskList;
|
|
113
|
-
var isSourceTask = sourceListType === nodes.taskList;
|
|
114
|
-
var isTargetBulletOrOrdered = targetNodeType === nodes.bulletList || targetNodeType === nodes.orderedList;
|
|
101
|
+
var sourceListType = sourceNode.type;
|
|
102
|
+
var isSourceBulletOrOrdered = isBulletOrOrderedList(sourceListType);
|
|
103
|
+
var isTargetTask = isTaskList(targetNodeType);
|
|
104
|
+
var isSourceTask = isTaskList(sourceListType);
|
|
105
|
+
var isTargetBulletOrOrdered = isBulletOrOrderedList(targetNodeType);
|
|
115
106
|
|
|
116
107
|
// Check if we need structure transformation
|
|
117
108
|
var needsStructureTransform = isSourceBulletOrOrdered && isTargetTask || isSourceTask && isTargetBulletOrOrdered;
|
|
118
109
|
try {
|
|
119
110
|
if (!needsStructureTransform) {
|
|
120
111
|
// Simple type change for same structure lists (bullet <-> ordered)
|
|
121
|
-
|
|
112
|
+
// Apply to the main list
|
|
113
|
+
tr.setNodeMarkup(sourcePos, targetNodeType);
|
|
114
|
+
|
|
115
|
+
// Apply to nested lists
|
|
116
|
+
var listStart = sourcePos;
|
|
117
|
+
var listEnd = sourcePos + sourceNode.nodeSize;
|
|
118
|
+
var supportedListTypesSet = getSupportedListTypesSet(nodes);
|
|
119
|
+
tr.doc.nodesBetween(listStart, listEnd, function (node, pos, parent) {
|
|
120
|
+
// Only process nested lists (not the root list we already handled)
|
|
121
|
+
if (supportedListTypesSet.has(node.type) && pos !== sourcePos) {
|
|
122
|
+
var isNestedList = parent && (supportedListTypesSet.has(parent.type) || parent.type === nodes.listItem);
|
|
123
|
+
if (isNestedList) {
|
|
124
|
+
var shouldTransformNode = node.type === sourceListType || isBulletOrOrderedList(node.type) && isTargetBulletOrOrdered;
|
|
125
|
+
if (shouldTransformNode) {
|
|
126
|
+
tr.setNodeMarkup(pos, targetNodeType);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return true; // Continue traversing
|
|
131
|
+
});
|
|
132
|
+
return tr;
|
|
122
133
|
} else {
|
|
123
|
-
|
|
134
|
+
return transformListStructure(context);
|
|
124
135
|
}
|
|
125
136
|
} catch (_unused) {
|
|
126
137
|
return null;
|
|
127
138
|
}
|
|
128
|
-
return tr;
|
|
129
139
|
};
|
|
@@ -87,7 +87,7 @@ export var isBlockNode = function isBlockNode(node) {
|
|
|
87
87
|
return ['paragraph', 'heading', 'codeBlock'].includes(node.type.name);
|
|
88
88
|
};
|
|
89
89
|
export var isListNode = function isListNode(node) {
|
|
90
|
-
return ['bulletList', 'orderedList', 'taskList'
|
|
90
|
+
return ['bulletList', 'orderedList', 'taskList'].includes(node.type.name);
|
|
91
91
|
};
|
|
92
92
|
export var isContainerNode = function isContainerNode(node) {
|
|
93
93
|
return ['panel', 'expand', 'blockquote'].includes(node.type.name);
|
|
@@ -100,4 +100,18 @@ export var isListNodeType = function isListNodeType(nodeType) {
|
|
|
100
100
|
};
|
|
101
101
|
export var isContainerNodeType = function isContainerNodeType(nodeType) {
|
|
102
102
|
return ['panel', 'expand', 'blockquote'].includes(nodeType.name);
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
// List type utilities
|
|
106
|
+
export var isBulletOrOrderedList = function isBulletOrOrderedList(nodeType) {
|
|
107
|
+
return nodeType.name === 'bulletList' || nodeType.name === 'orderedList';
|
|
108
|
+
};
|
|
109
|
+
export var isTaskList = function isTaskList(nodeType) {
|
|
110
|
+
return nodeType.name === 'taskList';
|
|
111
|
+
};
|
|
112
|
+
export var getSupportedListTypes = function getSupportedListTypes(nodes) {
|
|
113
|
+
return [nodes.bulletList, nodes.orderedList, nodes.taskList].filter(Boolean);
|
|
114
|
+
};
|
|
115
|
+
export var getSupportedListTypesSet = function getSupportedListTypesSet(nodes) {
|
|
116
|
+
return new Set(getSupportedListTypes(nodes));
|
|
103
117
|
};
|
|
@@ -1,9 +1,5 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type { Transaction } from '@atlaskit/editor-prosemirror/state';
|
|
1
|
+
import type { TransformContext } from '../types';
|
|
3
2
|
/**
|
|
4
|
-
* Transform list structure
|
|
3
|
+
* Transform list structure between different list types
|
|
5
4
|
*/
|
|
6
|
-
export declare const transformListStructure: (
|
|
7
|
-
node: PMNode;
|
|
8
|
-
pos: number;
|
|
9
|
-
}, targetNodeType: NodeType, nodes: Record<string, NodeType>) => Transaction;
|
|
5
|
+
export declare const transformListStructure: (context: TransformContext) => import("prosemirror-state").Transaction;
|
|
@@ -19,4 +19,4 @@ export declare const liftListToBlockType: () => null;
|
|
|
19
19
|
/**
|
|
20
20
|
* Transform between different list types
|
|
21
21
|
*/
|
|
22
|
-
export declare const transformBetweenListTypes: (
|
|
22
|
+
export declare const transformBetweenListTypes: (context: TransformContext) => Transaction | null;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
|
|
2
2
|
import type { Transaction } from '@atlaskit/editor-prosemirror/state';
|
|
3
3
|
import type { FormatNodeTargetType } from './types';
|
|
4
|
-
export declare function transformNodeToTargetType(tr: Transaction, sourceNode: PMNode, sourcePos: number
|
|
4
|
+
export declare function transformNodeToTargetType(tr: Transaction, sourceNode: PMNode, sourcePos: number, targetType: FormatNodeTargetType): Transaction | null;
|
|
@@ -3,7 +3,7 @@ import type { Transaction } from '@atlaskit/editor-prosemirror/state';
|
|
|
3
3
|
export type FormatNodeTargetType = 'heading1' | 'heading2' | 'heading3' | 'heading4' | 'heading5' | 'heading6' | 'paragraph' | 'blockquote' | 'expand' | 'layout' | 'panel' | 'codeBlock' | 'bulletList' | 'orderedList' | 'taskList';
|
|
4
4
|
export interface TransformContext {
|
|
5
5
|
sourceNode: PMNode;
|
|
6
|
-
sourcePos: number
|
|
6
|
+
sourcePos: number;
|
|
7
7
|
targetAttrs?: Record<string, unknown>;
|
|
8
8
|
targetNodeType: NodeType;
|
|
9
9
|
tr: Transaction;
|
|
@@ -10,3 +10,7 @@ export declare const isContainerNode: (node: PMNode) => boolean;
|
|
|
10
10
|
export declare const isBlockNodeType: (nodeType: NodeType) => boolean;
|
|
11
11
|
export declare const isListNodeType: (nodeType: NodeType) => boolean;
|
|
12
12
|
export declare const isContainerNodeType: (nodeType: NodeType) => boolean;
|
|
13
|
+
export declare const isBulletOrOrderedList: (nodeType: NodeType) => boolean;
|
|
14
|
+
export declare const isTaskList: (nodeType: NodeType) => boolean;
|
|
15
|
+
export declare const getSupportedListTypes: (nodes: Record<string, NodeType>) => NodeType[];
|
|
16
|
+
export declare const getSupportedListTypesSet: (nodes: Record<string, NodeType>) => Set<NodeType>;
|
|
@@ -1,9 +1,5 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type { Transaction } from '@atlaskit/editor-prosemirror/state';
|
|
1
|
+
import type { TransformContext } from '../types';
|
|
3
2
|
/**
|
|
4
|
-
* Transform list structure
|
|
3
|
+
* Transform list structure between different list types
|
|
5
4
|
*/
|
|
6
|
-
export declare const transformListStructure: (
|
|
7
|
-
node: PMNode;
|
|
8
|
-
pos: number;
|
|
9
|
-
}, targetNodeType: NodeType, nodes: Record<string, NodeType>) => Transaction;
|
|
5
|
+
export declare const transformListStructure: (context: TransformContext) => import("prosemirror-state").Transaction;
|
|
@@ -19,4 +19,4 @@ export declare const liftListToBlockType: () => null;
|
|
|
19
19
|
/**
|
|
20
20
|
* Transform between different list types
|
|
21
21
|
*/
|
|
22
|
-
export declare const transformBetweenListTypes: (
|
|
22
|
+
export declare const transformBetweenListTypes: (context: TransformContext) => Transaction | null;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
|
|
2
2
|
import type { Transaction } from '@atlaskit/editor-prosemirror/state';
|
|
3
3
|
import type { FormatNodeTargetType } from './types';
|
|
4
|
-
export declare function transformNodeToTargetType(tr: Transaction, sourceNode: PMNode, sourcePos: number
|
|
4
|
+
export declare function transformNodeToTargetType(tr: Transaction, sourceNode: PMNode, sourcePos: number, targetType: FormatNodeTargetType): Transaction | null;
|
|
@@ -3,7 +3,7 @@ import type { Transaction } from '@atlaskit/editor-prosemirror/state';
|
|
|
3
3
|
export type FormatNodeTargetType = 'heading1' | 'heading2' | 'heading3' | 'heading4' | 'heading5' | 'heading6' | 'paragraph' | 'blockquote' | 'expand' | 'layout' | 'panel' | 'codeBlock' | 'bulletList' | 'orderedList' | 'taskList';
|
|
4
4
|
export interface TransformContext {
|
|
5
5
|
sourceNode: PMNode;
|
|
6
|
-
sourcePos: number
|
|
6
|
+
sourcePos: number;
|
|
7
7
|
targetAttrs?: Record<string, unknown>;
|
|
8
8
|
targetNodeType: NodeType;
|
|
9
9
|
tr: Transaction;
|
|
@@ -10,3 +10,7 @@ export declare const isContainerNode: (node: PMNode) => boolean;
|
|
|
10
10
|
export declare const isBlockNodeType: (nodeType: NodeType) => boolean;
|
|
11
11
|
export declare const isListNodeType: (nodeType: NodeType) => boolean;
|
|
12
12
|
export declare const isContainerNodeType: (nodeType: NodeType) => boolean;
|
|
13
|
+
export declare const isBulletOrOrderedList: (nodeType: NodeType) => boolean;
|
|
14
|
+
export declare const isTaskList: (nodeType: NodeType) => boolean;
|
|
15
|
+
export declare const getSupportedListTypes: (nodes: Record<string, NodeType>) => NodeType[];
|
|
16
|
+
export declare const getSupportedListTypesSet: (nodes: Record<string, NodeType>) => Set<NodeType>;
|
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.4",
|
|
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.13.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",
|
|
@@ -37,16 +37,16 @@
|
|
|
37
37
|
"@atlaskit/editor-prosemirror": "7.0.0",
|
|
38
38
|
"@atlaskit/editor-shared-styles": "^3.6.0",
|
|
39
39
|
"@atlaskit/editor-tables": "^2.9.0",
|
|
40
|
-
"@atlaskit/editor-toolbar": "^0.
|
|
40
|
+
"@atlaskit/editor-toolbar": "^0.8.0",
|
|
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.13.0",
|
|
45
|
+
"@atlaskit/tokens": "^6.2.0",
|
|
46
46
|
"@babel/runtime": "^7.0.0"
|
|
47
47
|
},
|
|
48
48
|
"peerDependencies": {
|
|
49
|
-
"@atlaskit/editor-common": "^108.
|
|
49
|
+
"@atlaskit/editor-common": "^108.2.0",
|
|
50
50
|
"react": "^18.2.0",
|
|
51
51
|
"react-intl-next": "npm:react-intl@^5.18.1"
|
|
52
52
|
},
|