@atlaskit/editor-plugin-block-menu 5.2.1 → 5.2.2

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
+ ## 5.2.2
4
+
5
+ ### Patch Changes
6
+
7
+ - [`8696c9d95fe26`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/8696c9d95fe26) -
8
+ [ux] EDITOR-3382 Block menu copy link for multi select
9
+ - Updated dependencies
10
+
3
11
  ## 5.2.1
4
12
 
5
13
  ### Patch Changes
@@ -9,6 +9,7 @@ exports.CopyLinkDropdownItem = void 0;
9
9
  var _react = _interopRequireWildcard(require("react"));
10
10
  var _reactIntlNext = require("react-intl-next");
11
11
  var _analytics = require("@atlaskit/editor-common/analytics");
12
+ var _hooks = require("@atlaskit/editor-common/hooks");
12
13
  var _messages = require("@atlaskit/editor-common/messages");
13
14
  var _editorToolbar = require("@atlaskit/editor-toolbar");
14
15
  var _link = _interopRequireDefault(require("@atlaskit/icon/core/link"));
@@ -21,18 +22,38 @@ var _copyLink = require("./utils/copyLink");
21
22
  var _isNestedNode = require("./utils/isNestedNode");
22
23
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
23
24
  var CopyLinkDropdownItemContent = function CopyLinkDropdownItemContent(_ref) {
24
- var _api$selection;
25
25
  var api = _ref.api,
26
26
  config = _ref.config;
27
27
  var _useIntl = (0, _reactIntlNext.useIntl)(),
28
28
  formatMessage = _useIntl.formatMessage;
29
29
  var _useBlockMenu = (0, _blockMenuProvider.useBlockMenu)(),
30
30
  onDropdownOpenChanged = _useBlockMenu.onDropdownOpenChanged;
31
- 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;
31
+ var _ref2 = config || {},
32
+ getLinkPath = _ref2.getLinkPath,
33
+ blockLinkHashPrefix = _ref2.blockLinkHashPrefix;
34
+ var _useSharedPluginState = (0, _hooks.useSharedPluginStateWithSelector)(api, ['blockControls', 'selection', 'core'], function (_ref3) {
35
+ var blockControlsState = _ref3.blockControlsState,
36
+ selectionState = _ref3.selectionState,
37
+ coreState = _ref3.coreState;
38
+ return {
39
+ menuTriggerBy: blockControlsState === null || blockControlsState === void 0 ? void 0 : blockControlsState.menuTriggerBy,
40
+ 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
43
+ };
44
+ }),
45
+ preservedSelection = _useSharedPluginState.preservedSelection,
46
+ defaultSelection = _useSharedPluginState.defaultSelection,
47
+ menuTriggerBy = _useSharedPluginState.menuTriggerBy,
48
+ schema = _useSharedPluginState.schema;
49
+ var selection = preservedSelection || defaultSelection;
32
50
  var handleClick = (0, _react.useCallback)(function () {
33
- api === null || api === void 0 || api.core.actions.execute(function (_ref2) {
51
+ if (!selection || !schema) {
52
+ return;
53
+ }
54
+ api === null || api === void 0 || api.core.actions.execute(function (_ref4) {
34
55
  var _api$analytics, _api$blockControls;
35
- var tr = _ref2.tr;
56
+ var tr = _ref4.tr;
36
57
  var payload = {
37
58
  action: _analytics.ACTION.CLICKED,
38
59
  actionSubject: _analytics.ACTION_SUBJECT.BLOCK_MENU_ITEM,
@@ -50,10 +71,15 @@ var CopyLinkDropdownItemContent = function CopyLinkDropdownItemContent(_ref) {
50
71
  return tr;
51
72
  });
52
73
  onDropdownOpenChanged(false);
53
- (0, _copyLink.copyLink)(config === null || config === void 0 ? void 0 : config.getLinkPath, config === null || config === void 0 ? void 0 : config.blockLinkHashPrefix, api).then(function (success) {
74
+ (0, _copyLink.copyLink)({
75
+ getLinkPath: getLinkPath,
76
+ blockLinkHashPrefix: blockLinkHashPrefix,
77
+ selection: selection,
78
+ schema: schema
79
+ }).then(function (success) {
54
80
  if (success) {
55
- api === null || api === void 0 || api.core.actions.execute(function (_ref3) {
56
- var tr = _ref3.tr;
81
+ api === null || api === void 0 || api.core.actions.execute(function (_ref5) {
82
+ var tr = _ref5.tr;
57
83
  tr.setMeta(_main.blockMenuPluginKey, {
58
84
  showFlag: _blockMenuPluginType.FLAG_ID.LINK_COPIED_TO_CLIPBOARD
59
85
  });
@@ -61,19 +87,10 @@ var CopyLinkDropdownItemContent = function CopyLinkDropdownItemContent(_ref) {
61
87
  });
62
88
  }
63
89
  });
64
- }, [config === null || config === void 0 ? void 0 : config.getLinkPath, config === null || config === void 0 ? void 0 : config.blockLinkHashPrefix, api, onDropdownOpenChanged]);
65
- var checkIsNestedNode = (0, _react.useCallback)(function () {
66
- var _api$selection2, _api$blockControls2;
67
- 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;
68
- 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;
69
- if (!selection || !menuTriggerBy) {
70
- return false;
71
- }
72
- return (0, _isNestedNode.isNestedNode)(selection, menuTriggerBy);
73
- }, [api]);
90
+ }, [api, blockLinkHashPrefix, getLinkPath, onDropdownOpenChanged, schema, selection]);
74
91
 
75
92
  // Hide copy link when `platform_editor_adf_with_localid` feature flag is off or when the node is nested or on empty line
76
- if (!(0, _platformFeatureFlags.fg)('platform_editor_adf_with_localid') || checkIsNestedNode() || !!(selection !== null && selection !== void 0 && selection.empty)) {
93
+ if (!(0, _platformFeatureFlags.fg)('platform_editor_adf_with_localid') || !!menuTriggerBy && (0, _isNestedNode.isNestedNode)(selection, menuTriggerBy) || selection !== null && selection !== void 0 && selection.empty) {
77
94
  return null;
78
95
  }
79
96
  return /*#__PURE__*/_react.default.createElement(_editorToolbar.ToolbarDropdownItem, {
@@ -9,33 +9,24 @@ var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"))
9
9
  var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
10
10
  var _blockMenu = require("@atlaskit/editor-common/block-menu");
11
11
  var _clipboard = require("@atlaskit/editor-common/clipboard");
12
- var _state = require("@atlaskit/editor-prosemirror/state");
13
- var _editorTables = require("@atlaskit/editor-tables");
12
+ var _monitoring = require("@atlaskit/editor-common/monitoring");
13
+ var _utils = require("../../editor-commands/transform-node-utils/utils");
14
14
  var copyLink = exports.copyLink = /*#__PURE__*/function () {
15
- var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(getLinkPath) {
16
- var blockLinkHashPrefix,
17
- api,
18
- _api$selection,
19
- node,
20
- selection,
21
- path,
22
- url,
23
- href,
24
- _args = arguments;
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;
25
17
  return _regenerator.default.wrap(function _callee$(_context) {
26
18
  while (1) switch (_context.prev = _context.next) {
27
19
  case 0:
28
- blockLinkHashPrefix = _args.length > 1 && _args[1] !== undefined ? _args[1] : _blockMenu.DEFAULT_BLOCK_LINK_HASH_PREFIX;
29
- api = _args.length > 2 ? _args[2] : undefined;
30
- _context.prev = 2;
31
- 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;
32
- if (selection instanceof _state.NodeSelection && selection.node) {
33
- node = selection.node;
34
- } else if (selection instanceof _state.TextSelection) {
35
- node = selection.$from.node();
36
- } else if (selection instanceof _editorTables.CellSelection) {
37
- node = selection.$anchorCell.node(-1);
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);
22
+ if (blockRange) {
23
+ _context.next = 4;
24
+ break;
38
25
  }
26
+ return _context.abrupt("return", false);
27
+ case 4:
28
+ // get the link to the first node in the selection
29
+ node = blockRange.$from.nodeAfter;
39
30
  if (!(!node || !node.attrs || !node.attrs.localId)) {
40
31
  _context.next = 7;
41
32
  break;
@@ -43,30 +34,31 @@ var copyLink = exports.copyLink = /*#__PURE__*/function () {
43
34
  return _context.abrupt("return", false);
44
35
  case 7:
45
36
  path = (getLinkPath === null || getLinkPath === void 0 ? void 0 : getLinkPath()) || location.pathname;
46
- if (path) {
47
- _context.next = 10;
48
- break;
49
- }
50
- return _context.abrupt("return", false);
51
- case 10:
52
- url = new URL(location.origin + path); // append the localId as a hash fragment in the form #block-{localId}
53
- url.hash = "".concat(blockLinkHashPrefix).concat(node.attrs.localId);
37
+ _context.prev = 8;
38
+ url = new URL(location.origin + path);
39
+ url.hash = (0, _blockMenu.createBlockLinkHashValue)(node.attrs.localId, blockLinkHashPrefix);
54
40
  href = url.toString();
55
- _context.next = 15;
41
+ _context.next = 14;
56
42
  return (0, _clipboard.copyToClipboard)(href);
57
- case 15:
58
- return _context.abrupt("return", true);
59
- case 18:
60
- _context.prev = 18;
61
- _context.t0 = _context["catch"](2);
43
+ case 14:
44
+ _context.next = 20;
45
+ break;
46
+ case 16:
47
+ _context.prev = 16;
48
+ _context.t0 = _context["catch"](8);
49
+ (0, _monitoring.logException)(_context.t0, {
50
+ location: 'editor-plugin-block-menu'
51
+ });
62
52
  return _context.abrupt("return", false);
53
+ case 20:
54
+ return _context.abrupt("return", true);
63
55
  case 21:
64
56
  case "end":
65
57
  return _context.stop();
66
58
  }
67
- }, _callee, null, [[2, 18]]);
59
+ }, _callee, null, [[8, 16]]);
68
60
  }));
69
61
  return function copyLink(_x) {
70
- return _ref.apply(this, arguments);
62
+ return _ref2.apply(this, arguments);
71
63
  };
72
64
  }();
@@ -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';
@@ -15,15 +16,38 @@ const CopyLinkDropdownItemContent = ({
15
16
  api,
16
17
  config
17
18
  }) => {
18
- var _api$selection, _api$selection$shared, _api$selection$shared2;
19
19
  const {
20
20
  formatMessage
21
21
  } = useIntl();
22
22
  const {
23
23
  onDropdownOpenChanged
24
24
  } = useBlockMenu();
25
- 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) === null || _api$selection$shared === void 0 ? void 0 : (_api$selection$shared2 = _api$selection$shared.currentState()) === null || _api$selection$shared2 === void 0 ? void 0 : _api$selection$shared2.selection;
25
+ const {
26
+ getLinkPath,
27
+ blockLinkHashPrefix
28
+ } = config || {};
29
+ const {
30
+ preservedSelection,
31
+ defaultSelection,
32
+ menuTriggerBy,
33
+ schema
34
+ } = useSharedPluginStateWithSelector(api, ['blockControls', 'selection', 'core'], ({
35
+ blockControlsState,
36
+ selectionState,
37
+ coreState
38
+ }) => {
39
+ return {
40
+ menuTriggerBy: blockControlsState === null || blockControlsState === void 0 ? void 0 : blockControlsState.menuTriggerBy,
41
+ 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
44
+ };
45
+ });
46
+ const selection = preservedSelection || defaultSelection;
26
47
  const handleClick = useCallback(() => {
48
+ if (!selection || !schema) {
49
+ return;
50
+ }
27
51
  api === null || api === void 0 ? void 0 : api.core.actions.execute(({
28
52
  tr
29
53
  }) => {
@@ -45,7 +69,12 @@ const CopyLinkDropdownItemContent = ({
45
69
  return tr;
46
70
  });
47
71
  onDropdownOpenChanged(false);
48
- copyLink(config === null || config === void 0 ? void 0 : config.getLinkPath, config === null || config === void 0 ? void 0 : config.blockLinkHashPrefix, api).then(success => {
72
+ copyLink({
73
+ getLinkPath,
74
+ blockLinkHashPrefix,
75
+ selection,
76
+ schema
77
+ }).then(success => {
49
78
  if (success) {
50
79
  api === null || api === void 0 ? void 0 : api.core.actions.execute(({
51
80
  tr
@@ -57,19 +86,10 @@ const CopyLinkDropdownItemContent = ({
57
86
  });
58
87
  }
59
88
  });
60
- }, [config === null || config === void 0 ? void 0 : config.getLinkPath, config === null || config === void 0 ? void 0 : config.blockLinkHashPrefix, api, onDropdownOpenChanged]);
61
- const checkIsNestedNode = useCallback(() => {
62
- var _api$selection2, _api$selection2$share, _api$selection2$share2, _api$blockControls2, _api$blockControls2$s, _api$blockControls2$s2;
63
- const selection = api === null || api === void 0 ? void 0 : (_api$selection2 = api.selection) === null || _api$selection2 === void 0 ? void 0 : (_api$selection2$share = _api$selection2.sharedState) === null || _api$selection2$share === void 0 ? void 0 : (_api$selection2$share2 = _api$selection2$share.currentState()) === null || _api$selection2$share2 === void 0 ? void 0 : _api$selection2$share2.selection;
64
- const menuTriggerBy = api === null || api === void 0 ? void 0 : (_api$blockControls2 = api.blockControls) === null || _api$blockControls2 === void 0 ? void 0 : (_api$blockControls2$s = _api$blockControls2.sharedState) === null || _api$blockControls2$s === void 0 ? void 0 : (_api$blockControls2$s2 = _api$blockControls2$s.currentState()) === null || _api$blockControls2$s2 === void 0 ? void 0 : _api$blockControls2$s2.menuTriggerBy;
65
- if (!selection || !menuTriggerBy) {
66
- return false;
67
- }
68
- return isNestedNode(selection, menuTriggerBy);
69
- }, [api]);
89
+ }, [api, blockLinkHashPrefix, getLinkPath, onDropdownOpenChanged, schema, selection]);
70
90
 
71
91
  // Hide copy link when `platform_editor_adf_with_localid` feature flag is off or when the node is nested or on empty line
72
- if (!fg('platform_editor_adf_with_localid') || checkIsNestedNode() || !!(selection !== null && selection !== void 0 && selection.empty)) {
92
+ if (!fg('platform_editor_adf_with_localid') || !!menuTriggerBy && isNestedNode(selection, menuTriggerBy) || selection !== null && selection !== void 0 && selection.empty) {
73
93
  return null;
74
94
  }
75
95
  return /*#__PURE__*/React.createElement(ToolbarDropdownItem, {
@@ -1,33 +1,34 @@
1
- import { DEFAULT_BLOCK_LINK_HASH_PREFIX } from '@atlaskit/editor-common/block-menu';
1
+ import { createBlockLinkHashValue, DEFAULT_BLOCK_LINK_HASH_PREFIX } from '@atlaskit/editor-common/block-menu';
2
2
  import { copyToClipboard } from '@atlaskit/editor-common/clipboard';
3
- import { NodeSelection, TextSelection } from '@atlaskit/editor-prosemirror/state';
4
- import { CellSelection } from '@atlaskit/editor-tables';
5
- export const copyLink = async (getLinkPath, blockLinkHashPrefix = DEFAULT_BLOCK_LINK_HASH_PREFIX, api) => {
3
+ import { logException } from '@atlaskit/editor-common/monitoring';
4
+ import { expandSelectionToBlockRange } from '../../editor-commands/transform-node-utils/utils';
5
+ export const copyLink = async ({
6
+ getLinkPath,
7
+ blockLinkHashPrefix = DEFAULT_BLOCK_LINK_HASH_PREFIX,
8
+ selection,
9
+ schema
10
+ }) => {
11
+ const blockRange = expandSelectionToBlockRange(selection, schema);
12
+ if (!blockRange) {
13
+ return false;
14
+ }
15
+
16
+ // get the link to the first node in the selection
17
+ const node = blockRange.$from.nodeAfter;
18
+ if (!node || !node.attrs || !node.attrs.localId) {
19
+ return false;
20
+ }
21
+ const path = (getLinkPath === null || getLinkPath === void 0 ? void 0 : getLinkPath()) || location.pathname;
6
22
  try {
7
- var _api$selection, _api$selection$shared;
8
- let node;
9
- 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;
10
- if (selection instanceof NodeSelection && selection.node) {
11
- node = selection.node;
12
- } else if (selection instanceof TextSelection) {
13
- node = selection.$from.node();
14
- } else if (selection instanceof CellSelection) {
15
- node = selection.$anchorCell.node(-1);
16
- }
17
- if (!node || !node.attrs || !node.attrs.localId) {
18
- return false;
19
- }
20
- const path = (getLinkPath === null || getLinkPath === void 0 ? void 0 : getLinkPath()) || location.pathname;
21
- if (!path) {
22
- return false;
23
- }
24
23
  const url = new URL(location.origin + path);
25
- // append the localId as a hash fragment in the form #block-{localId}
26
- url.hash = `${blockLinkHashPrefix}${node.attrs.localId}`;
24
+ url.hash = createBlockLinkHashValue(node.attrs.localId, blockLinkHashPrefix);
27
25
  const href = url.toString();
28
26
  await copyToClipboard(href);
29
- return true;
30
- } catch (e) {
27
+ } catch (error) {
28
+ logException(error, {
29
+ location: 'editor-plugin-block-menu'
30
+ });
31
31
  return false;
32
32
  }
33
+ return true;
33
34
  };
@@ -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,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,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.2",
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",