@atlaskit/editor-plugin-selection-extension 3.0.1 → 3.1.1

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 (35) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/cjs/pm-plugins/actions.js +93 -0
  3. package/dist/cjs/pm-plugins/main.js +21 -0
  4. package/dist/cjs/pm-plugins/utils/getOffsetByPath.js +83 -0
  5. package/dist/cjs/pm-plugins/utils/index.js +23 -6
  6. package/dist/cjs/selectionExtensionPlugin.js +29 -2
  7. package/dist/cjs/types/index.js +2 -0
  8. package/dist/cjs/ui/extension/SelectionExtensionComponentWrapper.js +12 -6
  9. package/dist/es2019/pm-plugins/actions.js +93 -0
  10. package/dist/es2019/pm-plugins/main.js +22 -0
  11. package/dist/es2019/pm-plugins/utils/getOffsetByPath.js +76 -0
  12. package/dist/es2019/pm-plugins/utils/index.js +22 -5
  13. package/dist/es2019/selectionExtensionPlugin.js +31 -2
  14. package/dist/es2019/types/index.js +2 -0
  15. package/dist/es2019/ui/extension/SelectionExtensionComponentWrapper.js +11 -4
  16. package/dist/esm/pm-plugins/actions.js +87 -0
  17. package/dist/esm/pm-plugins/main.js +21 -0
  18. package/dist/esm/pm-plugins/utils/getOffsetByPath.js +78 -0
  19. package/dist/esm/pm-plugins/utils/index.js +21 -5
  20. package/dist/esm/selectionExtensionPlugin.js +29 -2
  21. package/dist/esm/types/index.js +2 -0
  22. package/dist/esm/ui/extension/SelectionExtensionComponentWrapper.js +13 -7
  23. package/dist/types/pm-plugins/actions.d.ts +8 -0
  24. package/dist/types/pm-plugins/main.d.ts +24 -0
  25. package/dist/types/pm-plugins/utils/getOffsetByPath.d.ts +14 -0
  26. package/dist/types/pm-plugins/utils/index.d.ts +12 -2
  27. package/dist/types/selectionExtensionPluginType.d.ts +8 -1
  28. package/dist/types/types/index.d.ts +17 -1
  29. package/dist/types-ts4.5/pm-plugins/actions.d.ts +8 -0
  30. package/dist/types-ts4.5/pm-plugins/main.d.ts +24 -0
  31. package/dist/types-ts4.5/pm-plugins/utils/getOffsetByPath.d.ts +14 -0
  32. package/dist/types-ts4.5/pm-plugins/utils/index.d.ts +12 -2
  33. package/dist/types-ts4.5/selectionExtensionPluginType.d.ts +8 -1
  34. package/dist/types-ts4.5/types/index.d.ts +17 -1
  35. package/package.json +3 -2
@@ -1,3 +1,4 @@
1
+ import isEqual from 'lodash/isEqual';
1
2
  import { JSONTransformer } from '@atlaskit/editor-json-transformer';
2
3
  import { TextSelection } from '@atlaskit/editor-prosemirror/state';
3
4
  import { CellSelection, TableMap } from '@atlaskit/editor-tables';
@@ -28,11 +29,13 @@ const getSelectionInfoFromSameNode = selection => {
28
29
  pointer: `/content/${$from.index()}/text`,
29
30
  position: $to.parentOffset - 1
30
31
  }
31
- }]
32
+ }],
33
+ nodePos: $from.before() // position before the selection
32
34
  };
33
35
  };
34
36
  const getSelectionInfoFromCellSelection = selection => {
35
37
  const selectedNode = selection.$anchorCell.node(-1);
38
+ const nodePos = selection.$anchorCell.before(-1);
36
39
  const selectionRanges = [];
37
40
  const rect = getSelectedRect(selection);
38
41
  for (let row = rect.top; row < rect.bottom; row++) {
@@ -47,14 +50,16 @@ const getSelectionInfoFromCellSelection = selection => {
47
50
  }
48
51
  return {
49
52
  selectedNode,
50
- selectionRanges
53
+ selectionRanges,
54
+ nodePos
51
55
  };
52
56
  };
53
57
  export const getSelectionInfo = state => {
54
58
  const selection = state.selection;
55
59
  let selectionInfo = {
56
60
  selectedNode: selection.$from.node(),
57
- selectionRanges: []
61
+ selectionRanges: [],
62
+ nodePos: selection.$from.before() // default to the position before the selection
58
63
  };
59
64
  if (selection instanceof TextSelection) {
60
65
  const {
@@ -70,9 +75,21 @@ export const getSelectionInfo = state => {
70
75
  selectionInfo = getSelectionInfoFromCellSelection(selection);
71
76
  }
72
77
  const serializer = new JSONTransformer();
73
- const selectedNodeAdf = serializer.encodeNode(selectionInfo.selectedNode);
78
+ const {
79
+ selectionRanges,
80
+ selectedNode,
81
+ nodePos
82
+ } = selectionInfo;
83
+ const selectedNodeAdf = serializer.encodeNode(selectedNode);
74
84
  return {
75
85
  selectedNodeAdf,
76
- selectionRanges: selectionInfo.selectionRanges
86
+ selectionRanges,
87
+ selectedNode,
88
+ nodePos
77
89
  };
90
+ };
91
+ export const validateSelectedNode = (selectedNodeAdf, selectedNode) => {
92
+ const serializer = new JSONTransformer();
93
+ const selectedNodeAdfFromState = serializer.encodeNode(selectedNode);
94
+ return isEqual(selectedNodeAdf, selectedNodeAdfFromState);
78
95
  };
@@ -2,8 +2,10 @@ import React from 'react';
2
2
  import { selectionExtensionMessages } from '@atlaskit/editor-common/messages';
3
3
  import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
4
4
  import { fg } from '@atlaskit/platform-feature-flags';
5
+ import { insertSmartLinks } from './pm-plugins/actions';
5
6
  import { createPlugin, selectionExtensionPluginKey } from './pm-plugins/main';
6
7
  import { getSelectionInfo } from './pm-plugins/utils';
8
+ import { SelectionExtensionActionTypes } from './types';
7
9
  import { SelectionExtensionComponentWrapper } from './ui/extension/SelectionExtensionComponentWrapper';
8
10
  import { getBoundingBoxFromSelection } from './ui/getBoundingBoxFromSelection';
9
11
  import { selectionToolbar } from './ui/selectionToolbar';
@@ -41,6 +43,21 @@ export const selectionExtensionPlugin = ({
41
43
  });
42
44
  }
43
45
  },
46
+ actions: {
47
+ insertSmartLinks: (linkInsertionOptions, selectedNodeAdf) => {
48
+ if (!editorViewRef.current) {
49
+ return {
50
+ status: 'error',
51
+ message: 'Editor view is not available'
52
+ };
53
+ }
54
+ const {
55
+ state,
56
+ dispatch
57
+ } = editorViewRef.current;
58
+ return insertSmartLinks(linkInsertionOptions, selectedNodeAdf)(state, dispatch);
59
+ }
60
+ },
44
61
  contentComponent: ({
45
62
  editorView
46
63
  }) => {
@@ -134,16 +151,28 @@ export const selectionExtensionPlugin = ({
134
151
  selection
135
152
  };
136
153
  if (fg('platform_editor_selection_extension_api_v2')) {
137
- var _extension$onClick;
154
+ var _extension$onClick, _api$core;
138
155
  const {
139
156
  selectedNodeAdf,
140
- selectionRanges
157
+ selectionRanges,
158
+ selectedNode,
159
+ nodePos
141
160
  } = getSelectionInfo(view.state);
142
161
  onClickCallbackOptions = {
143
162
  selectedNodeAdf,
144
163
  selectionRanges
145
164
  };
146
165
  (_extension$onClick = extension.onClick) === null || _extension$onClick === void 0 ? void 0 : _extension$onClick.call(extension, onClickCallbackOptions);
166
+ api === null || api === void 0 ? void 0 : (_api$core = api.core) === null || _api$core === void 0 ? void 0 : _api$core.actions.execute(({
167
+ tr
168
+ }) => {
169
+ tr.setMeta(selectionExtensionPluginKey, {
170
+ type: SelectionExtensionActionTypes.SET_SELECTED_NODE,
171
+ selectedNode,
172
+ nodePos
173
+ });
174
+ return tr;
175
+ });
147
176
  } else {
148
177
  if (extension.onClick) {
149
178
  extension.onClick(onClickCallbackOptions);
@@ -10,5 +10,7 @@ export let SelectionExtensionActionTypes = /*#__PURE__*/function (SelectionExten
10
10
  SelectionExtensionActionTypes["SET_ACTIVE_EXTENSION"] = "set-active-extension";
11
11
  SelectionExtensionActionTypes["UPDATE_ACTIVE_EXTENSION_COORDS"] = "update-active-extension-coords";
12
12
  SelectionExtensionActionTypes["CLEAR_ACTIVE_EXTENSION"] = "clear-active-extension";
13
+ SelectionExtensionActionTypes["SET_SELECTED_NODE"] = "set-selected-node";
14
+ SelectionExtensionActionTypes["START_TRACK_CHANGES"] = "start-track-changes";
13
15
  return SelectionExtensionActionTypes;
14
16
  }({});
@@ -1,10 +1,17 @@
1
1
  import React, { useCallback, useEffect, useRef } from 'react';
2
2
  import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
3
- import { useSharedPluginState, sharedPluginStateHookMigratorFactory } from '@atlaskit/editor-common/hooks';
4
- import { useSharedPluginStateSelector } from '@atlaskit/editor-common/use-shared-plugin-state-selector';
3
+ import { useSharedPluginState, sharedPluginStateHookMigratorFactory, useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
5
4
  const useSharedState = sharedPluginStateHookMigratorFactory(api => {
6
- const activeExtension = useSharedPluginStateSelector(api, 'selectionExtension.activeExtension');
7
- const mode = useSharedPluginStateSelector(api, 'editorViewMode.mode');
5
+ const {
6
+ activeExtension,
7
+ mode
8
+ } = useSharedPluginStateWithSelector(api, ['selectionExtension', 'editorViewMode'], states => {
9
+ var _states$selectionExte, _states$editorViewMod;
10
+ return {
11
+ activeExtension: (_states$selectionExte = states.selectionExtensionState) === null || _states$selectionExte === void 0 ? void 0 : _states$selectionExte.activeExtension,
12
+ mode: (_states$editorViewMod = states.editorViewModeState) === null || _states$editorViewMod === void 0 ? void 0 : _states$editorViewMod.mode
13
+ };
14
+ });
8
15
  return {
9
16
  editorViewModeState: undefined,
10
17
  mode,
@@ -0,0 +1,87 @@
1
+ import { SelectionExtensionActionTypes } from '../types';
2
+ import { selectionExtensionPluginKey } from './main';
3
+ import { validateSelectedNode } from './utils';
4
+ import { getOffsetByPath } from './utils/getOffsetByPath';
5
+ var insertLinkTr = function insertLinkTr(tr, link, offset, schema) {
6
+ var newFromPos = tr.mapping.map(offset.from);
7
+ var newToPos = tr.mapping.map(offset.to || offset.from);
8
+ var smartLink = schema.nodes.inlineCard.createChecked({
9
+ url: link
10
+ });
11
+ return tr.replaceWith(newFromPos, newToPos, smartLink);
12
+ };
13
+ export var insertSmartLinks = function insertSmartLinks(linkInsertionOption, selectedNodeAdf) {
14
+ return function (state, dispatch) {
15
+ var _selectionExtensionPl;
16
+ var tr = state.tr,
17
+ schema = state.schema;
18
+ if (!Array.isArray(linkInsertionOption)) {
19
+ linkInsertionOption = [linkInsertionOption];
20
+ }
21
+ if (linkInsertionOption.length === 0) {
22
+ return {
23
+ status: 'error',
24
+ message: 'No link insertion options provided'
25
+ };
26
+ }
27
+
28
+ // we need to track if any changes were made since user click the toolbar button
29
+ // if there is change, we insert the links at the bottom of the page instead
30
+ var docChangedAfterClick = ((_selectionExtensionPl = selectionExtensionPluginKey.getState(state)) === null || _selectionExtensionPl === void 0 ? void 0 : _selectionExtensionPl.docChangedAfterClick) || false;
31
+ if (docChangedAfterClick) {
32
+ var docEnd = state.doc.content.size;
33
+ linkInsertionOption.forEach(function (option) {
34
+ var link = option.link;
35
+ tr.insert(tr.mapping.map(docEnd), schema.nodes.inlineCard.createChecked({
36
+ url: link
37
+ }));
38
+ });
39
+ tr.setMeta(selectionExtensionPluginKey, {
40
+ type: SelectionExtensionActionTypes.START_TRACK_CHANGES,
41
+ startTrackChanges: false // Reset the flag when starting to track changes
42
+ });
43
+ dispatch(tr);
44
+ return {
45
+ status: 'success',
46
+ message: 'Links inserted to page bottom successfully'
47
+ };
48
+ }
49
+ var newTr = tr;
50
+ try {
51
+ var _selectionExtensionPl2, _selectionExtensionPl3;
52
+ var selectedNode = (_selectionExtensionPl2 = selectionExtensionPluginKey.getState(state)) === null || _selectionExtensionPl2 === void 0 ? void 0 : _selectionExtensionPl2.selectedNode;
53
+ var nodePos = (_selectionExtensionPl3 = selectionExtensionPluginKey.getState(state)) === null || _selectionExtensionPl3 === void 0 ? void 0 : _selectionExtensionPl3.nodePos;
54
+ if (!selectedNode || nodePos === undefined) {
55
+ throw new Error('No selected node or node position found');
56
+ }
57
+
58
+ // Validate if the selectedNodeAdf matches the selected node we have in the state
59
+ if (!validateSelectedNode(selectedNodeAdf, selectedNode)) {
60
+ throw new Error('Selected node ADF does not match the previous stored node');
61
+ }
62
+ linkInsertionOption.forEach(function (option) {
63
+ var link = option.link,
64
+ insertPosition = option.insertPosition;
65
+ var pointer = insertPosition.pointer,
66
+ from = insertPosition.from,
67
+ to = insertPosition.to;
68
+ var offset = getOffsetByPath(selectedNode, nodePos, pointer, from, to);
69
+ newTr = insertLinkTr(tr, link, offset, schema);
70
+ });
71
+ } catch (error) {
72
+ return {
73
+ status: 'error',
74
+ message: error instanceof Error ? error.message : 'Unknown error'
75
+ };
76
+ }
77
+ newTr.setMeta(selectionExtensionPluginKey, {
78
+ type: SelectionExtensionActionTypes.START_TRACK_CHANGES,
79
+ startTrackChanges: false // Reset the flag when starting to track changes
80
+ });
81
+ dispatch(newTr);
82
+ return {
83
+ status: 'success',
84
+ message: 'Links inserted successfully'
85
+ };
86
+ };
87
+ };
@@ -3,6 +3,7 @@ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbol
3
3
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
4
4
  import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
5
5
  import { PluginKey } from '@atlaskit/editor-prosemirror/state';
6
+ import { ReplaceAroundStep, ReplaceStep } from '@atlaskit/editor-prosemirror/transform';
6
7
  import { SelectionExtensionActionTypes } from '../types';
7
8
  export var selectionExtensionPluginKey = new PluginKey('selectionExtensionPlugin');
8
9
  export var createPlugin = function createPlugin() {
@@ -25,6 +26,26 @@ export var createPlugin = function createPlugin() {
25
26
  return _objectSpread(_objectSpread({}, pluginState), {}, {
26
27
  activeExtension: undefined
27
28
  });
29
+ case SelectionExtensionActionTypes.SET_SELECTED_NODE:
30
+ return _objectSpread(_objectSpread({}, pluginState), {}, {
31
+ selectedNode: meta.selectedNode,
32
+ nodePos: meta.nodePos,
33
+ startTrackChanges: true,
34
+ docChangedAfterClick: false // Reset the flag when starting to track changes
35
+ });
36
+ case SelectionExtensionActionTypes.START_TRACK_CHANGES:
37
+ return _objectSpread(_objectSpread({}, pluginState), {}, {
38
+ startTrackChanges: meta.startTrackChanges
39
+ });
40
+ }
41
+ var docChangedAfterClick = pluginState.startTrackChanges && tr.steps.some(function (step) {
42
+ return step instanceof ReplaceStep || step instanceof ReplaceAroundStep;
43
+ });
44
+ if (docChangedAfterClick) {
45
+ return _objectSpread(_objectSpread({}, pluginState), {}, {
46
+ docChangedAfterClick: true,
47
+ startTrackChanges: false // Reset the flag to stop tracking after the document has changed
48
+ });
28
49
  }
29
50
  return pluginState;
30
51
  }
@@ -0,0 +1,78 @@
1
+ import { Fragment, Node as PMNode } from '@atlaskit/editor-prosemirror/model';
2
+
3
+ // TODO: ED-28434 - move this to a shared package
4
+ // mirror code from https://bitbucket.org/atlassian/pf-adf-service/src/master/src/lib/update/get-offset.ts
5
+
6
+ export function getOffsetByPath(root, pos, pointer) {
7
+ var from = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
8
+ var to = arguments.length > 4 ? arguments[4] : undefined;
9
+ var parts = pointer.split('/');
10
+ var ref = root;
11
+ var len = parts.length;
12
+ // -1 to account for the root node (usually doc)
13
+ // The start of the document, right before the first content, is position 0.
14
+ var offset = pos; //-1;
15
+
16
+ for (var i = 1; i < len; i++) {
17
+ var key = parts[i];
18
+ if (ref instanceof Fragment && /^[0-9]+$/.test(key)) {
19
+ var index = parseInt(key, 10);
20
+ if (index >= ref.childCount) {
21
+ throw new Error("JSON pointer \"".concat(pointer, "\" points to non-existing location."));
22
+ }
23
+ var nextRef = ref.child(index);
24
+ while (index--) {
25
+ offset += ref.child(index).nodeSize;
26
+ }
27
+ ref = nextRef;
28
+ } else if (ref instanceof PMNode) {
29
+ /**
30
+ * Reference: https://prosemirror.net/docs/guide/#doc.data_structures
31
+ * +----------------------------------+
32
+ * | Node |
33
+ * | ^^^^ |
34
+ * | type: NodeType |
35
+ * | content: Fragment |
36
+ * | [ Node, Node, ...] |
37
+ * | attrs: Object |
38
+ * | marks: Mark |
39
+ * | [ |
40
+ * | type: MarkType |
41
+ * | attrs: Object |
42
+ * | ] |
43
+ * +----------------------------------+
44
+ */
45
+ switch (key) {
46
+ case 'content':
47
+ // Entering or leaving a node that is not a leaf node (i.e. supports content) counts as one token.
48
+ offset++;
49
+ ref = ref.content;
50
+ break;
51
+ case 'attrs':
52
+ return {
53
+ type: 'attrs',
54
+ from: offset + from,
55
+ path: parts.slice(i + 1)
56
+ };
57
+ case 'text':
58
+ if (!ref.isText) {
59
+ throw new Error("\"".concat(parts.slice(0, i).join('/'), "\" doesn't have any \"text\" node!"));
60
+ }
61
+ continue;
62
+ default:
63
+ throw new Error("JSON pointer \"".concat(pointer, "\" points to an unsupported location."));
64
+ }
65
+ } else {
66
+ throw new Error("JSON pointer \"".concat(pointer, "\" points to an unsupported entity."));
67
+ }
68
+ }
69
+ if (ref instanceof Fragment) {
70
+ throw new Error("Expected a Node, but the JSON pointer \"".concat(pointer, "\" points to a Fragment."));
71
+ }
72
+ return {
73
+ type: 'node',
74
+ from: offset + from,
75
+ to: offset + (to !== null && to !== void 0 ? to : ref.nodeSize),
76
+ matches: [to ? ref.textBetween(from, to) : ref.textContent]
77
+ };
78
+ }
@@ -1,3 +1,4 @@
1
+ import isEqual from 'lodash/isEqual';
1
2
  import { JSONTransformer } from '@atlaskit/editor-json-transformer';
2
3
  import { TextSelection } from '@atlaskit/editor-prosemirror/state';
3
4
  import { CellSelection, TableMap } from '@atlaskit/editor-tables';
@@ -24,11 +25,13 @@ var getSelectionInfoFromSameNode = function getSelectionInfoFromSameNode(selecti
24
25
  pointer: "/content/".concat($from.index(), "/text"),
25
26
  position: $to.parentOffset - 1
26
27
  }
27
- }]
28
+ }],
29
+ nodePos: $from.before() // position before the selection
28
30
  };
29
31
  };
30
32
  var getSelectionInfoFromCellSelection = function getSelectionInfoFromCellSelection(selection) {
31
33
  var selectedNode = selection.$anchorCell.node(-1);
34
+ var nodePos = selection.$anchorCell.before(-1);
32
35
  var selectionRanges = [];
33
36
  var rect = getSelectedRect(selection);
34
37
  for (var row = rect.top; row < rect.bottom; row++) {
@@ -43,14 +46,16 @@ var getSelectionInfoFromCellSelection = function getSelectionInfoFromCellSelecti
43
46
  }
44
47
  return {
45
48
  selectedNode: selectedNode,
46
- selectionRanges: selectionRanges
49
+ selectionRanges: selectionRanges,
50
+ nodePos: nodePos
47
51
  };
48
52
  };
49
53
  export var getSelectionInfo = function getSelectionInfo(state) {
50
54
  var selection = state.selection;
51
55
  var selectionInfo = {
52
56
  selectedNode: selection.$from.node(),
53
- selectionRanges: []
57
+ selectionRanges: [],
58
+ nodePos: selection.$from.before() // default to the position before the selection
54
59
  };
55
60
  if (selection instanceof TextSelection) {
56
61
  var $from = selection.$from,
@@ -64,9 +69,20 @@ export var getSelectionInfo = function getSelectionInfo(state) {
64
69
  selectionInfo = getSelectionInfoFromCellSelection(selection);
65
70
  }
66
71
  var serializer = new JSONTransformer();
67
- var selectedNodeAdf = serializer.encodeNode(selectionInfo.selectedNode);
72
+ var _selectionInfo = selectionInfo,
73
+ selectionRanges = _selectionInfo.selectionRanges,
74
+ selectedNode = _selectionInfo.selectedNode,
75
+ nodePos = _selectionInfo.nodePos;
76
+ var selectedNodeAdf = serializer.encodeNode(selectedNode);
68
77
  return {
69
78
  selectedNodeAdf: selectedNodeAdf,
70
- selectionRanges: selectionInfo.selectionRanges
79
+ selectionRanges: selectionRanges,
80
+ selectedNode: selectedNode,
81
+ nodePos: nodePos
71
82
  };
83
+ };
84
+ export var validateSelectedNode = function validateSelectedNode(selectedNodeAdf, selectedNode) {
85
+ var serializer = new JSONTransformer();
86
+ var selectedNodeAdfFromState = serializer.encodeNode(selectedNode);
87
+ return isEqual(selectedNodeAdf, selectedNodeAdfFromState);
72
88
  };
@@ -3,8 +3,10 @@ import React from 'react';
3
3
  import { selectionExtensionMessages } from '@atlaskit/editor-common/messages';
4
4
  import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
5
5
  import { fg } from '@atlaskit/platform-feature-flags';
6
+ import { insertSmartLinks as _insertSmartLinks } from './pm-plugins/actions';
6
7
  import { createPlugin, selectionExtensionPluginKey } from './pm-plugins/main';
7
8
  import { getSelectionInfo } from './pm-plugins/utils';
9
+ import { SelectionExtensionActionTypes } from './types';
8
10
  import { SelectionExtensionComponentWrapper } from './ui/extension/SelectionExtensionComponentWrapper';
9
11
  import { getBoundingBoxFromSelection } from './ui/getBoundingBoxFromSelection';
10
12
  import { selectionToolbar as _selectionToolbar } from './ui/selectionToolbar';
@@ -43,6 +45,20 @@ export var selectionExtensionPlugin = function selectionExtensionPlugin(_ref) {
43
45
  };
44
46
  }
45
47
  },
48
+ actions: {
49
+ insertSmartLinks: function insertSmartLinks(linkInsertionOptions, selectedNodeAdf) {
50
+ if (!editorViewRef.current) {
51
+ return {
52
+ status: 'error',
53
+ message: 'Editor view is not available'
54
+ };
55
+ }
56
+ var _editorViewRef$curren = editorViewRef.current,
57
+ state = _editorViewRef$curren.state,
58
+ dispatch = _editorViewRef$curren.dispatch;
59
+ return _insertSmartLinks(linkInsertionOptions, selectedNodeAdf)(state, dispatch);
60
+ }
61
+ },
46
62
  contentComponent: function contentComponent(_ref4) {
47
63
  var _api$analytics;
48
64
  var editorView = _ref4.editorView;
@@ -130,15 +146,26 @@ export var selectionExtensionPlugin = function selectionExtensionPlugin(_ref) {
130
146
  selection: selection
131
147
  };
132
148
  if (fg('platform_editor_selection_extension_api_v2')) {
133
- var _extension$onClick;
149
+ var _extension$onClick, _api$core;
134
150
  var _getSelectionInfo = getSelectionInfo(view.state),
135
151
  selectedNodeAdf = _getSelectionInfo.selectedNodeAdf,
136
- selectionRanges = _getSelectionInfo.selectionRanges;
152
+ selectionRanges = _getSelectionInfo.selectionRanges,
153
+ selectedNode = _getSelectionInfo.selectedNode,
154
+ nodePos = _getSelectionInfo.nodePos;
137
155
  onClickCallbackOptions = {
138
156
  selectedNodeAdf: selectedNodeAdf,
139
157
  selectionRanges: selectionRanges
140
158
  };
141
159
  (_extension$onClick = extension.onClick) === null || _extension$onClick === void 0 || _extension$onClick.call(extension, onClickCallbackOptions);
160
+ api === null || api === void 0 || (_api$core = api.core) === null || _api$core === void 0 || _api$core.actions.execute(function (_ref5) {
161
+ var tr = _ref5.tr;
162
+ tr.setMeta(selectionExtensionPluginKey, {
163
+ type: SelectionExtensionActionTypes.SET_SELECTED_NODE,
164
+ selectedNode: selectedNode,
165
+ nodePos: nodePos
166
+ });
167
+ return tr;
168
+ });
142
169
  } else {
143
170
  if (extension.onClick) {
144
171
  extension.onClick(onClickCallbackOptions);
@@ -10,5 +10,7 @@ export var SelectionExtensionActionTypes = /*#__PURE__*/function (SelectionExten
10
10
  SelectionExtensionActionTypes["SET_ACTIVE_EXTENSION"] = "set-active-extension";
11
11
  SelectionExtensionActionTypes["UPDATE_ACTIVE_EXTENSION_COORDS"] = "update-active-extension-coords";
12
12
  SelectionExtensionActionTypes["CLEAR_ACTIVE_EXTENSION"] = "clear-active-extension";
13
+ SelectionExtensionActionTypes["SET_SELECTED_NODE"] = "set-selected-node";
14
+ SelectionExtensionActionTypes["START_TRACK_CHANGES"] = "start-track-changes";
13
15
  return SelectionExtensionActionTypes;
14
16
  }({});
@@ -1,19 +1,25 @@
1
1
  import React, { useCallback, useEffect, useRef } from 'react';
2
2
  import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
3
- import { useSharedPluginState, sharedPluginStateHookMigratorFactory } from '@atlaskit/editor-common/hooks';
4
- import { useSharedPluginStateSelector } from '@atlaskit/editor-common/use-shared-plugin-state-selector';
3
+ import { useSharedPluginState, sharedPluginStateHookMigratorFactory, useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
5
4
  var useSharedState = sharedPluginStateHookMigratorFactory(function (api) {
6
- var activeExtension = useSharedPluginStateSelector(api, 'selectionExtension.activeExtension');
7
- var mode = useSharedPluginStateSelector(api, 'editorViewMode.mode');
5
+ var _useSharedPluginState = useSharedPluginStateWithSelector(api, ['selectionExtension', 'editorViewMode'], function (states) {
6
+ var _states$selectionExte, _states$editorViewMod;
7
+ return {
8
+ activeExtension: (_states$selectionExte = states.selectionExtensionState) === null || _states$selectionExte === void 0 ? void 0 : _states$selectionExte.activeExtension,
9
+ mode: (_states$editorViewMod = states.editorViewModeState) === null || _states$editorViewMod === void 0 ? void 0 : _states$editorViewMod.mode
10
+ };
11
+ }),
12
+ activeExtension = _useSharedPluginState.activeExtension,
13
+ mode = _useSharedPluginState.mode;
8
14
  return {
9
15
  editorViewModeState: undefined,
10
16
  mode: mode,
11
17
  activeExtension: activeExtension
12
18
  };
13
19
  }, function (api) {
14
- var _useSharedPluginState = useSharedPluginState(api, ['selectionExtension', 'editorViewMode']),
15
- selectionExtensionState = _useSharedPluginState.selectionExtensionState,
16
- editorViewModeState = _useSharedPluginState.editorViewModeState;
20
+ var _useSharedPluginState2 = useSharedPluginState(api, ['selectionExtension', 'editorViewMode']),
21
+ selectionExtensionState = _useSharedPluginState2.selectionExtensionState,
22
+ editorViewModeState = _useSharedPluginState2.editorViewModeState;
17
23
  return {
18
24
  editorViewModeState: editorViewModeState,
19
25
  mode: editorViewModeState === null || editorViewModeState === void 0 ? void 0 : editorViewModeState.mode,
@@ -0,0 +1,8 @@
1
+ import { type ADFEntity } from '@atlaskit/adf-utils/types';
2
+ import type { CommandDispatch } from '@atlaskit/editor-common/types';
3
+ import type { EditorState } from '@atlaskit/editor-prosemirror/state';
4
+ import { type LinkInsertionOption } from '../types';
5
+ export declare const insertSmartLinks: (linkInsertionOption: LinkInsertionOption | LinkInsertionOption[], selectedNodeAdf: ADFEntity) => (state: EditorState, dispatch: CommandDispatch) => {
6
+ status: 'success' | 'error';
7
+ message?: string;
8
+ };
@@ -4,4 +4,28 @@ import { type SelectionExtensionPluginState } from '../types';
4
4
  export declare const selectionExtensionPluginKey: PluginKey<SelectionExtensionPluginState>;
5
5
  export declare const createPlugin: () => SafePlugin<SelectionExtensionPluginState | {
6
6
  activeExtension: any;
7
+ selectedNode?: import("prosemirror-model").Node | undefined;
8
+ nodePos?: number | undefined;
9
+ startTrackChanges?: boolean | undefined;
10
+ docChangedAfterClick?: boolean | undefined;
11
+ } | {
12
+ selectedNode: any;
13
+ nodePos: any;
14
+ startTrackChanges: boolean;
15
+ docChangedAfterClick: boolean;
16
+ activeExtension?: {
17
+ extension: import("../types").SelectionExtension;
18
+ selection: import("../types").SelectionExtensionSelectionInfo;
19
+ coords: import("../types").SelectionExtensionCoords;
20
+ } | undefined;
21
+ } | {
22
+ startTrackChanges: any;
23
+ activeExtension?: {
24
+ extension: import("../types").SelectionExtension;
25
+ selection: import("../types").SelectionExtensionSelectionInfo;
26
+ coords: import("../types").SelectionExtensionCoords;
27
+ } | undefined;
28
+ selectedNode?: import("prosemirror-model").Node | undefined;
29
+ nodePos?: number | undefined;
30
+ docChangedAfterClick?: boolean | undefined;
7
31
  }>;
@@ -0,0 +1,14 @@
1
+ import { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
2
+ export interface NodeOffset {
3
+ type: 'node';
4
+ from: number;
5
+ to: number;
6
+ matches: string[];
7
+ }
8
+ export interface AttrsOffset {
9
+ type: 'attrs';
10
+ from: number;
11
+ path: string[];
12
+ }
13
+ export type Offset = NodeOffset | AttrsOffset;
14
+ export declare function getOffsetByPath(root: PMNode, pos: number, pointer: string, from?: number, to?: number): Offset;
@@ -1,3 +1,13 @@
1
+ import { type ADFEntity } from '@atlaskit/adf-utils/types';
2
+ import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
1
3
  import { type EditorState } from '@atlaskit/editor-prosemirror/state';
2
- import { type SelectionExtensionFnOptions } from '../../types';
3
- export declare const getSelectionInfo: (state: EditorState) => SelectionExtensionFnOptions;
4
+ import { type SelectionRange } from '../../types';
5
+ type SelectionInfo = {
6
+ selectedNodeAdf: ADFEntity;
7
+ selectionRanges: SelectionRange[];
8
+ selectedNode: PMNode;
9
+ nodePos: number;
10
+ };
11
+ export declare const getSelectionInfo: (state: EditorState) => SelectionInfo;
12
+ export declare const validateSelectedNode: (selectedNodeAdf: ADFEntity, selectedNode: PMNode) => boolean;
13
+ export {};
@@ -1,8 +1,9 @@
1
+ import { type ADFEntity } from '@atlaskit/adf-utils/types';
1
2
  import type { EditorCommand, NextEditorPlugin, OptionalPlugin } from '@atlaskit/editor-common/types';
2
3
  import type { AnalyticsPlugin } from '@atlaskit/editor-plugin-analytics';
3
4
  import type { EditorViewModePlugin } from '@atlaskit/editor-plugin-editor-viewmode';
4
5
  import type { SelectionToolbarPlugin } from '@atlaskit/editor-plugin-selection-toolbar';
5
- import type { SelectionExtension, SelectionExtensionPluginOptions, SelectionExtensionPluginState, SelectionExtensionSelectionInfo } from './types';
6
+ import type { LinkInsertionOption, SelectionExtension, SelectionExtensionPluginOptions, SelectionExtensionPluginState, SelectionExtensionSelectionInfo } from './types';
6
7
  export type SelectionExtensionPlugin = NextEditorPlugin<'selectionExtension', {
7
8
  pluginConfiguration: SelectionExtensionPluginOptions | undefined;
8
9
  dependencies: [
@@ -18,4 +19,10 @@ export type SelectionExtensionPlugin = NextEditorPlugin<'selectionExtension', {
18
19
  }) => EditorCommand;
19
20
  clearActiveExtension: () => EditorCommand;
20
21
  };
22
+ actions: {
23
+ insertSmartLinks: (linkInsertionOption: LinkInsertionOption | LinkInsertionOption[], selectedNodeAdf: ADFEntity) => {
24
+ status: 'success' | 'error';
25
+ message?: string;
26
+ };
27
+ };
21
28
  }>;
@@ -2,6 +2,7 @@
2
2
  import type { ADFEntity } from '@atlaskit/adf-utils/types';
3
3
  import { type MenuItem } from '@atlaskit/editor-common/ui-menu';
4
4
  import type { ViewMode } from '@atlaskit/editor-plugin-editor-viewmode';
5
+ import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
5
6
  export type MenuItemsType = Array<{
6
7
  items: MenuItem[];
7
8
  }>;
@@ -70,10 +71,21 @@ export type SelectionExtensionCoords = {
70
71
  top: number;
71
72
  bottom: number;
72
73
  };
74
+ export type InsertPosition = {
75
+ pointer: string;
76
+ from?: number;
77
+ to?: number;
78
+ };
79
+ export type LinkInsertionOption = {
80
+ link: string;
81
+ insertPosition: InsertPosition;
82
+ };
73
83
  export declare enum SelectionExtensionActionTypes {
74
84
  SET_ACTIVE_EXTENSION = "set-active-extension",
75
85
  UPDATE_ACTIVE_EXTENSION_COORDS = "update-active-extension-coords",
76
- CLEAR_ACTIVE_EXTENSION = "clear-active-extension"
86
+ CLEAR_ACTIVE_EXTENSION = "clear-active-extension",
87
+ SET_SELECTED_NODE = "set-selected-node",
88
+ START_TRACK_CHANGES = "start-track-changes"
77
89
  }
78
90
  export type UpdateActiveExtensionAction = {
79
91
  type: SelectionExtensionActionTypes.SET_ACTIVE_EXTENSION;
@@ -90,5 +102,9 @@ export type SelectionExtensionPluginState = {
90
102
  selection: SelectionExtensionSelectionInfo;
91
103
  coords: SelectionExtensionCoords;
92
104
  };
105
+ selectedNode?: PMNode;
106
+ nodePos?: number;
107
+ startTrackChanges?: boolean;
108
+ docChangedAfterClick?: boolean;
93
109
  };
94
110
  export {};