@atlaskit/editor-plugin-selection-extension 3.0.0 → 3.1.0
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 +14 -0
- package/dist/cjs/pm-plugins/actions.js +69 -0
- package/dist/cjs/pm-plugins/main.js +5 -0
- package/dist/cjs/pm-plugins/utils/getOffsetByPath.js +83 -0
- package/dist/cjs/pm-plugins/utils/index.js +23 -6
- package/dist/cjs/selectionExtensionPlugin.js +29 -2
- package/dist/cjs/types/index.js +1 -0
- package/dist/es2019/pm-plugins/actions.js +67 -0
- package/dist/es2019/pm-plugins/main.js +6 -0
- package/dist/es2019/pm-plugins/utils/getOffsetByPath.js +76 -0
- package/dist/es2019/pm-plugins/utils/index.js +22 -5
- package/dist/es2019/selectionExtensionPlugin.js +31 -2
- package/dist/es2019/types/index.js +1 -0
- package/dist/esm/pm-plugins/actions.js +63 -0
- package/dist/esm/pm-plugins/main.js +5 -0
- package/dist/esm/pm-plugins/utils/getOffsetByPath.js +78 -0
- package/dist/esm/pm-plugins/utils/index.js +21 -5
- package/dist/esm/selectionExtensionPlugin.js +29 -2
- package/dist/esm/types/index.js +1 -0
- package/dist/types/pm-plugins/actions.d.ts +8 -0
- package/dist/types/pm-plugins/main.d.ts +10 -0
- package/dist/types/pm-plugins/utils/getOffsetByPath.d.ts +14 -0
- package/dist/types/pm-plugins/utils/index.d.ts +12 -2
- package/dist/types/selectionExtensionPluginType.d.ts +8 -1
- package/dist/types/types/index.d.ts +14 -1
- package/dist/types-ts4.5/pm-plugins/actions.d.ts +8 -0
- package/dist/types-ts4.5/pm-plugins/main.d.ts +10 -0
- package/dist/types-ts4.5/pm-plugins/utils/getOffsetByPath.d.ts +14 -0
- package/dist/types-ts4.5/pm-plugins/utils/index.d.ts +12 -2
- package/dist/types-ts4.5/selectionExtensionPluginType.d.ts +8 -1
- package/dist/types-ts4.5/types/index.d.ts +14 -1
- package/package.json +5 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-selection-extension
|
|
2
2
|
|
|
3
|
+
## 3.1.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#181784](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/181784)
|
|
8
|
+
[`e3cd18b4fc263`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/e3cd18b4fc263) -
|
|
9
|
+
Create a new action insertSmartLinks to allow inserting multiple smart links in page
|
|
10
|
+
|
|
11
|
+
## 3.0.1
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- Updated dependencies
|
|
16
|
+
|
|
3
17
|
## 3.0.0
|
|
4
18
|
|
|
5
19
|
### Major Changes
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.insertSmartLinks = void 0;
|
|
7
|
+
var _main = require("./main");
|
|
8
|
+
var _utils = require("./utils");
|
|
9
|
+
var _getOffsetByPath = require("./utils/getOffsetByPath");
|
|
10
|
+
var insertLinkTr = function insertLinkTr(tr, link, offset, schema) {
|
|
11
|
+
var newFromPos = tr.mapping.map(offset.from);
|
|
12
|
+
var newToPos = tr.mapping.map(offset.to || offset.from);
|
|
13
|
+
var smartLink = schema.nodes.inlineCard.createChecked({
|
|
14
|
+
url: link
|
|
15
|
+
});
|
|
16
|
+
return tr.replaceWith(newFromPos, newToPos, smartLink);
|
|
17
|
+
};
|
|
18
|
+
var insertSmartLinks = exports.insertSmartLinks = function insertSmartLinks(linkInsertionOption, selectedNodeAdf) {
|
|
19
|
+
return function (state, dispatch) {
|
|
20
|
+
var tr = state.tr,
|
|
21
|
+
schema = state.schema;
|
|
22
|
+
if (!Array.isArray(linkInsertionOption)) {
|
|
23
|
+
linkInsertionOption = [linkInsertionOption];
|
|
24
|
+
}
|
|
25
|
+
if (linkInsertionOption.length === 0) {
|
|
26
|
+
return {
|
|
27
|
+
status: 'error',
|
|
28
|
+
message: 'No link insertion options provided'
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// TODO: ED-28365 - we need to track if any changes were made since user click the toolbar button
|
|
33
|
+
// if there is change, we should insert the link at the bottom of the page
|
|
34
|
+
|
|
35
|
+
var newTr = tr;
|
|
36
|
+
try {
|
|
37
|
+
var _selectionExtensionPl, _selectionExtensionPl2;
|
|
38
|
+
var selectedNode = (_selectionExtensionPl = _main.selectionExtensionPluginKey.getState(state)) === null || _selectionExtensionPl === void 0 ? void 0 : _selectionExtensionPl.selectedNode;
|
|
39
|
+
var nodePos = (_selectionExtensionPl2 = _main.selectionExtensionPluginKey.getState(state)) === null || _selectionExtensionPl2 === void 0 ? void 0 : _selectionExtensionPl2.nodePos;
|
|
40
|
+
if (!selectedNode || nodePos === undefined) {
|
|
41
|
+
throw new Error('No selected node or node position found');
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Validate if the selectedNodeAdf matches the selected node we have in the state
|
|
45
|
+
if (!(0, _utils.validateSelectedNode)(selectedNodeAdf, selectedNode)) {
|
|
46
|
+
throw new Error('Selected node ADF does not match the previous stored node');
|
|
47
|
+
}
|
|
48
|
+
linkInsertionOption.forEach(function (option) {
|
|
49
|
+
var link = option.link,
|
|
50
|
+
insertPosition = option.insertPosition;
|
|
51
|
+
var pointer = insertPosition.pointer,
|
|
52
|
+
from = insertPosition.from,
|
|
53
|
+
to = insertPosition.to;
|
|
54
|
+
var offset = (0, _getOffsetByPath.getOffsetByPath)(selectedNode, nodePos, pointer, from, to);
|
|
55
|
+
newTr = insertLinkTr(tr, link, offset, schema);
|
|
56
|
+
});
|
|
57
|
+
} catch (error) {
|
|
58
|
+
return {
|
|
59
|
+
status: 'error',
|
|
60
|
+
message: error instanceof Error ? error.message : 'Unknown error'
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
dispatch(newTr);
|
|
64
|
+
return {
|
|
65
|
+
status: 'success',
|
|
66
|
+
message: 'Links inserted successfully'
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
};
|
|
@@ -32,6 +32,11 @@ var createPlugin = exports.createPlugin = function createPlugin() {
|
|
|
32
32
|
return _objectSpread(_objectSpread({}, pluginState), {}, {
|
|
33
33
|
activeExtension: undefined
|
|
34
34
|
});
|
|
35
|
+
case _types.SelectionExtensionActionTypes.SET_SELECTED_NODE:
|
|
36
|
+
return _objectSpread(_objectSpread({}, pluginState), {}, {
|
|
37
|
+
selectedNode: meta.selectedNode,
|
|
38
|
+
nodePos: meta.nodePos
|
|
39
|
+
});
|
|
35
40
|
}
|
|
36
41
|
return pluginState;
|
|
37
42
|
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.getOffsetByPath = getOffsetByPath;
|
|
7
|
+
var _model = require("@atlaskit/editor-prosemirror/model");
|
|
8
|
+
// TODO: ED-28434 - move this to a shared package
|
|
9
|
+
// mirror code from https://bitbucket.org/atlassian/pf-adf-service/src/master/src/lib/update/get-offset.ts
|
|
10
|
+
|
|
11
|
+
function getOffsetByPath(root, pos, pointer) {
|
|
12
|
+
var from = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
|
|
13
|
+
var to = arguments.length > 4 ? arguments[4] : undefined;
|
|
14
|
+
var parts = pointer.split('/');
|
|
15
|
+
var ref = root;
|
|
16
|
+
var len = parts.length;
|
|
17
|
+
// -1 to account for the root node (usually doc)
|
|
18
|
+
// The start of the document, right before the first content, is position 0.
|
|
19
|
+
var offset = pos; //-1;
|
|
20
|
+
|
|
21
|
+
for (var i = 1; i < len; i++) {
|
|
22
|
+
var key = parts[i];
|
|
23
|
+
if (ref instanceof _model.Fragment && /^[0-9]+$/.test(key)) {
|
|
24
|
+
var index = parseInt(key, 10);
|
|
25
|
+
if (index >= ref.childCount) {
|
|
26
|
+
throw new Error("JSON pointer \"".concat(pointer, "\" points to non-existing location."));
|
|
27
|
+
}
|
|
28
|
+
var nextRef = ref.child(index);
|
|
29
|
+
while (index--) {
|
|
30
|
+
offset += ref.child(index).nodeSize;
|
|
31
|
+
}
|
|
32
|
+
ref = nextRef;
|
|
33
|
+
} else if (ref instanceof _model.Node) {
|
|
34
|
+
/**
|
|
35
|
+
* Reference: https://prosemirror.net/docs/guide/#doc.data_structures
|
|
36
|
+
* +----------------------------------+
|
|
37
|
+
* | Node |
|
|
38
|
+
* | ^^^^ |
|
|
39
|
+
* | type: NodeType |
|
|
40
|
+
* | content: Fragment |
|
|
41
|
+
* | [ Node, Node, ...] |
|
|
42
|
+
* | attrs: Object |
|
|
43
|
+
* | marks: Mark |
|
|
44
|
+
* | [ |
|
|
45
|
+
* | type: MarkType |
|
|
46
|
+
* | attrs: Object |
|
|
47
|
+
* | ] |
|
|
48
|
+
* +----------------------------------+
|
|
49
|
+
*/
|
|
50
|
+
switch (key) {
|
|
51
|
+
case 'content':
|
|
52
|
+
// Entering or leaving a node that is not a leaf node (i.e. supports content) counts as one token.
|
|
53
|
+
offset++;
|
|
54
|
+
ref = ref.content;
|
|
55
|
+
break;
|
|
56
|
+
case 'attrs':
|
|
57
|
+
return {
|
|
58
|
+
type: 'attrs',
|
|
59
|
+
from: offset + from,
|
|
60
|
+
path: parts.slice(i + 1)
|
|
61
|
+
};
|
|
62
|
+
case 'text':
|
|
63
|
+
if (!ref.isText) {
|
|
64
|
+
throw new Error("\"".concat(parts.slice(0, i).join('/'), "\" doesn't have any \"text\" node!"));
|
|
65
|
+
}
|
|
66
|
+
continue;
|
|
67
|
+
default:
|
|
68
|
+
throw new Error("JSON pointer \"".concat(pointer, "\" points to an unsupported location."));
|
|
69
|
+
}
|
|
70
|
+
} else {
|
|
71
|
+
throw new Error("JSON pointer \"".concat(pointer, "\" points to an unsupported entity."));
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
if (ref instanceof _model.Fragment) {
|
|
75
|
+
throw new Error("Expected a Node, but the JSON pointer \"".concat(pointer, "\" points to a Fragment."));
|
|
76
|
+
}
|
|
77
|
+
return {
|
|
78
|
+
type: 'node',
|
|
79
|
+
from: offset + from,
|
|
80
|
+
to: offset + (to !== null && to !== void 0 ? to : ref.nodeSize),
|
|
81
|
+
matches: [to ? ref.textBetween(from, to) : ref.textContent]
|
|
82
|
+
};
|
|
83
|
+
}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
3
4
|
Object.defineProperty(exports, "__esModule", {
|
|
4
5
|
value: true
|
|
5
6
|
});
|
|
6
|
-
exports.getSelectionInfo = void 0;
|
|
7
|
+
exports.validateSelectedNode = exports.getSelectionInfo = void 0;
|
|
8
|
+
var _isEqual = _interopRequireDefault(require("lodash/isEqual"));
|
|
7
9
|
var _editorJsonTransformer = require("@atlaskit/editor-json-transformer");
|
|
8
10
|
var _state = require("@atlaskit/editor-prosemirror/state");
|
|
9
11
|
var _editorTables = require("@atlaskit/editor-tables");
|
|
@@ -30,11 +32,13 @@ var getSelectionInfoFromSameNode = function getSelectionInfoFromSameNode(selecti
|
|
|
30
32
|
pointer: "/content/".concat($from.index(), "/text"),
|
|
31
33
|
position: $to.parentOffset - 1
|
|
32
34
|
}
|
|
33
|
-
}]
|
|
35
|
+
}],
|
|
36
|
+
nodePos: $from.before() // position before the selection
|
|
34
37
|
};
|
|
35
38
|
};
|
|
36
39
|
var getSelectionInfoFromCellSelection = function getSelectionInfoFromCellSelection(selection) {
|
|
37
40
|
var selectedNode = selection.$anchorCell.node(-1);
|
|
41
|
+
var nodePos = selection.$anchorCell.before(-1);
|
|
38
42
|
var selectionRanges = [];
|
|
39
43
|
var rect = getSelectedRect(selection);
|
|
40
44
|
for (var row = rect.top; row < rect.bottom; row++) {
|
|
@@ -49,14 +53,16 @@ var getSelectionInfoFromCellSelection = function getSelectionInfoFromCellSelecti
|
|
|
49
53
|
}
|
|
50
54
|
return {
|
|
51
55
|
selectedNode: selectedNode,
|
|
52
|
-
selectionRanges: selectionRanges
|
|
56
|
+
selectionRanges: selectionRanges,
|
|
57
|
+
nodePos: nodePos
|
|
53
58
|
};
|
|
54
59
|
};
|
|
55
60
|
var getSelectionInfo = exports.getSelectionInfo = function getSelectionInfo(state) {
|
|
56
61
|
var selection = state.selection;
|
|
57
62
|
var selectionInfo = {
|
|
58
63
|
selectedNode: selection.$from.node(),
|
|
59
|
-
selectionRanges: []
|
|
64
|
+
selectionRanges: [],
|
|
65
|
+
nodePos: selection.$from.before() // default to the position before the selection
|
|
60
66
|
};
|
|
61
67
|
if (selection instanceof _state.TextSelection) {
|
|
62
68
|
var $from = selection.$from,
|
|
@@ -70,9 +76,20 @@ var getSelectionInfo = exports.getSelectionInfo = function getSelectionInfo(stat
|
|
|
70
76
|
selectionInfo = getSelectionInfoFromCellSelection(selection);
|
|
71
77
|
}
|
|
72
78
|
var serializer = new _editorJsonTransformer.JSONTransformer();
|
|
73
|
-
var
|
|
79
|
+
var _selectionInfo = selectionInfo,
|
|
80
|
+
selectionRanges = _selectionInfo.selectionRanges,
|
|
81
|
+
selectedNode = _selectionInfo.selectedNode,
|
|
82
|
+
nodePos = _selectionInfo.nodePos;
|
|
83
|
+
var selectedNodeAdf = serializer.encodeNode(selectedNode);
|
|
74
84
|
return {
|
|
75
85
|
selectedNodeAdf: selectedNodeAdf,
|
|
76
|
-
selectionRanges:
|
|
86
|
+
selectionRanges: selectionRanges,
|
|
87
|
+
selectedNode: selectedNode,
|
|
88
|
+
nodePos: nodePos
|
|
77
89
|
};
|
|
90
|
+
};
|
|
91
|
+
var validateSelectedNode = exports.validateSelectedNode = function validateSelectedNode(selectedNodeAdf, selectedNode) {
|
|
92
|
+
var serializer = new _editorJsonTransformer.JSONTransformer();
|
|
93
|
+
var selectedNodeAdfFromState = serializer.encodeNode(selectedNode);
|
|
94
|
+
return (0, _isEqual.default)(selectedNodeAdf, selectedNodeAdfFromState);
|
|
78
95
|
};
|
|
@@ -10,8 +10,10 @@ var _react = _interopRequireDefault(require("react"));
|
|
|
10
10
|
var _messages = require("@atlaskit/editor-common/messages");
|
|
11
11
|
var _safePlugin = require("@atlaskit/editor-common/safe-plugin");
|
|
12
12
|
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
|
|
13
|
+
var _actions = require("./pm-plugins/actions");
|
|
13
14
|
var _main = require("./pm-plugins/main");
|
|
14
15
|
var _utils = require("./pm-plugins/utils");
|
|
16
|
+
var _types = require("./types");
|
|
15
17
|
var _SelectionExtensionComponentWrapper = require("./ui/extension/SelectionExtensionComponentWrapper");
|
|
16
18
|
var _getBoundingBoxFromSelection = require("./ui/getBoundingBoxFromSelection");
|
|
17
19
|
var _selectionToolbar2 = require("./ui/selectionToolbar");
|
|
@@ -50,6 +52,20 @@ var selectionExtensionPlugin = exports.selectionExtensionPlugin = function selec
|
|
|
50
52
|
};
|
|
51
53
|
}
|
|
52
54
|
},
|
|
55
|
+
actions: {
|
|
56
|
+
insertSmartLinks: function insertSmartLinks(linkInsertionOptions, selectedNodeAdf) {
|
|
57
|
+
if (!editorViewRef.current) {
|
|
58
|
+
return {
|
|
59
|
+
status: 'error',
|
|
60
|
+
message: 'Editor view is not available'
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
var _editorViewRef$curren = editorViewRef.current,
|
|
64
|
+
state = _editorViewRef$curren.state,
|
|
65
|
+
dispatch = _editorViewRef$curren.dispatch;
|
|
66
|
+
return (0, _actions.insertSmartLinks)(linkInsertionOptions, selectedNodeAdf)(state, dispatch);
|
|
67
|
+
}
|
|
68
|
+
},
|
|
53
69
|
contentComponent: function contentComponent(_ref4) {
|
|
54
70
|
var _api$analytics;
|
|
55
71
|
var editorView = _ref4.editorView;
|
|
@@ -137,15 +153,26 @@ var selectionExtensionPlugin = exports.selectionExtensionPlugin = function selec
|
|
|
137
153
|
selection: selection
|
|
138
154
|
};
|
|
139
155
|
if ((0, _platformFeatureFlags.fg)('platform_editor_selection_extension_api_v2')) {
|
|
140
|
-
var _extension$onClick;
|
|
156
|
+
var _extension$onClick, _api$core;
|
|
141
157
|
var _getSelectionInfo = (0, _utils.getSelectionInfo)(view.state),
|
|
142
158
|
selectedNodeAdf = _getSelectionInfo.selectedNodeAdf,
|
|
143
|
-
selectionRanges = _getSelectionInfo.selectionRanges
|
|
159
|
+
selectionRanges = _getSelectionInfo.selectionRanges,
|
|
160
|
+
selectedNode = _getSelectionInfo.selectedNode,
|
|
161
|
+
nodePos = _getSelectionInfo.nodePos;
|
|
144
162
|
onClickCallbackOptions = {
|
|
145
163
|
selectedNodeAdf: selectedNodeAdf,
|
|
146
164
|
selectionRanges: selectionRanges
|
|
147
165
|
};
|
|
148
166
|
(_extension$onClick = extension.onClick) === null || _extension$onClick === void 0 || _extension$onClick.call(extension, onClickCallbackOptions);
|
|
167
|
+
api === null || api === void 0 || (_api$core = api.core) === null || _api$core === void 0 || _api$core.actions.execute(function (_ref5) {
|
|
168
|
+
var tr = _ref5.tr;
|
|
169
|
+
tr.setMeta(_main.selectionExtensionPluginKey, {
|
|
170
|
+
type: _types.SelectionExtensionActionTypes.SET_SELECTED_NODE,
|
|
171
|
+
selectedNode: selectedNode,
|
|
172
|
+
nodePos: nodePos
|
|
173
|
+
});
|
|
174
|
+
return tr;
|
|
175
|
+
});
|
|
149
176
|
} else {
|
|
150
177
|
if (extension.onClick) {
|
|
151
178
|
extension.onClick(onClickCallbackOptions);
|
package/dist/cjs/types/index.js
CHANGED
|
@@ -14,5 +14,6 @@ var SelectionExtensionActionTypes = exports.SelectionExtensionActionTypes = /*#_
|
|
|
14
14
|
SelectionExtensionActionTypes["SET_ACTIVE_EXTENSION"] = "set-active-extension";
|
|
15
15
|
SelectionExtensionActionTypes["UPDATE_ACTIVE_EXTENSION_COORDS"] = "update-active-extension-coords";
|
|
16
16
|
SelectionExtensionActionTypes["CLEAR_ACTIVE_EXTENSION"] = "clear-active-extension";
|
|
17
|
+
SelectionExtensionActionTypes["SET_SELECTED_NODE"] = "set-selected-node";
|
|
17
18
|
return SelectionExtensionActionTypes;
|
|
18
19
|
}({});
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { selectionExtensionPluginKey } from './main';
|
|
2
|
+
import { validateSelectedNode } from './utils';
|
|
3
|
+
import { getOffsetByPath } from './utils/getOffsetByPath';
|
|
4
|
+
const insertLinkTr = (tr, link, offset, schema) => {
|
|
5
|
+
const newFromPos = tr.mapping.map(offset.from);
|
|
6
|
+
const newToPos = tr.mapping.map(offset.to || offset.from);
|
|
7
|
+
const smartLink = schema.nodes.inlineCard.createChecked({
|
|
8
|
+
url: link
|
|
9
|
+
});
|
|
10
|
+
return tr.replaceWith(newFromPos, newToPos, smartLink);
|
|
11
|
+
};
|
|
12
|
+
export const insertSmartLinks = (linkInsertionOption, selectedNodeAdf) => (state, dispatch) => {
|
|
13
|
+
const {
|
|
14
|
+
tr,
|
|
15
|
+
schema
|
|
16
|
+
} = state;
|
|
17
|
+
if (!Array.isArray(linkInsertionOption)) {
|
|
18
|
+
linkInsertionOption = [linkInsertionOption];
|
|
19
|
+
}
|
|
20
|
+
if (linkInsertionOption.length === 0) {
|
|
21
|
+
return {
|
|
22
|
+
status: 'error',
|
|
23
|
+
message: 'No link insertion options provided'
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// TODO: ED-28365 - we need to track if any changes were made since user click the toolbar button
|
|
28
|
+
// if there is change, we should insert the link at the bottom of the page
|
|
29
|
+
|
|
30
|
+
let newTr = tr;
|
|
31
|
+
try {
|
|
32
|
+
var _selectionExtensionPl, _selectionExtensionPl2;
|
|
33
|
+
const selectedNode = (_selectionExtensionPl = selectionExtensionPluginKey.getState(state)) === null || _selectionExtensionPl === void 0 ? void 0 : _selectionExtensionPl.selectedNode;
|
|
34
|
+
const nodePos = (_selectionExtensionPl2 = selectionExtensionPluginKey.getState(state)) === null || _selectionExtensionPl2 === void 0 ? void 0 : _selectionExtensionPl2.nodePos;
|
|
35
|
+
if (!selectedNode || nodePos === undefined) {
|
|
36
|
+
throw new Error('No selected node or node position found');
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Validate if the selectedNodeAdf matches the selected node we have in the state
|
|
40
|
+
if (!validateSelectedNode(selectedNodeAdf, selectedNode)) {
|
|
41
|
+
throw new Error('Selected node ADF does not match the previous stored node');
|
|
42
|
+
}
|
|
43
|
+
linkInsertionOption.forEach(option => {
|
|
44
|
+
const {
|
|
45
|
+
link,
|
|
46
|
+
insertPosition
|
|
47
|
+
} = option;
|
|
48
|
+
const {
|
|
49
|
+
pointer,
|
|
50
|
+
from,
|
|
51
|
+
to
|
|
52
|
+
} = insertPosition;
|
|
53
|
+
const offset = getOffsetByPath(selectedNode, nodePos, pointer, from, to);
|
|
54
|
+
newTr = insertLinkTr(tr, link, offset, schema);
|
|
55
|
+
});
|
|
56
|
+
} catch (error) {
|
|
57
|
+
return {
|
|
58
|
+
status: 'error',
|
|
59
|
+
message: error instanceof Error ? error.message : 'Unknown error'
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
dispatch(newTr);
|
|
63
|
+
return {
|
|
64
|
+
status: 'success',
|
|
65
|
+
message: 'Links inserted successfully'
|
|
66
|
+
};
|
|
67
|
+
};
|
|
@@ -24,6 +24,12 @@ export const createPlugin = () => {
|
|
|
24
24
|
...pluginState,
|
|
25
25
|
activeExtension: undefined
|
|
26
26
|
};
|
|
27
|
+
case SelectionExtensionActionTypes.SET_SELECTED_NODE:
|
|
28
|
+
return {
|
|
29
|
+
...pluginState,
|
|
30
|
+
selectedNode: meta.selectedNode,
|
|
31
|
+
nodePos: meta.nodePos
|
|
32
|
+
};
|
|
27
33
|
}
|
|
28
34
|
return pluginState;
|
|
29
35
|
}
|
|
@@ -0,0 +1,76 @@
|
|
|
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, from = 0, to) {
|
|
7
|
+
const parts = pointer.split('/');
|
|
8
|
+
let ref = root;
|
|
9
|
+
const len = parts.length;
|
|
10
|
+
// -1 to account for the root node (usually doc)
|
|
11
|
+
// The start of the document, right before the first content, is position 0.
|
|
12
|
+
let offset = pos; //-1;
|
|
13
|
+
|
|
14
|
+
for (let i = 1; i < len; i++) {
|
|
15
|
+
const key = parts[i];
|
|
16
|
+
if (ref instanceof Fragment && /^[0-9]+$/u.test(key)) {
|
|
17
|
+
let index = parseInt(key, 10);
|
|
18
|
+
if (index >= ref.childCount) {
|
|
19
|
+
throw new Error(`JSON pointer "${pointer}" points to non-existing location.`);
|
|
20
|
+
}
|
|
21
|
+
const nextRef = ref.child(index);
|
|
22
|
+
while (index--) {
|
|
23
|
+
offset += ref.child(index).nodeSize;
|
|
24
|
+
}
|
|
25
|
+
ref = nextRef;
|
|
26
|
+
} else if (ref instanceof PMNode) {
|
|
27
|
+
/**
|
|
28
|
+
* Reference: https://prosemirror.net/docs/guide/#doc.data_structures
|
|
29
|
+
* +----------------------------------+
|
|
30
|
+
* | Node |
|
|
31
|
+
* | ^^^^ |
|
|
32
|
+
* | type: NodeType |
|
|
33
|
+
* | content: Fragment |
|
|
34
|
+
* | [ Node, Node, ...] |
|
|
35
|
+
* | attrs: Object |
|
|
36
|
+
* | marks: Mark |
|
|
37
|
+
* | [ |
|
|
38
|
+
* | type: MarkType |
|
|
39
|
+
* | attrs: Object |
|
|
40
|
+
* | ] |
|
|
41
|
+
* +----------------------------------+
|
|
42
|
+
*/
|
|
43
|
+
switch (key) {
|
|
44
|
+
case 'content':
|
|
45
|
+
// Entering or leaving a node that is not a leaf node (i.e. supports content) counts as one token.
|
|
46
|
+
offset++;
|
|
47
|
+
ref = ref.content;
|
|
48
|
+
break;
|
|
49
|
+
case 'attrs':
|
|
50
|
+
return {
|
|
51
|
+
type: 'attrs',
|
|
52
|
+
from: offset + from,
|
|
53
|
+
path: parts.slice(i + 1)
|
|
54
|
+
};
|
|
55
|
+
case 'text':
|
|
56
|
+
if (!ref.isText) {
|
|
57
|
+
throw new Error(`"${parts.slice(0, i).join('/')}" doesn't have any "text" node!`);
|
|
58
|
+
}
|
|
59
|
+
continue;
|
|
60
|
+
default:
|
|
61
|
+
throw new Error(`JSON pointer "${pointer}" points to an unsupported location.`);
|
|
62
|
+
}
|
|
63
|
+
} else {
|
|
64
|
+
throw new Error(`JSON pointer "${pointer}" points to an unsupported entity.`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
if (ref instanceof Fragment) {
|
|
68
|
+
throw new Error(`Expected a Node, but the JSON pointer "${pointer}" points to a Fragment.`);
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
type: 'node',
|
|
72
|
+
from: offset + from,
|
|
73
|
+
to: offset + (to !== null && to !== void 0 ? to : ref.nodeSize),
|
|
74
|
+
matches: [to ? ref.textBetween(from, to) : ref.textContent]
|
|
75
|
+
};
|
|
76
|
+
}
|
|
@@ -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
|
|
78
|
+
const {
|
|
79
|
+
selectionRanges,
|
|
80
|
+
selectedNode,
|
|
81
|
+
nodePos
|
|
82
|
+
} = selectionInfo;
|
|
83
|
+
const selectedNodeAdf = serializer.encodeNode(selectedNode);
|
|
74
84
|
return {
|
|
75
85
|
selectedNodeAdf,
|
|
76
|
-
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,6 @@ 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";
|
|
13
14
|
return SelectionExtensionActionTypes;
|
|
14
15
|
}({});
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { selectionExtensionPluginKey } from './main';
|
|
2
|
+
import { validateSelectedNode } from './utils';
|
|
3
|
+
import { getOffsetByPath } from './utils/getOffsetByPath';
|
|
4
|
+
var insertLinkTr = function insertLinkTr(tr, link, offset, schema) {
|
|
5
|
+
var newFromPos = tr.mapping.map(offset.from);
|
|
6
|
+
var newToPos = tr.mapping.map(offset.to || offset.from);
|
|
7
|
+
var smartLink = schema.nodes.inlineCard.createChecked({
|
|
8
|
+
url: link
|
|
9
|
+
});
|
|
10
|
+
return tr.replaceWith(newFromPos, newToPos, smartLink);
|
|
11
|
+
};
|
|
12
|
+
export var insertSmartLinks = function insertSmartLinks(linkInsertionOption, selectedNodeAdf) {
|
|
13
|
+
return function (state, dispatch) {
|
|
14
|
+
var tr = state.tr,
|
|
15
|
+
schema = state.schema;
|
|
16
|
+
if (!Array.isArray(linkInsertionOption)) {
|
|
17
|
+
linkInsertionOption = [linkInsertionOption];
|
|
18
|
+
}
|
|
19
|
+
if (linkInsertionOption.length === 0) {
|
|
20
|
+
return {
|
|
21
|
+
status: 'error',
|
|
22
|
+
message: 'No link insertion options provided'
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// TODO: ED-28365 - we need to track if any changes were made since user click the toolbar button
|
|
27
|
+
// if there is change, we should insert the link at the bottom of the page
|
|
28
|
+
|
|
29
|
+
var newTr = tr;
|
|
30
|
+
try {
|
|
31
|
+
var _selectionExtensionPl, _selectionExtensionPl2;
|
|
32
|
+
var selectedNode = (_selectionExtensionPl = selectionExtensionPluginKey.getState(state)) === null || _selectionExtensionPl === void 0 ? void 0 : _selectionExtensionPl.selectedNode;
|
|
33
|
+
var nodePos = (_selectionExtensionPl2 = selectionExtensionPluginKey.getState(state)) === null || _selectionExtensionPl2 === void 0 ? void 0 : _selectionExtensionPl2.nodePos;
|
|
34
|
+
if (!selectedNode || nodePos === undefined) {
|
|
35
|
+
throw new Error('No selected node or node position found');
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Validate if the selectedNodeAdf matches the selected node we have in the state
|
|
39
|
+
if (!validateSelectedNode(selectedNodeAdf, selectedNode)) {
|
|
40
|
+
throw new Error('Selected node ADF does not match the previous stored node');
|
|
41
|
+
}
|
|
42
|
+
linkInsertionOption.forEach(function (option) {
|
|
43
|
+
var link = option.link,
|
|
44
|
+
insertPosition = option.insertPosition;
|
|
45
|
+
var pointer = insertPosition.pointer,
|
|
46
|
+
from = insertPosition.from,
|
|
47
|
+
to = insertPosition.to;
|
|
48
|
+
var offset = getOffsetByPath(selectedNode, nodePos, pointer, from, to);
|
|
49
|
+
newTr = insertLinkTr(tr, link, offset, schema);
|
|
50
|
+
});
|
|
51
|
+
} catch (error) {
|
|
52
|
+
return {
|
|
53
|
+
status: 'error',
|
|
54
|
+
message: error instanceof Error ? error.message : 'Unknown error'
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
dispatch(newTr);
|
|
58
|
+
return {
|
|
59
|
+
status: 'success',
|
|
60
|
+
message: 'Links inserted successfully'
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
};
|
|
@@ -25,6 +25,11 @@ export var createPlugin = function createPlugin() {
|
|
|
25
25
|
return _objectSpread(_objectSpread({}, pluginState), {}, {
|
|
26
26
|
activeExtension: undefined
|
|
27
27
|
});
|
|
28
|
+
case SelectionExtensionActionTypes.SET_SELECTED_NODE:
|
|
29
|
+
return _objectSpread(_objectSpread({}, pluginState), {}, {
|
|
30
|
+
selectedNode: meta.selectedNode,
|
|
31
|
+
nodePos: meta.nodePos
|
|
32
|
+
});
|
|
28
33
|
}
|
|
29
34
|
return pluginState;
|
|
30
35
|
}
|
|
@@ -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
|
|
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:
|
|
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);
|
package/dist/esm/types/index.js
CHANGED
|
@@ -10,5 +10,6 @@ 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";
|
|
13
14
|
return SelectionExtensionActionTypes;
|
|
14
15
|
}({});
|
|
@@ -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,14 @@ 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
|
+
} | {
|
|
10
|
+
selectedNode: any;
|
|
11
|
+
nodePos: any;
|
|
12
|
+
activeExtension?: {
|
|
13
|
+
extension: import("../types").SelectionExtension;
|
|
14
|
+
selection: import("../types").SelectionExtensionSelectionInfo;
|
|
15
|
+
coords: import("../types").SelectionExtensionCoords;
|
|
16
|
+
} | undefined;
|
|
7
17
|
}>;
|
|
@@ -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
|
|
3
|
-
|
|
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,20 @@ 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"
|
|
77
88
|
}
|
|
78
89
|
export type UpdateActiveExtensionAction = {
|
|
79
90
|
type: SelectionExtensionActionTypes.SET_ACTIVE_EXTENSION;
|
|
@@ -90,5 +101,7 @@ export type SelectionExtensionPluginState = {
|
|
|
90
101
|
selection: SelectionExtensionSelectionInfo;
|
|
91
102
|
coords: SelectionExtensionCoords;
|
|
92
103
|
};
|
|
104
|
+
selectedNode?: PMNode;
|
|
105
|
+
nodePos?: number;
|
|
93
106
|
};
|
|
94
107
|
export {};
|
|
@@ -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,14 @@ 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
|
+
} | {
|
|
10
|
+
selectedNode: any;
|
|
11
|
+
nodePos: any;
|
|
12
|
+
activeExtension?: {
|
|
13
|
+
extension: import("../types").SelectionExtension;
|
|
14
|
+
selection: import("../types").SelectionExtensionSelectionInfo;
|
|
15
|
+
coords: import("../types").SelectionExtensionCoords;
|
|
16
|
+
} | undefined;
|
|
7
17
|
}>;
|
|
@@ -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
|
|
3
|
-
|
|
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,20 @@ 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"
|
|
77
88
|
}
|
|
78
89
|
export type UpdateActiveExtensionAction = {
|
|
79
90
|
type: SelectionExtensionActionTypes.SET_ACTIVE_EXTENSION;
|
|
@@ -90,5 +101,7 @@ export type SelectionExtensionPluginState = {
|
|
|
90
101
|
selection: SelectionExtensionSelectionInfo;
|
|
91
102
|
coords: SelectionExtensionCoords;
|
|
92
103
|
};
|
|
104
|
+
selectedNode?: PMNode;
|
|
105
|
+
nodePos?: number;
|
|
93
106
|
};
|
|
94
107
|
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-selection-extension",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.1.0",
|
|
4
4
|
"description": "editor-plugin-selection-extension plugin for @atlaskit/editor-core",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -42,16 +42,17 @@
|
|
|
42
42
|
"@atlaskit/editor-plugin-selection-toolbar": "^4.0.0",
|
|
43
43
|
"@atlaskit/editor-prosemirror": "7.0.0",
|
|
44
44
|
"@atlaskit/editor-tables": "^2.9.0",
|
|
45
|
-
"@atlaskit/icon": "^27.
|
|
45
|
+
"@atlaskit/icon": "^27.3.0",
|
|
46
46
|
"@atlaskit/platform-feature-flags": "^1.1.0",
|
|
47
47
|
"@atlaskit/primitives": "^14.10.0",
|
|
48
|
-
"@atlaskit/tmp-editor-statsig": "^
|
|
48
|
+
"@atlaskit/tmp-editor-statsig": "^9.0.0",
|
|
49
49
|
"@babel/runtime": "^7.0.0",
|
|
50
|
+
"lodash": "^4.17.21",
|
|
50
51
|
"react-intl-next": "npm:react-intl@^5.18.1",
|
|
51
52
|
"uuid": "^3.1.0"
|
|
52
53
|
},
|
|
53
54
|
"peerDependencies": {
|
|
54
|
-
"@atlaskit/editor-common": "^107.
|
|
55
|
+
"@atlaskit/editor-common": "^107.7.0",
|
|
55
56
|
"react": "^18.2.0"
|
|
56
57
|
},
|
|
57
58
|
"devDependencies": {
|