@atlaskit/editor-plugin-block-menu 0.0.20 → 1.0.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.
Files changed (38) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/cjs/editor-commands/formatNode.js +6 -3
  3. package/dist/cjs/editor-commands/transforms/block-transforms.js +22 -10
  4. package/dist/cjs/editor-commands/transforms/container-transforms.js +40 -7
  5. package/dist/cjs/editor-commands/transforms/inline-node-transforms.js +27 -0
  6. package/dist/cjs/editor-commands/transforms/list/transformBetweenListTypes.js +102 -0
  7. package/dist/cjs/editor-commands/transforms/list-transforms.js +51 -19
  8. package/dist/cjs/editor-commands/transforms/utils.js +1 -1
  9. package/dist/cjs/ui/block-menu-components.js +1 -2
  10. package/dist/es2019/editor-commands/formatNode.js +6 -3
  11. package/dist/es2019/editor-commands/transforms/block-transforms.js +29 -15
  12. package/dist/es2019/editor-commands/transforms/container-transforms.js +35 -2
  13. package/dist/es2019/editor-commands/transforms/inline-node-transforms.js +21 -0
  14. package/dist/es2019/editor-commands/transforms/list/transformBetweenListTypes.js +98 -0
  15. package/dist/es2019/editor-commands/transforms/list-transforms.js +49 -15
  16. package/dist/es2019/editor-commands/transforms/utils.js +1 -1
  17. package/dist/es2019/ui/block-menu-components.js +1 -2
  18. package/dist/esm/editor-commands/formatNode.js +6 -3
  19. package/dist/esm/editor-commands/transforms/block-transforms.js +23 -11
  20. package/dist/esm/editor-commands/transforms/container-transforms.js +39 -7
  21. package/dist/esm/editor-commands/transforms/inline-node-transforms.js +21 -0
  22. package/dist/esm/editor-commands/transforms/list/transformBetweenListTypes.js +95 -0
  23. package/dist/esm/editor-commands/transforms/list-transforms.js +50 -18
  24. package/dist/esm/editor-commands/transforms/utils.js +1 -1
  25. package/dist/esm/ui/block-menu-components.js +1 -2
  26. package/dist/types/editor-commands/transforms/container-transforms.d.ts +2 -2
  27. package/dist/types/editor-commands/transforms/inline-node-transforms.d.ts +3 -0
  28. package/dist/types/editor-commands/transforms/list/transformBetweenListTypes.d.ts +9 -0
  29. package/dist/types/editor-commands/transforms/list-transforms.d.ts +1 -6
  30. package/dist/types/editor-commands/transforms/types.d.ts +3 -3
  31. package/dist/types/editor-commands/transforms/utils.d.ts +1 -1
  32. package/dist/types-ts4.5/editor-commands/transforms/container-transforms.d.ts +2 -2
  33. package/dist/types-ts4.5/editor-commands/transforms/inline-node-transforms.d.ts +3 -0
  34. package/dist/types-ts4.5/editor-commands/transforms/list/transformBetweenListTypes.d.ts +9 -0
  35. package/dist/types-ts4.5/editor-commands/transforms/list-transforms.d.ts +1 -6
  36. package/dist/types-ts4.5/editor-commands/transforms/types.d.ts +3 -3
  37. package/dist/types-ts4.5/editor-commands/transforms/utils.d.ts +1 -1
  38. package/package.json +7 -12
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Extract all inline content from a node
3
+ */
4
+ const extractInlineContent = node => {
5
+ const inlineContent = [];
6
+ for (let i = 0; i < node.childCount; i++) {
7
+ inlineContent.push(node.child(i));
8
+ }
9
+ return inlineContent;
10
+ };
11
+
12
+ /**
13
+ * Transform list structure
14
+ */
15
+ export const transformListStructure = (tr, listNode, targetNodeType, nodes) => {
16
+ try {
17
+ const {
18
+ node: sourceList,
19
+ pos: listPos
20
+ } = listNode;
21
+ const {
22
+ bulletList,
23
+ orderedList,
24
+ taskList,
25
+ listItem,
26
+ taskItem,
27
+ paragraph
28
+ } = nodes;
29
+ const isSourceBulletOrOrdered = sourceList.type === bulletList || sourceList.type === orderedList;
30
+ const isTargetTask = targetNodeType === taskList;
31
+ const isSourceTask = sourceList.type === taskList;
32
+ const newListItems = [];
33
+ const listStart = listPos;
34
+ const listEnd = listPos + sourceList.nodeSize;
35
+
36
+ // Use nodesBetween to efficiently traverse the list structure
37
+ tr.doc.nodesBetween(listStart, listEnd, (node, pos, parent) => {
38
+ // Only process direct children of the list (depth 1)
39
+ if (parent !== sourceList) {
40
+ return true; // Continue traversal
41
+ }
42
+ if (isSourceBulletOrOrdered && isTargetTask) {
43
+ // Converting from bullet/ordered list to task list
44
+ // Extract inline content from all children within listItem
45
+ if (node.type === listItem) {
46
+ const inlineContent = [];
47
+
48
+ // Extract all inline content from all child nodes
49
+ for (let i = 0; i < node.childCount; i++) {
50
+ const child = node.child(i);
51
+ if (child.type === paragraph) {
52
+ // Extract inline content from paragraphs
53
+ inlineContent.push(...extractInlineContent(child));
54
+ } else if (child.isBlock) {
55
+ // For other block content types eg. codeBlock, extract their text content and create text nodes
56
+ const textContent = child.textContent;
57
+ if (textContent) {
58
+ const textNode = tr.doc.type.schema.text(textContent);
59
+ inlineContent.push(textNode);
60
+ }
61
+ } else {
62
+ // Already inline content, add directly
63
+ inlineContent.push(child);
64
+ }
65
+ }
66
+ if (inlineContent.length > 0) {
67
+ const newItem = taskItem.create(null, inlineContent);
68
+ newListItems.push(newItem);
69
+ }
70
+ }
71
+ } else if (isSourceTask && !isTargetTask) {
72
+ // Converting from task list to bullet/ordered list
73
+ // Structure: taskItem > inline content -> listItem > paragraph > inline content
74
+ if (node.type === taskItem) {
75
+ const inlineContent = extractInlineContent(node);
76
+ if (inlineContent.length > 0) {
77
+ const paragraphNode = paragraph.create(null, inlineContent);
78
+ const newListItem = listItem.create(null, paragraphNode);
79
+ newListItems.push(newListItem);
80
+ }
81
+ }
82
+ }
83
+ return false; // Don't traverse into children of list items
84
+ });
85
+ if (newListItems.length === 0) {
86
+ return tr;
87
+ }
88
+
89
+ // Create new list with transformed items
90
+ const newList = targetNodeType.create(null, newListItems);
91
+
92
+ // Replace the entire list
93
+ tr.replaceWith(listStart, listEnd, newList);
94
+ return tr;
95
+ } catch {
96
+ return tr;
97
+ }
98
+ };
@@ -1,16 +1,17 @@
1
1
  import { findWrapping } from '@atlaskit/editor-prosemirror/transform';
2
2
  import { findParentNodeOfType } from '@atlaskit/editor-prosemirror/utils';
3
+ import { transformListStructure } from './list/transformBetweenListTypes';
3
4
  import { isBlockNodeType, isContainerNodeType, isListNodeType } from './utils';
4
5
 
5
6
  /**
6
7
  * Transform selection to list type
7
8
  */
8
- export const transformToList = ({
9
- tr,
10
- targetNodeType,
11
- targetAttrs
12
- }) => {
13
- // Wrap selection in list of target type
9
+ export const transformBlockToList = context => {
10
+ const {
11
+ tr,
12
+ targetNodeType,
13
+ targetAttrs
14
+ } = context;
14
15
  const {
15
16
  $from,
16
17
  $to
@@ -19,13 +20,32 @@ export const transformToList = ({
19
20
  if (!range) {
20
21
  return null;
21
22
  }
23
+ const {
24
+ nodes
25
+ } = tr.doc.type.schema;
26
+ const isTargetTask = targetNodeType === nodes.taskList;
27
+
28
+ // Handle task lists differently due to their structure
29
+ // TODO: ED-29152 - Implement task list transformation
30
+ if (isTargetTask) {
31
+ return null;
32
+ }
33
+
34
+ // For headings, convert to paragraph first since headings cannot be direct children of list items
35
+ const sourceNode = tr.doc.nodeAt(range.start);
36
+ if (sourceNode && sourceNode.type.name.startsWith('heading')) {
37
+ tr.setBlockType(range.start, range.end, nodes.paragraph);
38
+ }
22
39
 
23
- // Find if we can wrap the selection in the target list type
24
- const wrapping = findWrapping(range, targetNodeType, targetAttrs);
40
+ // Get the current range (updated if we converted from heading)
41
+ const currentRange = tr.selection.$from.blockRange(tr.selection.$to) || range;
42
+
43
+ // Wrap in the target list type
44
+ const wrapping = findWrapping(currentRange, targetNodeType, targetAttrs);
25
45
  if (!wrapping) {
26
46
  return null;
27
47
  }
28
- tr.wrap(range, wrapping);
48
+ tr.wrap(currentRange, wrapping);
29
49
  return tr;
30
50
  };
31
51
 
@@ -77,16 +97,30 @@ export const transformBetweenListTypes = ({
77
97
  nodes
78
98
  } = tr.doc.type.schema;
79
99
 
80
- // Find the list node
81
- const listNode = findParentNodeOfType([nodes.bulletList, nodes.orderedList, nodes.taskList])(selection);
100
+ // Find the list node - support bullet lists, ordered lists, and task lists
101
+ const supportedListTypes = [nodes.bulletList, nodes.orderedList, nodes.taskList].filter(Boolean); // Filter out undefined nodes in case some schemas don't have all types
102
+
103
+ const listNode = findParentNodeOfType(supportedListTypes)(selection);
82
104
  if (!listNode) {
83
105
  return null;
84
106
  }
107
+ const sourceListType = listNode.node.type;
108
+ const isSourceBulletOrOrdered = sourceListType === nodes.bulletList || sourceListType === nodes.orderedList;
109
+ const isTargetTask = targetNodeType === nodes.taskList;
110
+ const isSourceTask = sourceListType === nodes.taskList;
111
+ const isTargetBulletOrOrdered = targetNodeType === nodes.bulletList || targetNodeType === nodes.orderedList;
112
+
113
+ // Check if we need structure transformation
114
+ const needsStructureTransform = isSourceBulletOrOrdered && isTargetTask || isSourceTask && isTargetBulletOrOrdered;
85
115
  try {
86
- // Change the list type while preserving content
87
- tr.setNodeMarkup(listNode.pos, targetNodeType);
88
- return tr;
89
- } catch (e) {
116
+ if (!needsStructureTransform) {
117
+ // Simple type change for same structure lists (bullet <-> ordered)
118
+ tr.setNodeMarkup(listNode.pos, targetNodeType);
119
+ } else {
120
+ tr = transformListStructure(tr, listNode, targetNodeType, nodes);
121
+ }
122
+ } catch {
90
123
  return null;
91
124
  }
125
+ return tr;
92
126
  };
@@ -61,7 +61,7 @@ export const getTargetNodeInfo = (targetType, nodes) => {
61
61
  panelType: 'info'
62
62
  }
63
63
  };
64
- case 'codeblock':
64
+ case 'codeBlock':
65
65
  return {
66
66
  nodeType: nodes.codeBlock
67
67
  };
@@ -3,7 +3,6 @@ import { MOVE_UP_MENU_ITEM, MOVE_UP_DOWN_MENU_SECTION, MOVE_DOWN_MENU_ITEM, MOVE
3
3
  import { ToolbarDropdownItemSection, ToolbarNestedDropdownMenu } from '@atlaskit/editor-toolbar';
4
4
  import ChangesIcon from '@atlaskit/icon/core/changes';
5
5
  import ChevronRightIcon from '@atlaskit/icon/core/chevron-right';
6
- import { fg } from '@atlaskit/platform-feature-flags';
7
6
  import CopyBlockMenuItem from './copy-block';
8
7
  import { CopyLinkDropdownItem } from './copy-link';
9
8
  import { DeleteDropdownItem } from './delete-button';
@@ -88,7 +87,7 @@ export const getBlockMenuComponents = ({
88
87
  api,
89
88
  config
90
89
  }) => {
91
- return [...(fg('platform_editor_block_menu_format') ? getFormatMenuComponents() : []), {
90
+ return [...getFormatMenuComponents(), {
92
91
  type: 'block-menu-section',
93
92
  key: COPY_MENU_SECTION.key,
94
93
  rank: BLOCK_MENU_SECTION_RANK[COPY_MENU_SECTION.key],
@@ -21,19 +21,22 @@ export var formatNode = function formatNode(targetType) {
21
21
  nodePos = selectedNode.pos;
22
22
  } else {
23
23
  // Try to find parent node (including list parents)
24
- var parentNode = findParentNodeOfType([nodes.blockquote, nodes.panel, nodes.expand, nodes.codeBlock, nodes.listItem, nodes.layoutSection])(selection);
24
+ var parentNode = findParentNodeOfType([nodes.blockquote, nodes.panel, nodes.expand, nodes.codeBlock, nodes.listItem, nodes.taskItem, nodes.layoutSection])(selection);
25
25
  if (parentNode) {
26
26
  nodeToFormat = parentNode.node;
27
27
  nodePos = parentNode.pos;
28
-
28
+ var paragraphOrHeadingNode = findParentNodeOfType([nodes.paragraph, nodes.heading])(selection);
29
29
  // Special case: if we found a listItem, check if we need the parent list instead
30
- if (parentNode.node.type === nodes.listItem) {
30
+ if (parentNode.node.type === nodes.listItem || parentNode.node.type === nodes.taskItem) {
31
31
  var listParent = findParentNodeOfType([nodes.bulletList, nodes.orderedList, nodes.taskList])(selection);
32
32
  if (listParent) {
33
33
  // For list transformations, we want the list parent, not the listItem
34
34
  nodeToFormat = listParent.node;
35
35
  nodePos = listParent.pos;
36
36
  }
37
+ } else if (paragraphOrHeadingNode) {
38
+ nodeToFormat = paragraphOrHeadingNode.node;
39
+ nodePos = paragraphOrHeadingNode.pos;
37
40
  }
38
41
  }
39
42
  }
@@ -1,32 +1,44 @@
1
1
  import { transformToContainer } from './container-transforms';
2
- import { transformToList } from './list-transforms';
2
+ import { getInlineNodeTextContent } from './inline-node-transforms';
3
+ import { transformBlockToList } from './list-transforms';
3
4
  import { isListNodeType, isContainerNodeType, isBlockNodeType } from './utils';
4
5
 
5
6
  /**
6
7
  * Transform block nodes (paragraph, heading, codeblock)
7
8
  */
8
9
  export var transformBlockNode = function transformBlockNode(context) {
9
- var tr = context.tr,
10
- targetNodeType = context.targetNodeType,
11
- targetAttrs = context.targetAttrs;
12
- var selection = tr.selection;
13
- var $from = selection.$from,
14
- $to = selection.$to;
10
+ var targetNodeType = context.targetNodeType;
15
11
 
16
12
  // Handle transformation to list types
17
13
  if (isListNodeType(targetNodeType)) {
18
- return transformToList(context);
14
+ return transformBlockToList(context);
19
15
  }
20
16
 
21
17
  // Handle transformation to container types (panel, expand, blockquote)
22
18
  if (isContainerNodeType(targetNodeType)) {
23
- return transformToContainer();
19
+ return transformToContainer(context);
24
20
  }
25
21
 
26
22
  // Handle block type transformation (paragraph, heading, codeblock)
27
23
  if (isBlockNodeType(targetNodeType)) {
28
- tr.setBlockType($from.pos, $to.pos, targetNodeType, targetAttrs);
29
- return tr;
24
+ return transformToBlockNode(context);
30
25
  }
31
26
  return null;
27
+ };
28
+ var transformToBlockNode = function transformToBlockNode(context) {
29
+ var tr = context.tr,
30
+ targetNodeType = context.targetNodeType,
31
+ targetAttrs = context.targetAttrs;
32
+ var selection = tr.selection,
33
+ doc = tr.doc;
34
+ var $from = selection.$from,
35
+ $to = selection.$to;
36
+ var schema = doc.type.schema;
37
+ if (targetNodeType === schema.nodes.codeBlock) {
38
+ var textContent = getInlineNodeTextContent(selection.content().content, tr);
39
+ var node = schema.nodes.codeBlock.createChecked(undefined, textContent);
40
+ return tr.replaceRangeWith(selection.from, selection.to, node);
41
+ }
42
+ tr.setBlockType($from.pos, $to.pos, targetNodeType, targetAttrs);
43
+ return tr;
32
44
  };
@@ -1,20 +1,52 @@
1
+ import { Fragment } from '@atlaskit/editor-prosemirror/model';
1
2
  import { isBlockNodeType, isListNodeType, isContainerNodeType } from './utils';
3
+ var convertInvalidNodeToValidNodeType = function convertInvalidNodeToValidNodeType(sourceContent, sourceNodeType, validNodeType, withMarks) {
4
+ var validTransformedContent = [];
5
+ // Headings are not valid inside headings so convert heading nodes to paragraphs
6
+ sourceContent.forEach(function (node) {
7
+ if (sourceNodeType === node.type) {
8
+ validTransformedContent.push(validNodeType.createChecked(node.attrs, node.content, withMarks ? node.marks : undefined));
9
+ } else {
10
+ validTransformedContent.push(node);
11
+ }
12
+ });
13
+ return Fragment.from(validTransformedContent);
14
+ };
2
15
 
3
16
  /**
4
17
  * Transform selection to container type
5
18
  */
6
- export var transformToContainer = function transformToContainer() {
7
- return null;
19
+ export var transformToContainer = function transformToContainer(_ref) {
20
+ var tr = _ref.tr,
21
+ sourceNode = _ref.sourceNode,
22
+ targetNodeType = _ref.targetNodeType,
23
+ targetAttrs = _ref.targetAttrs;
24
+ var selection = tr.selection;
25
+ var schema = tr.doc.type.schema;
26
+ var content = selection.content().content;
27
+ var transformedContent = content;
28
+ if (sourceNode.type === schema.nodes.codeBlock) {
29
+ transformedContent = convertInvalidNodeToValidNodeType(transformedContent, schema.nodes.codeBlock, schema.nodes.paragraph);
30
+ }
31
+ if (targetNodeType === schema.nodes.blockquote) {
32
+ transformedContent = convertInvalidNodeToValidNodeType(transformedContent, schema.nodes.heading, schema.nodes.paragraph, true);
33
+ }
34
+ var newNode = targetNodeType.createAndFill(targetAttrs, transformedContent);
35
+ if (!newNode) {
36
+ return null;
37
+ }
38
+ tr.replaceRangeWith(selection.from, selection.to, newNode);
39
+ return tr;
8
40
  };
9
41
 
10
42
  /**
11
43
  * Transform container nodes (panel, expand, blockquote)
12
44
  */
13
- export var transformContainerNode = function transformContainerNode(_ref) {
14
- var tr = _ref.tr,
15
- sourcePos = _ref.sourcePos,
16
- targetNodeType = _ref.targetNodeType,
17
- targetAttrs = _ref.targetAttrs;
45
+ export var transformContainerNode = function transformContainerNode(_ref2) {
46
+ var tr = _ref2.tr,
47
+ sourcePos = _ref2.sourcePos,
48
+ targetNodeType = _ref2.targetNodeType,
49
+ targetAttrs = _ref2.targetAttrs;
18
50
  if (sourcePos === null) {
19
51
  return null;
20
52
  }
@@ -0,0 +1,21 @@
1
+ export var getInlineNodeTextContent = function getInlineNodeTextContent(sourceContent, tr) {
2
+ var validTransformedContent = '';
3
+ var schema = tr.doc.type.schema;
4
+ if (sourceContent.content.length > 1) {
5
+ return;
6
+ }
7
+ // Headings are not valid inside headings so convert heading nodes to paragraphs
8
+ sourceContent.forEach(function (node) {
9
+ if (['paragraph', 'heading'].includes(node.type.name)) {
10
+ node.content.forEach(function (inlineNode) {
11
+ if (inlineNode.type.name === 'status') {
12
+ validTransformedContent += inlineNode.attrs.text;
13
+ } else {
14
+ validTransformedContent += "".concat(inlineNode.textContent);
15
+ }
16
+ });
17
+ validTransformedContent;
18
+ }
19
+ });
20
+ return schema.text(validTransformedContent);
21
+ };
@@ -0,0 +1,95 @@
1
+ import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
2
+ /**
3
+ * Extract all inline content from a node
4
+ */
5
+ var extractInlineContent = function extractInlineContent(node) {
6
+ var inlineContent = [];
7
+ for (var i = 0; i < node.childCount; i++) {
8
+ inlineContent.push(node.child(i));
9
+ }
10
+ return inlineContent;
11
+ };
12
+
13
+ /**
14
+ * Transform list structure
15
+ */
16
+ export var transformListStructure = function transformListStructure(tr, listNode, targetNodeType, nodes) {
17
+ try {
18
+ var sourceList = listNode.node,
19
+ listPos = listNode.pos;
20
+ var bulletList = nodes.bulletList,
21
+ orderedList = nodes.orderedList,
22
+ taskList = nodes.taskList,
23
+ listItem = nodes.listItem,
24
+ taskItem = nodes.taskItem,
25
+ paragraph = nodes.paragraph;
26
+ var isSourceBulletOrOrdered = sourceList.type === bulletList || sourceList.type === orderedList;
27
+ var isTargetTask = targetNodeType === taskList;
28
+ var isSourceTask = sourceList.type === taskList;
29
+ var newListItems = [];
30
+ var listStart = listPos;
31
+ var listEnd = listPos + sourceList.nodeSize;
32
+
33
+ // Use nodesBetween to efficiently traverse the list structure
34
+ tr.doc.nodesBetween(listStart, listEnd, function (node, pos, parent) {
35
+ // Only process direct children of the list (depth 1)
36
+ if (parent !== sourceList) {
37
+ return true; // Continue traversal
38
+ }
39
+ if (isSourceBulletOrOrdered && isTargetTask) {
40
+ // Converting from bullet/ordered list to task list
41
+ // Extract inline content from all children within listItem
42
+ if (node.type === listItem) {
43
+ var inlineContent = [];
44
+
45
+ // Extract all inline content from all child nodes
46
+ for (var i = 0; i < node.childCount; i++) {
47
+ var child = node.child(i);
48
+ if (child.type === paragraph) {
49
+ // Extract inline content from paragraphs
50
+ inlineContent.push.apply(inlineContent, _toConsumableArray(extractInlineContent(child)));
51
+ } else if (child.isBlock) {
52
+ // For other block content types eg. codeBlock, extract their text content and create text nodes
53
+ var textContent = child.textContent;
54
+ if (textContent) {
55
+ var textNode = tr.doc.type.schema.text(textContent);
56
+ inlineContent.push(textNode);
57
+ }
58
+ } else {
59
+ // Already inline content, add directly
60
+ inlineContent.push(child);
61
+ }
62
+ }
63
+ if (inlineContent.length > 0) {
64
+ var newItem = taskItem.create(null, inlineContent);
65
+ newListItems.push(newItem);
66
+ }
67
+ }
68
+ } else if (isSourceTask && !isTargetTask) {
69
+ // Converting from task list to bullet/ordered list
70
+ // Structure: taskItem > inline content -> listItem > paragraph > inline content
71
+ if (node.type === taskItem) {
72
+ var _inlineContent = extractInlineContent(node);
73
+ if (_inlineContent.length > 0) {
74
+ var paragraphNode = paragraph.create(null, _inlineContent);
75
+ var newListItem = listItem.create(null, paragraphNode);
76
+ newListItems.push(newListItem);
77
+ }
78
+ }
79
+ }
80
+ return false; // Don't traverse into children of list items
81
+ });
82
+ if (newListItems.length === 0) {
83
+ return tr;
84
+ }
85
+
86
+ // Create new list with transformed items
87
+ var newList = targetNodeType.create(null, newListItems);
88
+
89
+ // Replace the entire list
90
+ tr.replaceWith(listStart, listEnd, newList);
91
+ return tr;
92
+ } catch (_unused) {
93
+ return tr;
94
+ }
95
+ };
@@ -1,15 +1,15 @@
1
1
  import { findWrapping } from '@atlaskit/editor-prosemirror/transform';
2
2
  import { findParentNodeOfType } from '@atlaskit/editor-prosemirror/utils';
3
+ import { transformListStructure } from './list/transformBetweenListTypes';
3
4
  import { isBlockNodeType, isContainerNodeType, isListNodeType } from './utils';
4
5
 
5
6
  /**
6
7
  * Transform selection to list type
7
8
  */
8
- export var transformToList = function transformToList(_ref) {
9
- var tr = _ref.tr,
10
- targetNodeType = _ref.targetNodeType,
11
- targetAttrs = _ref.targetAttrs;
12
- // Wrap selection in list of target type
9
+ export var transformBlockToList = function transformBlockToList(context) {
10
+ var tr = context.tr,
11
+ targetNodeType = context.targetNodeType,
12
+ targetAttrs = context.targetAttrs;
13
13
  var _tr$selection = tr.selection,
14
14
  $from = _tr$selection.$from,
15
15
  $to = _tr$selection.$to;
@@ -17,13 +17,30 @@ export var transformToList = function transformToList(_ref) {
17
17
  if (!range) {
18
18
  return null;
19
19
  }
20
+ var nodes = tr.doc.type.schema.nodes;
21
+ var isTargetTask = targetNodeType === nodes.taskList;
22
+
23
+ // Handle task lists differently due to their structure
24
+ // TODO: ED-29152 - Implement task list transformation
25
+ if (isTargetTask) {
26
+ return null;
27
+ }
28
+
29
+ // For headings, convert to paragraph first since headings cannot be direct children of list items
30
+ var sourceNode = tr.doc.nodeAt(range.start);
31
+ if (sourceNode && sourceNode.type.name.startsWith('heading')) {
32
+ tr.setBlockType(range.start, range.end, nodes.paragraph);
33
+ }
34
+
35
+ // Get the current range (updated if we converted from heading)
36
+ var currentRange = tr.selection.$from.blockRange(tr.selection.$to) || range;
20
37
 
21
- // Find if we can wrap the selection in the target list type
22
- var wrapping = findWrapping(range, targetNodeType, targetAttrs);
38
+ // Wrap in the target list type
39
+ var wrapping = findWrapping(currentRange, targetNodeType, targetAttrs);
23
40
  if (!wrapping) {
24
41
  return null;
25
42
  }
26
- tr.wrap(range, wrapping);
43
+ tr.wrap(currentRange, wrapping);
27
44
  return tr;
28
45
  };
29
46
 
@@ -62,22 +79,37 @@ export var liftListToBlockType = function liftListToBlockType() {
62
79
  /**
63
80
  * Transform between different list types
64
81
  */
65
- export var transformBetweenListTypes = function transformBetweenListTypes(_ref2) {
66
- var tr = _ref2.tr,
67
- targetNodeType = _ref2.targetNodeType;
68
- var selection = tr.selection;
82
+ export var transformBetweenListTypes = function transformBetweenListTypes(_ref) {
83
+ var tr = _ref.tr,
84
+ targetNodeType = _ref.targetNodeType;
85
+ var _tr = tr,
86
+ selection = _tr.selection;
69
87
  var nodes = tr.doc.type.schema.nodes;
70
88
 
71
- // Find the list node
72
- var listNode = findParentNodeOfType([nodes.bulletList, nodes.orderedList, nodes.taskList])(selection);
89
+ // Find the list node - support bullet lists, ordered lists, and task lists
90
+ var supportedListTypes = [nodes.bulletList, nodes.orderedList, nodes.taskList].filter(Boolean); // Filter out undefined nodes in case some schemas don't have all types
91
+
92
+ var listNode = findParentNodeOfType(supportedListTypes)(selection);
73
93
  if (!listNode) {
74
94
  return null;
75
95
  }
96
+ var sourceListType = listNode.node.type;
97
+ var isSourceBulletOrOrdered = sourceListType === nodes.bulletList || sourceListType === nodes.orderedList;
98
+ var isTargetTask = targetNodeType === nodes.taskList;
99
+ var isSourceTask = sourceListType === nodes.taskList;
100
+ var isTargetBulletOrOrdered = targetNodeType === nodes.bulletList || targetNodeType === nodes.orderedList;
101
+
102
+ // Check if we need structure transformation
103
+ var needsStructureTransform = isSourceBulletOrOrdered && isTargetTask || isSourceTask && isTargetBulletOrOrdered;
76
104
  try {
77
- // Change the list type while preserving content
78
- tr.setNodeMarkup(listNode.pos, targetNodeType);
79
- return tr;
80
- } catch (e) {
105
+ if (!needsStructureTransform) {
106
+ // Simple type change for same structure lists (bullet <-> ordered)
107
+ tr.setNodeMarkup(listNode.pos, targetNodeType);
108
+ } else {
109
+ tr = transformListStructure(tr, listNode, targetNodeType, nodes);
110
+ }
111
+ } catch (_unused) {
81
112
  return null;
82
113
  }
114
+ return tr;
83
115
  };
@@ -61,7 +61,7 @@ export var getTargetNodeInfo = function getTargetNodeInfo(targetType, nodes) {
61
61
  panelType: 'info'
62
62
  }
63
63
  };
64
- case 'codeblock':
64
+ case 'codeBlock':
65
65
  return {
66
66
  nodeType: nodes.codeBlock
67
67
  };
@@ -4,7 +4,6 @@ import { MOVE_UP_MENU_ITEM, MOVE_UP_DOWN_MENU_SECTION, MOVE_DOWN_MENU_ITEM, MOVE
4
4
  import { ToolbarDropdownItemSection, ToolbarNestedDropdownMenu } from '@atlaskit/editor-toolbar';
5
5
  import ChangesIcon from '@atlaskit/icon/core/changes';
6
6
  import ChevronRightIcon from '@atlaskit/icon/core/chevron-right';
7
- import { fg } from '@atlaskit/platform-feature-flags';
8
7
  import CopyBlockMenuItem from './copy-block';
9
8
  import { CopyLinkDropdownItem } from './copy-link';
10
9
  import { DeleteDropdownItem } from './delete-button';
@@ -91,7 +90,7 @@ var getFormatMenuComponents = function getFormatMenuComponents() {
91
90
  export var getBlockMenuComponents = function getBlockMenuComponents(_ref4) {
92
91
  var api = _ref4.api,
93
92
  config = _ref4.config;
94
- return [].concat(_toConsumableArray(fg('platform_editor_block_menu_format') ? getFormatMenuComponents() : []), [{
93
+ return [].concat(_toConsumableArray(getFormatMenuComponents()), [{
95
94
  type: 'block-menu-section',
96
95
  key: COPY_MENU_SECTION.key,
97
96
  rank: BLOCK_MENU_SECTION_RANK[COPY_MENU_SECTION.key],
@@ -1,8 +1,8 @@
1
- import type { TransformFunction } from './types';
1
+ import type { TransformContext, TransformFunction } from './types';
2
2
  /**
3
3
  * Transform selection to container type
4
4
  */
5
- export declare const transformToContainer: () => null;
5
+ export declare const transformToContainer: ({ tr, sourceNode, targetNodeType, targetAttrs, }: TransformContext) => import("prosemirror-state").Transaction | null;
6
6
  /**
7
7
  * Transform container nodes (panel, expand, blockquote)
8
8
  */
@@ -0,0 +1,3 @@
1
+ import type { Fragment } from '@atlaskit/editor-prosemirror/model';
2
+ import type { Transaction } from '@atlaskit/editor-prosemirror/state';
3
+ export declare const getInlineNodeTextContent: (sourceContent: Fragment, tr: Transaction) => import("prosemirror-model").Node | undefined;
@@ -0,0 +1,9 @@
1
+ import type { Node as PMNode, NodeType } from '@atlaskit/editor-prosemirror/model';
2
+ import type { Transaction } from '@atlaskit/editor-prosemirror/state';
3
+ /**
4
+ * Transform list structure
5
+ */
6
+ export declare const transformListStructure: (tr: Transaction, listNode: {
7
+ node: PMNode;
8
+ pos: number;
9
+ }, targetNodeType: NodeType, nodes: Record<string, NodeType>) => Transaction;
@@ -1,14 +1,9 @@
1
- import type { NodeType } from '@atlaskit/editor-prosemirror/model';
2
1
  import type { Transaction } from '@atlaskit/editor-prosemirror/state';
3
2
  import type { TransformContext, TransformFunction } from './types';
4
3
  /**
5
4
  * Transform selection to list type
6
5
  */
7
- export declare const transformToList: ({ tr, targetNodeType, targetAttrs, }: {
8
- targetAttrs?: Record<string, unknown>;
9
- targetNodeType: NodeType;
10
- tr: Transaction;
11
- }) => Transaction | null;
6
+ export declare const transformBlockToList: (context: TransformContext) => Transaction | null;
12
7
  /**
13
8
  * Transform list nodes
14
9
  */