@atlaskit/editor-plugin-block-menu 5.2.1 → 5.2.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.
Files changed (28) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/cjs/editor-commands/transform-node-utils/{flattenListStep.js → steps/flattenListStep.js} +3 -5
  3. package/dist/cjs/editor-commands/transform-node-utils/steps/listToListStep.js +232 -0
  4. package/dist/cjs/editor-commands/transform-node-utils/transform.js +4 -3
  5. package/dist/cjs/ui/copy-link.js +35 -18
  6. package/dist/cjs/ui/utils/copyLink.js +30 -38
  7. package/dist/es2019/editor-commands/transform-node-utils/{flattenListStep.js → steps/flattenListStep.js} +3 -5
  8. package/dist/es2019/editor-commands/transform-node-utils/steps/listToListStep.js +225 -0
  9. package/dist/es2019/editor-commands/transform-node-utils/transform.js +4 -3
  10. package/dist/es2019/ui/copy-link.js +35 -15
  11. package/dist/es2019/ui/utils/copyLink.js +26 -25
  12. package/dist/esm/editor-commands/transform-node-utils/{flattenListStep.js → steps/flattenListStep.js} +3 -5
  13. package/dist/esm/editor-commands/transform-node-utils/steps/listToListStep.js +226 -0
  14. package/dist/esm/editor-commands/transform-node-utils/transform.js +4 -3
  15. package/dist/esm/ui/copy-link.js +36 -19
  16. package/dist/esm/ui/utils/copyLink.js +31 -39
  17. package/dist/{types-ts4.5/editor-commands/transform-node-utils → types/editor-commands/transform-node-utils/steps}/flattenListStep.d.ts +1 -1
  18. package/dist/types/editor-commands/transform-node-utils/steps/listToListStep.d.ts +65 -0
  19. package/dist/{types-ts4.5/editor-commands/transform-node-utils → types/editor-commands/transform-node-utils/steps}/unwrapListStep.d.ts +1 -1
  20. package/dist/types/ui/utils/copyLink.d.ts +10 -3
  21. package/dist/{types/editor-commands/transform-node-utils → types-ts4.5/editor-commands/transform-node-utils/steps}/flattenListStep.d.ts +1 -1
  22. package/dist/types-ts4.5/editor-commands/transform-node-utils/steps/listToListStep.d.ts +65 -0
  23. package/dist/{types/editor-commands/transform-node-utils → types-ts4.5/editor-commands/transform-node-utils/steps}/unwrapListStep.d.ts +1 -1
  24. package/dist/types-ts4.5/ui/utils/copyLink.d.ts +10 -3
  25. package/package.json +2 -2
  26. /package/dist/cjs/editor-commands/transform-node-utils/{unwrapListStep.js → steps/unwrapListStep.js} +0 -0
  27. /package/dist/es2019/editor-commands/transform-node-utils/{unwrapListStep.js → steps/unwrapListStep.js} +0 -0
  28. /package/dist/esm/editor-commands/transform-node-utils/{unwrapListStep.js → steps/unwrapListStep.js} +0 -0
@@ -1,6 +1,7 @@
1
1
  import React, { useCallback } from 'react';
2
- import { useIntl, injectIntl } from 'react-intl-next';
2
+ import { injectIntl, useIntl } from 'react-intl-next';
3
3
  import { ACTION, ACTION_SUBJECT, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
4
+ import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
4
5
  import { blockMenuMessages as messages } from '@atlaskit/editor-common/messages';
5
6
  import { ToolbarDropdownItem } from '@atlaskit/editor-toolbar';
6
7
  import LinkIcon from '@atlaskit/icon/core/link';
@@ -12,18 +13,38 @@ import { BLOCK_MENU_ITEM_NAME } from './consts';
12
13
  import { copyLink } from './utils/copyLink';
13
14
  import { isNestedNode } from './utils/isNestedNode';
14
15
  var CopyLinkDropdownItemContent = function CopyLinkDropdownItemContent(_ref) {
15
- var _api$selection;
16
16
  var api = _ref.api,
17
17
  config = _ref.config;
18
18
  var _useIntl = useIntl(),
19
19
  formatMessage = _useIntl.formatMessage;
20
20
  var _useBlockMenu = useBlockMenu(),
21
21
  onDropdownOpenChanged = _useBlockMenu.onDropdownOpenChanged;
22
- var selection = api === null || api === void 0 || (_api$selection = api.selection) === null || _api$selection === void 0 || (_api$selection = _api$selection.sharedState) === null || _api$selection === void 0 || (_api$selection = _api$selection.currentState()) === null || _api$selection === void 0 ? void 0 : _api$selection.selection;
22
+ var _ref2 = config || {},
23
+ getLinkPath = _ref2.getLinkPath,
24
+ blockLinkHashPrefix = _ref2.blockLinkHashPrefix;
25
+ var _useSharedPluginState = useSharedPluginStateWithSelector(api, ['blockControls', 'selection', 'core'], function (_ref3) {
26
+ var blockControlsState = _ref3.blockControlsState,
27
+ selectionState = _ref3.selectionState,
28
+ coreState = _ref3.coreState;
29
+ return {
30
+ menuTriggerBy: blockControlsState === null || blockControlsState === void 0 ? void 0 : blockControlsState.menuTriggerBy,
31
+ 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
34
+ };
35
+ }),
36
+ preservedSelection = _useSharedPluginState.preservedSelection,
37
+ defaultSelection = _useSharedPluginState.defaultSelection,
38
+ menuTriggerBy = _useSharedPluginState.menuTriggerBy,
39
+ schema = _useSharedPluginState.schema;
40
+ var selection = preservedSelection || defaultSelection;
23
41
  var handleClick = useCallback(function () {
24
- api === null || api === void 0 || api.core.actions.execute(function (_ref2) {
42
+ if (!selection || !schema) {
43
+ return;
44
+ }
45
+ api === null || api === void 0 || api.core.actions.execute(function (_ref4) {
25
46
  var _api$analytics, _api$blockControls;
26
- var tr = _ref2.tr;
47
+ var tr = _ref4.tr;
27
48
  var payload = {
28
49
  action: ACTION.CLICKED,
29
50
  actionSubject: ACTION_SUBJECT.BLOCK_MENU_ITEM,
@@ -41,10 +62,15 @@ var CopyLinkDropdownItemContent = function CopyLinkDropdownItemContent(_ref) {
41
62
  return tr;
42
63
  });
43
64
  onDropdownOpenChanged(false);
44
- copyLink(config === null || config === void 0 ? void 0 : config.getLinkPath, config === null || config === void 0 ? void 0 : config.blockLinkHashPrefix, api).then(function (success) {
65
+ copyLink({
66
+ getLinkPath: getLinkPath,
67
+ blockLinkHashPrefix: blockLinkHashPrefix,
68
+ selection: selection,
69
+ schema: schema
70
+ }).then(function (success) {
45
71
  if (success) {
46
- api === null || api === void 0 || api.core.actions.execute(function (_ref3) {
47
- var tr = _ref3.tr;
72
+ api === null || api === void 0 || api.core.actions.execute(function (_ref5) {
73
+ var tr = _ref5.tr;
48
74
  tr.setMeta(blockMenuPluginKey, {
49
75
  showFlag: FLAG_ID.LINK_COPIED_TO_CLIPBOARD
50
76
  });
@@ -52,19 +78,10 @@ var CopyLinkDropdownItemContent = function CopyLinkDropdownItemContent(_ref) {
52
78
  });
53
79
  }
54
80
  });
55
- }, [config === null || config === void 0 ? void 0 : config.getLinkPath, config === null || config === void 0 ? void 0 : config.blockLinkHashPrefix, api, onDropdownOpenChanged]);
56
- var checkIsNestedNode = useCallback(function () {
57
- var _api$selection2, _api$blockControls2;
58
- var selection = api === null || api === void 0 || (_api$selection2 = api.selection) === null || _api$selection2 === void 0 || (_api$selection2 = _api$selection2.sharedState) === null || _api$selection2 === void 0 || (_api$selection2 = _api$selection2.currentState()) === null || _api$selection2 === void 0 ? void 0 : _api$selection2.selection;
59
- var menuTriggerBy = api === null || api === void 0 || (_api$blockControls2 = api.blockControls) === null || _api$blockControls2 === void 0 || (_api$blockControls2 = _api$blockControls2.sharedState) === null || _api$blockControls2 === void 0 || (_api$blockControls2 = _api$blockControls2.currentState()) === null || _api$blockControls2 === void 0 ? void 0 : _api$blockControls2.menuTriggerBy;
60
- if (!selection || !menuTriggerBy) {
61
- return false;
62
- }
63
- return isNestedNode(selection, menuTriggerBy);
64
- }, [api]);
81
+ }, [api, blockLinkHashPrefix, getLinkPath, onDropdownOpenChanged, schema, selection]);
65
82
 
66
83
  // Hide copy link when `platform_editor_adf_with_localid` feature flag is off or when the node is nested or on empty line
67
- if (!fg('platform_editor_adf_with_localid') || checkIsNestedNode() || !!(selection !== null && selection !== void 0 && selection.empty)) {
84
+ if (!fg('platform_editor_adf_with_localid') || !!menuTriggerBy && isNestedNode(selection, menuTriggerBy) || selection !== null && selection !== void 0 && selection.empty) {
68
85
  return null;
69
86
  }
70
87
  return /*#__PURE__*/React.createElement(ToolbarDropdownItem, {
@@ -1,34 +1,25 @@
1
1
  import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
2
2
  import _regeneratorRuntime from "@babel/runtime/regenerator";
3
- import { DEFAULT_BLOCK_LINK_HASH_PREFIX } from '@atlaskit/editor-common/block-menu';
3
+ import { createBlockLinkHashValue, DEFAULT_BLOCK_LINK_HASH_PREFIX } from '@atlaskit/editor-common/block-menu';
4
4
  import { copyToClipboard } from '@atlaskit/editor-common/clipboard';
5
- import { NodeSelection, TextSelection } from '@atlaskit/editor-prosemirror/state';
6
- import { CellSelection } from '@atlaskit/editor-tables';
5
+ import { logException } from '@atlaskit/editor-common/monitoring';
6
+ import { expandSelectionToBlockRange } from '../../editor-commands/transform-node-utils/utils';
7
7
  export var copyLink = /*#__PURE__*/function () {
8
- var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(getLinkPath) {
9
- var blockLinkHashPrefix,
10
- api,
11
- _api$selection,
12
- node,
13
- selection,
14
- path,
15
- url,
16
- href,
17
- _args = arguments;
8
+ var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(_ref) {
9
+ var getLinkPath, _ref$blockLinkHashPre, blockLinkHashPrefix, selection, schema, blockRange, node, path, url, href;
18
10
  return _regeneratorRuntime.wrap(function _callee$(_context) {
19
11
  while (1) switch (_context.prev = _context.next) {
20
12
  case 0:
21
- blockLinkHashPrefix = _args.length > 1 && _args[1] !== undefined ? _args[1] : DEFAULT_BLOCK_LINK_HASH_PREFIX;
22
- api = _args.length > 2 ? _args[2] : undefined;
23
- _context.prev = 2;
24
- selection = api === null || api === void 0 || (_api$selection = api.selection) === null || _api$selection === void 0 || (_api$selection = _api$selection.sharedState.currentState()) === null || _api$selection === void 0 ? void 0 : _api$selection.selection;
25
- if (selection instanceof NodeSelection && selection.node) {
26
- node = selection.node;
27
- } else if (selection instanceof TextSelection) {
28
- node = selection.$from.node();
29
- } else if (selection instanceof CellSelection) {
30
- node = selection.$anchorCell.node(-1);
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);
15
+ if (blockRange) {
16
+ _context.next = 4;
17
+ break;
31
18
  }
19
+ return _context.abrupt("return", false);
20
+ case 4:
21
+ // get the link to the first node in the selection
22
+ node = blockRange.$from.nodeAfter;
32
23
  if (!(!node || !node.attrs || !node.attrs.localId)) {
33
24
  _context.next = 7;
34
25
  break;
@@ -36,30 +27,31 @@ export var copyLink = /*#__PURE__*/function () {
36
27
  return _context.abrupt("return", false);
37
28
  case 7:
38
29
  path = (getLinkPath === null || getLinkPath === void 0 ? void 0 : getLinkPath()) || location.pathname;
39
- if (path) {
40
- _context.next = 10;
41
- break;
42
- }
43
- return _context.abrupt("return", false);
44
- case 10:
45
- url = new URL(location.origin + path); // append the localId as a hash fragment in the form #block-{localId}
46
- url.hash = "".concat(blockLinkHashPrefix).concat(node.attrs.localId);
30
+ _context.prev = 8;
31
+ url = new URL(location.origin + path);
32
+ url.hash = createBlockLinkHashValue(node.attrs.localId, blockLinkHashPrefix);
47
33
  href = url.toString();
48
- _context.next = 15;
34
+ _context.next = 14;
49
35
  return copyToClipboard(href);
50
- case 15:
51
- return _context.abrupt("return", true);
52
- case 18:
53
- _context.prev = 18;
54
- _context.t0 = _context["catch"](2);
36
+ case 14:
37
+ _context.next = 20;
38
+ break;
39
+ case 16:
40
+ _context.prev = 16;
41
+ _context.t0 = _context["catch"](8);
42
+ logException(_context.t0, {
43
+ location: 'editor-plugin-block-menu'
44
+ });
55
45
  return _context.abrupt("return", false);
46
+ case 20:
47
+ return _context.abrupt("return", true);
56
48
  case 21:
57
49
  case "end":
58
50
  return _context.stop();
59
51
  }
60
- }, _callee, null, [[2, 18]]);
52
+ }, _callee, null, [[8, 16]]);
61
53
  }));
62
54
  return function copyLink(_x) {
63
- return _ref.apply(this, arguments);
55
+ return _ref2.apply(this, arguments);
64
56
  };
65
57
  }();
@@ -1,4 +1,4 @@
1
- import type { TransformStep } from './types';
1
+ import type { TransformStep } from '../types';
2
2
  /**
3
3
  * Given an array of nodes, returns an array with the flattened children of any list node
4
4
  * to it's first ancestor list, maintaining document order.
@@ -0,0 +1,65 @@
1
+ import type { TransformStep } from '../types';
2
+ /**
3
+ * Transform step that converts between bulletList, orderedList, and taskList types.
4
+ * This step maintains the order and indentation of the list by recursively
5
+ * converting all nested lists while preserving the structure. It also handles
6
+ * conversion between listItem and taskItem types.
7
+ *
8
+ * When converting to taskList/taskItem, unsupported content (images, codeBlocks) is filtered out.
9
+ *
10
+ * @example
11
+ * Input (bulletList with nested bulletList):
12
+ * - bulletList
13
+ * - listItem "1"
14
+ * - bulletList
15
+ * - listItem "1.1"
16
+ * - bulletList
17
+ * - listItem "1.1.1"
18
+ * - listItem "1.2"
19
+ * - listItem "2"
20
+ *
21
+ * Output (orderedList with nested orderedList):
22
+ * 1. orderedList
23
+ * 1. listItem "1"
24
+ * 1. orderedList
25
+ * 1. listItem "1.1"
26
+ * 1. orderedList
27
+ * 1. listItem "1.1.1"
28
+ * 2. listItem "1.2"
29
+ * 2. listItem "2"
30
+ *
31
+ * @example
32
+ * Input (bulletList with nested taskList):
33
+ * - bulletList
34
+ * - listItem "Regular item"
35
+ * - taskList
36
+ * - taskItem "Task 1" (checked)
37
+ * - taskItem "Task 2" (unchecked)
38
+ *
39
+ * Output (orderedList with nested orderedList, taskItems converted to listItems):
40
+ * 1. orderedList
41
+ * 1. listItem "Regular item"
42
+ * 1. orderedList
43
+ * 1. listItem "Task 1"
44
+ * 2. listItem "Task 2"
45
+ *
46
+ * @example
47
+ * Input (bulletList to taskList, with paragraph extraction):
48
+ * - bulletList
49
+ * - listItem
50
+ * - paragraph "Text content"
51
+ * - listItem
52
+ * - paragraph "Text"
53
+ * - codeBlock "code"
54
+ * - mediaSingle (image)
55
+ *
56
+ * Output (taskList with text extracted from paragraphs, unsupported content filtered):
57
+ * - taskList
58
+ * - taskItem "Text content" (text extracted from paragraph)
59
+ * - taskItem "Text" (text extracted, codeBlock and image filtered out)
60
+ *
61
+ * @param nodes - The nodes to transform
62
+ * @param context - The transformation context containing schema and target node type
63
+ * @returns The transformed nodes
64
+ */
65
+ export declare const listToListStep: TransformStep;
@@ -1,4 +1,4 @@
1
- import type { TransformStep } from './types';
1
+ import type { TransformStep } from '../types';
2
2
  /**
3
3
  * Given an array of nodes, processes each list removing all parent list nodes and
4
4
  * just returning their child contents.
@@ -1,3 +1,10 @@
1
- import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
2
- import type { BlockMenuPlugin } from '../../blockMenuPluginType';
3
- export declare const copyLink: (getLinkPath?: () => string | null, blockLinkHashPrefix?: string, api?: ExtractInjectionAPI<BlockMenuPlugin>) => Promise<boolean>;
1
+ import type { Schema } from '@atlaskit/editor-prosemirror/model';
2
+ import type { Selection } from '@atlaskit/editor-prosemirror/state';
3
+ type CopyLinkOptions = {
4
+ blockLinkHashPrefix?: string;
5
+ getLinkPath?: () => string | null;
6
+ schema: Schema;
7
+ selection: Selection;
8
+ };
9
+ export declare const copyLink: ({ getLinkPath, blockLinkHashPrefix, selection, schema, }: CopyLinkOptions) => Promise<boolean>;
10
+ export {};
@@ -1,4 +1,4 @@
1
- import type { TransformStep } from './types';
1
+ import type { TransformStep } from '../types';
2
2
  /**
3
3
  * Given an array of nodes, returns an array with the flattened children of any list node
4
4
  * to it's first ancestor list, maintaining document order.
@@ -0,0 +1,65 @@
1
+ import type { TransformStep } from '../types';
2
+ /**
3
+ * Transform step that converts between bulletList, orderedList, and taskList types.
4
+ * This step maintains the order and indentation of the list by recursively
5
+ * converting all nested lists while preserving the structure. It also handles
6
+ * conversion between listItem and taskItem types.
7
+ *
8
+ * When converting to taskList/taskItem, unsupported content (images, codeBlocks) is filtered out.
9
+ *
10
+ * @example
11
+ * Input (bulletList with nested bulletList):
12
+ * - bulletList
13
+ * - listItem "1"
14
+ * - bulletList
15
+ * - listItem "1.1"
16
+ * - bulletList
17
+ * - listItem "1.1.1"
18
+ * - listItem "1.2"
19
+ * - listItem "2"
20
+ *
21
+ * Output (orderedList with nested orderedList):
22
+ * 1. orderedList
23
+ * 1. listItem "1"
24
+ * 1. orderedList
25
+ * 1. listItem "1.1"
26
+ * 1. orderedList
27
+ * 1. listItem "1.1.1"
28
+ * 2. listItem "1.2"
29
+ * 2. listItem "2"
30
+ *
31
+ * @example
32
+ * Input (bulletList with nested taskList):
33
+ * - bulletList
34
+ * - listItem "Regular item"
35
+ * - taskList
36
+ * - taskItem "Task 1" (checked)
37
+ * - taskItem "Task 2" (unchecked)
38
+ *
39
+ * Output (orderedList with nested orderedList, taskItems converted to listItems):
40
+ * 1. orderedList
41
+ * 1. listItem "Regular item"
42
+ * 1. orderedList
43
+ * 1. listItem "Task 1"
44
+ * 2. listItem "Task 2"
45
+ *
46
+ * @example
47
+ * Input (bulletList to taskList, with paragraph extraction):
48
+ * - bulletList
49
+ * - listItem
50
+ * - paragraph "Text content"
51
+ * - listItem
52
+ * - paragraph "Text"
53
+ * - codeBlock "code"
54
+ * - mediaSingle (image)
55
+ *
56
+ * Output (taskList with text extracted from paragraphs, unsupported content filtered):
57
+ * - taskList
58
+ * - taskItem "Text content" (text extracted from paragraph)
59
+ * - taskItem "Text" (text extracted, codeBlock and image filtered out)
60
+ *
61
+ * @param nodes - The nodes to transform
62
+ * @param context - The transformation context containing schema and target node type
63
+ * @returns The transformed nodes
64
+ */
65
+ export declare const listToListStep: TransformStep;
@@ -1,4 +1,4 @@
1
- import type { TransformStep } from './types';
1
+ import type { TransformStep } from '../types';
2
2
  /**
3
3
  * Given an array of nodes, processes each list removing all parent list nodes and
4
4
  * just returning their child contents.
@@ -1,3 +1,10 @@
1
- import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
2
- import type { BlockMenuPlugin } from '../../blockMenuPluginType';
3
- export declare const copyLink: (getLinkPath?: () => string | null, blockLinkHashPrefix?: string, api?: ExtractInjectionAPI<BlockMenuPlugin>) => Promise<boolean>;
1
+ import type { Schema } from '@atlaskit/editor-prosemirror/model';
2
+ import type { Selection } from '@atlaskit/editor-prosemirror/state';
3
+ type CopyLinkOptions = {
4
+ blockLinkHashPrefix?: string;
5
+ getLinkPath?: () => string | null;
6
+ schema: Schema;
7
+ selection: Selection;
8
+ };
9
+ export declare const copyLink: ({ getLinkPath, blockLinkHashPrefix, selection, schema, }: CopyLinkOptions) => Promise<boolean>;
10
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-block-menu",
3
- "version": "5.2.1",
3
+ "version": "5.2.3",
4
4
  "description": "BlockMenu plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -39,7 +39,7 @@
39
39
  "@atlaskit/editor-shared-styles": "^3.10.0",
40
40
  "@atlaskit/editor-tables": "^2.9.0",
41
41
  "@atlaskit/editor-toolbar": "^0.18.0",
42
- "@atlaskit/flag": "^17.5.0",
42
+ "@atlaskit/flag": "^17.6.0",
43
43
  "@atlaskit/icon": "^29.0.0",
44
44
  "@atlaskit/platform-feature-flags": "^1.1.0",
45
45
  "@atlaskit/platform-feature-flags-react": "^0.4.0",