@atlaskit/editor-plugin-block-menu 6.0.9 → 6.0.12

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 (39) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/dist/cjs/editor-commands/transform-node-utils/TRANSFORMATION_MATRIX.js +224 -0
  3. package/dist/cjs/editor-commands/transform-node-utils/steps/convertEachNodeStep.js +58 -1
  4. package/dist/cjs/editor-commands/transform-node-utils/transform.js +4 -238
  5. package/dist/cjs/ui/block-menu-components.js +12 -0
  6. package/dist/cjs/ui/block-menu-renderer/BlockMenuComponent.js +3 -3
  7. package/dist/cjs/ui/block-menu-renderer/utils.js +4 -7
  8. package/dist/cjs/ui/hooks/useSuggestedItems.js +4 -37
  9. package/dist/cjs/ui/utils/createMenuItemsMap.js +19 -0
  10. package/dist/cjs/ui/utils/getSuggestedItemsFromSelection.js +40 -0
  11. package/dist/es2019/editor-commands/transform-node-utils/TRANSFORMATION_MATRIX.js +219 -0
  12. package/dist/es2019/editor-commands/transform-node-utils/steps/convertEachNodeStep.js +56 -1
  13. package/dist/es2019/editor-commands/transform-node-utils/transform.js +5 -240
  14. package/dist/es2019/ui/block-menu-components.js +13 -1
  15. package/dist/es2019/ui/block-menu-renderer/BlockMenuComponent.js +3 -3
  16. package/dist/es2019/ui/block-menu-renderer/utils.js +4 -7
  17. package/dist/es2019/ui/hooks/useSuggestedItems.js +4 -28
  18. package/dist/es2019/ui/utils/createMenuItemsMap.js +9 -0
  19. package/dist/es2019/ui/utils/getSuggestedItemsFromSelection.js +30 -0
  20. package/dist/esm/editor-commands/transform-node-utils/TRANSFORMATION_MATRIX.js +219 -0
  21. package/dist/esm/editor-commands/transform-node-utils/steps/convertEachNodeStep.js +58 -1
  22. package/dist/esm/editor-commands/transform-node-utils/transform.js +5 -240
  23. package/dist/esm/ui/block-menu-components.js +12 -0
  24. package/dist/esm/ui/block-menu-renderer/BlockMenuComponent.js +3 -3
  25. package/dist/esm/ui/block-menu-renderer/utils.js +4 -7
  26. package/dist/esm/ui/hooks/useSuggestedItems.js +4 -37
  27. package/dist/esm/ui/utils/createMenuItemsMap.js +13 -0
  28. package/dist/esm/ui/utils/getSuggestedItemsFromSelection.js +35 -0
  29. package/dist/types/blockMenuPluginType.d.ts +1 -0
  30. package/dist/types/editor-commands/transform-node-utils/TRANSFORMATION_MATRIX.d.ts +2 -0
  31. package/dist/types/ui/block-menu-renderer/utils.d.ts +2 -3
  32. package/dist/types/ui/utils/createMenuItemsMap.d.ts +6 -0
  33. package/dist/types/ui/utils/getSuggestedItemsFromSelection.d.ts +6 -0
  34. package/dist/types-ts4.5/blockMenuPluginType.d.ts +1 -0
  35. package/dist/types-ts4.5/editor-commands/transform-node-utils/TRANSFORMATION_MATRIX.d.ts +2 -0
  36. package/dist/types-ts4.5/ui/block-menu-renderer/utils.d.ts +2 -3
  37. package/dist/types-ts4.5/ui/utils/createMenuItemsMap.d.ts +6 -0
  38. package/dist/types-ts4.5/ui/utils/getSuggestedItemsFromSelection.d.ts +6 -0
  39. package/package.json +6 -6
@@ -11,6 +11,8 @@ import { MoveDownDropdownItem } from './move-down';
11
11
  import { MoveUpDropdownItem } from './move-up';
12
12
  import { SuggestedItemsMenuSection } from './suggested-items-menu-section';
13
13
  import { SuggestedMenuItems } from './suggested-menu-items';
14
+ import { createMenuItemsMap } from './utils/createMenuItemsMap';
15
+ import { getSuggestedItemsFromSelection } from './utils/getSuggestedItemsFromSelection';
14
16
  const getMoveUpMoveDownMenuComponents = api => {
15
17
  return [{
16
18
  type: 'block-menu-item',
@@ -79,7 +81,17 @@ const getTurnIntoMenuComponents = api => {
79
81
  },
80
82
  component: () => /*#__PURE__*/React.createElement(SuggestedMenuItems, {
81
83
  api: api
82
- })
84
+ }),
85
+ isHidden: () => {
86
+ var _api$blockMenu, _api$selection, _api$selection$shared, _api$blockControls, _api$blockControls$sh;
87
+ const blockMenuComponents = api === null || api === void 0 ? void 0 : (_api$blockMenu = api.blockMenu) === null || _api$blockMenu === void 0 ? void 0 : _api$blockMenu.actions.getBlockMenuComponents();
88
+ const menuItemsMap = createMenuItemsMap(blockMenuComponents);
89
+ const selection = api === null || api === void 0 ? void 0 : (_api$selection = api.selection) === null || _api$selection === void 0 ? void 0 : (_api$selection$shared = _api$selection.sharedState.currentState()) === null || _api$selection$shared === void 0 ? void 0 : _api$selection$shared.selection;
90
+ const preservedSelection = api === null || api === void 0 ? void 0 : (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 ? void 0 : (_api$blockControls$sh = _api$blockControls.sharedState.currentState()) === null || _api$blockControls$sh === void 0 ? void 0 : _api$blockControls$sh.preservedSelection;
91
+ const currentSelection = preservedSelection || selection;
92
+ const suggestedItems = getSuggestedItemsFromSelection(menuItemsMap, currentSelection);
93
+ return suggestedItems.length === 0;
94
+ }
83
95
  }, {
84
96
  type: 'block-menu-section',
85
97
  key: TRANSFORM_CREATE_MENU_SECTION.key,
@@ -9,15 +9,15 @@ export const BlockMenuComponent = ({
9
9
  childrenMap,
10
10
  fallbacks
11
11
  }) => {
12
+ if (!willComponentRender(registeredComponent, childrenMap)) {
13
+ return null;
14
+ }
12
15
  if (registeredComponent.type === 'block-menu-item') {
13
16
  const ItemComponent = registeredComponent.component || fallbacks['block-menu-item'];
14
17
  return /*#__PURE__*/React.createElement(ItemComponent, {
15
18
  key: registeredComponent.key
16
19
  });
17
20
  }
18
- if (!willComponentRender(registeredComponent, childrenMap)) {
19
- return null;
20
- }
21
21
  const ParentComponent = registeredComponent.component || fallbacks[registeredComponent.type];
22
22
  const childrenMapKey = getChildrenMapKey(registeredComponent.key, registeredComponent.type);
23
23
  const registeredComponents = childrenMap.get(childrenMapKey);
@@ -74,20 +74,17 @@ export const buildChildrenMap = components => {
74
74
  * Determines whether a component will render based on its type and children
75
75
  *
76
76
  * Rules:
77
- * - An item will not render if has a component that returns null
78
- * - A nested menu will render if it has at least one registered child component
77
+ * - An item will not render if it has isHidden that returns true OR if its component returns null (fallback)
78
+ * - A nested menu will render if at least one section, that has at least one registered child
79
79
  * - A section will render if it has at least one registered child component that will render
80
80
  *
81
- * NOTE: This requires invoking each item's component function to check for null return
82
81
  */
83
82
  export const willComponentRender = (registeredComponent, childrenMap) => {
84
83
  if (registeredComponent.type === 'block-menu-item') {
85
- return registeredComponent.component ? registeredComponent.component() !== null : true;
84
+ var _registeredComponent$;
85
+ return !(registeredComponent !== null && registeredComponent !== void 0 && (_registeredComponent$ = registeredComponent.isHidden) !== null && _registeredComponent$ !== void 0 && _registeredComponent$.call(registeredComponent));
86
86
  }
87
87
  const childrenMapKey = getChildrenMapKey(registeredComponent.key, registeredComponent.type);
88
88
  const registeredComponents = childrenMap.get(childrenMapKey) || [];
89
- if (registeredComponent.type === 'block-menu-nested') {
90
- return registeredComponents.length > 0;
91
- }
92
89
  return registeredComponents.some(childComponent => willComponentRender(childComponent, childrenMap));
93
90
  };
@@ -1,8 +1,7 @@
1
1
  import { useMemo } from 'react';
2
2
  import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
3
- import { expandSelectionToBlockRange } from '@atlaskit/editor-common/selection';
4
- import { getBlockNodesInRange } from '../../editor-commands/transform-node-utils/utils';
5
- import { getSortedSuggestedItems } from '../utils/suggested-items-rank';
3
+ import { createMenuItemsMap } from '../utils/createMenuItemsMap';
4
+ import { getSuggestedItemsFromSelection } from '../utils/getSuggestedItemsFromSelection';
6
5
  export const useSuggestedItems = api => {
7
6
  var _api$blockMenu;
8
7
  const {
@@ -17,34 +16,11 @@ export const useSuggestedItems = api => {
17
16
  });
18
17
  const blockMenuComponents = api === null || api === void 0 ? void 0 : (_api$blockMenu = api.blockMenu) === null || _api$blockMenu === void 0 ? void 0 : _api$blockMenu.actions.getBlockMenuComponents();
19
18
  const menuItemsMap = useMemo(() => {
20
- if (!blockMenuComponents) {
21
- return new Map();
22
- }
23
- return new Map(blockMenuComponents.filter(c => c.type === 'block-menu-item').map(item => [item.key, item]));
19
+ return createMenuItemsMap(blockMenuComponents);
24
20
  }, [blockMenuComponents]);
25
21
  const suggestedItems = useMemo(() => {
26
22
  const currentSelection = preservedSelection || selection;
27
- if (menuItemsMap.size === 0 || !currentSelection) {
28
- return [];
29
- }
30
- const {
31
- range
32
- } = expandSelectionToBlockRange(currentSelection);
33
- if (!range) {
34
- return [];
35
- }
36
- const blockNodes = getBlockNodesInRange(range);
37
- if (blockNodes.length === 0) {
38
- return [];
39
- }
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;
46
- const sortedKeys = getSortedSuggestedItems(nodeTypeName);
47
- return sortedKeys.map(key => menuItemsMap.get(key)).filter(item => item !== undefined);
23
+ return getSuggestedItemsFromSelection(menuItemsMap, currentSelection);
48
24
  }, [menuItemsMap, preservedSelection, selection]);
49
25
  return suggestedItems;
50
26
  };
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Helper function to create menu items map from block menu components.
3
+ */
4
+ export const createMenuItemsMap = blockMenuComponents => {
5
+ if (!blockMenuComponents) {
6
+ return new Map();
7
+ }
8
+ return new Map(blockMenuComponents.filter(c => c.type === 'block-menu-item').map(item => [item.key, item]));
9
+ };
@@ -0,0 +1,30 @@
1
+ import { expandSelectionToBlockRange } from '@atlaskit/editor-common/selection';
2
+ import { getBlockNodesInRange } from '../../editor-commands/transform-node-utils/utils';
3
+ import { getSortedSuggestedItems } from '../utils/suggested-items-rank';
4
+
5
+ /**
6
+ * Pure function to calculate suggested items based on selection and menu components.
7
+ */
8
+ export const getSuggestedItemsFromSelection = (menuItemsMap, currentSelection) => {
9
+ if (menuItemsMap.size === 0 || !currentSelection) {
10
+ return [];
11
+ }
12
+ const {
13
+ range
14
+ } = expandSelectionToBlockRange(currentSelection);
15
+ if (!range) {
16
+ return [];
17
+ }
18
+ const blockNodes = getBlockNodesInRange(range);
19
+ if (blockNodes.length === 0) {
20
+ return [];
21
+ }
22
+ const firstNodeType = blockNodes[0].type.name;
23
+ const allSameType = blockNodes.every(node => node.type.name === firstNodeType);
24
+ if (!allSameType) {
25
+ return [];
26
+ }
27
+ const nodeTypeName = firstNodeType;
28
+ const sortedKeys = getSortedSuggestedItems(nodeTypeName);
29
+ return sortedKeys.map(key => menuItemsMap.get(key)).filter(item => item !== undefined);
30
+ };
@@ -0,0 +1,219 @@
1
+ import { flattenStep } from './flattenStep';
2
+ import { applyTargetTextTypeStep } from './steps/applyTargetTextTypeStep';
3
+ import { convertEachNodeStep } from './steps/convertEachNodeStep';
4
+ import { decisionListToListStep } from './steps/decisionListToListStep';
5
+ import { flattenListStep } from './steps/flattenListStep';
6
+ import { listToDecisionListStep } from './steps/listToDecisionListStep';
7
+ import { listToListStep } from './steps/listToListStep';
8
+ import { mergeNeighbourListsStep } from './steps/mergeNeighbourListsStep';
9
+ import { unwrapLayoutStep } from './steps/unwrapLayoutStep';
10
+ import { unwrapListStep } from './steps/unwrapListStep';
11
+ import { wrapBlockquoteToDecisionListStep } from './steps/wrapBlockquoteToDecisionListStep';
12
+ import { wrapMixedContentStep } from './steps/wrapMixedContentStep';
13
+ import { unwrapExpandStep } from './unwrapExpandStep';
14
+ import { unwrapStep } from './unwrapStep';
15
+ import { wrapIntoListStep } from './wrapIntoListStep';
16
+ import { wrapStep } from './wrapStep';
17
+
18
+ // Transform steps for all node type pairs.
19
+ // If a transformation is not defined (undefined), it is not available.
20
+ export var TRANSFORMATION_MATRIX = {
21
+ paragraph: {
22
+ heading: [flattenStep, applyTargetTextTypeStep],
23
+ blockquote: [wrapMixedContentStep],
24
+ codeBlock: [wrapMixedContentStep],
25
+ expand: [wrapMixedContentStep],
26
+ nestedExpand: [wrapMixedContentStep],
27
+ layoutSection: [wrapMixedContentStep],
28
+ panel: [wrapMixedContentStep],
29
+ bulletList: [wrapIntoListStep],
30
+ orderedList: [wrapIntoListStep],
31
+ taskList: [wrapIntoListStep],
32
+ decisionList: [wrapIntoListStep]
33
+ },
34
+ heading: {
35
+ heading: [flattenStep, applyTargetTextTypeStep],
36
+ paragraph: [flattenStep, applyTargetTextTypeStep],
37
+ blockquote: [wrapMixedContentStep],
38
+ codeBlock: [wrapMixedContentStep],
39
+ expand: [wrapMixedContentStep],
40
+ nestedExpand: [wrapMixedContentStep],
41
+ layoutSection: [wrapMixedContentStep],
42
+ panel: [wrapMixedContentStep],
43
+ bulletList: [wrapIntoListStep],
44
+ orderedList: [wrapIntoListStep],
45
+ taskList: [wrapIntoListStep],
46
+ decisionList: [wrapIntoListStep]
47
+ },
48
+ panel: {
49
+ blockquote: [unwrapStep, wrapMixedContentStep],
50
+ codeBlock: [unwrapStep, wrapMixedContentStep],
51
+ expand: [unwrapStep, wrapStep],
52
+ nestedExpand: [unwrapStep, wrapStep],
53
+ layoutSection: [unwrapStep, wrapMixedContentStep],
54
+ paragraph: [unwrapStep]
55
+ },
56
+ expand: {
57
+ panel: [unwrapExpandStep, wrapMixedContentStep],
58
+ blockquote: [unwrapExpandStep, wrapMixedContentStep],
59
+ layoutSection: [unwrapExpandStep, wrapMixedContentStep],
60
+ nestedExpand: [unwrapExpandStep, wrapStep],
61
+ paragraph: [unwrapExpandStep]
62
+ },
63
+ nestedExpand: {
64
+ panel: [unwrapExpandStep, wrapMixedContentStep],
65
+ blockquote: [unwrapExpandStep, wrapMixedContentStep],
66
+ layoutSection: [unwrapExpandStep, wrapMixedContentStep],
67
+ paragraph: [unwrapExpandStep]
68
+ },
69
+ blockquote: {
70
+ expand: [wrapStep],
71
+ nestedExpand: [wrapStep],
72
+ layoutSection: [wrapMixedContentStep],
73
+ panel: [unwrapStep, wrapStep],
74
+ paragraph: [unwrapStep],
75
+ heading: [unwrapStep, applyTargetTextTypeStep],
76
+ decisionList: [unwrapStep, wrapBlockquoteToDecisionListStep]
77
+ },
78
+ layoutSection: {
79
+ blockquote: [unwrapLayoutStep, wrapMixedContentStep],
80
+ expand: [unwrapLayoutStep, wrapStep],
81
+ nestedExpand: [unwrapLayoutStep, wrapStep],
82
+ panel: [unwrapLayoutStep, wrapMixedContentStep],
83
+ paragraph: [unwrapLayoutStep]
84
+ },
85
+ codeBlock: {
86
+ blockquote: [wrapStep],
87
+ expand: [wrapStep],
88
+ nestedExpand: [wrapStep],
89
+ layoutSection: [wrapMixedContentStep],
90
+ panel: [wrapStep],
91
+ paragraph: [applyTargetTextTypeStep]
92
+ },
93
+ bulletList: {
94
+ orderedList: [listToListStep],
95
+ taskList: [listToListStep],
96
+ decisionList: [flattenListStep, listToDecisionListStep],
97
+ blockquote: [wrapStep],
98
+ expand: [wrapStep],
99
+ nestedExpand: [wrapStep],
100
+ layoutSection: [wrapMixedContentStep],
101
+ panel: [wrapStep],
102
+ paragraph: [flattenListStep, unwrapListStep, applyTargetTextTypeStep]
103
+ },
104
+ orderedList: {
105
+ bulletList: [listToListStep],
106
+ taskList: [listToListStep],
107
+ decisionList: [flattenListStep, listToDecisionListStep],
108
+ blockquote: [wrapStep],
109
+ expand: [wrapStep],
110
+ nestedExpand: [wrapStep],
111
+ layoutSection: [wrapMixedContentStep],
112
+ panel: [wrapStep],
113
+ paragraph: [flattenListStep, unwrapListStep, applyTargetTextTypeStep]
114
+ },
115
+ taskList: {
116
+ bulletList: [listToListStep],
117
+ orderedList: [listToListStep],
118
+ decisionList: [flattenListStep, listToDecisionListStep],
119
+ expand: [wrapStep],
120
+ nestedExpand: [wrapStep],
121
+ layoutSection: [wrapMixedContentStep],
122
+ panel: [wrapStep],
123
+ paragraph: [flattenListStep, unwrapListStep, applyTargetTextTypeStep]
124
+ },
125
+ table: {
126
+ expand: [wrapStep],
127
+ nestedExpand: [wrapStep],
128
+ layoutSection: [wrapMixedContentStep]
129
+ },
130
+ mediaSingle: {
131
+ blockquote: [wrapStep],
132
+ expand: [wrapStep],
133
+ nestedExpand: [wrapStep],
134
+ layoutSection: [wrapMixedContentStep],
135
+ panel: [wrapStep],
136
+ bulletList: [wrapIntoListStep],
137
+ orderedList: [wrapIntoListStep]
138
+ },
139
+ mediaGroup: {
140
+ blockquote: [wrapStep],
141
+ expand: [wrapStep],
142
+ nestedExpand: [wrapStep],
143
+ layoutSection: [wrapMixedContentStep],
144
+ panel: [wrapStep]
145
+ },
146
+ media: {
147
+ blockquote: [wrapStep],
148
+ codeBlock: [wrapStep],
149
+ expand: [wrapStep],
150
+ nestedExpand: [wrapStep],
151
+ layoutSection: [wrapStep],
152
+ panel: [wrapStep],
153
+ bulletList: [wrapIntoListStep],
154
+ orderedList: [wrapIntoListStep],
155
+ taskList: [wrapIntoListStep],
156
+ decisionList: [wrapIntoListStep]
157
+ },
158
+ decisionList: {
159
+ bulletList: [decisionListToListStep],
160
+ orderedList: [decisionListToListStep],
161
+ taskList: [decisionListToListStep],
162
+ blockquote: [unwrapListStep, wrapStep],
163
+ codeBlock: [unwrapListStep, wrapMixedContentStep],
164
+ expand: [wrapStep],
165
+ nestedExpand: [wrapStep],
166
+ layoutSection: [wrapMixedContentStep],
167
+ panel: [wrapStep],
168
+ paragraph: [flattenListStep, unwrapListStep, applyTargetTextTypeStep],
169
+ heading: [flattenListStep, unwrapListStep, applyTargetTextTypeStep]
170
+ },
171
+ blockCard: {
172
+ expand: [wrapStep],
173
+ nestedExpand: [wrapStep],
174
+ layoutSection: [wrapMixedContentStep],
175
+ panel: [wrapStep]
176
+ },
177
+ embedCard: {
178
+ expand: [wrapStep],
179
+ nestedExpand: [wrapStep],
180
+ layoutSection: [wrapMixedContentStep]
181
+ },
182
+ extension: {
183
+ blockquote: [wrapStep],
184
+ expand: [wrapStep],
185
+ nestedExpand: [wrapStep],
186
+ layoutSection: [wrapMixedContentStep],
187
+ panel: [wrapStep]
188
+ },
189
+ bodiedExtension: {
190
+ nestedExpand: [wrapStep],
191
+ layoutSection: [wrapMixedContentStep]
192
+ },
193
+ multiBodiedExtension: {
194
+ blockquote: [wrapStep],
195
+ codeBlock: [wrapStep],
196
+ expand: [wrapStep],
197
+ nestedExpand: [wrapStep],
198
+ layoutSection: [wrapStep],
199
+ panel: [wrapStep],
200
+ bulletList: [wrapIntoListStep],
201
+ orderedList: [wrapIntoListStep],
202
+ taskList: [wrapIntoListStep],
203
+ decisionList: [wrapIntoListStep]
204
+ },
205
+ multi: {
206
+ blockquote: [wrapMixedContentStep],
207
+ codeBlock: [wrapMixedContentStep],
208
+ expand: [wrapMixedContentStep],
209
+ nestedExpand: [wrapMixedContentStep],
210
+ layoutSection: [wrapMixedContentStep],
211
+ panel: [wrapMixedContentStep],
212
+ bulletList: [convertEachNodeStep, mergeNeighbourListsStep],
213
+ orderedList: [convertEachNodeStep, mergeNeighbourListsStep],
214
+ taskList: [convertEachNodeStep, mergeNeighbourListsStep],
215
+ decisionList: [convertEachNodeStep, mergeNeighbourListsStep],
216
+ paragraph: [convertEachNodeStep],
217
+ heading: [applyTargetTextTypeStep]
218
+ }
219
+ };
@@ -3,6 +3,46 @@ function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol
3
3
  function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
4
4
  function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
5
5
  import { convertNodesToTargetType } from '../transform';
6
+ /**
7
+ * Handles the edge case where transforming multi-selection to decisionList results in
8
+ * all content breaking out (no valid children for the target). In this case, creates an empty
9
+ * decisionList to ensure the target type exists.
10
+ *
11
+ * Similar to handleEmptyContainerEdgeCase in wrapMixedContentStep, but specifically for
12
+ * multi-to-decisionList transformations where blockquotes break out.
13
+ *
14
+ * @param result - The current result nodes after processing
15
+ * @param hasCreatedDecisionList - Whether a decisionList was already created during processing
16
+ * @param targetNodeTypeName - The target node type name
17
+ * @param schema - The schema
18
+ * @returns The result nodes with an empty decisionList prepended if needed, or the original result
19
+ */
20
+ var handleEmptyDecisionListEdgeCase = function handleEmptyDecisionListEdgeCase(result, hasCreatedDecisionList, targetNodeTypeName, schema) {
21
+ // Only apply this edge case for decisionList target
22
+ if (targetNodeTypeName !== 'decisionList') {
23
+ return result;
24
+ }
25
+
26
+ // If no decisionList was created but we have nodes in result, all content broke out
27
+ var allContentBrokeOut = !hasCreatedDecisionList && result.length > 0;
28
+ if (!allContentBrokeOut) {
29
+ return result;
30
+ }
31
+
32
+ // Create an empty decisionList
33
+ var decisionListType = schema.nodes.decisionList;
34
+ var decisionItemType = schema.nodes.decisionItem;
35
+ if (decisionListType && decisionItemType) {
36
+ var emptyDecisionItem = decisionItemType.createAndFill();
37
+ if (emptyDecisionItem) {
38
+ var emptyDecisionList = decisionListType.createAndFill({}, [emptyDecisionItem]);
39
+ if (emptyDecisionList) {
40
+ return [emptyDecisionList].concat(_toConsumableArray(result));
41
+ }
42
+ }
43
+ }
44
+ return result;
45
+ };
6
46
  export var convertEachNodeStep = function convertEachNodeStep(nodes, context) {
7
47
  var schema = context.schema,
8
48
  targetNodeTypeName = context.targetNodeTypeName,
@@ -11,12 +51,19 @@ export var convertEachNodeStep = function convertEachNodeStep(nodes, context) {
11
51
  if (!targetNodeType) {
12
52
  return nodes;
13
53
  }
54
+ var blockquoteType = schema.nodes.blockquote;
14
55
  var resultNodes = [];
56
+ var hasCreatedDecisionList = false;
15
57
  var _iterator = _createForOfIteratorHelper(nodes),
16
58
  _step;
17
59
  try {
18
60
  for (_iterator.s(); !(_step = _iterator.n()).done;) {
19
61
  var node = _step.value;
62
+ // Edge case: blockquotes should break out when transforming to decisionList
63
+ if (targetNodeTypeName === 'decisionList' && blockquoteType && node.type === blockquoteType) {
64
+ resultNodes.push(node);
65
+ continue;
66
+ }
20
67
  var transformedNodes = convertNodesToTargetType({
21
68
  sourceNodes: [node],
22
69
  targetNodeType: targetNodeType,
@@ -26,14 +73,24 @@ export var convertEachNodeStep = function convertEachNodeStep(nodes, context) {
26
73
  });
27
74
  if (transformedNodes.length > 0) {
28
75
  resultNodes.push.apply(resultNodes, _toConsumableArray(transformedNodes));
76
+ // Track if we created a decisionList
77
+
78
+ if (targetNodeTypeName === 'decisionList' && transformedNodes.some(function (n) {
79
+ return n.type === targetNodeType;
80
+ })) {
81
+ hasCreatedDecisionList = true;
82
+ }
29
83
  } else {
30
84
  resultNodes.push(node);
31
85
  }
32
86
  }
87
+
88
+ // Handle edge case: if no decisionList was created, create an empty one
33
89
  } catch (err) {
34
90
  _iterator.e(err);
35
91
  } finally {
36
92
  _iterator.f();
37
93
  }
38
- return resultNodes;
94
+ var finalResult = handleEmptyDecisionListEdgeCase(resultNodes, hasCreatedDecisionList, targetNodeTypeName, schema);
95
+ return finalResult;
39
96
  };