@atlaskit/editor-plugin-block-menu 9.0.19 → 9.1.1
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 +17 -0
- package/dist/cjs/editor-commands/transform-node-utils/TRANSFORMATION_MATRIX.js +5 -5
- package/dist/cjs/editor-commands/transform-node-utils/{unwrapExpandStep.js → steps/unwrapExpandStep.js} +1 -1
- package/dist/cjs/editor-commands/transform-node-utils/{wrapIntoListStep.js → steps/wrapIntoListStep.js} +2 -2
- package/dist/cjs/editor-commands/transform-node-utils/{wrapStep.js → steps/wrapStep.js} +2 -2
- package/dist/cjs/editor-commands/transform-node-utils/utils.js +4 -1
- package/dist/cjs/editor-commands/transformNode.js +1 -1
- package/dist/es2019/editor-commands/transform-node-utils/TRANSFORMATION_MATRIX.js +5 -6
- package/dist/es2019/editor-commands/transform-node-utils/{unwrapExpandStep.js → steps/unwrapExpandStep.js} +1 -1
- package/dist/es2019/editor-commands/transform-node-utils/{wrapIntoListStep.js → steps/wrapIntoListStep.js} +2 -2
- package/dist/es2019/editor-commands/transform-node-utils/{wrapStep.js → steps/wrapStep.js} +2 -2
- package/dist/es2019/editor-commands/transform-node-utils/utils.js +3 -0
- package/dist/es2019/editor-commands/transformNode.js +1 -1
- package/dist/esm/editor-commands/transform-node-utils/TRANSFORMATION_MATRIX.js +5 -6
- package/dist/esm/editor-commands/transform-node-utils/{unwrapExpandStep.js → steps/unwrapExpandStep.js} +1 -1
- package/dist/esm/editor-commands/transform-node-utils/{wrapIntoListStep.js → steps/wrapIntoListStep.js} +2 -2
- package/dist/esm/editor-commands/transform-node-utils/{wrapStep.js → steps/wrapStep.js} +2 -2
- package/dist/esm/editor-commands/transform-node-utils/utils.js +3 -0
- package/dist/esm/editor-commands/transformNode.js +1 -1
- package/dist/types/blockMenuPluginType.d.ts +1 -1
- package/dist/types/editor-commands/selection.d.ts +1 -1
- package/dist/types/editor-commands/transform-node-utils/{flattenStep.d.ts → steps/flattenStep.d.ts} +1 -1
- package/dist/types/editor-commands/transform-node-utils/{unwrapExpandStep.d.ts → steps/unwrapExpandStep.d.ts} +1 -1
- package/dist/types/editor-commands/transform-node-utils/{unwrapStep.d.ts → steps/unwrapStep.d.ts} +1 -1
- package/dist/{types-ts4.5/editor-commands/transform-node-utils → types/editor-commands/transform-node-utils/steps}/wrapIntoListStep.d.ts +1 -1
- package/dist/types/editor-commands/transform-node-utils/{wrapStep.d.ts → steps/wrapStep.d.ts} +1 -1
- package/dist/types/editor-commands/transform-node-utils/utils.d.ts +1 -0
- package/dist/types/editor-commands/transformNode.d.ts +1 -1
- package/dist/{types-ts4.5/editor-commands/transforms → types/editor-commands}/types.d.ts +0 -3
- package/dist/types/index.d.ts +1 -1
- package/dist/types-ts4.5/blockMenuPluginType.d.ts +1 -1
- package/dist/types-ts4.5/editor-commands/selection.d.ts +1 -1
- package/dist/types-ts4.5/editor-commands/transform-node-utils/{flattenStep.d.ts → steps/flattenStep.d.ts} +1 -1
- package/dist/types-ts4.5/editor-commands/transform-node-utils/{unwrapExpandStep.d.ts → steps/unwrapExpandStep.d.ts} +1 -1
- package/dist/types-ts4.5/editor-commands/transform-node-utils/{unwrapStep.d.ts → steps/unwrapStep.d.ts} +1 -1
- package/dist/{types/editor-commands/transform-node-utils → types-ts4.5/editor-commands/transform-node-utils/steps}/wrapIntoListStep.d.ts +1 -1
- package/dist/types-ts4.5/editor-commands/transform-node-utils/{wrapStep.d.ts → steps/wrapStep.d.ts} +1 -1
- package/dist/types-ts4.5/editor-commands/transform-node-utils/utils.d.ts +1 -0
- package/dist/types-ts4.5/editor-commands/transformNode.d.ts +1 -1
- package/dist/{types/editor-commands/transforms → types-ts4.5/editor-commands}/types.d.ts +0 -3
- package/dist/types-ts4.5/index.d.ts +1 -1
- package/docs/0-intro.tsx +5 -5
- package/package.json +4 -4
- package/dist/cjs/editor-commands/transforms/block-transforms.js +0 -55
- package/dist/cjs/editor-commands/transforms/container-transforms.js +0 -448
- package/dist/cjs/editor-commands/transforms/inline-node-transforms.js +0 -39
- package/dist/cjs/editor-commands/transforms/layout/utils.js +0 -355
- package/dist/cjs/editor-commands/transforms/layout-transforms.js +0 -79
- package/dist/cjs/editor-commands/transforms/list/transformOrderedUnorderedListToBlockNodes.js +0 -97
- package/dist/cjs/editor-commands/transforms/list/transformTaskListToBlockNodes.js +0 -59
- package/dist/cjs/editor-commands/transforms/list/transformToTaskList.js +0 -44
- package/dist/cjs/editor-commands/transforms/list-transforms.js +0 -161
- package/dist/cjs/editor-commands/transforms/transformNodeToTargetType.js +0 -77
- package/dist/cjs/editor-commands/transforms/utils.js +0 -260
- package/dist/es2019/editor-commands/transforms/block-transforms.js +0 -58
- package/dist/es2019/editor-commands/transforms/container-transforms.js +0 -449
- package/dist/es2019/editor-commands/transforms/inline-node-transforms.js +0 -33
- package/dist/es2019/editor-commands/transforms/layout/utils.js +0 -334
- package/dist/es2019/editor-commands/transforms/layout-transforms.js +0 -75
- package/dist/es2019/editor-commands/transforms/list/transformOrderedUnorderedListToBlockNodes.js +0 -93
- package/dist/es2019/editor-commands/transforms/list/transformTaskListToBlockNodes.js +0 -47
- package/dist/es2019/editor-commands/transforms/list/transformToTaskList.js +0 -38
- package/dist/es2019/editor-commands/transforms/list-transforms.js +0 -168
- package/dist/es2019/editor-commands/transforms/transformNodeToTargetType.js +0 -76
- package/dist/es2019/editor-commands/transforms/utils.js +0 -248
- package/dist/esm/editor-commands/transforms/block-transforms.js +0 -50
- package/dist/esm/editor-commands/transforms/container-transforms.js +0 -441
- package/dist/esm/editor-commands/transforms/inline-node-transforms.js +0 -33
- package/dist/esm/editor-commands/transforms/layout/utils.js +0 -348
- package/dist/esm/editor-commands/transforms/layout-transforms.js +0 -72
- package/dist/esm/editor-commands/transforms/list/transformOrderedUnorderedListToBlockNodes.js +0 -90
- package/dist/esm/editor-commands/transforms/list/transformTaskListToBlockNodes.js +0 -53
- package/dist/esm/editor-commands/transforms/list/transformToTaskList.js +0 -37
- package/dist/esm/editor-commands/transforms/list-transforms.js +0 -155
- package/dist/esm/editor-commands/transforms/transformNodeToTargetType.js +0 -72
- package/dist/esm/editor-commands/transforms/utils.js +0 -253
- package/dist/types/editor-commands/transforms/block-transforms.d.ts +0 -5
- package/dist/types/editor-commands/transforms/container-transforms.d.ts +0 -20
- package/dist/types/editor-commands/transforms/inline-node-transforms.d.ts +0 -6
- package/dist/types/editor-commands/transforms/layout/utils.d.ts +0 -5
- package/dist/types/editor-commands/transforms/layout-transforms.d.ts +0 -6
- package/dist/types/editor-commands/transforms/list/transformOrderedUnorderedListToBlockNodes.d.ts +0 -3
- package/dist/types/editor-commands/transforms/list/transformTaskListToBlockNodes.d.ts +0 -3
- package/dist/types/editor-commands/transforms/list/transformToTaskList.d.ts +0 -10
- package/dist/types/editor-commands/transforms/list-transforms.d.ts +0 -23
- package/dist/types/editor-commands/transforms/transformNodeToTargetType.d.ts +0 -14
- package/dist/types/editor-commands/transforms/utils.d.ts +0 -45
- package/dist/types-ts4.5/editor-commands/transforms/block-transforms.d.ts +0 -5
- package/dist/types-ts4.5/editor-commands/transforms/container-transforms.d.ts +0 -20
- package/dist/types-ts4.5/editor-commands/transforms/inline-node-transforms.d.ts +0 -6
- package/dist/types-ts4.5/editor-commands/transforms/layout/utils.d.ts +0 -5
- package/dist/types-ts4.5/editor-commands/transforms/layout-transforms.d.ts +0 -6
- package/dist/types-ts4.5/editor-commands/transforms/list/transformOrderedUnorderedListToBlockNodes.d.ts +0 -3
- package/dist/types-ts4.5/editor-commands/transforms/list/transformTaskListToBlockNodes.d.ts +0 -3
- package/dist/types-ts4.5/editor-commands/transforms/list/transformToTaskList.d.ts +0 -10
- package/dist/types-ts4.5/editor-commands/transforms/list-transforms.d.ts +0 -23
- package/dist/types-ts4.5/editor-commands/transforms/transformNodeToTargetType.d.ts +0 -14
- package/dist/types-ts4.5/editor-commands/transforms/utils.d.ts +0 -45
- /package/dist/cjs/editor-commands/transform-node-utils/{flattenStep.js → steps/flattenStep.js} +0 -0
- /package/dist/cjs/editor-commands/transform-node-utils/{unwrapStep.js → steps/unwrapStep.js} +0 -0
- /package/dist/cjs/editor-commands/{transforms/types.js → types.js} +0 -0
- /package/dist/es2019/editor-commands/transform-node-utils/{flattenStep.js → steps/flattenStep.js} +0 -0
- /package/dist/es2019/editor-commands/transform-node-utils/{unwrapStep.js → steps/unwrapStep.js} +0 -0
- /package/dist/es2019/editor-commands/{transforms/types.js → types.js} +0 -0
- /package/dist/esm/editor-commands/transform-node-utils/{flattenStep.js → steps/flattenStep.js} +0 -0
- /package/dist/esm/editor-commands/transform-node-utils/{unwrapStep.js → steps/unwrapStep.js} +0 -0
- /package/dist/esm/editor-commands/{transforms/types.js → types.js} +0 -0
|
@@ -1,168 +0,0 @@
|
|
|
1
|
-
import { transformBetweenListTypes, isTaskList } from '@atlaskit/editor-common/transforms';
|
|
2
|
-
import { Fragment } from '@atlaskit/editor-prosemirror/model';
|
|
3
|
-
import { findWrapping } from '@atlaskit/editor-prosemirror/transform';
|
|
4
|
-
import { transformOrderedUnorderedListToBlockNodes } from './list/transformOrderedUnorderedListToBlockNodes';
|
|
5
|
-
import { transformTaskListToBlockNodes } from './list/transformTaskListToBlockNodes';
|
|
6
|
-
import { transformToTaskList } from './list/transformToTaskList';
|
|
7
|
-
import { isBlockNodeType, isContainerNodeType, isListNodeType } from './utils';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Transform selection to list type
|
|
11
|
-
*/
|
|
12
|
-
export const transformBlockToList = context => {
|
|
13
|
-
const {
|
|
14
|
-
tr,
|
|
15
|
-
sourceNode,
|
|
16
|
-
targetNodeType,
|
|
17
|
-
targetAttrs
|
|
18
|
-
} = context;
|
|
19
|
-
const {
|
|
20
|
-
$from,
|
|
21
|
-
$to
|
|
22
|
-
} = tr.selection;
|
|
23
|
-
const schema = tr.doc.type.schema;
|
|
24
|
-
const range = $from.blockRange($to);
|
|
25
|
-
if (!range) {
|
|
26
|
-
return null;
|
|
27
|
-
}
|
|
28
|
-
const {
|
|
29
|
-
nodes
|
|
30
|
-
} = tr.doc.type.schema;
|
|
31
|
-
const isTargetTask = isTaskList(targetNodeType);
|
|
32
|
-
|
|
33
|
-
// Handle task lists differently due to their structure
|
|
34
|
-
if (isTargetTask) {
|
|
35
|
-
return transformToTaskList(tr, range, targetNodeType, targetAttrs, nodes);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
// filter marks that are not allowed in the target node type
|
|
39
|
-
if (sourceNode.type === schema.nodes.paragraph || sourceNode.type === schema.nodes.heading) {
|
|
40
|
-
const allowedMarks = targetNodeType.allowedMarks(sourceNode.marks);
|
|
41
|
-
tr.setNodeMarkup(range.start, null, null, allowedMarks);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// For headings, convert to paragraph first since headings cannot be direct children of list items
|
|
45
|
-
if (sourceNode && sourceNode.type.name.startsWith('heading')) {
|
|
46
|
-
tr.setBlockType(range.start, range.end, nodes.paragraph);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// Get the current range (updated if we converted from heading)
|
|
50
|
-
const currentRange = tr.selection.$from.blockRange(tr.selection.$to) || range;
|
|
51
|
-
|
|
52
|
-
// Wrap in the target list type
|
|
53
|
-
const wrapping = findWrapping(currentRange, targetNodeType, targetAttrs);
|
|
54
|
-
if (!wrapping) {
|
|
55
|
-
return null;
|
|
56
|
-
}
|
|
57
|
-
tr.wrap(currentRange, wrapping);
|
|
58
|
-
return tr;
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Transform list to block nodes
|
|
63
|
-
*/
|
|
64
|
-
export const transformListToBlockNodes = context => {
|
|
65
|
-
const {
|
|
66
|
-
sourceNode
|
|
67
|
-
} = context;
|
|
68
|
-
if (sourceNode.type.name === 'taskList') {
|
|
69
|
-
return transformTaskListToBlockNodes(context);
|
|
70
|
-
} else {
|
|
71
|
-
return transformOrderedUnorderedListToBlockNodes(context);
|
|
72
|
-
}
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Wraps bulletList, orderedList or taskList in node of container type
|
|
77
|
-
*/
|
|
78
|
-
export const transformListToContainer = context => {
|
|
79
|
-
const {
|
|
80
|
-
tr,
|
|
81
|
-
sourceNode,
|
|
82
|
-
sourcePos,
|
|
83
|
-
targetNodeType,
|
|
84
|
-
targetAttrs
|
|
85
|
-
} = context;
|
|
86
|
-
if (sourcePos === null) {
|
|
87
|
-
return null;
|
|
88
|
-
}
|
|
89
|
-
const {
|
|
90
|
-
schema
|
|
91
|
-
} = tr.doc.type;
|
|
92
|
-
const {
|
|
93
|
-
blockquote,
|
|
94
|
-
taskList,
|
|
95
|
-
taskItem,
|
|
96
|
-
paragraph
|
|
97
|
-
} = schema.nodes;
|
|
98
|
-
|
|
99
|
-
// Special case: Task list -> Blockquote
|
|
100
|
-
// Flattens the task list before wrapping by blockquote
|
|
101
|
-
if (sourceNode.type === taskList && targetNodeType === blockquote) {
|
|
102
|
-
const extractParagraphsFromTaskList = node => {
|
|
103
|
-
const paragraphs = [];
|
|
104
|
-
node.forEach(child => {
|
|
105
|
-
if (child.type === taskItem) {
|
|
106
|
-
if (child.content.size > 0) {
|
|
107
|
-
const paragraphNode = paragraph.createChecked({}, child.content.content);
|
|
108
|
-
paragraphs.push(paragraphNode);
|
|
109
|
-
}
|
|
110
|
-
} else if (child.type === taskList) {
|
|
111
|
-
paragraphs.push(...extractParagraphsFromTaskList(child));
|
|
112
|
-
}
|
|
113
|
-
});
|
|
114
|
-
return paragraphs;
|
|
115
|
-
};
|
|
116
|
-
const liftedParagraphs = extractParagraphsFromTaskList(sourceNode);
|
|
117
|
-
const containerNode = targetNodeType.createAndFill(targetAttrs, Fragment.from(liftedParagraphs));
|
|
118
|
-
if (!containerNode) {
|
|
119
|
-
return null;
|
|
120
|
-
}
|
|
121
|
-
tr.replaceWith(sourcePos, sourcePos + sourceNode.nodeSize, containerNode);
|
|
122
|
-
return tr;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
// Default case
|
|
126
|
-
const containerNode = targetNodeType.createAndFill(targetAttrs, [sourceNode]);
|
|
127
|
-
if (!containerNode) {
|
|
128
|
-
return null;
|
|
129
|
-
}
|
|
130
|
-
tr.replaceWith(sourcePos, sourcePos + sourceNode.nodeSize, containerNode);
|
|
131
|
-
return tr;
|
|
132
|
-
};
|
|
133
|
-
|
|
134
|
-
/**
|
|
135
|
-
* Transform list nodes
|
|
136
|
-
*/
|
|
137
|
-
export const transformListNode = context => {
|
|
138
|
-
const {
|
|
139
|
-
targetNodeType
|
|
140
|
-
} = context;
|
|
141
|
-
// Transform list to block type
|
|
142
|
-
if (isBlockNodeType(targetNodeType)) {
|
|
143
|
-
// Lift list items out of the list and convert to target block type
|
|
144
|
-
return transformListToBlockNodes(context);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
// Transform list to container type
|
|
148
|
-
if (isContainerNodeType(targetNodeType)) {
|
|
149
|
-
// Wrap list items into container type, where possible
|
|
150
|
-
return transformListToContainer(context);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
// Transform between list types
|
|
154
|
-
if (isListNodeType(targetNodeType)) {
|
|
155
|
-
return transformBetweenListTypes(context);
|
|
156
|
-
}
|
|
157
|
-
return null;
|
|
158
|
-
};
|
|
159
|
-
|
|
160
|
-
/**
|
|
161
|
-
* Lift list content and convert to block type
|
|
162
|
-
*/
|
|
163
|
-
export const liftListToBlockType = () => {
|
|
164
|
-
// Convert to target block type directly
|
|
165
|
-
return null;
|
|
166
|
-
};
|
|
167
|
-
|
|
168
|
-
// transformBetweenListTypes is now imported from @atlaskit/editor-common/transforms
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
import { transformBlockNode } from './block-transforms';
|
|
2
|
-
import { transformContainerNode, unwrapAndConvertToList } from './container-transforms';
|
|
3
|
-
import { convertToLayout, transformLayoutNode } from './layout-transforms';
|
|
4
|
-
import { transformListNode } from './list-transforms';
|
|
5
|
-
import { getTargetNodeInfo, isBlockNode, isListNode, isListNodeType, isContainerNode, isLayoutNodeType, isLayoutNode } from './utils';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Transforms a source node to the specified target type.
|
|
9
|
-
* Throws errors on failure which should be caught at the command level.
|
|
10
|
-
*
|
|
11
|
-
* @param tr - The transaction to apply transformations to
|
|
12
|
-
* @param sourceNode - The node to transform
|
|
13
|
-
* @param sourcePos - The position of the source node in the document
|
|
14
|
-
* @param targetType - The target node type to transform to
|
|
15
|
-
* @returns The modified transaction if successful, null if transformation is not possible
|
|
16
|
-
*/
|
|
17
|
-
export function transformNodeToTargetType(tr, sourceNode, sourcePos, targetType) {
|
|
18
|
-
const {
|
|
19
|
-
nodes
|
|
20
|
-
} = tr.doc.type.schema;
|
|
21
|
-
const targetNodeInfo = getTargetNodeInfo(targetType, nodes);
|
|
22
|
-
if (!targetNodeInfo) {
|
|
23
|
-
return null;
|
|
24
|
-
}
|
|
25
|
-
const {
|
|
26
|
-
nodeType: targetNodeType,
|
|
27
|
-
attrs: targetAttrs
|
|
28
|
-
} = targetNodeInfo;
|
|
29
|
-
|
|
30
|
-
// Early return if trying to transform to the same type
|
|
31
|
-
if (sourceNode.type.name === targetNodeType.name) {
|
|
32
|
-
// For headings, also check if the level matches
|
|
33
|
-
if (targetNodeType.name === 'heading') {
|
|
34
|
-
var _sourceNode$attrs;
|
|
35
|
-
const sourceLevel = (_sourceNode$attrs = sourceNode.attrs) === null || _sourceNode$attrs === void 0 ? void 0 : _sourceNode$attrs.level;
|
|
36
|
-
const targetLevel = targetAttrs === null || targetAttrs === void 0 ? void 0 : targetAttrs.level;
|
|
37
|
-
if (sourceLevel === targetLevel) {
|
|
38
|
-
return tr;
|
|
39
|
-
}
|
|
40
|
-
} else {
|
|
41
|
-
return tr;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
// Prepare transformation context
|
|
46
|
-
const transformationContext = {
|
|
47
|
-
tr,
|
|
48
|
-
sourceNode,
|
|
49
|
-
sourcePos,
|
|
50
|
-
targetNodeType,
|
|
51
|
-
targetAttrs
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
// Route to appropriate transformation strategy based on source node type
|
|
55
|
-
if (isLayoutNodeType(targetNodeType)) {
|
|
56
|
-
return convertToLayout(transformationContext);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// special case codeblock to listType
|
|
60
|
-
if (sourceNode.type.name === 'codeBlock' && isListNodeType(targetNodeType)) {
|
|
61
|
-
return unwrapAndConvertToList(transformationContext);
|
|
62
|
-
}
|
|
63
|
-
if (isLayoutNode(sourceNode)) {
|
|
64
|
-
return transformLayoutNode(transformationContext);
|
|
65
|
-
}
|
|
66
|
-
if (isBlockNode(sourceNode)) {
|
|
67
|
-
return transformBlockNode(transformationContext);
|
|
68
|
-
}
|
|
69
|
-
if (isListNode(sourceNode)) {
|
|
70
|
-
return transformListNode(transformationContext);
|
|
71
|
-
}
|
|
72
|
-
if (isContainerNode(sourceNode)) {
|
|
73
|
-
return transformContainerNode(transformationContext);
|
|
74
|
-
}
|
|
75
|
-
return null;
|
|
76
|
-
}
|
|
@@ -1,248 +0,0 @@
|
|
|
1
|
-
import { breakoutResizableNodes } from '@atlaskit/editor-common/utils';
|
|
2
|
-
import { Fragment } from '@atlaskit/editor-prosemirror/model';
|
|
3
|
-
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
|
|
4
|
-
export const getTargetNodeInfo = (targetType, nodes) => {
|
|
5
|
-
switch (targetType) {
|
|
6
|
-
case 'heading1':
|
|
7
|
-
return {
|
|
8
|
-
nodeType: nodes.heading,
|
|
9
|
-
attrs: {
|
|
10
|
-
level: 1
|
|
11
|
-
}
|
|
12
|
-
};
|
|
13
|
-
case 'heading2':
|
|
14
|
-
return {
|
|
15
|
-
nodeType: nodes.heading,
|
|
16
|
-
attrs: {
|
|
17
|
-
level: 2
|
|
18
|
-
}
|
|
19
|
-
};
|
|
20
|
-
case 'heading3':
|
|
21
|
-
return {
|
|
22
|
-
nodeType: nodes.heading,
|
|
23
|
-
attrs: {
|
|
24
|
-
level: 3
|
|
25
|
-
}
|
|
26
|
-
};
|
|
27
|
-
case 'heading4':
|
|
28
|
-
return {
|
|
29
|
-
nodeType: nodes.heading,
|
|
30
|
-
attrs: {
|
|
31
|
-
level: 4
|
|
32
|
-
}
|
|
33
|
-
};
|
|
34
|
-
case 'heading5':
|
|
35
|
-
return {
|
|
36
|
-
nodeType: nodes.heading,
|
|
37
|
-
attrs: {
|
|
38
|
-
level: 5
|
|
39
|
-
}
|
|
40
|
-
};
|
|
41
|
-
case 'heading6':
|
|
42
|
-
return {
|
|
43
|
-
nodeType: nodes.heading,
|
|
44
|
-
attrs: {
|
|
45
|
-
level: 6
|
|
46
|
-
}
|
|
47
|
-
};
|
|
48
|
-
case 'paragraph':
|
|
49
|
-
return {
|
|
50
|
-
nodeType: nodes.paragraph
|
|
51
|
-
};
|
|
52
|
-
case 'blockquote':
|
|
53
|
-
return {
|
|
54
|
-
nodeType: nodes.blockquote
|
|
55
|
-
};
|
|
56
|
-
case 'expand':
|
|
57
|
-
return {
|
|
58
|
-
nodeType: nodes.expand
|
|
59
|
-
};
|
|
60
|
-
case 'panel':
|
|
61
|
-
return {
|
|
62
|
-
nodeType: nodes.panel,
|
|
63
|
-
attrs: {
|
|
64
|
-
panelType: 'info'
|
|
65
|
-
}
|
|
66
|
-
};
|
|
67
|
-
case 'codeBlock':
|
|
68
|
-
return {
|
|
69
|
-
nodeType: nodes.codeBlock
|
|
70
|
-
};
|
|
71
|
-
case 'bulletList':
|
|
72
|
-
return {
|
|
73
|
-
nodeType: nodes.bulletList
|
|
74
|
-
};
|
|
75
|
-
case 'orderedList':
|
|
76
|
-
return {
|
|
77
|
-
nodeType: nodes.orderedList
|
|
78
|
-
};
|
|
79
|
-
case 'taskList':
|
|
80
|
-
return {
|
|
81
|
-
nodeType: nodes.taskList
|
|
82
|
-
};
|
|
83
|
-
case 'layoutSection':
|
|
84
|
-
return {
|
|
85
|
-
nodeType: nodes.layoutSection
|
|
86
|
-
};
|
|
87
|
-
default:
|
|
88
|
-
return null;
|
|
89
|
-
}
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
// Helper functions to categorize node types
|
|
93
|
-
export const isBlockNode = node => {
|
|
94
|
-
return ['paragraph', 'heading', 'codeBlock'].includes(node.type.name);
|
|
95
|
-
};
|
|
96
|
-
export const isHeadingOrParagraphNode = node => {
|
|
97
|
-
return ['paragraph', 'heading'].includes(node.type.name);
|
|
98
|
-
};
|
|
99
|
-
export const isListNode = node => {
|
|
100
|
-
return ['bulletList', 'orderedList', 'taskList'].includes(node.type.name);
|
|
101
|
-
};
|
|
102
|
-
export const isContainerNode = node => {
|
|
103
|
-
return ['panel', 'expand', 'blockquote'].includes(node.type.name);
|
|
104
|
-
};
|
|
105
|
-
export const isBlockNodeType = nodeType => {
|
|
106
|
-
return ['paragraph', 'heading', 'codeBlock'].includes(nodeType.name);
|
|
107
|
-
};
|
|
108
|
-
export const isListNodeType = nodeType => {
|
|
109
|
-
return ['bulletList', 'orderedList', 'taskList'].includes(nodeType.name);
|
|
110
|
-
};
|
|
111
|
-
export const isContainerNodeType = nodeType => {
|
|
112
|
-
return ['panel', 'expand', 'blockquote'].includes(nodeType.name);
|
|
113
|
-
};
|
|
114
|
-
|
|
115
|
-
// List type utilities moved to @atlaskit/editor-common/transforms
|
|
116
|
-
|
|
117
|
-
export const isLayoutNodeType = nodeType => {
|
|
118
|
-
return nodeType.name === 'layoutSection';
|
|
119
|
-
};
|
|
120
|
-
export const isLayoutNode = node => {
|
|
121
|
-
return node.type.name === 'layoutSection';
|
|
122
|
-
};
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* Check if a node should be extracted as a standalone block node
|
|
126
|
-
* rather than converted to inline content
|
|
127
|
-
*/
|
|
128
|
-
export const isBlockNodeForExtraction = node => {
|
|
129
|
-
const blockNodesForExtraction = ['table', 'mediaSingle', 'extension', 'bodiedExtension', 'blockCard', 'embedCard'];
|
|
130
|
-
return blockNodesForExtraction.includes(node.type.name);
|
|
131
|
-
};
|
|
132
|
-
|
|
133
|
-
/**
|
|
134
|
-
* Get a function that checks if content is supported in the target container type
|
|
135
|
-
*/
|
|
136
|
-
export const getContentSupportChecker = targetNodeType => {
|
|
137
|
-
return node => {
|
|
138
|
-
// Check if the target container type can contain this node
|
|
139
|
-
try {
|
|
140
|
-
return targetNodeType.validContent(Fragment.from(node));
|
|
141
|
-
} catch {
|
|
142
|
-
return false;
|
|
143
|
-
}
|
|
144
|
-
};
|
|
145
|
-
};
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
* Convert a node to inline content that can be placed in a paragraph
|
|
149
|
-
*/
|
|
150
|
-
export const convertNodeToInlineContent = (node, schema) => {
|
|
151
|
-
// Extract text and inline nodes from any complex node
|
|
152
|
-
const inlineNodes = [];
|
|
153
|
-
node.descendants(childNode => {
|
|
154
|
-
if (childNode.isText) {
|
|
155
|
-
inlineNodes.push(childNode);
|
|
156
|
-
} else if (childNode.isInline) {
|
|
157
|
-
inlineNodes.push(childNode);
|
|
158
|
-
}
|
|
159
|
-
return true; // Continue traversing
|
|
160
|
-
});
|
|
161
|
-
|
|
162
|
-
// If no inline content was found but the node has text content,
|
|
163
|
-
// create a text node with the full text content
|
|
164
|
-
if (inlineNodes.length === 0 && node.textContent) {
|
|
165
|
-
return [schema.text(node.textContent)];
|
|
166
|
-
}
|
|
167
|
-
return inlineNodes;
|
|
168
|
-
};
|
|
169
|
-
|
|
170
|
-
/**
|
|
171
|
-
* Filter marks from content based on the target node type
|
|
172
|
-
* @param content The content fragment to filter
|
|
173
|
-
* @param targetNodeType The target node type to check against
|
|
174
|
-
* @returns A new fragment with marks filtered for the target node type
|
|
175
|
-
*/
|
|
176
|
-
export const filterMarksForTargetNodeType = (content, targetNodeType) => {
|
|
177
|
-
const withValidMarks = [];
|
|
178
|
-
content.forEach(node => {
|
|
179
|
-
if (node.marks.length > 0) {
|
|
180
|
-
const allowedMarks = targetNodeType.allowedMarks(node.marks);
|
|
181
|
-
const updatedNode = node.mark(allowedMarks);
|
|
182
|
-
withValidMarks.push(updatedNode);
|
|
183
|
-
} else {
|
|
184
|
-
withValidMarks.push(node);
|
|
185
|
-
}
|
|
186
|
-
});
|
|
187
|
-
return Fragment.from(withValidMarks);
|
|
188
|
-
};
|
|
189
|
-
|
|
190
|
-
/** * Convert content from a code block node into multiple paragraph nodes
|
|
191
|
-
*/
|
|
192
|
-
export const convertCodeBlockContentToParagraphs = (codeBlockNode, schema) => {
|
|
193
|
-
const paragraphNodes = [];
|
|
194
|
-
const codeText = codeBlockNode.textContent;
|
|
195
|
-
const lines = codeText.split('\n');
|
|
196
|
-
lines.forEach(line => {
|
|
197
|
-
const paragraphNode = schema.nodes.paragraph.create(null, line ? schema.text(line) : null);
|
|
198
|
-
paragraphNodes.push(paragraphNode);
|
|
199
|
-
});
|
|
200
|
-
return paragraphNodes;
|
|
201
|
-
};
|
|
202
|
-
const isBreakoutMarkSupported = nodeType => {
|
|
203
|
-
return editorExperiment('platform_synced_block', true) ? breakoutResizableNodes.includes(nodeType.name) : ['codeBlock', 'expand', 'layoutSection'].includes(nodeType.name);
|
|
204
|
-
};
|
|
205
|
-
export const getMarksWithBreakout = (sourceNode, targetNodeType) => {
|
|
206
|
-
const allowedMarks = targetNodeType.allowedMarks(sourceNode.marks);
|
|
207
|
-
const sourceBreakoutMark = sourceNode.marks.find(mark => mark.type.name === 'breakout');
|
|
208
|
-
if (sourceBreakoutMark && isBreakoutMarkSupported(targetNodeType)) {
|
|
209
|
-
// Check if breakout mark is already in allowedMarks to avoid duplicates
|
|
210
|
-
const hasBreakoutMark = allowedMarks.some(mark => mark.type.name === 'breakout');
|
|
211
|
-
return hasBreakoutMark ? allowedMarks : [...allowedMarks, sourceBreakoutMark];
|
|
212
|
-
}
|
|
213
|
-
return allowedMarks;
|
|
214
|
-
};
|
|
215
|
-
|
|
216
|
-
/**
|
|
217
|
-
* Determines the conversion type based on source and target node types
|
|
218
|
-
* This is for analytics use - these types match existing analytics events for consistency
|
|
219
|
-
*/
|
|
220
|
-
export const getConversionType = (from, to) => {
|
|
221
|
-
// Block node insertion: block-like elements inserted from empty line or wrapping text/list
|
|
222
|
-
const blockNodes = ['panel', 'expand', 'codeBlock', 'layoutSection', 'taskList'];
|
|
223
|
-
const textNodes = ['paragraph', 'blockquote'];
|
|
224
|
-
const headingNodes = ['heading1', 'heading2', 'heading3', 'heading4', 'heading5', 'heading6'];
|
|
225
|
-
const listNodes = ['bulletList', 'orderedList'];
|
|
226
|
-
|
|
227
|
-
// Check if converting to block nodes from text/heading/list nodes
|
|
228
|
-
if (blockNodes.includes(to) && (textNodes.includes(from) || headingNodes.includes(from) || listNodes.includes(from))) {
|
|
229
|
-
return 'blockNodeInserted';
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
// Check if converting from paragraph/blockquote to list
|
|
233
|
-
if (listNodes.includes(to) && textNodes.includes(from)) {
|
|
234
|
-
return 'listInserted';
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
// Check if converting from list to paragraph/heading/blockquote or between list types
|
|
238
|
-
if (listNodes.includes(from) && (listNodes.includes(to) || textNodes.includes(to))) {
|
|
239
|
-
return 'listConverted';
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
// Text formatting: conversions among paragraph/headings/blockquote
|
|
243
|
-
if ((textNodes.includes(from) || headingNodes.includes(from)) && (textNodes.includes(to) || headingNodes.includes(to))) {
|
|
244
|
-
return 'textFormatted';
|
|
245
|
-
}
|
|
246
|
-
// For other conversions, we do not have a matching event category
|
|
247
|
-
return undefined;
|
|
248
|
-
};
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { transformToContainer, unwrapAndConvertToBlockType } from './container-transforms';
|
|
2
|
-
import { getInlineNodeTextNode } from './inline-node-transforms';
|
|
3
|
-
import { transformBlockToList } from './list-transforms';
|
|
4
|
-
import { isListNodeType, isContainerNodeType, isBlockNodeType } from './utils';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Transform block nodes (paragraph, heading, codeblock)
|
|
8
|
-
*/
|
|
9
|
-
export var transformBlockNode = function transformBlockNode(context) {
|
|
10
|
-
var targetNodeType = context.targetNodeType;
|
|
11
|
-
|
|
12
|
-
// Handle transformation to list types
|
|
13
|
-
if (isListNodeType(targetNodeType)) {
|
|
14
|
-
return transformBlockToList(context);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
// Handle transformation to container types (panel, expand, blockquote)
|
|
18
|
-
if (isContainerNodeType(targetNodeType)) {
|
|
19
|
-
return transformToContainer(context);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
// Handle block type transformation (paragraph, heading, codeblock)
|
|
23
|
-
if (isBlockNodeType(targetNodeType)) {
|
|
24
|
-
return transformToBlockNode(context);
|
|
25
|
-
}
|
|
26
|
-
return null;
|
|
27
|
-
};
|
|
28
|
-
var transformToBlockNode = function transformToBlockNode(context) {
|
|
29
|
-
var tr = context.tr,
|
|
30
|
-
targetNodeType = context.targetNodeType,
|
|
31
|
-
targetAttrs = context.targetAttrs,
|
|
32
|
-
sourceNode = context.sourceNode;
|
|
33
|
-
var selection = tr.selection,
|
|
34
|
-
doc = tr.doc;
|
|
35
|
-
var $from = selection.$from,
|
|
36
|
-
$to = selection.$to;
|
|
37
|
-
var schema = doc.type.schema;
|
|
38
|
-
if (targetNodeType === schema.nodes.codeBlock) {
|
|
39
|
-
var textContent = getInlineNodeTextNode(selection.content().content, schema);
|
|
40
|
-
var node = schema.nodes.codeBlock.createChecked(undefined, textContent);
|
|
41
|
-
return tr.replaceRangeWith(selection.from, selection.to, node);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// code block acts like a container, we need to unwrap it
|
|
45
|
-
if (sourceNode.type === schema.nodes.codeBlock) {
|
|
46
|
-
return unwrapAndConvertToBlockType(context);
|
|
47
|
-
}
|
|
48
|
-
tr.setBlockType($from.pos, $to.pos, targetNodeType, targetAttrs);
|
|
49
|
-
return tr;
|
|
50
|
-
};
|