@atlaskit/editor-plugin-block-menu 4.0.2 → 4.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # @atlaskit/editor-plugin-block-menu
2
2
 
3
+ ## 4.0.3
4
+
5
+ ### Patch Changes
6
+
7
+ - [`c158b1ba4f0fd`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/c158b1ba4f0fd) -
8
+ ED-29388: fix converting empty list
9
+ - Updated dependencies
10
+
3
11
  ## 4.0.2
4
12
 
5
13
  ### Patch Changes
@@ -23,6 +23,9 @@
23
23
  {
24
24
  "path": "../../../design-system/dropdown-menu/afm-dev-agents/tsconfig.json"
25
25
  },
26
+ {
27
+ "path": "../../editor-plugin-analytics/afm-dev-agents/tsconfig.json"
28
+ },
26
29
  {
27
30
  "path": "../../editor-plugin-block-controls/afm-dev-agents/tsconfig.json"
28
31
  },
@@ -23,6 +23,9 @@
23
23
  {
24
24
  "path": "../../../design-system/dropdown-menu/afm-jira/tsconfig.json"
25
25
  },
26
+ {
27
+ "path": "../../editor-plugin-analytics/afm-jira/tsconfig.json"
28
+ },
26
29
  {
27
30
  "path": "../../editor-plugin-block-controls/afm-jira/tsconfig.json"
28
31
  },
@@ -23,6 +23,9 @@
23
23
  {
24
24
  "path": "../../../design-system/dropdown-menu/afm-passionfruit/tsconfig.json"
25
25
  },
26
+ {
27
+ "path": "../../editor-plugin-analytics/afm-passionfruit/tsconfig.json"
28
+ },
26
29
  {
27
30
  "path": "../../editor-plugin-block-controls/afm-passionfruit/tsconfig.json"
28
31
  },
@@ -23,6 +23,9 @@
23
23
  {
24
24
  "path": "../../../design-system/dropdown-menu/afm-post-office/tsconfig.json"
25
25
  },
26
+ {
27
+ "path": "../../editor-plugin-analytics/afm-post-office/tsconfig.json"
28
+ },
26
29
  {
27
30
  "path": "../../editor-plugin-block-controls/afm-post-office/tsconfig.json"
28
31
  },
@@ -23,6 +23,9 @@
23
23
  {
24
24
  "path": "../../../design-system/dropdown-menu/afm-rovo-extension/tsconfig.json"
25
25
  },
26
+ {
27
+ "path": "../../editor-plugin-analytics/afm-rovo-extension/tsconfig.json"
28
+ },
26
29
  {
27
30
  "path": "../../editor-plugin-block-controls/afm-rovo-extension/tsconfig.json"
28
31
  },
@@ -23,6 +23,9 @@
23
23
  {
24
24
  "path": "../../../design-system/dropdown-menu/afm-townsquare/tsconfig.json"
25
25
  },
26
+ {
27
+ "path": "../../editor-plugin-analytics/afm-townsquare/tsconfig.json"
28
+ },
26
29
  {
27
30
  "path": "../../editor-plugin-block-controls/afm-townsquare/tsconfig.json"
28
31
  },
@@ -3,14 +3,16 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.formatNode = void 0;
6
+ exports.formatNodeSelectEmptyList = exports.formatNode = void 0;
7
7
  var _analytics = require("@atlaskit/editor-common/analytics");
8
+ var _state = require("@atlaskit/editor-prosemirror/state");
8
9
  var _utils = require("@atlaskit/editor-prosemirror/utils");
9
10
  var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
10
11
  var _expValEqualsNoExposure = require("@atlaskit/tmp-editor-statsig/exp-val-equals-no-exposure");
11
12
  var _selection = require("./selection");
12
13
  var _layoutTransforms = require("./transforms/layout-transforms");
13
14
  var _transformNodeToTargetType = require("./transforms/transformNodeToTargetType");
15
+ var _utils2 = require("./transforms/utils");
14
16
  /**
15
17
  * Handles formatting when selection is empty by inserting a new target node
16
18
  */
@@ -50,6 +52,42 @@ var formatNodeWhenSelectionEmpty = function formatNodeWhenSelectionEmpty(tr, tar
50
52
  return tr;
51
53
  };
52
54
 
55
+ /**
56
+ * Handles formatting when an empty list is selected
57
+ * Converting an empty list to a target node, will remove the list and replace with an empty target node
58
+ */
59
+ var formatNodeSelectEmptyList = exports.formatNodeSelectEmptyList = function formatNodeSelectEmptyList(tr, targetType, listNode, schema) {
60
+ var nodes = schema.nodes;
61
+ var headingLevel = 1;
62
+ var finalTargetType = targetType;
63
+ if (targetType.startsWith('heading')) {
64
+ var levelString = targetType.slice(-1);
65
+ var level = parseInt(levelString, 10);
66
+ if (!isNaN(level) && level >= 1 && level <= 6) {
67
+ headingLevel = level;
68
+ finalTargetType = 'heading';
69
+ }
70
+ }
71
+ var replaceNode = null;
72
+ if (finalTargetType === 'layoutSection') {
73
+ var emptyPara = nodes.paragraph.createAndFill();
74
+ if (emptyPara) {
75
+ replaceNode = (0, _layoutTransforms.createDefaultLayoutSection)(schema, emptyPara);
76
+ }
77
+ } else if (finalTargetType === 'heading') {
78
+ replaceNode = nodes.heading.createAndFill({
79
+ level: headingLevel
80
+ });
81
+ } else {
82
+ replaceNode = nodes[finalTargetType].createAndFill();
83
+ }
84
+ if (replaceNode) {
85
+ tr.replaceWith(listNode.pos, listNode.pos + listNode.node.nodeSize, replaceNode);
86
+ tr.setSelection(new _state.TextSelection(tr.doc.resolve(listNode.pos)));
87
+ }
88
+ return tr;
89
+ };
90
+
53
91
  /**
54
92
  * Formats the current node or selection to the specified target type
55
93
  * @param api - The editor API injection that provides access to analytics and other plugin actions
@@ -69,7 +107,26 @@ var formatNode = exports.formatNode = function formatNode(api) {
69
107
 
70
108
  // when selection is empty, we insert a empty target node
71
109
  if (selection.empty && (0, _expValEqualsNoExposure.expValEqualsNoExposure)('platform_editor_block_menu_empty_line', 'isEnabled', true)) {
72
- return formatNodeWhenSelectionEmpty(tr, targetType, nodePos, schema);
110
+ var listNodes = [];
111
+ // need to find if there is any list node in the current selection
112
+ // As when select a empty list, selection is empty, but we want to convert the list instead of inserting a target node
113
+ // findSelectedNodeOfType does not work when selection is empty, so we use nodesBetween
114
+ tr.doc.nodesBetween(selection.from, selection.to, function (node, pos) {
115
+ if ((0, _utils2.isListNodeType)(node.type)) {
116
+ listNodes.push({
117
+ node: node,
118
+ pos: pos
119
+ });
120
+ }
121
+ });
122
+ // get the first list node as when click on drag handle if there are list node
123
+ // can only select one list at a time, so we just need to find the first one
124
+ if (listNodes.length > 0 && (0, _platformFeatureFlags.fg)('platform_editor_block_menu_patch_2')) {
125
+ var firstChild = listNodes[0];
126
+ return formatNodeSelectEmptyList(tr, targetType, firstChild, schema);
127
+ } else {
128
+ return formatNodeWhenSelectionEmpty(tr, targetType, nodePos, schema);
129
+ }
73
130
  }
74
131
 
75
132
  // Try to find the current node from selection
@@ -1,10 +1,13 @@
1
1
  import { ACTION, ACTION_SUBJECT, EVENT_TYPE, INPUT_METHOD } from '@atlaskit/editor-common/analytics';
2
+ import { TextSelection } from '@atlaskit/editor-prosemirror/state';
2
3
  import { findParentNodeOfType, findSelectedNodeOfType, safeInsert as pmSafeInsert } from '@atlaskit/editor-prosemirror/utils';
3
4
  import { fg } from '@atlaskit/platform-feature-flags';
4
5
  import { expValEqualsNoExposure } from '@atlaskit/tmp-editor-statsig/exp-val-equals-no-exposure';
5
6
  import { setSelectionAfterTransform } from './selection';
6
7
  import { createDefaultLayoutSection } from './transforms/layout-transforms';
7
8
  import { transformNodeToTargetType } from './transforms/transformNodeToTargetType';
9
+ import { isListNodeType } from './transforms/utils';
10
+
8
11
  /**
9
12
  * Handles formatting when selection is empty by inserting a new target node
10
13
  */
@@ -48,6 +51,44 @@ const formatNodeWhenSelectionEmpty = (tr, targetType, nodePos, schema) => {
48
51
  return tr;
49
52
  };
50
53
 
54
+ /**
55
+ * Handles formatting when an empty list is selected
56
+ * Converting an empty list to a target node, will remove the list and replace with an empty target node
57
+ */
58
+ export const formatNodeSelectEmptyList = (tr, targetType, listNode, schema) => {
59
+ const {
60
+ nodes
61
+ } = schema;
62
+ let headingLevel = 1;
63
+ let finalTargetType = targetType;
64
+ if (targetType.startsWith('heading')) {
65
+ const levelString = targetType.slice(-1);
66
+ const level = parseInt(levelString, 10);
67
+ if (!isNaN(level) && level >= 1 && level <= 6) {
68
+ headingLevel = level;
69
+ finalTargetType = 'heading';
70
+ }
71
+ }
72
+ let replaceNode = null;
73
+ if (finalTargetType === 'layoutSection') {
74
+ const emptyPara = nodes.paragraph.createAndFill();
75
+ if (emptyPara) {
76
+ replaceNode = createDefaultLayoutSection(schema, emptyPara);
77
+ }
78
+ } else if (finalTargetType === 'heading') {
79
+ replaceNode = nodes.heading.createAndFill({
80
+ level: headingLevel
81
+ });
82
+ } else {
83
+ replaceNode = nodes[finalTargetType].createAndFill();
84
+ }
85
+ if (replaceNode) {
86
+ tr.replaceWith(listNode.pos, listNode.pos + listNode.node.nodeSize, replaceNode);
87
+ tr.setSelection(new TextSelection(tr.doc.resolve(listNode.pos)));
88
+ }
89
+ return tr;
90
+ };
91
+
51
92
  /**
52
93
  * Formats the current node or selection to the specified target type
53
94
  * @param api - The editor API injection that provides access to analytics and other plugin actions
@@ -71,7 +112,26 @@ export const formatNode = api => targetType => {
71
112
 
72
113
  // when selection is empty, we insert a empty target node
73
114
  if (selection.empty && expValEqualsNoExposure('platform_editor_block_menu_empty_line', 'isEnabled', true)) {
74
- return formatNodeWhenSelectionEmpty(tr, targetType, nodePos, schema);
115
+ const listNodes = [];
116
+ // need to find if there is any list node in the current selection
117
+ // As when select a empty list, selection is empty, but we want to convert the list instead of inserting a target node
118
+ // findSelectedNodeOfType does not work when selection is empty, so we use nodesBetween
119
+ tr.doc.nodesBetween(selection.from, selection.to, (node, pos) => {
120
+ if (isListNodeType(node.type)) {
121
+ listNodes.push({
122
+ node,
123
+ pos
124
+ });
125
+ }
126
+ });
127
+ // get the first list node as when click on drag handle if there are list node
128
+ // can only select one list at a time, so we just need to find the first one
129
+ if (listNodes.length > 0 && fg('platform_editor_block_menu_patch_2')) {
130
+ const firstChild = listNodes[0];
131
+ return formatNodeSelectEmptyList(tr, targetType, firstChild, schema);
132
+ } else {
133
+ return formatNodeWhenSelectionEmpty(tr, targetType, nodePos, schema);
134
+ }
75
135
  }
76
136
 
77
137
  // Try to find the current node from selection
@@ -1,10 +1,13 @@
1
1
  import { ACTION, ACTION_SUBJECT, EVENT_TYPE, INPUT_METHOD } from '@atlaskit/editor-common/analytics';
2
+ import { TextSelection } from '@atlaskit/editor-prosemirror/state';
2
3
  import { findParentNodeOfType, findSelectedNodeOfType, safeInsert as pmSafeInsert } from '@atlaskit/editor-prosemirror/utils';
3
4
  import { fg } from '@atlaskit/platform-feature-flags';
4
5
  import { expValEqualsNoExposure } from '@atlaskit/tmp-editor-statsig/exp-val-equals-no-exposure';
5
6
  import { setSelectionAfterTransform } from './selection';
6
7
  import { createDefaultLayoutSection } from './transforms/layout-transforms';
7
8
  import { transformNodeToTargetType } from './transforms/transformNodeToTargetType';
9
+ import { isListNodeType } from './transforms/utils';
10
+
8
11
  /**
9
12
  * Handles formatting when selection is empty by inserting a new target node
10
13
  */
@@ -44,6 +47,42 @@ var formatNodeWhenSelectionEmpty = function formatNodeWhenSelectionEmpty(tr, tar
44
47
  return tr;
45
48
  };
46
49
 
50
+ /**
51
+ * Handles formatting when an empty list is selected
52
+ * Converting an empty list to a target node, will remove the list and replace with an empty target node
53
+ */
54
+ export var formatNodeSelectEmptyList = function formatNodeSelectEmptyList(tr, targetType, listNode, schema) {
55
+ var nodes = schema.nodes;
56
+ var headingLevel = 1;
57
+ var finalTargetType = targetType;
58
+ if (targetType.startsWith('heading')) {
59
+ var levelString = targetType.slice(-1);
60
+ var level = parseInt(levelString, 10);
61
+ if (!isNaN(level) && level >= 1 && level <= 6) {
62
+ headingLevel = level;
63
+ finalTargetType = 'heading';
64
+ }
65
+ }
66
+ var replaceNode = null;
67
+ if (finalTargetType === 'layoutSection') {
68
+ var emptyPara = nodes.paragraph.createAndFill();
69
+ if (emptyPara) {
70
+ replaceNode = createDefaultLayoutSection(schema, emptyPara);
71
+ }
72
+ } else if (finalTargetType === 'heading') {
73
+ replaceNode = nodes.heading.createAndFill({
74
+ level: headingLevel
75
+ });
76
+ } else {
77
+ replaceNode = nodes[finalTargetType].createAndFill();
78
+ }
79
+ if (replaceNode) {
80
+ tr.replaceWith(listNode.pos, listNode.pos + listNode.node.nodeSize, replaceNode);
81
+ tr.setSelection(new TextSelection(tr.doc.resolve(listNode.pos)));
82
+ }
83
+ return tr;
84
+ };
85
+
47
86
  /**
48
87
  * Formats the current node or selection to the specified target type
49
88
  * @param api - The editor API injection that provides access to analytics and other plugin actions
@@ -63,7 +102,26 @@ export var formatNode = function formatNode(api) {
63
102
 
64
103
  // when selection is empty, we insert a empty target node
65
104
  if (selection.empty && expValEqualsNoExposure('platform_editor_block_menu_empty_line', 'isEnabled', true)) {
66
- return formatNodeWhenSelectionEmpty(tr, targetType, nodePos, schema);
105
+ var listNodes = [];
106
+ // need to find if there is any list node in the current selection
107
+ // As when select a empty list, selection is empty, but we want to convert the list instead of inserting a target node
108
+ // findSelectedNodeOfType does not work when selection is empty, so we use nodesBetween
109
+ tr.doc.nodesBetween(selection.from, selection.to, function (node, pos) {
110
+ if (isListNodeType(node.type)) {
111
+ listNodes.push({
112
+ node: node,
113
+ pos: pos
114
+ });
115
+ }
116
+ });
117
+ // get the first list node as when click on drag handle if there are list node
118
+ // can only select one list at a time, so we just need to find the first one
119
+ if (listNodes.length > 0 && fg('platform_editor_block_menu_patch_2')) {
120
+ var firstChild = listNodes[0];
121
+ return formatNodeSelectEmptyList(tr, targetType, firstChild, schema);
122
+ } else {
123
+ return formatNodeWhenSelectionEmpty(tr, targetType, nodePos, schema);
124
+ }
67
125
  }
68
126
 
69
127
  // Try to find the current node from selection
@@ -1,6 +1,16 @@
1
1
  import type { EditorCommand, ExtractInjectionAPI } from '@atlaskit/editor-common/types';
2
+ import { type Schema, type Node as PMNode } from '@atlaskit/editor-prosemirror/model';
3
+ import { type Transaction } from '@atlaskit/editor-prosemirror/state';
2
4
  import type { BlockMenuPlugin } from '../blockMenuPluginType';
3
5
  import type { FormatNodeTargetType } from './transforms/types';
6
+ /**
7
+ * Handles formatting when an empty list is selected
8
+ * Converting an empty list to a target node, will remove the list and replace with an empty target node
9
+ */
10
+ export declare const formatNodeSelectEmptyList: (tr: Transaction, targetType: FormatNodeTargetType, listNode: {
11
+ node: PMNode;
12
+ pos: number;
13
+ }, schema: Schema) => Transaction;
4
14
  /**
5
15
  * Formats the current node or selection to the specified target type
6
16
  * @param api - The editor API injection that provides access to analytics and other plugin actions
@@ -1,6 +1,16 @@
1
1
  import type { EditorCommand, ExtractInjectionAPI } from '@atlaskit/editor-common/types';
2
+ import { type Schema, type Node as PMNode } from '@atlaskit/editor-prosemirror/model';
3
+ import { type Transaction } from '@atlaskit/editor-prosemirror/state';
2
4
  import type { BlockMenuPlugin } from '../blockMenuPluginType';
3
5
  import type { FormatNodeTargetType } from './transforms/types';
6
+ /**
7
+ * Handles formatting when an empty list is selected
8
+ * Converting an empty list to a target node, will remove the list and replace with an empty target node
9
+ */
10
+ export declare const formatNodeSelectEmptyList: (tr: Transaction, targetType: FormatNodeTargetType, listNode: {
11
+ node: PMNode;
12
+ pos: number;
13
+ }, schema: Schema) => Transaction;
4
14
  /**
5
15
  * Formats the current node or selection to the specified target type
6
16
  * @param api - The editor API injection that provides access to analytics and other plugin actions
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-block-menu",
3
- "version": "4.0.2",
3
+ "version": "4.0.3",
4
4
  "description": "BlockMenu plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -30,7 +30,7 @@
30
30
  "dependencies": {
31
31
  "@atlaskit/css": "^0.14.0",
32
32
  "@atlaskit/dropdown-menu": "^16.3.0",
33
- "@atlaskit/editor-plugin-analytics": "^6.0.0",
33
+ "@atlaskit/editor-plugin-analytics": "^6.1.0",
34
34
  "@atlaskit/editor-plugin-block-controls": "^7.1.0",
35
35
  "@atlaskit/editor-plugin-decorations": "^6.1.0",
36
36
  "@atlaskit/editor-plugin-selection": "^6.0.0",
@@ -40,7 +40,7 @@
40
40
  "@atlaskit/editor-tables": "^2.9.0",
41
41
  "@atlaskit/editor-toolbar": "^0.10.0",
42
42
  "@atlaskit/icon": "^28.3.0",
43
- "@atlaskit/icon-lab": "^5.7.0",
43
+ "@atlaskit/icon-lab": "^5.8.0",
44
44
  "@atlaskit/platform-feature-flags": "^1.1.0",
45
45
  "@atlaskit/primitives": "^14.15.0",
46
46
  "@atlaskit/tmp-editor-statsig": "^12.32.0",
@@ -48,7 +48,7 @@
48
48
  "@babel/runtime": "^7.0.0"
49
49
  },
50
50
  "peerDependencies": {
51
- "@atlaskit/editor-common": "^110.2.0",
51
+ "@atlaskit/editor-common": "^110.3.0",
52
52
  "react": "^18.2.0",
53
53
  "react-intl-next": "npm:react-intl@^5.18.1"
54
54
  },