@atlaskit/editor-plugin-block-menu 5.2.12 → 5.2.14

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 (32) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/cjs/editor-commands/transform-node-utils/steps/wrapMixedContentStep.js +43 -2
  3. package/dist/cjs/editor-commands/transform-node-utils/transform.js +2 -1
  4. package/dist/cjs/editor-commands/transform-node-utils/utils.js +1 -53
  5. package/dist/cjs/editor-commands/transformNode.js +4 -4
  6. package/dist/cjs/ui/copy-link.js +7 -11
  7. package/dist/cjs/ui/hooks/useSuggestedItems.js +11 -4
  8. package/dist/cjs/ui/utils/copyLink.js +4 -4
  9. package/dist/cjs/ui/utils/suggested-items-rank.js +1 -1
  10. package/dist/es2019/editor-commands/transform-node-utils/steps/wrapMixedContentStep.js +41 -2
  11. package/dist/es2019/editor-commands/transform-node-utils/transform.js +2 -1
  12. package/dist/es2019/editor-commands/transform-node-utils/utils.js +0 -54
  13. package/dist/es2019/editor-commands/transformNode.js +2 -2
  14. package/dist/es2019/ui/copy-link.js +7 -11
  15. package/dist/es2019/ui/hooks/useSuggestedItems.js +10 -5
  16. package/dist/es2019/ui/utils/copyLink.js +3 -4
  17. package/dist/es2019/ui/utils/suggested-items-rank.js +0 -5
  18. package/dist/esm/editor-commands/transform-node-utils/steps/wrapMixedContentStep.js +42 -2
  19. package/dist/esm/editor-commands/transform-node-utils/transform.js +2 -1
  20. package/dist/esm/editor-commands/transform-node-utils/utils.js +0 -52
  21. package/dist/esm/editor-commands/transformNode.js +2 -2
  22. package/dist/esm/ui/copy-link.js +7 -11
  23. package/dist/esm/ui/hooks/useSuggestedItems.js +12 -5
  24. package/dist/esm/ui/utils/copyLink.js +4 -4
  25. package/dist/esm/ui/utils/suggested-items-rank.js +1 -1
  26. package/dist/types/editor-commands/transform-node-utils/steps/wrapMixedContentStep.d.ts +1 -0
  27. package/dist/types/editor-commands/transform-node-utils/utils.d.ts +1 -17
  28. package/dist/types/ui/utils/copyLink.d.ts +1 -3
  29. package/dist/types-ts4.5/editor-commands/transform-node-utils/steps/wrapMixedContentStep.d.ts +1 -0
  30. package/dist/types-ts4.5/editor-commands/transform-node-utils/utils.d.ts +1 -17
  31. package/dist/types-ts4.5/ui/utils/copyLink.d.ts +1 -3
  32. package/package.json +2 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # @atlaskit/editor-plugin-block-menu
2
2
 
3
+ ## 5.2.14
4
+
5
+ ### Patch Changes
6
+
7
+ - [`6bf9c33a49f72`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/6bf9c33a49f72) -
8
+ [ux] Add check for empty transformation and create blank node
9
+ - Updated dependencies
10
+
11
+ ## 5.2.13
12
+
13
+ ### Patch Changes
14
+
15
+ - [`8da61d284b811`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/8da61d284b811) -
16
+ EDITOR-3911 Expand selection to block range
17
+ - [`010fbe9d85b12`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/010fbe9d85b12) -
18
+ [ux] Fix bug / make wrap of expand convert to nestedExpand node
19
+ - Updated dependencies
20
+
3
21
  ## 5.2.12
4
22
 
5
23
  ### Patch Changes
@@ -1,9 +1,11 @@
1
1
  "use strict";
2
2
 
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
3
4
  Object.defineProperty(exports, "__esModule", {
4
5
  value: true
5
6
  });
6
7
  exports.wrapMixedContentStep = void 0;
8
+ var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
7
9
  var _model = require("@atlaskit/editor-prosemirror/model");
8
10
  var _types = require("../types");
9
11
  /**
@@ -48,6 +50,38 @@ var canWrapInTarget = function canWrapInTarget(node, targetNodeType, targetNodeT
48
50
  return targetNodeType.validContent(_model.Fragment.from(node));
49
51
  };
50
52
 
53
+ /**
54
+ * Handles the edge case where transforming from a container to another container results in
55
+ * all content breaking out (no valid children for the target). In this case, creates an empty
56
+ * container to ensure the target container type is created.
57
+ *
58
+ * We can determine if there were no valid children by checking if no container was created
59
+ * (`!hasCreatedContainer`) and there are nodes in the result (`result.length > 0`), which
60
+ * means all content broke out rather than being wrapped.
61
+ *
62
+ * @param result - The current result nodes after processing
63
+ * @param hasCreatedContainer - Whether a container was already created during processing
64
+ * @param fromNode - The original source node (before unwrapping)
65
+ * @param targetNodeType - The target container type
66
+ * @param targetNodeTypeName - The target container type name
67
+ * @param schema - The schema
68
+ * @returns The result nodes with an empty container prepended if needed, or the original result
69
+ */
70
+ var handleEmptyContainerEdgeCase = function handleEmptyContainerEdgeCase(result, hasCreatedContainer, fromNode, targetNodeType, targetNodeTypeName, schema) {
71
+ var isFromContainer = _types.NODE_CATEGORY_BY_TYPE[fromNode.type.name] === 'container';
72
+ var isTargetContainer = _types.NODE_CATEGORY_BY_TYPE[targetNodeTypeName] === 'container';
73
+ // If no container was created but we have nodes in result, all content broke out
74
+ // (meaning there were no valid children that could be wrapped)
75
+ var allContentBrokeOut = !hasCreatedContainer && result.length > 0;
76
+ var shouldCreateEmptyTarget = isFromContainer && isTargetContainer && allContentBrokeOut;
77
+ if (shouldCreateEmptyTarget) {
78
+ var emptyParagraph = schema.nodes.paragraph.create();
79
+ var emptyContainer = targetNodeType.create({}, emptyParagraph);
80
+ return [emptyContainer].concat((0, _toConsumableArray2.default)(result));
81
+ }
82
+ return result;
83
+ };
84
+
51
85
  /**
52
86
  * A wrap step that handles mixed content according to the Compatibility Matrix:
53
87
  * - Wraps consecutive compatible nodes into the target container
@@ -65,21 +99,25 @@ var canWrapInTarget = function canWrapInTarget(node, targetNodeType, targetNodeT
65
99
  * Example: expand(p('a'), table(), p('b')) → panel: [panel(p('a')), table(), panel(p('b'))]
66
100
  * Example: expand(p('a'), panel(p('x')), p('b')) → panel: [panel(p('a')), panel(p('x')), panel(p('b'))]
67
101
  * Example: expand(p('a'), nestedExpand({title: 'inner'})(p('x')), p('b')) → panel: [panel(p('a')), expand({title: 'inner'})(p('x')), panel(p('b'))]
102
+ * Example: expand(nestedExpand()(p())) → panel: [panel(), expand()(p())] (empty panel when all content breaks out)
68
103
  */
69
104
  var wrapMixedContentStep = exports.wrapMixedContentStep = function wrapMixedContentStep(nodes, context) {
70
105
  var schema = context.schema,
71
- targetNodeTypeName = context.targetNodeTypeName;
106
+ targetNodeTypeName = context.targetNodeTypeName,
107
+ fromNode = context.fromNode;
72
108
  var targetNodeType = schema.nodes[targetNodeTypeName];
73
109
  if (!targetNodeType) {
74
110
  return nodes;
75
111
  }
76
112
  var result = [];
77
113
  var currentContainerContent = [];
114
+ var hasCreatedContainer = false;
78
115
  var flushCurrentContainer = function flushCurrentContainer() {
79
116
  if (currentContainerContent.length > 0) {
80
117
  var containerNode = targetNodeType.createAndFill({}, _model.Fragment.fromArray(currentContainerContent));
81
118
  if (containerNode) {
82
119
  result.push(containerNode);
120
+ hasCreatedContainer = true;
83
121
  }
84
122
  currentContainerContent = [];
85
123
  }
@@ -110,5 +148,8 @@ var wrapMixedContentStep = exports.wrapMixedContentStep = function wrapMixedCont
110
148
 
111
149
  // Flush any remaining content into a container
112
150
  flushCurrentContainer();
113
- return result.length > 0 ? result : nodes;
151
+
152
+ // Handle edge case: create empty container if all content broke out
153
+ var finalResult = handleEmptyContainerEdgeCase(result, hasCreatedContainer, fromNode, targetNodeType, targetNodeTypeName, schema);
154
+ return finalResult.length > 0 ? finalResult : nodes;
114
155
  };
@@ -133,7 +133,8 @@ var TRANSFORM_STEPS_OVERRIDE = {
133
133
  decisionList: {
134
134
  bulletList: [_decisionListToListStep.decisionListToListStep],
135
135
  orderedList: [_decisionListToListStep.decisionListToListStep],
136
- taskList: [_decisionListToListStep.decisionListToListStep]
136
+ taskList: [_decisionListToListStep.decisionListToListStep],
137
+ layoutSection: [_wrapIntoLayoutStep.wrapIntoLayoutStep]
137
138
  }
138
139
  };
139
140
  var getTransformStepsForNodeTypes = function getTransformStepsForNodeTypes(selectedNodeTypeName, targetNodeTypeName) {
@@ -3,12 +3,10 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.isListType = exports.getTargetNodeTypeNameInContext = exports.getSelectedNode = exports.getBlockNodesInRange = exports.expandSelectionToBlockRange = exports.convertNestedExpandToExpand = exports.convertExpandToNestedExpand = void 0;
7
- var _selection = require("@atlaskit/editor-common/selection");
6
+ exports.isListType = exports.getTargetNodeTypeNameInContext = exports.getSelectedNode = exports.getBlockNodesInRange = exports.convertNestedExpandToExpand = exports.convertExpandToNestedExpand = void 0;
8
7
  var _state = require("@atlaskit/editor-prosemirror/state");
9
8
  var _utils = require("@atlaskit/editor-prosemirror/utils");
10
9
  var _editorTables = require("@atlaskit/editor-tables");
11
- var _utils2 = require("@atlaskit/editor-tables/utils");
12
10
  var getSelectedNode = exports.getSelectedNode = function getSelectedNode(selection) {
13
11
  if (selection instanceof _state.NodeSelection) {
14
12
  return {
@@ -57,56 +55,6 @@ var getTargetNodeTypeNameInContext = exports.getTargetNodeTypeNameInContext = fu
57
55
  }
58
56
  return nodeTypeName;
59
57
  };
60
-
61
- /**
62
- * Use common expandToBlockRange function to get the correct range for the selection
63
- * For example, if selection starts in a listItem, go find the bullet list or ordered list, their $from
64
- * @param selection
65
- * @param schema
66
- * @returns
67
- */
68
- var expandSelectionToBlockRange = exports.expandSelectionToBlockRange = function expandSelectionToBlockRange(selection, schema) {
69
- var nodes = schema.nodes;
70
- var nodesNeedToExpandRange = [nodes.bulletList, nodes.orderedList, nodes.taskList, nodes.listItem, nodes.taskItem];
71
-
72
- // when adding nodes.tableRow, tableHeader, tableCell in nodesNeedToExpandRang,
73
- // expandToBlockRange does not return expected table start position, sometimes even freeze editor
74
- // so handle table in the below logic
75
- if ((0, _utils2.isTableSelected)(selection)) {
76
- var table = (0, _utils2.findTable)(selection);
77
- if (table) {
78
- var $from = selection.$from.doc.resolve(table.pos);
79
- var $to = selection.$from.doc.resolve(table.pos + table.node.nodeSize - 1);
80
- return {
81
- $from: $from,
82
- $to: $to,
83
- range: $from.blockRange($to)
84
- };
85
- }
86
- }
87
-
88
- // when selecting a file, selection is on media
89
- // need to find media group and return its pos
90
- if (selection instanceof _state.NodeSelection) {
91
- if (selection.node.type === nodes.media) {
92
- var mediaGroup = (0, _utils.findParentNodeOfType)(nodes.mediaGroup)(selection);
93
- if (mediaGroup) {
94
- var _$from = selection.$from.doc.resolve(mediaGroup.pos);
95
- var _$to = selection.$from.doc.resolve(mediaGroup.pos + mediaGroup.node.nodeSize);
96
- return {
97
- $from: _$from,
98
- $to: _$to
99
- };
100
- }
101
- }
102
- }
103
- return (0, _selection.expandToBlockRange)(selection.$from, selection.$to, function (node) {
104
- if (nodesNeedToExpandRange.includes(node.type)) {
105
- return false;
106
- }
107
- return true;
108
- });
109
- };
110
58
  var isListType = exports.isListType = function isListType(node, schema) {
111
59
  var lists = [schema.nodes.taskList, schema.nodes.bulletList, schema.nodes.orderedList];
112
60
  return lists.some(function (list) {
@@ -4,12 +4,12 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.transformNode = void 0;
7
+ var _selection = require("@atlaskit/editor-common/selection");
7
8
  var _model = require("@atlaskit/editor-prosemirror/model");
8
9
  var _state = require("@atlaskit/editor-prosemirror/state");
9
10
  var _isNestedNode = require("../ui/utils/isNestedNode");
10
11
  var _transform = require("./transform-node-utils/transform");
11
- var _utils = require("./transform-node-utils/utils");
12
- var _utils2 = require("./transforms/utils");
12
+ var _utils = require("./transforms/utils");
13
13
  var transformNode = exports.transformNode = function transformNode(api) {
14
14
  return (
15
15
  // eslint-disable-next-line no-unused-vars
@@ -23,13 +23,13 @@ var transformNode = exports.transformNode = function transformNode(api) {
23
23
  }
24
24
  var schema = tr.doc.type.schema;
25
25
  var nodes = schema.nodes;
26
- var _expandSelectionToBlo = (0, _utils.expandSelectionToBlockRange)(preservedSelection, schema),
26
+ var _expandSelectionToBlo = (0, _selection.expandSelectionToBlockRange)(preservedSelection),
27
27
  $from = _expandSelectionToBlo.$from,
28
28
  $to = _expandSelectionToBlo.$to;
29
29
  var isNested = (0, _isNestedNode.isNestedNode)(preservedSelection, '');
30
30
  var selectedParent = $from.parent;
31
31
  var fragment = _model.Fragment.empty;
32
- var isList = (0, _utils2.isListNode)(selectedParent);
32
+ var isList = (0, _utils.isListNode)(selectedParent);
33
33
  var slice = tr.doc.slice(isList ? $from.pos - 1 : $from.pos, isList ? $to.pos + 1 : $to.pos);
34
34
  slice.content.forEach(function (node) {
35
35
  var outputNode = (0, _transform.getOutputNodes)({
@@ -31,24 +31,21 @@ var CopyLinkDropdownItemContent = function CopyLinkDropdownItemContent(_ref) {
31
31
  var _ref2 = config || {},
32
32
  getLinkPath = _ref2.getLinkPath,
33
33
  blockLinkHashPrefix = _ref2.blockLinkHashPrefix;
34
- var _useSharedPluginState = (0, _hooks.useSharedPluginStateWithSelector)(api, ['blockControls', 'selection', 'core'], function (_ref3) {
34
+ var _useSharedPluginState = (0, _hooks.useSharedPluginStateWithSelector)(api, ['blockControls', 'selection'], function (_ref3) {
35
35
  var blockControlsState = _ref3.blockControlsState,
36
- selectionState = _ref3.selectionState,
37
- coreState = _ref3.coreState;
36
+ selectionState = _ref3.selectionState;
38
37
  return {
39
38
  menuTriggerBy: blockControlsState === null || blockControlsState === void 0 ? void 0 : blockControlsState.menuTriggerBy,
40
39
  preservedSelection: blockControlsState === null || blockControlsState === void 0 ? void 0 : blockControlsState.preservedSelection,
41
- defaultSelection: selectionState === null || selectionState === void 0 ? void 0 : selectionState.selection,
42
- schema: coreState === null || coreState === void 0 ? void 0 : coreState.schema
40
+ defaultSelection: selectionState === null || selectionState === void 0 ? void 0 : selectionState.selection
43
41
  };
44
42
  }),
45
43
  preservedSelection = _useSharedPluginState.preservedSelection,
46
44
  defaultSelection = _useSharedPluginState.defaultSelection,
47
- menuTriggerBy = _useSharedPluginState.menuTriggerBy,
48
- schema = _useSharedPluginState.schema;
45
+ menuTriggerBy = _useSharedPluginState.menuTriggerBy;
49
46
  var selection = preservedSelection || defaultSelection;
50
47
  var handleClick = (0, _react.useCallback)(function () {
51
- if (!selection || !schema) {
48
+ if (!selection) {
52
49
  return;
53
50
  }
54
51
  api === null || api === void 0 || api.core.actions.execute(function (_ref4) {
@@ -74,8 +71,7 @@ var CopyLinkDropdownItemContent = function CopyLinkDropdownItemContent(_ref) {
74
71
  (0, _copyLink.copyLink)({
75
72
  getLinkPath: getLinkPath,
76
73
  blockLinkHashPrefix: blockLinkHashPrefix,
77
- selection: selection,
78
- schema: schema
74
+ selection: selection
79
75
  }).then(function (success) {
80
76
  if (success) {
81
77
  api === null || api === void 0 || api.core.actions.execute(function (_ref5) {
@@ -87,7 +83,7 @@ var CopyLinkDropdownItemContent = function CopyLinkDropdownItemContent(_ref) {
87
83
  });
88
84
  }
89
85
  });
90
- }, [api, blockLinkHashPrefix, getLinkPath, onDropdownOpenChanged, schema, selection]);
86
+ }, [api, blockLinkHashPrefix, getLinkPath, onDropdownOpenChanged, selection]);
91
87
 
92
88
  // Hide copy link when `platform_editor_adf_with_localid` feature flag is off or when the node is nested or on empty line
93
89
  if (!(0, _platformFeatureFlags.fg)('platform_editor_adf_with_localid') || !!menuTriggerBy && (0, _isNestedNode.isNestedNode)(selection, menuTriggerBy) || selection !== null && selection !== void 0 && selection.empty) {
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.useSuggestedItems = void 0;
7
7
  var _react = require("react");
8
8
  var _hooks = require("@atlaskit/editor-common/hooks");
9
+ var _selection = require("@atlaskit/editor-common/selection");
9
10
  var _utils = require("../../editor-commands/transform-node-utils/utils");
10
11
  var _suggestedItemsRank = require("../utils/suggested-items-rank");
11
12
  var useSuggestedItems = exports.useSuggestedItems = function useSuggestedItems(api) {
@@ -35,17 +36,23 @@ var useSuggestedItems = exports.useSuggestedItems = function useSuggestedItems(a
35
36
  if (menuItemsMap.size === 0 || !currentSelection) {
36
37
  return [];
37
38
  }
38
- var _expandSelectionToBlo = (0, _utils.expandSelectionToBlockRange)(currentSelection, currentSelection.$from.doc.type.schema),
39
+ var _expandSelectionToBlo = (0, _selection.expandSelectionToBlockRange)(currentSelection),
39
40
  range = _expandSelectionToBlo.range;
40
41
  if (!range) {
41
42
  return [];
42
43
  }
43
44
  var blockNodes = (0, _utils.getBlockNodesInRange)(range);
44
- var singleNode = blockNodes.length === 1 ? blockNodes[0] : undefined;
45
- if (!singleNode) {
45
+ if (blockNodes.length === 0) {
46
46
  return [];
47
47
  }
48
- var nodeTypeName = singleNode.type.name;
48
+ var firstNodeType = blockNodes[0].type.name;
49
+ var allSameType = blockNodes.every(function (node) {
50
+ return node.type.name === firstNodeType;
51
+ });
52
+ if (!allSameType) {
53
+ return [];
54
+ }
55
+ var nodeTypeName = firstNodeType;
49
56
  var sortedKeys = (0, _suggestedItemsRank.getSortedSuggestedItems)(nodeTypeName);
50
57
  return sortedKeys.map(function (key) {
51
58
  return menuItemsMap.get(key);
@@ -10,15 +10,15 @@ var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/
10
10
  var _blockMenu = require("@atlaskit/editor-common/block-menu");
11
11
  var _clipboard = require("@atlaskit/editor-common/clipboard");
12
12
  var _monitoring = require("@atlaskit/editor-common/monitoring");
13
- var _utils = require("../../editor-commands/transform-node-utils/utils");
13
+ var _selection = require("@atlaskit/editor-common/selection");
14
14
  var copyLink = exports.copyLink = /*#__PURE__*/function () {
15
15
  var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(_ref) {
16
- var getLinkPath, _ref$blockLinkHashPre, blockLinkHashPrefix, selection, schema, blockRange, node, path, url, href;
16
+ var getLinkPath, _ref$blockLinkHashPre, blockLinkHashPrefix, selection, blockRange, node, path, url, href;
17
17
  return _regenerator.default.wrap(function _callee$(_context) {
18
18
  while (1) switch (_context.prev = _context.next) {
19
19
  case 0:
20
- getLinkPath = _ref.getLinkPath, _ref$blockLinkHashPre = _ref.blockLinkHashPrefix, blockLinkHashPrefix = _ref$blockLinkHashPre === void 0 ? _blockMenu.DEFAULT_BLOCK_LINK_HASH_PREFIX : _ref$blockLinkHashPre, selection = _ref.selection, schema = _ref.schema;
21
- blockRange = (0, _utils.expandSelectionToBlockRange)(selection, schema);
20
+ getLinkPath = _ref.getLinkPath, _ref$blockLinkHashPre = _ref.blockLinkHashPrefix, blockLinkHashPrefix = _ref$blockLinkHashPre === void 0 ? _blockMenu.DEFAULT_BLOCK_LINK_HASH_PREFIX : _ref$blockLinkHashPre, selection = _ref.selection;
21
+ blockRange = (0, _selection.expandSelectionToBlockRange)(selection);
22
22
  if (blockRange) {
23
23
  _context.next = 4;
24
24
  break;
@@ -43,7 +43,7 @@ var BLOCK_MENU_NODE_TYPES = exports.BLOCK_MENU_NODE_TYPES = {
43
43
  EMBED_CARD: 'embedCard',
44
44
  TABLE: 'table'
45
45
  };
46
- var TRANSFORM_SUGGESTED_ITEMS_RANK = exports.TRANSFORM_SUGGESTED_ITEMS_RANK = (_TRANSFORM_SUGGESTED_ = {}, (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)(_TRANSFORM_SUGGESTED_, BLOCK_MENU_NODE_TYPES.PARAGRAPH, (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)({}, _blockMenu.TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key, 100), _blockMenu.TRANSFORM_HEADINGS_H1_MENU_ITEM.key, 200), _blockMenu.TRANSFORM_HEADINGS_H2_MENU_ITEM.key, 300)), BLOCK_MENU_NODE_TYPES.EXPAND, (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)({}, _blockMenu.TRANSFORM_STRUCTURE_LAYOUT_MENU_ITEM.key, 100), _blockMenu.TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key, 200), _blockMenu.TRANSFORM_STRUCTURE_PARAGRAPH_MENU_ITEM.key, 300)), BLOCK_MENU_NODE_TYPES.BLOCKQUOTE, (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)({}, _blockMenu.TRANSFORM_STRUCTURE_EXPAND_MENU_ITEM.key, 100), _blockMenu.TRANSFORM_STRUCTURE_LAYOUT_MENU_ITEM.key, 200), _blockMenu.TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key, 300)), BLOCK_MENU_NODE_TYPES.LAYOUT_SECTION, (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)({}, _blockMenu.TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key, 100), _blockMenu.TRANSFORM_STRUCTURE_EXPAND_MENU_ITEM.key, 200), _blockMenu.TRANSFORM_STRUCTURE_PARAGRAPH_MENU_ITEM.key, 300)), BLOCK_MENU_NODE_TYPES.PANEL, (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)({}, _blockMenu.TRANSFORM_STRUCTURE_QUOTE_MENU_ITEM.key, 100), _blockMenu.TRANSFORM_STRUCTURE_CODE_BLOCK_MENU_ITEM.key, 200), _blockMenu.TRANSFORM_STRUCTURE_EXPAND_MENU_ITEM.key, 300)), BLOCK_MENU_NODE_TYPES.CODE_BLOCK, (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)({}, _blockMenu.TRANSFORM_STRUCTURE_EXPAND_MENU_ITEM.key, 100), _blockMenu.TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key, 200), _blockMenu.TRANSFORM_STRUCTURE_PARAGRAPH_MENU_ITEM.key, 300)), BLOCK_MENU_NODE_TYPES.DECISION, (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)({}, _blockMenu.TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key, 100), _blockMenu.TRANSFORM_STRUCTURE_QUOTE_MENU_ITEM.key, 200), _blockMenu.TRANSFORM_STRUCTURE_LAYOUT_MENU_ITEM.key, 300)), BLOCK_MENU_NODE_TYPES.BULLET_LIST, (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)({}, _blockMenu.TRANSFORM_STRUCTURE_NUMBERED_LIST_MENU_ITEM.key, 100), _blockMenu.TRANSFORM_STRUCTURE_QUOTE_MENU_ITEM.key, 200), _blockMenu.TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key, 300)), BLOCK_MENU_NODE_TYPES.ORDERED_LIST, (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)({}, _blockMenu.TRANSFORM_STRUCTURE_TASK_LIST_MENU_ITEM.key, 100), _blockMenu.TRANSFORM_STRUCTURE_BULLETED_LIST_MENU_ITEM.key, 200), _blockMenu.TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key, 300)), BLOCK_MENU_NODE_TYPES.HEADING, (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)({}, _blockMenu.TRANSFORM_STRUCTURE_PARAGRAPH_MENU_ITEM.key, 100), _blockMenu.TRANSFORM_STRUCTURE_BULLETED_LIST_MENU_ITEM.key, 200), _blockMenu.TRANSFORM_STRUCTURE_QUOTE_MENU_ITEM.key, 300)), (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)(_TRANSFORM_SUGGESTED_, BLOCK_MENU_NODE_TYPES.TASK_LIST, (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)({}, _blockMenu.TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key, 100), _blockMenu.TRANSFORM_STRUCTURE_NUMBERED_LIST_MENU_ITEM.key, 200), _blockMenu.TRANSFORM_STRUCTURE_BULLETED_LIST_MENU_ITEM.key, 300)), BLOCK_MENU_NODE_TYPES.MEDIA_SINGLE, (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)({}, _blockMenu.TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key, 100), _blockMenu.TRANSFORM_STRUCTURE_EXPAND_MENU_ITEM.key, 200), _blockMenu.TRANSFORM_STRUCTURE_QUOTE_MENU_ITEM.key, 300)), BLOCK_MENU_NODE_TYPES.EXTENSION, (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)({}, _blockMenu.TRANSFORM_STRUCTURE_EXPAND_MENU_ITEM.key, 100), _blockMenu.TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key, 200), _blockMenu.TRANSFORM_STRUCTURE_LAYOUT_MENU_ITEM.key, 300)), BLOCK_MENU_NODE_TYPES.BODIED_EXTENSION, (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)({}, _blockMenu.TRANSFORM_STRUCTURE_EXPAND_MENU_ITEM.key, 100), _blockMenu.TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key, 200), _blockMenu.TRANSFORM_STRUCTURE_LAYOUT_MENU_ITEM.key, 300)));
46
+ var TRANSFORM_SUGGESTED_ITEMS_RANK = exports.TRANSFORM_SUGGESTED_ITEMS_RANK = (_TRANSFORM_SUGGESTED_ = {}, (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)(_TRANSFORM_SUGGESTED_, BLOCK_MENU_NODE_TYPES.PARAGRAPH, (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)({}, _blockMenu.TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key, 100), _blockMenu.TRANSFORM_HEADINGS_H1_MENU_ITEM.key, 200), _blockMenu.TRANSFORM_HEADINGS_H2_MENU_ITEM.key, 300)), BLOCK_MENU_NODE_TYPES.EXPAND, (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)({}, _blockMenu.TRANSFORM_STRUCTURE_LAYOUT_MENU_ITEM.key, 100), _blockMenu.TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key, 200), _blockMenu.TRANSFORM_STRUCTURE_PARAGRAPH_MENU_ITEM.key, 300)), BLOCK_MENU_NODE_TYPES.BLOCKQUOTE, (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)({}, _blockMenu.TRANSFORM_STRUCTURE_EXPAND_MENU_ITEM.key, 100), _blockMenu.TRANSFORM_STRUCTURE_LAYOUT_MENU_ITEM.key, 200), _blockMenu.TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key, 300)), BLOCK_MENU_NODE_TYPES.LAYOUT_SECTION, (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)({}, _blockMenu.TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key, 100), _blockMenu.TRANSFORM_STRUCTURE_EXPAND_MENU_ITEM.key, 200), _blockMenu.TRANSFORM_STRUCTURE_PARAGRAPH_MENU_ITEM.key, 300)), BLOCK_MENU_NODE_TYPES.PANEL, (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)({}, _blockMenu.TRANSFORM_STRUCTURE_QUOTE_MENU_ITEM.key, 100), _blockMenu.TRANSFORM_STRUCTURE_CODE_BLOCK_MENU_ITEM.key, 200), _blockMenu.TRANSFORM_STRUCTURE_EXPAND_MENU_ITEM.key, 300)), BLOCK_MENU_NODE_TYPES.CODE_BLOCK, (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)({}, _blockMenu.TRANSFORM_STRUCTURE_EXPAND_MENU_ITEM.key, 100), _blockMenu.TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key, 200), _blockMenu.TRANSFORM_STRUCTURE_PARAGRAPH_MENU_ITEM.key, 300)), BLOCK_MENU_NODE_TYPES.DECISION, (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)({}, _blockMenu.TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key, 100), _blockMenu.TRANSFORM_STRUCTURE_QUOTE_MENU_ITEM.key, 200), _blockMenu.TRANSFORM_STRUCTURE_LAYOUT_MENU_ITEM.key, 300)), BLOCK_MENU_NODE_TYPES.BULLET_LIST, (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)({}, _blockMenu.TRANSFORM_STRUCTURE_NUMBERED_LIST_MENU_ITEM.key, 100), _blockMenu.TRANSFORM_STRUCTURE_QUOTE_MENU_ITEM.key, 200), _blockMenu.TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key, 300)), BLOCK_MENU_NODE_TYPES.ORDERED_LIST, (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)({}, _blockMenu.TRANSFORM_STRUCTURE_TASK_LIST_MENU_ITEM.key, 100), _blockMenu.TRANSFORM_STRUCTURE_BULLETED_LIST_MENU_ITEM.key, 200), _blockMenu.TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key, 300)), BLOCK_MENU_NODE_TYPES.HEADING, (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)({}, _blockMenu.TRANSFORM_STRUCTURE_PARAGRAPH_MENU_ITEM.key, 100), _blockMenu.TRANSFORM_STRUCTURE_BULLETED_LIST_MENU_ITEM.key, 200), _blockMenu.TRANSFORM_STRUCTURE_QUOTE_MENU_ITEM.key, 300)), (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)(_TRANSFORM_SUGGESTED_, BLOCK_MENU_NODE_TYPES.TASK_LIST, (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)({}, _blockMenu.TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key, 100), _blockMenu.TRANSFORM_STRUCTURE_NUMBERED_LIST_MENU_ITEM.key, 200), _blockMenu.TRANSFORM_STRUCTURE_BULLETED_LIST_MENU_ITEM.key, 300)), BLOCK_MENU_NODE_TYPES.MEDIA_SINGLE, (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)({}, _blockMenu.TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key, 100), _blockMenu.TRANSFORM_STRUCTURE_EXPAND_MENU_ITEM.key, 200), _blockMenu.TRANSFORM_STRUCTURE_QUOTE_MENU_ITEM.key, 300)), BLOCK_MENU_NODE_TYPES.EXTENSION, (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)({}, _blockMenu.TRANSFORM_STRUCTURE_EXPAND_MENU_ITEM.key, 100), _blockMenu.TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key, 200), _blockMenu.TRANSFORM_STRUCTURE_LAYOUT_MENU_ITEM.key, 300)));
47
47
  var getSuggestedItemsForNodeType = exports.getSuggestedItemsForNodeType = function getSuggestedItemsForNodeType(nodeType) {
48
48
  return TRANSFORM_SUGGESTED_ITEMS_RANK[nodeType];
49
49
  };
@@ -43,6 +43,38 @@ const canWrapInTarget = (node, targetNodeType, targetNodeTypeName) => {
43
43
  return targetNodeType.validContent(Fragment.from(node));
44
44
  };
45
45
 
46
+ /**
47
+ * Handles the edge case where transforming from a container to another container results in
48
+ * all content breaking out (no valid children for the target). In this case, creates an empty
49
+ * container to ensure the target container type is created.
50
+ *
51
+ * We can determine if there were no valid children by checking if no container was created
52
+ * (`!hasCreatedContainer`) and there are nodes in the result (`result.length > 0`), which
53
+ * means all content broke out rather than being wrapped.
54
+ *
55
+ * @param result - The current result nodes after processing
56
+ * @param hasCreatedContainer - Whether a container was already created during processing
57
+ * @param fromNode - The original source node (before unwrapping)
58
+ * @param targetNodeType - The target container type
59
+ * @param targetNodeTypeName - The target container type name
60
+ * @param schema - The schema
61
+ * @returns The result nodes with an empty container prepended if needed, or the original result
62
+ */
63
+ const handleEmptyContainerEdgeCase = (result, hasCreatedContainer, fromNode, targetNodeType, targetNodeTypeName, schema) => {
64
+ const isFromContainer = NODE_CATEGORY_BY_TYPE[fromNode.type.name] === 'container';
65
+ const isTargetContainer = NODE_CATEGORY_BY_TYPE[targetNodeTypeName] === 'container';
66
+ // If no container was created but we have nodes in result, all content broke out
67
+ // (meaning there were no valid children that could be wrapped)
68
+ const allContentBrokeOut = !hasCreatedContainer && result.length > 0;
69
+ const shouldCreateEmptyTarget = isFromContainer && isTargetContainer && allContentBrokeOut;
70
+ if (shouldCreateEmptyTarget) {
71
+ const emptyParagraph = schema.nodes.paragraph.create();
72
+ const emptyContainer = targetNodeType.create({}, emptyParagraph);
73
+ return [emptyContainer, ...result];
74
+ }
75
+ return result;
76
+ };
77
+
46
78
  /**
47
79
  * A wrap step that handles mixed content according to the Compatibility Matrix:
48
80
  * - Wraps consecutive compatible nodes into the target container
@@ -60,11 +92,13 @@ const canWrapInTarget = (node, targetNodeType, targetNodeTypeName) => {
60
92
  * Example: expand(p('a'), table(), p('b')) → panel: [panel(p('a')), table(), panel(p('b'))]
61
93
  * Example: expand(p('a'), panel(p('x')), p('b')) → panel: [panel(p('a')), panel(p('x')), panel(p('b'))]
62
94
  * Example: expand(p('a'), nestedExpand({title: 'inner'})(p('x')), p('b')) → panel: [panel(p('a')), expand({title: 'inner'})(p('x')), panel(p('b'))]
95
+ * Example: expand(nestedExpand()(p())) → panel: [panel(), expand()(p())] (empty panel when all content breaks out)
63
96
  */
64
97
  export const wrapMixedContentStep = (nodes, context) => {
65
98
  const {
66
99
  schema,
67
- targetNodeTypeName
100
+ targetNodeTypeName,
101
+ fromNode
68
102
  } = context;
69
103
  const targetNodeType = schema.nodes[targetNodeTypeName];
70
104
  if (!targetNodeType) {
@@ -72,11 +106,13 @@ export const wrapMixedContentStep = (nodes, context) => {
72
106
  }
73
107
  const result = [];
74
108
  let currentContainerContent = [];
109
+ let hasCreatedContainer = false;
75
110
  const flushCurrentContainer = () => {
76
111
  if (currentContainerContent.length > 0) {
77
112
  const containerNode = targetNodeType.createAndFill({}, Fragment.fromArray(currentContainerContent));
78
113
  if (containerNode) {
79
114
  result.push(containerNode);
115
+ hasCreatedContainer = true;
80
116
  }
81
117
  currentContainerContent = [];
82
118
  }
@@ -107,5 +143,8 @@ export const wrapMixedContentStep = (nodes, context) => {
107
143
 
108
144
  // Flush any remaining content into a container
109
145
  flushCurrentContainer();
110
- return result.length > 0 ? result : nodes;
146
+
147
+ // Handle edge case: create empty container if all content broke out
148
+ const finalResult = handleEmptyContainerEdgeCase(result, hasCreatedContainer, fromNode, targetNodeType, targetNodeTypeName, schema);
149
+ return finalResult.length > 0 ? finalResult : nodes;
111
150
  };
@@ -128,7 +128,8 @@ const TRANSFORM_STEPS_OVERRIDE = {
128
128
  decisionList: {
129
129
  bulletList: [decisionListToListStep],
130
130
  orderedList: [decisionListToListStep],
131
- taskList: [decisionListToListStep]
131
+ taskList: [decisionListToListStep],
132
+ layoutSection: [wrapIntoLayoutStep]
132
133
  }
133
134
  };
134
135
  const getTransformStepsForNodeTypes = (selectedNodeTypeName, targetNodeTypeName) => {
@@ -1,8 +1,6 @@
1
- import { expandToBlockRange } from '@atlaskit/editor-common/selection';
2
1
  import { NodeSelection, TextSelection } from '@atlaskit/editor-prosemirror/state';
3
2
  import { findParentNodeOfType } from '@atlaskit/editor-prosemirror/utils';
4
3
  import { CellSelection } from '@atlaskit/editor-tables';
5
- import { findTable, isTableSelected } from '@atlaskit/editor-tables/utils';
6
4
  export const getSelectedNode = selection => {
7
5
  if (selection instanceof NodeSelection) {
8
6
  return {
@@ -52,58 +50,6 @@ export const getTargetNodeTypeNameInContext = (nodeTypeName, isNested) => {
52
50
  }
53
51
  return nodeTypeName;
54
52
  };
55
-
56
- /**
57
- * Use common expandToBlockRange function to get the correct range for the selection
58
- * For example, if selection starts in a listItem, go find the bullet list or ordered list, their $from
59
- * @param selection
60
- * @param schema
61
- * @returns
62
- */
63
- export const expandSelectionToBlockRange = (selection, schema) => {
64
- const {
65
- nodes
66
- } = schema;
67
- const nodesNeedToExpandRange = [nodes.bulletList, nodes.orderedList, nodes.taskList, nodes.listItem, nodes.taskItem];
68
-
69
- // when adding nodes.tableRow, tableHeader, tableCell in nodesNeedToExpandRang,
70
- // expandToBlockRange does not return expected table start position, sometimes even freeze editor
71
- // so handle table in the below logic
72
- if (isTableSelected(selection)) {
73
- const table = findTable(selection);
74
- if (table) {
75
- const $from = selection.$from.doc.resolve(table.pos);
76
- const $to = selection.$from.doc.resolve(table.pos + table.node.nodeSize - 1);
77
- return {
78
- $from,
79
- $to,
80
- range: $from.blockRange($to)
81
- };
82
- }
83
- }
84
-
85
- // when selecting a file, selection is on media
86
- // need to find media group and return its pos
87
- if (selection instanceof NodeSelection) {
88
- if (selection.node.type === nodes.media) {
89
- const mediaGroup = findParentNodeOfType(nodes.mediaGroup)(selection);
90
- if (mediaGroup) {
91
- const $from = selection.$from.doc.resolve(mediaGroup.pos);
92
- const $to = selection.$from.doc.resolve(mediaGroup.pos + mediaGroup.node.nodeSize);
93
- return {
94
- $from,
95
- $to
96
- };
97
- }
98
- }
99
- }
100
- return expandToBlockRange(selection.$from, selection.$to, node => {
101
- if (nodesNeedToExpandRange.includes(node.type)) {
102
- return false;
103
- }
104
- return true;
105
- });
106
- };
107
53
  export const isListType = (node, schema) => {
108
54
  const lists = [schema.nodes.taskList, schema.nodes.bulletList, schema.nodes.orderedList];
109
55
  return lists.some(list => list === node.type);
@@ -1,8 +1,8 @@
1
+ import { expandSelectionToBlockRange } from '@atlaskit/editor-common/selection';
1
2
  import { Fragment } from '@atlaskit/editor-prosemirror/model';
2
3
  import { NodeSelection } from '@atlaskit/editor-prosemirror/state';
3
4
  import { isNestedNode } from '../ui/utils/isNestedNode';
4
5
  import { getOutputNodes } from './transform-node-utils/transform';
5
- import { expandSelectionToBlockRange } from './transform-node-utils/utils';
6
6
  import { isListNode } from './transforms/utils';
7
7
  export const transformNode = api =>
8
8
  // eslint-disable-next-line no-unused-vars
@@ -22,7 +22,7 @@ export const transformNode = api =>
22
22
  const {
23
23
  $from,
24
24
  $to
25
- } = expandSelectionToBlockRange(preservedSelection, schema);
25
+ } = expandSelectionToBlockRange(preservedSelection);
26
26
  const isNested = isNestedNode(preservedSelection, '');
27
27
  const selectedParent = $from.parent;
28
28
  let fragment = Fragment.empty;
@@ -29,23 +29,20 @@ const CopyLinkDropdownItemContent = ({
29
29
  const {
30
30
  preservedSelection,
31
31
  defaultSelection,
32
- menuTriggerBy,
33
- schema
34
- } = useSharedPluginStateWithSelector(api, ['blockControls', 'selection', 'core'], ({
32
+ menuTriggerBy
33
+ } = useSharedPluginStateWithSelector(api, ['blockControls', 'selection'], ({
35
34
  blockControlsState,
36
- selectionState,
37
- coreState
35
+ selectionState
38
36
  }) => {
39
37
  return {
40
38
  menuTriggerBy: blockControlsState === null || blockControlsState === void 0 ? void 0 : blockControlsState.menuTriggerBy,
41
39
  preservedSelection: blockControlsState === null || blockControlsState === void 0 ? void 0 : blockControlsState.preservedSelection,
42
- defaultSelection: selectionState === null || selectionState === void 0 ? void 0 : selectionState.selection,
43
- schema: coreState === null || coreState === void 0 ? void 0 : coreState.schema
40
+ defaultSelection: selectionState === null || selectionState === void 0 ? void 0 : selectionState.selection
44
41
  };
45
42
  });
46
43
  const selection = preservedSelection || defaultSelection;
47
44
  const handleClick = useCallback(() => {
48
- if (!selection || !schema) {
45
+ if (!selection) {
49
46
  return;
50
47
  }
51
48
  api === null || api === void 0 ? void 0 : api.core.actions.execute(({
@@ -72,8 +69,7 @@ const CopyLinkDropdownItemContent = ({
72
69
  copyLink({
73
70
  getLinkPath,
74
71
  blockLinkHashPrefix,
75
- selection,
76
- schema
72
+ selection
77
73
  }).then(success => {
78
74
  if (success) {
79
75
  api === null || api === void 0 ? void 0 : api.core.actions.execute(({
@@ -86,7 +82,7 @@ const CopyLinkDropdownItemContent = ({
86
82
  });
87
83
  }
88
84
  });
89
- }, [api, blockLinkHashPrefix, getLinkPath, onDropdownOpenChanged, schema, selection]);
85
+ }, [api, blockLinkHashPrefix, getLinkPath, onDropdownOpenChanged, selection]);
90
86
 
91
87
  // Hide copy link when `platform_editor_adf_with_localid` feature flag is off or when the node is nested or on empty line
92
88
  if (!fg('platform_editor_adf_with_localid') || !!menuTriggerBy && isNestedNode(selection, menuTriggerBy) || selection !== null && selection !== void 0 && selection.empty) {
@@ -1,6 +1,7 @@
1
1
  import { useMemo } from 'react';
2
2
  import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
3
- import { getBlockNodesInRange, expandSelectionToBlockRange } from '../../editor-commands/transform-node-utils/utils';
3
+ import { expandSelectionToBlockRange } from '@atlaskit/editor-common/selection';
4
+ import { getBlockNodesInRange } from '../../editor-commands/transform-node-utils/utils';
4
5
  import { getSortedSuggestedItems } from '../utils/suggested-items-rank';
5
6
  export const useSuggestedItems = api => {
6
7
  var _api$blockMenu;
@@ -28,16 +29,20 @@ export const useSuggestedItems = api => {
28
29
  }
29
30
  const {
30
31
  range
31
- } = expandSelectionToBlockRange(currentSelection, currentSelection.$from.doc.type.schema);
32
+ } = expandSelectionToBlockRange(currentSelection);
32
33
  if (!range) {
33
34
  return [];
34
35
  }
35
36
  const blockNodes = getBlockNodesInRange(range);
36
- const singleNode = blockNodes.length === 1 ? blockNodes[0] : undefined;
37
- if (!singleNode) {
37
+ if (blockNodes.length === 0) {
38
38
  return [];
39
39
  }
40
- const nodeTypeName = singleNode.type.name;
40
+ const firstNodeType = blockNodes[0].type.name;
41
+ const allSameType = blockNodes.every(node => node.type.name === firstNodeType);
42
+ if (!allSameType) {
43
+ return [];
44
+ }
45
+ const nodeTypeName = firstNodeType;
41
46
  const sortedKeys = getSortedSuggestedItems(nodeTypeName);
42
47
  return sortedKeys.map(key => menuItemsMap.get(key)).filter(item => item !== undefined);
43
48
  }, [menuItemsMap, preservedSelection, selection]);
@@ -1,14 +1,13 @@
1
1
  import { createBlockLinkHashValue, DEFAULT_BLOCK_LINK_HASH_PREFIX } from '@atlaskit/editor-common/block-menu';
2
2
  import { copyToClipboard } from '@atlaskit/editor-common/clipboard';
3
3
  import { logException } from '@atlaskit/editor-common/monitoring';
4
- import { expandSelectionToBlockRange } from '../../editor-commands/transform-node-utils/utils';
4
+ import { expandSelectionToBlockRange } from '@atlaskit/editor-common/selection';
5
5
  export const copyLink = async ({
6
6
  getLinkPath,
7
7
  blockLinkHashPrefix = DEFAULT_BLOCK_LINK_HASH_PREFIX,
8
- selection,
9
- schema
8
+ selection
10
9
  }) => {
11
- const blockRange = expandSelectionToBlockRange(selection, schema);
10
+ const blockRange = expandSelectionToBlockRange(selection);
12
11
  if (!blockRange) {
13
12
  return false;
14
13
  }
@@ -99,11 +99,6 @@ export const TRANSFORM_SUGGESTED_ITEMS_RANK = {
99
99
  [TRANSFORM_STRUCTURE_EXPAND_MENU_ITEM.key]: 100,
100
100
  [TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key]: 200,
101
101
  [TRANSFORM_STRUCTURE_LAYOUT_MENU_ITEM.key]: 300
102
- },
103
- [BLOCK_MENU_NODE_TYPES.BODIED_EXTENSION]: {
104
- [TRANSFORM_STRUCTURE_EXPAND_MENU_ITEM.key]: 100,
105
- [TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key]: 200,
106
- [TRANSFORM_STRUCTURE_LAYOUT_MENU_ITEM.key]: 300
107
102
  }
108
103
  };
109
104
  export const getSuggestedItemsForNodeType = nodeType => {
@@ -1,3 +1,4 @@
1
+ import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
1
2
  import { Fragment } from '@atlaskit/editor-prosemirror/model';
2
3
  import { NODE_CATEGORY_BY_TYPE } from '../types';
3
4
 
@@ -43,6 +44,38 @@ var canWrapInTarget = function canWrapInTarget(node, targetNodeType, targetNodeT
43
44
  return targetNodeType.validContent(Fragment.from(node));
44
45
  };
45
46
 
47
+ /**
48
+ * Handles the edge case where transforming from a container to another container results in
49
+ * all content breaking out (no valid children for the target). In this case, creates an empty
50
+ * container to ensure the target container type is created.
51
+ *
52
+ * We can determine if there were no valid children by checking if no container was created
53
+ * (`!hasCreatedContainer`) and there are nodes in the result (`result.length > 0`), which
54
+ * means all content broke out rather than being wrapped.
55
+ *
56
+ * @param result - The current result nodes after processing
57
+ * @param hasCreatedContainer - Whether a container was already created during processing
58
+ * @param fromNode - The original source node (before unwrapping)
59
+ * @param targetNodeType - The target container type
60
+ * @param targetNodeTypeName - The target container type name
61
+ * @param schema - The schema
62
+ * @returns The result nodes with an empty container prepended if needed, or the original result
63
+ */
64
+ var handleEmptyContainerEdgeCase = function handleEmptyContainerEdgeCase(result, hasCreatedContainer, fromNode, targetNodeType, targetNodeTypeName, schema) {
65
+ var isFromContainer = NODE_CATEGORY_BY_TYPE[fromNode.type.name] === 'container';
66
+ var isTargetContainer = NODE_CATEGORY_BY_TYPE[targetNodeTypeName] === 'container';
67
+ // If no container was created but we have nodes in result, all content broke out
68
+ // (meaning there were no valid children that could be wrapped)
69
+ var allContentBrokeOut = !hasCreatedContainer && result.length > 0;
70
+ var shouldCreateEmptyTarget = isFromContainer && isTargetContainer && allContentBrokeOut;
71
+ if (shouldCreateEmptyTarget) {
72
+ var emptyParagraph = schema.nodes.paragraph.create();
73
+ var emptyContainer = targetNodeType.create({}, emptyParagraph);
74
+ return [emptyContainer].concat(_toConsumableArray(result));
75
+ }
76
+ return result;
77
+ };
78
+
46
79
  /**
47
80
  * A wrap step that handles mixed content according to the Compatibility Matrix:
48
81
  * - Wraps consecutive compatible nodes into the target container
@@ -60,21 +93,25 @@ var canWrapInTarget = function canWrapInTarget(node, targetNodeType, targetNodeT
60
93
  * Example: expand(p('a'), table(), p('b')) → panel: [panel(p('a')), table(), panel(p('b'))]
61
94
  * Example: expand(p('a'), panel(p('x')), p('b')) → panel: [panel(p('a')), panel(p('x')), panel(p('b'))]
62
95
  * Example: expand(p('a'), nestedExpand({title: 'inner'})(p('x')), p('b')) → panel: [panel(p('a')), expand({title: 'inner'})(p('x')), panel(p('b'))]
96
+ * Example: expand(nestedExpand()(p())) → panel: [panel(), expand()(p())] (empty panel when all content breaks out)
63
97
  */
64
98
  export var wrapMixedContentStep = function wrapMixedContentStep(nodes, context) {
65
99
  var schema = context.schema,
66
- targetNodeTypeName = context.targetNodeTypeName;
100
+ targetNodeTypeName = context.targetNodeTypeName,
101
+ fromNode = context.fromNode;
67
102
  var targetNodeType = schema.nodes[targetNodeTypeName];
68
103
  if (!targetNodeType) {
69
104
  return nodes;
70
105
  }
71
106
  var result = [];
72
107
  var currentContainerContent = [];
108
+ var hasCreatedContainer = false;
73
109
  var flushCurrentContainer = function flushCurrentContainer() {
74
110
  if (currentContainerContent.length > 0) {
75
111
  var containerNode = targetNodeType.createAndFill({}, Fragment.fromArray(currentContainerContent));
76
112
  if (containerNode) {
77
113
  result.push(containerNode);
114
+ hasCreatedContainer = true;
78
115
  }
79
116
  currentContainerContent = [];
80
117
  }
@@ -105,5 +142,8 @@ export var wrapMixedContentStep = function wrapMixedContentStep(nodes, context)
105
142
 
106
143
  // Flush any remaining content into a container
107
144
  flushCurrentContainer();
108
- return result.length > 0 ? result : nodes;
145
+
146
+ // Handle edge case: create empty container if all content broke out
147
+ var finalResult = handleEmptyContainerEdgeCase(result, hasCreatedContainer, fromNode, targetNodeType, targetNodeTypeName, schema);
148
+ return finalResult.length > 0 ? finalResult : nodes;
109
149
  };
@@ -128,7 +128,8 @@ var TRANSFORM_STEPS_OVERRIDE = {
128
128
  decisionList: {
129
129
  bulletList: [decisionListToListStep],
130
130
  orderedList: [decisionListToListStep],
131
- taskList: [decisionListToListStep]
131
+ taskList: [decisionListToListStep],
132
+ layoutSection: [wrapIntoLayoutStep]
132
133
  }
133
134
  };
134
135
  var getTransformStepsForNodeTypes = function getTransformStepsForNodeTypes(selectedNodeTypeName, targetNodeTypeName) {
@@ -1,8 +1,6 @@
1
- import { expandToBlockRange } from '@atlaskit/editor-common/selection';
2
1
  import { NodeSelection, TextSelection } from '@atlaskit/editor-prosemirror/state';
3
2
  import { findParentNodeOfType } from '@atlaskit/editor-prosemirror/utils';
4
3
  import { CellSelection } from '@atlaskit/editor-tables';
5
- import { findTable, isTableSelected } from '@atlaskit/editor-tables/utils';
6
4
  export var getSelectedNode = function getSelectedNode(selection) {
7
5
  if (selection instanceof NodeSelection) {
8
6
  return {
@@ -51,56 +49,6 @@ export var getTargetNodeTypeNameInContext = function getTargetNodeTypeNameInCont
51
49
  }
52
50
  return nodeTypeName;
53
51
  };
54
-
55
- /**
56
- * Use common expandToBlockRange function to get the correct range for the selection
57
- * For example, if selection starts in a listItem, go find the bullet list or ordered list, their $from
58
- * @param selection
59
- * @param schema
60
- * @returns
61
- */
62
- export var expandSelectionToBlockRange = function expandSelectionToBlockRange(selection, schema) {
63
- var nodes = schema.nodes;
64
- var nodesNeedToExpandRange = [nodes.bulletList, nodes.orderedList, nodes.taskList, nodes.listItem, nodes.taskItem];
65
-
66
- // when adding nodes.tableRow, tableHeader, tableCell in nodesNeedToExpandRang,
67
- // expandToBlockRange does not return expected table start position, sometimes even freeze editor
68
- // so handle table in the below logic
69
- if (isTableSelected(selection)) {
70
- var table = findTable(selection);
71
- if (table) {
72
- var $from = selection.$from.doc.resolve(table.pos);
73
- var $to = selection.$from.doc.resolve(table.pos + table.node.nodeSize - 1);
74
- return {
75
- $from: $from,
76
- $to: $to,
77
- range: $from.blockRange($to)
78
- };
79
- }
80
- }
81
-
82
- // when selecting a file, selection is on media
83
- // need to find media group and return its pos
84
- if (selection instanceof NodeSelection) {
85
- if (selection.node.type === nodes.media) {
86
- var mediaGroup = findParentNodeOfType(nodes.mediaGroup)(selection);
87
- if (mediaGroup) {
88
- var _$from = selection.$from.doc.resolve(mediaGroup.pos);
89
- var _$to = selection.$from.doc.resolve(mediaGroup.pos + mediaGroup.node.nodeSize);
90
- return {
91
- $from: _$from,
92
- $to: _$to
93
- };
94
- }
95
- }
96
- }
97
- return expandToBlockRange(selection.$from, selection.$to, function (node) {
98
- if (nodesNeedToExpandRange.includes(node.type)) {
99
- return false;
100
- }
101
- return true;
102
- });
103
- };
104
52
  export var isListType = function isListType(node, schema) {
105
53
  var lists = [schema.nodes.taskList, schema.nodes.bulletList, schema.nodes.orderedList];
106
54
  return lists.some(function (list) {
@@ -1,8 +1,8 @@
1
+ import { expandSelectionToBlockRange } from '@atlaskit/editor-common/selection';
1
2
  import { Fragment } from '@atlaskit/editor-prosemirror/model';
2
3
  import { NodeSelection } from '@atlaskit/editor-prosemirror/state';
3
4
  import { isNestedNode } from '../ui/utils/isNestedNode';
4
5
  import { getOutputNodes } from './transform-node-utils/transform';
5
- import { expandSelectionToBlockRange } from './transform-node-utils/utils';
6
6
  import { isListNode } from './transforms/utils';
7
7
  export var transformNode = function transformNode(api) {
8
8
  return (
@@ -17,7 +17,7 @@ export var transformNode = function transformNode(api) {
17
17
  }
18
18
  var schema = tr.doc.type.schema;
19
19
  var nodes = schema.nodes;
20
- var _expandSelectionToBlo = expandSelectionToBlockRange(preservedSelection, schema),
20
+ var _expandSelectionToBlo = expandSelectionToBlockRange(preservedSelection),
21
21
  $from = _expandSelectionToBlo.$from,
22
22
  $to = _expandSelectionToBlo.$to;
23
23
  var isNested = isNestedNode(preservedSelection, '');
@@ -22,24 +22,21 @@ var CopyLinkDropdownItemContent = function CopyLinkDropdownItemContent(_ref) {
22
22
  var _ref2 = config || {},
23
23
  getLinkPath = _ref2.getLinkPath,
24
24
  blockLinkHashPrefix = _ref2.blockLinkHashPrefix;
25
- var _useSharedPluginState = useSharedPluginStateWithSelector(api, ['blockControls', 'selection', 'core'], function (_ref3) {
25
+ var _useSharedPluginState = useSharedPluginStateWithSelector(api, ['blockControls', 'selection'], function (_ref3) {
26
26
  var blockControlsState = _ref3.blockControlsState,
27
- selectionState = _ref3.selectionState,
28
- coreState = _ref3.coreState;
27
+ selectionState = _ref3.selectionState;
29
28
  return {
30
29
  menuTriggerBy: blockControlsState === null || blockControlsState === void 0 ? void 0 : blockControlsState.menuTriggerBy,
31
30
  preservedSelection: blockControlsState === null || blockControlsState === void 0 ? void 0 : blockControlsState.preservedSelection,
32
- defaultSelection: selectionState === null || selectionState === void 0 ? void 0 : selectionState.selection,
33
- schema: coreState === null || coreState === void 0 ? void 0 : coreState.schema
31
+ defaultSelection: selectionState === null || selectionState === void 0 ? void 0 : selectionState.selection
34
32
  };
35
33
  }),
36
34
  preservedSelection = _useSharedPluginState.preservedSelection,
37
35
  defaultSelection = _useSharedPluginState.defaultSelection,
38
- menuTriggerBy = _useSharedPluginState.menuTriggerBy,
39
- schema = _useSharedPluginState.schema;
36
+ menuTriggerBy = _useSharedPluginState.menuTriggerBy;
40
37
  var selection = preservedSelection || defaultSelection;
41
38
  var handleClick = useCallback(function () {
42
- if (!selection || !schema) {
39
+ if (!selection) {
43
40
  return;
44
41
  }
45
42
  api === null || api === void 0 || api.core.actions.execute(function (_ref4) {
@@ -65,8 +62,7 @@ var CopyLinkDropdownItemContent = function CopyLinkDropdownItemContent(_ref) {
65
62
  copyLink({
66
63
  getLinkPath: getLinkPath,
67
64
  blockLinkHashPrefix: blockLinkHashPrefix,
68
- selection: selection,
69
- schema: schema
65
+ selection: selection
70
66
  }).then(function (success) {
71
67
  if (success) {
72
68
  api === null || api === void 0 || api.core.actions.execute(function (_ref5) {
@@ -78,7 +74,7 @@ var CopyLinkDropdownItemContent = function CopyLinkDropdownItemContent(_ref) {
78
74
  });
79
75
  }
80
76
  });
81
- }, [api, blockLinkHashPrefix, getLinkPath, onDropdownOpenChanged, schema, selection]);
77
+ }, [api, blockLinkHashPrefix, getLinkPath, onDropdownOpenChanged, selection]);
82
78
 
83
79
  // Hide copy link when `platform_editor_adf_with_localid` feature flag is off or when the node is nested or on empty line
84
80
  if (!fg('platform_editor_adf_with_localid') || !!menuTriggerBy && isNestedNode(selection, menuTriggerBy) || selection !== null && selection !== void 0 && selection.empty) {
@@ -1,6 +1,7 @@
1
1
  import { useMemo } from 'react';
2
2
  import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
3
- import { getBlockNodesInRange, expandSelectionToBlockRange } from '../../editor-commands/transform-node-utils/utils';
3
+ import { expandSelectionToBlockRange } from '@atlaskit/editor-common/selection';
4
+ import { getBlockNodesInRange } from '../../editor-commands/transform-node-utils/utils';
4
5
  import { getSortedSuggestedItems } from '../utils/suggested-items-rank';
5
6
  export var useSuggestedItems = function useSuggestedItems(api) {
6
7
  var _api$blockMenu;
@@ -29,17 +30,23 @@ export var useSuggestedItems = function useSuggestedItems(api) {
29
30
  if (menuItemsMap.size === 0 || !currentSelection) {
30
31
  return [];
31
32
  }
32
- var _expandSelectionToBlo = expandSelectionToBlockRange(currentSelection, currentSelection.$from.doc.type.schema),
33
+ var _expandSelectionToBlo = expandSelectionToBlockRange(currentSelection),
33
34
  range = _expandSelectionToBlo.range;
34
35
  if (!range) {
35
36
  return [];
36
37
  }
37
38
  var blockNodes = getBlockNodesInRange(range);
38
- var singleNode = blockNodes.length === 1 ? blockNodes[0] : undefined;
39
- if (!singleNode) {
39
+ if (blockNodes.length === 0) {
40
40
  return [];
41
41
  }
42
- var nodeTypeName = singleNode.type.name;
42
+ var firstNodeType = blockNodes[0].type.name;
43
+ var allSameType = blockNodes.every(function (node) {
44
+ return node.type.name === firstNodeType;
45
+ });
46
+ if (!allSameType) {
47
+ return [];
48
+ }
49
+ var nodeTypeName = firstNodeType;
43
50
  var sortedKeys = getSortedSuggestedItems(nodeTypeName);
44
51
  return sortedKeys.map(function (key) {
45
52
  return menuItemsMap.get(key);
@@ -3,15 +3,15 @@ import _regeneratorRuntime from "@babel/runtime/regenerator";
3
3
  import { createBlockLinkHashValue, DEFAULT_BLOCK_LINK_HASH_PREFIX } from '@atlaskit/editor-common/block-menu';
4
4
  import { copyToClipboard } from '@atlaskit/editor-common/clipboard';
5
5
  import { logException } from '@atlaskit/editor-common/monitoring';
6
- import { expandSelectionToBlockRange } from '../../editor-commands/transform-node-utils/utils';
6
+ import { expandSelectionToBlockRange } from '@atlaskit/editor-common/selection';
7
7
  export var copyLink = /*#__PURE__*/function () {
8
8
  var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(_ref) {
9
- var getLinkPath, _ref$blockLinkHashPre, blockLinkHashPrefix, selection, schema, blockRange, node, path, url, href;
9
+ var getLinkPath, _ref$blockLinkHashPre, blockLinkHashPrefix, selection, blockRange, node, path, url, href;
10
10
  return _regeneratorRuntime.wrap(function _callee$(_context) {
11
11
  while (1) switch (_context.prev = _context.next) {
12
12
  case 0:
13
- getLinkPath = _ref.getLinkPath, _ref$blockLinkHashPre = _ref.blockLinkHashPrefix, blockLinkHashPrefix = _ref$blockLinkHashPre === void 0 ? DEFAULT_BLOCK_LINK_HASH_PREFIX : _ref$blockLinkHashPre, selection = _ref.selection, schema = _ref.schema;
14
- blockRange = expandSelectionToBlockRange(selection, schema);
13
+ getLinkPath = _ref.getLinkPath, _ref$blockLinkHashPre = _ref.blockLinkHashPrefix, blockLinkHashPrefix = _ref$blockLinkHashPre === void 0 ? DEFAULT_BLOCK_LINK_HASH_PREFIX : _ref$blockLinkHashPre, selection = _ref.selection;
14
+ blockRange = expandSelectionToBlockRange(selection);
15
15
  if (blockRange) {
16
16
  _context.next = 4;
17
17
  break;
@@ -37,7 +37,7 @@ export var BLOCK_MENU_NODE_TYPES = {
37
37
  EMBED_CARD: 'embedCard',
38
38
  TABLE: 'table'
39
39
  };
40
- export var TRANSFORM_SUGGESTED_ITEMS_RANK = (_TRANSFORM_SUGGESTED_ = {}, _defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_TRANSFORM_SUGGESTED_, BLOCK_MENU_NODE_TYPES.PARAGRAPH, _defineProperty(_defineProperty(_defineProperty({}, TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key, 100), TRANSFORM_HEADINGS_H1_MENU_ITEM.key, 200), TRANSFORM_HEADINGS_H2_MENU_ITEM.key, 300)), BLOCK_MENU_NODE_TYPES.EXPAND, _defineProperty(_defineProperty(_defineProperty({}, TRANSFORM_STRUCTURE_LAYOUT_MENU_ITEM.key, 100), TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key, 200), TRANSFORM_STRUCTURE_PARAGRAPH_MENU_ITEM.key, 300)), BLOCK_MENU_NODE_TYPES.BLOCKQUOTE, _defineProperty(_defineProperty(_defineProperty({}, TRANSFORM_STRUCTURE_EXPAND_MENU_ITEM.key, 100), TRANSFORM_STRUCTURE_LAYOUT_MENU_ITEM.key, 200), TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key, 300)), BLOCK_MENU_NODE_TYPES.LAYOUT_SECTION, _defineProperty(_defineProperty(_defineProperty({}, TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key, 100), TRANSFORM_STRUCTURE_EXPAND_MENU_ITEM.key, 200), TRANSFORM_STRUCTURE_PARAGRAPH_MENU_ITEM.key, 300)), BLOCK_MENU_NODE_TYPES.PANEL, _defineProperty(_defineProperty(_defineProperty({}, TRANSFORM_STRUCTURE_QUOTE_MENU_ITEM.key, 100), TRANSFORM_STRUCTURE_CODE_BLOCK_MENU_ITEM.key, 200), TRANSFORM_STRUCTURE_EXPAND_MENU_ITEM.key, 300)), BLOCK_MENU_NODE_TYPES.CODE_BLOCK, _defineProperty(_defineProperty(_defineProperty({}, TRANSFORM_STRUCTURE_EXPAND_MENU_ITEM.key, 100), TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key, 200), TRANSFORM_STRUCTURE_PARAGRAPH_MENU_ITEM.key, 300)), BLOCK_MENU_NODE_TYPES.DECISION, _defineProperty(_defineProperty(_defineProperty({}, TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key, 100), TRANSFORM_STRUCTURE_QUOTE_MENU_ITEM.key, 200), TRANSFORM_STRUCTURE_LAYOUT_MENU_ITEM.key, 300)), BLOCK_MENU_NODE_TYPES.BULLET_LIST, _defineProperty(_defineProperty(_defineProperty({}, TRANSFORM_STRUCTURE_NUMBERED_LIST_MENU_ITEM.key, 100), TRANSFORM_STRUCTURE_QUOTE_MENU_ITEM.key, 200), TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key, 300)), BLOCK_MENU_NODE_TYPES.ORDERED_LIST, _defineProperty(_defineProperty(_defineProperty({}, TRANSFORM_STRUCTURE_TASK_LIST_MENU_ITEM.key, 100), TRANSFORM_STRUCTURE_BULLETED_LIST_MENU_ITEM.key, 200), TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key, 300)), BLOCK_MENU_NODE_TYPES.HEADING, _defineProperty(_defineProperty(_defineProperty({}, TRANSFORM_STRUCTURE_PARAGRAPH_MENU_ITEM.key, 100), TRANSFORM_STRUCTURE_BULLETED_LIST_MENU_ITEM.key, 200), TRANSFORM_STRUCTURE_QUOTE_MENU_ITEM.key, 300)), _defineProperty(_defineProperty(_defineProperty(_defineProperty(_TRANSFORM_SUGGESTED_, BLOCK_MENU_NODE_TYPES.TASK_LIST, _defineProperty(_defineProperty(_defineProperty({}, TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key, 100), TRANSFORM_STRUCTURE_NUMBERED_LIST_MENU_ITEM.key, 200), TRANSFORM_STRUCTURE_BULLETED_LIST_MENU_ITEM.key, 300)), BLOCK_MENU_NODE_TYPES.MEDIA_SINGLE, _defineProperty(_defineProperty(_defineProperty({}, TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key, 100), TRANSFORM_STRUCTURE_EXPAND_MENU_ITEM.key, 200), TRANSFORM_STRUCTURE_QUOTE_MENU_ITEM.key, 300)), BLOCK_MENU_NODE_TYPES.EXTENSION, _defineProperty(_defineProperty(_defineProperty({}, TRANSFORM_STRUCTURE_EXPAND_MENU_ITEM.key, 100), TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key, 200), TRANSFORM_STRUCTURE_LAYOUT_MENU_ITEM.key, 300)), BLOCK_MENU_NODE_TYPES.BODIED_EXTENSION, _defineProperty(_defineProperty(_defineProperty({}, TRANSFORM_STRUCTURE_EXPAND_MENU_ITEM.key, 100), TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key, 200), TRANSFORM_STRUCTURE_LAYOUT_MENU_ITEM.key, 300)));
40
+ export var TRANSFORM_SUGGESTED_ITEMS_RANK = (_TRANSFORM_SUGGESTED_ = {}, _defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_TRANSFORM_SUGGESTED_, BLOCK_MENU_NODE_TYPES.PARAGRAPH, _defineProperty(_defineProperty(_defineProperty({}, TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key, 100), TRANSFORM_HEADINGS_H1_MENU_ITEM.key, 200), TRANSFORM_HEADINGS_H2_MENU_ITEM.key, 300)), BLOCK_MENU_NODE_TYPES.EXPAND, _defineProperty(_defineProperty(_defineProperty({}, TRANSFORM_STRUCTURE_LAYOUT_MENU_ITEM.key, 100), TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key, 200), TRANSFORM_STRUCTURE_PARAGRAPH_MENU_ITEM.key, 300)), BLOCK_MENU_NODE_TYPES.BLOCKQUOTE, _defineProperty(_defineProperty(_defineProperty({}, TRANSFORM_STRUCTURE_EXPAND_MENU_ITEM.key, 100), TRANSFORM_STRUCTURE_LAYOUT_MENU_ITEM.key, 200), TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key, 300)), BLOCK_MENU_NODE_TYPES.LAYOUT_SECTION, _defineProperty(_defineProperty(_defineProperty({}, TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key, 100), TRANSFORM_STRUCTURE_EXPAND_MENU_ITEM.key, 200), TRANSFORM_STRUCTURE_PARAGRAPH_MENU_ITEM.key, 300)), BLOCK_MENU_NODE_TYPES.PANEL, _defineProperty(_defineProperty(_defineProperty({}, TRANSFORM_STRUCTURE_QUOTE_MENU_ITEM.key, 100), TRANSFORM_STRUCTURE_CODE_BLOCK_MENU_ITEM.key, 200), TRANSFORM_STRUCTURE_EXPAND_MENU_ITEM.key, 300)), BLOCK_MENU_NODE_TYPES.CODE_BLOCK, _defineProperty(_defineProperty(_defineProperty({}, TRANSFORM_STRUCTURE_EXPAND_MENU_ITEM.key, 100), TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key, 200), TRANSFORM_STRUCTURE_PARAGRAPH_MENU_ITEM.key, 300)), BLOCK_MENU_NODE_TYPES.DECISION, _defineProperty(_defineProperty(_defineProperty({}, TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key, 100), TRANSFORM_STRUCTURE_QUOTE_MENU_ITEM.key, 200), TRANSFORM_STRUCTURE_LAYOUT_MENU_ITEM.key, 300)), BLOCK_MENU_NODE_TYPES.BULLET_LIST, _defineProperty(_defineProperty(_defineProperty({}, TRANSFORM_STRUCTURE_NUMBERED_LIST_MENU_ITEM.key, 100), TRANSFORM_STRUCTURE_QUOTE_MENU_ITEM.key, 200), TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key, 300)), BLOCK_MENU_NODE_TYPES.ORDERED_LIST, _defineProperty(_defineProperty(_defineProperty({}, TRANSFORM_STRUCTURE_TASK_LIST_MENU_ITEM.key, 100), TRANSFORM_STRUCTURE_BULLETED_LIST_MENU_ITEM.key, 200), TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key, 300)), BLOCK_MENU_NODE_TYPES.HEADING, _defineProperty(_defineProperty(_defineProperty({}, TRANSFORM_STRUCTURE_PARAGRAPH_MENU_ITEM.key, 100), TRANSFORM_STRUCTURE_BULLETED_LIST_MENU_ITEM.key, 200), TRANSFORM_STRUCTURE_QUOTE_MENU_ITEM.key, 300)), _defineProperty(_defineProperty(_defineProperty(_TRANSFORM_SUGGESTED_, BLOCK_MENU_NODE_TYPES.TASK_LIST, _defineProperty(_defineProperty(_defineProperty({}, TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key, 100), TRANSFORM_STRUCTURE_NUMBERED_LIST_MENU_ITEM.key, 200), TRANSFORM_STRUCTURE_BULLETED_LIST_MENU_ITEM.key, 300)), BLOCK_MENU_NODE_TYPES.MEDIA_SINGLE, _defineProperty(_defineProperty(_defineProperty({}, TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key, 100), TRANSFORM_STRUCTURE_EXPAND_MENU_ITEM.key, 200), TRANSFORM_STRUCTURE_QUOTE_MENU_ITEM.key, 300)), BLOCK_MENU_NODE_TYPES.EXTENSION, _defineProperty(_defineProperty(_defineProperty({}, TRANSFORM_STRUCTURE_EXPAND_MENU_ITEM.key, 100), TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key, 200), TRANSFORM_STRUCTURE_LAYOUT_MENU_ITEM.key, 300)));
41
41
  export var getSuggestedItemsForNodeType = function getSuggestedItemsForNodeType(nodeType) {
42
42
  return TRANSFORM_SUGGESTED_ITEMS_RANK[nodeType];
43
43
  };
@@ -16,5 +16,6 @@ import type { TransformStep } from '../types';
16
16
  * Example: expand(p('a'), table(), p('b')) → panel: [panel(p('a')), table(), panel(p('b'))]
17
17
  * Example: expand(p('a'), panel(p('x')), p('b')) → panel: [panel(p('a')), panel(p('x')), panel(p('b'))]
18
18
  * Example: expand(p('a'), nestedExpand({title: 'inner'})(p('x')), p('b')) → panel: [panel(p('a')), expand({title: 'inner'})(p('x')), panel(p('b'))]
19
+ * Example: expand(nestedExpand()(p())) → panel: [panel(), expand()(p())] (empty panel when all content breaks out)
19
20
  */
20
21
  export declare const wrapMixedContentStep: TransformStep;
@@ -1,25 +1,9 @@
1
- import type { Schema, Node as PMNode, NodeRange } from '@atlaskit/editor-prosemirror/model';
1
+ import type { NodeRange, Node as PMNode, Schema } from '@atlaskit/editor-prosemirror/model';
2
2
  import type { Selection } from '@atlaskit/editor-prosemirror/state';
3
3
  import { type ContentNodeWithPos } from '@atlaskit/editor-prosemirror/utils';
4
4
  import type { NodeTypeName } from './types';
5
5
  export declare const getSelectedNode: (selection: Selection) => ContentNodeWithPos | undefined;
6
6
  export declare const getTargetNodeTypeNameInContext: (nodeTypeName: NodeTypeName | null, isNested?: boolean) => NodeTypeName | null;
7
- /**
8
- * Use common expandToBlockRange function to get the correct range for the selection
9
- * For example, if selection starts in a listItem, go find the bullet list or ordered list, their $from
10
- * @param selection
11
- * @param schema
12
- * @returns
13
- */
14
- export declare const expandSelectionToBlockRange: (selection: Selection, schema: Schema) => {
15
- $from: import("prosemirror-model").ResolvedPos;
16
- $to: import("prosemirror-model").ResolvedPos;
17
- range: NodeRange | null;
18
- } | {
19
- $from: import("prosemirror-model").ResolvedPos;
20
- $to: import("prosemirror-model").ResolvedPos;
21
- range?: undefined;
22
- };
23
7
  export declare const isListType: (node: PMNode, schema: Schema) => boolean;
24
8
  /**
25
9
  * Converts a nestedExpand to a regular expand node.
@@ -1,10 +1,8 @@
1
- import type { Schema } from '@atlaskit/editor-prosemirror/model';
2
1
  import type { Selection } from '@atlaskit/editor-prosemirror/state';
3
2
  type CopyLinkOptions = {
4
3
  blockLinkHashPrefix?: string;
5
4
  getLinkPath?: () => string | null;
6
- schema: Schema;
7
5
  selection: Selection;
8
6
  };
9
- export declare const copyLink: ({ getLinkPath, blockLinkHashPrefix, selection, schema, }: CopyLinkOptions) => Promise<boolean>;
7
+ export declare const copyLink: ({ getLinkPath, blockLinkHashPrefix, selection, }: CopyLinkOptions) => Promise<boolean>;
10
8
  export {};
@@ -16,5 +16,6 @@ import type { TransformStep } from '../types';
16
16
  * Example: expand(p('a'), table(), p('b')) → panel: [panel(p('a')), table(), panel(p('b'))]
17
17
  * Example: expand(p('a'), panel(p('x')), p('b')) → panel: [panel(p('a')), panel(p('x')), panel(p('b'))]
18
18
  * Example: expand(p('a'), nestedExpand({title: 'inner'})(p('x')), p('b')) → panel: [panel(p('a')), expand({title: 'inner'})(p('x')), panel(p('b'))]
19
+ * Example: expand(nestedExpand()(p())) → panel: [panel(), expand()(p())] (empty panel when all content breaks out)
19
20
  */
20
21
  export declare const wrapMixedContentStep: TransformStep;
@@ -1,25 +1,9 @@
1
- import type { Schema, Node as PMNode, NodeRange } from '@atlaskit/editor-prosemirror/model';
1
+ import type { NodeRange, Node as PMNode, Schema } from '@atlaskit/editor-prosemirror/model';
2
2
  import type { Selection } from '@atlaskit/editor-prosemirror/state';
3
3
  import { type ContentNodeWithPos } from '@atlaskit/editor-prosemirror/utils';
4
4
  import type { NodeTypeName } from './types';
5
5
  export declare const getSelectedNode: (selection: Selection) => ContentNodeWithPos | undefined;
6
6
  export declare const getTargetNodeTypeNameInContext: (nodeTypeName: NodeTypeName | null, isNested?: boolean) => NodeTypeName | null;
7
- /**
8
- * Use common expandToBlockRange function to get the correct range for the selection
9
- * For example, if selection starts in a listItem, go find the bullet list or ordered list, their $from
10
- * @param selection
11
- * @param schema
12
- * @returns
13
- */
14
- export declare const expandSelectionToBlockRange: (selection: Selection, schema: Schema) => {
15
- $from: import("prosemirror-model").ResolvedPos;
16
- $to: import("prosemirror-model").ResolvedPos;
17
- range: NodeRange | null;
18
- } | {
19
- $from: import("prosemirror-model").ResolvedPos;
20
- $to: import("prosemirror-model").ResolvedPos;
21
- range?: undefined;
22
- };
23
7
  export declare const isListType: (node: PMNode, schema: Schema) => boolean;
24
8
  /**
25
9
  * Converts a nestedExpand to a regular expand node.
@@ -1,10 +1,8 @@
1
- import type { Schema } from '@atlaskit/editor-prosemirror/model';
2
1
  import type { Selection } from '@atlaskit/editor-prosemirror/state';
3
2
  type CopyLinkOptions = {
4
3
  blockLinkHashPrefix?: string;
5
4
  getLinkPath?: () => string | null;
6
- schema: Schema;
7
5
  selection: Selection;
8
6
  };
9
- export declare const copyLink: ({ getLinkPath, blockLinkHashPrefix, selection, schema, }: CopyLinkOptions) => Promise<boolean>;
7
+ export declare const copyLink: ({ getLinkPath, blockLinkHashPrefix, selection, }: CopyLinkOptions) => Promise<boolean>;
10
8
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-block-menu",
3
- "version": "5.2.12",
3
+ "version": "5.2.14",
4
4
  "description": "BlockMenu plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -44,7 +44,7 @@
44
44
  "@atlaskit/platform-feature-flags": "^1.1.0",
45
45
  "@atlaskit/platform-feature-flags-react": "^0.4.0",
46
46
  "@atlaskit/primitives": "^16.4.0",
47
- "@atlaskit/tmp-editor-statsig": "^15.11.0",
47
+ "@atlaskit/tmp-editor-statsig": "^15.12.0",
48
48
  "@atlaskit/tokens": "^8.5.0",
49
49
  "@babel/runtime": "^7.0.0"
50
50
  },