@atlaskit/editor-plugin-selection-extension 3.4.0 → 3.4.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.
- package/CHANGELOG.md +9 -0
- package/dist/cjs/selectionExtensionPlugin.js +66 -34
- package/dist/cjs/ui/LegacyToolbarComponent.js +120 -0
- package/dist/cjs/ui/extensions.js +60 -0
- package/dist/cjs/ui/selectionToolbar.js +32 -5
- package/dist/es2019/selectionExtensionPlugin.js +54 -26
- package/dist/es2019/ui/LegacyToolbarComponent.js +109 -0
- package/dist/es2019/ui/extensions.js +54 -0
- package/dist/es2019/ui/selectionToolbar.js +38 -14
- package/dist/esm/selectionExtensionPlugin.js +66 -34
- package/dist/esm/ui/LegacyToolbarComponent.js +111 -0
- package/dist/esm/ui/extensions.js +54 -0
- package/dist/esm/ui/selectionToolbar.js +31 -5
- package/dist/types/index.d.ts +1 -1
- package/dist/types/selectionExtensionPluginType.d.ts +2 -0
- package/dist/types/types/index.d.ts +37 -1
- package/dist/types/ui/LegacyToolbarComponent.d.ts +16 -0
- package/dist/types/ui/extensions.d.ts +27 -0
- package/dist/types/ui/selectionToolbar.d.ts +7 -17
- package/dist/types-ts4.5/index.d.ts +1 -1
- package/dist/types-ts4.5/selectionExtensionPluginType.d.ts +2 -0
- package/dist/types-ts4.5/types/index.d.ts +37 -1
- package/dist/types-ts4.5/ui/LegacyToolbarComponent.d.ts +16 -0
- package/dist/types-ts4.5/ui/extensions.d.ts +27 -0
- package/dist/types-ts4.5/ui/selectionToolbar.d.ts +7 -17
- package/package.json +4 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-selection-extension
|
|
2
2
|
|
|
3
|
+
## 3.4.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#192343](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/192343)
|
|
8
|
+
[`9cb0878241016`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/9cb0878241016) -
|
|
9
|
+
ED-28736 more extensible selection extensions API
|
|
10
|
+
- Updated dependencies
|
|
11
|
+
|
|
3
12
|
## 3.4.0
|
|
4
13
|
|
|
5
14
|
### Minor Changes
|
|
@@ -17,7 +17,9 @@ var _main = require("./pm-plugins/main");
|
|
|
17
17
|
var _utils = require("./pm-plugins/utils");
|
|
18
18
|
var _types = require("./types");
|
|
19
19
|
var _SelectionExtensionComponentWrapper = require("./ui/extension/SelectionExtensionComponentWrapper");
|
|
20
|
+
var _extensions = require("./ui/extensions");
|
|
20
21
|
var _getBoundingBoxFromSelection = require("./ui/getBoundingBoxFromSelection");
|
|
22
|
+
var _LegacyToolbarComponent = require("./ui/LegacyToolbarComponent");
|
|
21
23
|
var _selectionToolbar2 = require("./ui/selectionToolbar");
|
|
22
24
|
var selectionExtensionPlugin = exports.selectionExtensionPlugin = function selectionExtensionPlugin(_ref) {
|
|
23
25
|
var api = _ref.api,
|
|
@@ -27,6 +29,30 @@ var selectionExtensionPlugin = exports.selectionExtensionPlugin = function selec
|
|
|
27
29
|
};
|
|
28
30
|
var cachedSelection;
|
|
29
31
|
var cachedOverflowMenuOptions;
|
|
32
|
+
var _ref2 = config || {},
|
|
33
|
+
_ref2$extensionList = _ref2.extensionList,
|
|
34
|
+
extensionList = _ref2$extensionList === void 0 ? [] : _ref2$extensionList,
|
|
35
|
+
_ref2$extensions = _ref2.extensions,
|
|
36
|
+
extensions = _ref2$extensions === void 0 ? {} : _ref2$extensions;
|
|
37
|
+
var _ref3 = extensions || {},
|
|
38
|
+
_ref3$firstParty = _ref3.firstParty,
|
|
39
|
+
firstParty = _ref3$firstParty === void 0 ? [] : _ref3$firstParty,
|
|
40
|
+
_ref3$external = _ref3.external,
|
|
41
|
+
external = _ref3$external === void 0 ? [] : _ref3$external;
|
|
42
|
+
if ((0, _platformFeatureFlags.fg)('platform_editor_selection_extension_api_v2')) {
|
|
43
|
+
var primaryToolbarItemExtensions = (0, _extensions.getToolbarItemExtensions)(extensionList, 'primaryToolbar');
|
|
44
|
+
if (primaryToolbarItemExtensions !== null && primaryToolbarItemExtensions !== void 0 && primaryToolbarItemExtensions.length) {
|
|
45
|
+
var _api$primaryToolbar;
|
|
46
|
+
api === null || api === void 0 || (_api$primaryToolbar = api.primaryToolbar) === null || _api$primaryToolbar === void 0 || (_api$primaryToolbar = _api$primaryToolbar.actions) === null || _api$primaryToolbar === void 0 || _api$primaryToolbar.registerComponent({
|
|
47
|
+
name: 'selectionExtension',
|
|
48
|
+
component: function component() {
|
|
49
|
+
return /*#__PURE__*/_react.default.createElement(_LegacyToolbarComponent.LegacyPrimaryToolbarComponent, {
|
|
50
|
+
primaryToolbarItemExtensions: primaryToolbarItemExtensions
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
}
|
|
30
56
|
return {
|
|
31
57
|
name: 'selectionExtension',
|
|
32
58
|
getSharedState: function getSharedState(editorState) {
|
|
@@ -37,8 +63,8 @@ var selectionExtensionPlugin = exports.selectionExtensionPlugin = function selec
|
|
|
37
63
|
},
|
|
38
64
|
commands: {
|
|
39
65
|
setActiveExtension: function setActiveExtension(extension) {
|
|
40
|
-
return function (
|
|
41
|
-
var tr =
|
|
66
|
+
return function (_ref4) {
|
|
67
|
+
var tr = _ref4.tr;
|
|
42
68
|
return tr.setMeta(_main.selectionExtensionPluginKey, {
|
|
43
69
|
type: 'set-active-extension',
|
|
44
70
|
extension: extension
|
|
@@ -46,8 +72,8 @@ var selectionExtensionPlugin = exports.selectionExtensionPlugin = function selec
|
|
|
46
72
|
};
|
|
47
73
|
},
|
|
48
74
|
clearActiveExtension: function clearActiveExtension() {
|
|
49
|
-
return function (
|
|
50
|
-
var tr =
|
|
75
|
+
return function (_ref5) {
|
|
76
|
+
var tr = _ref5.tr;
|
|
51
77
|
return tr.setMeta(_main.selectionExtensionPluginKey, {
|
|
52
78
|
type: 'clear-active-extension'
|
|
53
79
|
});
|
|
@@ -89,10 +115,14 @@ var selectionExtensionPlugin = exports.selectionExtensionPlugin = function selec
|
|
|
89
115
|
dispatch = _editorViewRef$curren3.dispatch;
|
|
90
116
|
return (0, _insertAdfAtEndOfDoc2.insertAdfAtEndOfDoc)(nodeAdf)(state, dispatch);
|
|
91
117
|
}
|
|
118
|
+
// NEXT PR: Implement this to return selectedNodeAdf, selectionRanges
|
|
119
|
+
// getSelectionAdf: () => {},
|
|
120
|
+
// NEXT PR: Implement this to return text, coords
|
|
121
|
+
// getSelectionText: () => {},
|
|
92
122
|
},
|
|
93
|
-
contentComponent: function contentComponent(
|
|
123
|
+
contentComponent: function contentComponent(_ref6) {
|
|
94
124
|
var _api$analytics;
|
|
95
|
-
var editorView =
|
|
125
|
+
var editorView = _ref6.editorView;
|
|
96
126
|
return /*#__PURE__*/_react.default.createElement(_SelectionExtensionComponentWrapper.SelectionExtensionComponentWrapper, {
|
|
97
127
|
editorView: editorView,
|
|
98
128
|
api: api,
|
|
@@ -105,25 +135,17 @@ var selectionExtensionPlugin = exports.selectionExtensionPlugin = function selec
|
|
|
105
135
|
if (!config) {
|
|
106
136
|
return;
|
|
107
137
|
}
|
|
108
|
-
var pageModes = config.pageModes
|
|
109
|
-
extensions = config.extensions;
|
|
138
|
+
var pageModes = config.pageModes;
|
|
110
139
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
* Check whether plugin contains any selection extensions
|
|
115
|
-
*/
|
|
116
|
-
if ((!(extensions !== null && extensions !== void 0 && extensions.firstParty) || extensions.firstParty.length === 0) && (!(extensions !== null && extensions !== void 0 && extensions.external) || extensions.external.length === 0)) {
|
|
140
|
+
// Extensions Config Validation
|
|
141
|
+
// Check whether plugin contains any selection extensions
|
|
142
|
+
if (!(firstParty !== null && firstParty !== void 0 && firstParty.length) && !(external !== null && external !== void 0 && external.length) && !(extensionList !== null && extensionList !== void 0 && extensionList.length)) {
|
|
117
143
|
return;
|
|
118
144
|
}
|
|
119
145
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
* Check if pageModes is provided and matches against current content mode
|
|
124
|
-
*
|
|
125
|
-
* TODO: This will eventially transition from mode to contentMode
|
|
126
|
-
*/
|
|
146
|
+
// Content Mode Validation
|
|
147
|
+
// Check if pageModes is provided and matches against current content mode
|
|
148
|
+
// This will eventially transition from mode to contentMode
|
|
127
149
|
var editorContentMode = api === null || api === void 0 || (_api$editorViewMode = api.editorViewMode) === null || _api$editorViewMode === void 0 || (_api$editorViewMode = _api$editorViewMode.sharedState.currentState()) === null || _api$editorViewMode === void 0 ? void 0 : _api$editorViewMode.mode;
|
|
128
150
|
if (pageModes) {
|
|
129
151
|
// Early Exit: consumer has set pageModes but editorContentMode is undefined
|
|
@@ -140,11 +162,8 @@ var selectionExtensionPlugin = exports.selectionExtensionPlugin = function selec
|
|
|
140
162
|
}
|
|
141
163
|
}
|
|
142
164
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
*
|
|
146
|
-
* Check if there is an active extension and hide the selection extension dropdown
|
|
147
|
-
*/
|
|
165
|
+
// Active Extension
|
|
166
|
+
// Check if there is an active extension and hide the selection extension dropdown
|
|
148
167
|
var selectionExtensionState = _main.selectionExtensionPluginKey.getState(state);
|
|
149
168
|
if (selectionExtensionState !== null && selectionExtensionState !== void 0 && selectionExtensionState.activeExtension) {
|
|
150
169
|
return;
|
|
@@ -187,8 +206,8 @@ var selectionExtensionPlugin = exports.selectionExtensionPlugin = function selec
|
|
|
187
206
|
selectionRanges: selectionRanges
|
|
188
207
|
};
|
|
189
208
|
(_extension$onClick = extension.onClick) === null || _extension$onClick === void 0 || _extension$onClick.call(extension, onClickCallbackOptions);
|
|
190
|
-
api === null || api === void 0 || (_api$core = api.core) === null || _api$core === void 0 || _api$core.actions.execute(function (
|
|
191
|
-
var tr =
|
|
209
|
+
api === null || api === void 0 || (_api$core = api.core) === null || _api$core === void 0 || _api$core.actions.execute(function (_ref7) {
|
|
210
|
+
var tr = _ref7.tr;
|
|
192
211
|
tr.setMeta(_main.selectionExtensionPluginKey, {
|
|
193
212
|
type: _types.SelectionExtensionActionTypes.SET_SELECTED_NODE,
|
|
194
213
|
selectedNode: selectedNode,
|
|
@@ -251,9 +270,7 @@ var selectionExtensionPlugin = exports.selectionExtensionPlugin = function selec
|
|
|
251
270
|
});
|
|
252
271
|
};
|
|
253
272
|
|
|
254
|
-
|
|
255
|
-
* Add a heading to the external extensions
|
|
256
|
-
*/
|
|
273
|
+
// Add a heading to the external extensions
|
|
257
274
|
var getExternalExtensions = function getExternalExtensions(extensions) {
|
|
258
275
|
var prefilteredExtensions = prefilterExtensions(extensions);
|
|
259
276
|
var externalExtensions = [];
|
|
@@ -270,13 +287,28 @@ var selectionExtensionPlugin = exports.selectionExtensionPlugin = function selec
|
|
|
270
287
|
}
|
|
271
288
|
return externalExtensions;
|
|
272
289
|
};
|
|
290
|
+
|
|
291
|
+
// NEXT PR: Make sure we cache the whole generated selection toolbar
|
|
292
|
+
// also debug this to make sure it's actually preventing unnecessary re-renders / work
|
|
273
293
|
if (cachedOverflowMenuOptions && state.selection.eq(cachedSelection) && (0, _platformFeatureFlags.fg)('platform_editor_selection_extension_api_v2')) {
|
|
274
|
-
return (0, _selectionToolbar2.selectionToolbar)(
|
|
294
|
+
return (0, _selectionToolbar2.selectionToolbar)({
|
|
295
|
+
overflowOptions: cachedOverflowMenuOptions,
|
|
296
|
+
extensionList: extensionList
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
var allFirstParty = (0, _toConsumableArray2.default)(firstParty);
|
|
300
|
+
var allExternal = (0, _toConsumableArray2.default)(external);
|
|
301
|
+
if ((0, _platformFeatureFlags.fg)('platform_editor_selection_extension_api_v2')) {
|
|
302
|
+
allFirstParty = [].concat((0, _toConsumableArray2.default)(firstParty), (0, _toConsumableArray2.default)((0, _extensions.getMenuItemExtensions)(extensionList, 'first-party')));
|
|
303
|
+
allExternal = [].concat((0, _toConsumableArray2.default)(external), (0, _toConsumableArray2.default)((0, _extensions.getMenuItemExtensions)(extensionList, 'external')));
|
|
275
304
|
}
|
|
276
|
-
var groupedExtensionsArray = [].concat((0, _toConsumableArray2.default)(getFirstPartyExtensions(
|
|
305
|
+
var groupedExtensionsArray = [].concat((0, _toConsumableArray2.default)(getFirstPartyExtensions(allFirstParty)), (0, _toConsumableArray2.default)(getExternalExtensions(allExternal)));
|
|
277
306
|
cachedOverflowMenuOptions = groupedExtensionsArray;
|
|
278
307
|
cachedSelection = state.selection;
|
|
279
|
-
return (0, _selectionToolbar2.selectionToolbar)(
|
|
308
|
+
return (0, _selectionToolbar2.selectionToolbar)({
|
|
309
|
+
overflowOptions: cachedOverflowMenuOptions,
|
|
310
|
+
extensionList: extensionList
|
|
311
|
+
});
|
|
280
312
|
}
|
|
281
313
|
},
|
|
282
314
|
pmPlugins: function pmPlugins() {
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
var _typeof = require("@babel/runtime/helpers/typeof");
|
|
5
|
+
Object.defineProperty(exports, "__esModule", {
|
|
6
|
+
value: true
|
|
7
|
+
});
|
|
8
|
+
exports.LegacyPrimaryToolbarComponent = exports.LegacyExtensionToolbarItem = void 0;
|
|
9
|
+
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
10
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
11
|
+
var _uiMenu = require("@atlaskit/editor-common/ui-menu");
|
|
12
|
+
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); }
|
|
13
|
+
var LegacyPrimaryToolbarComponent = exports.LegacyPrimaryToolbarComponent = function LegacyPrimaryToolbarComponent(_ref) {
|
|
14
|
+
var primaryToolbarItemExtensions = _ref.primaryToolbarItemExtensions;
|
|
15
|
+
// NEXT PR: need to render a separator after – if there are extensions added
|
|
16
|
+
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, primaryToolbarItemExtensions.map(function (toolbarItemExtension, i) {
|
|
17
|
+
var toolbarItem = toolbarItemExtension.getToolbarItem();
|
|
18
|
+
return /*#__PURE__*/_react.default.createElement(LegacyExtensionToolbarItem, {
|
|
19
|
+
key: toolbarItem.tooltip,
|
|
20
|
+
toolbarItem: toolbarItem
|
|
21
|
+
});
|
|
22
|
+
}));
|
|
23
|
+
};
|
|
24
|
+
var LegacyExtensionToolbarItem = exports.LegacyExtensionToolbarItem = function LegacyExtensionToolbarItem(_ref2) {
|
|
25
|
+
var toolbarItem = _ref2.toolbarItem,
|
|
26
|
+
getMenuItems = _ref2.getMenuItems;
|
|
27
|
+
var _useState = (0, _react.useState)(false),
|
|
28
|
+
_useState2 = (0, _slicedToArray2.default)(_useState, 2),
|
|
29
|
+
isOpen = _useState2[0],
|
|
30
|
+
setIsOpen = _useState2[1];
|
|
31
|
+
var Icon = toolbarItem.icon,
|
|
32
|
+
tooltip = toolbarItem.tooltip,
|
|
33
|
+
isDisabled = toolbarItem.isDisabled,
|
|
34
|
+
onClick = toolbarItem.onClick,
|
|
35
|
+
_label = toolbarItem.label;
|
|
36
|
+
if (!getMenuItems) {
|
|
37
|
+
return /*#__PURE__*/_react.default.createElement(_uiMenu.ToolbarButton, {
|
|
38
|
+
spacing: "default",
|
|
39
|
+
disabled: isDisabled,
|
|
40
|
+
selected: isOpen,
|
|
41
|
+
title: tooltip,
|
|
42
|
+
"aria-label": tooltip,
|
|
43
|
+
"aria-expanded": isOpen,
|
|
44
|
+
"aria-haspopup": true,
|
|
45
|
+
onClick: onClick,
|
|
46
|
+
iconBefore: /*#__PURE__*/_react.default.createElement(Icon, {
|
|
47
|
+
label: tooltip
|
|
48
|
+
})
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
var toggleOpen = function toggleOpen() {
|
|
52
|
+
setIsOpen(function (prev) {
|
|
53
|
+
return !prev;
|
|
54
|
+
});
|
|
55
|
+
};
|
|
56
|
+
var toggleOpenByKeyboard = function toggleOpenByKeyboard(event) {
|
|
57
|
+
if (event.key === 'Enter' || event.key === ' ') {
|
|
58
|
+
event.preventDefault();
|
|
59
|
+
toggleOpen();
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
var handleItemActivated = function handleItemActivated(_ref3) {
|
|
63
|
+
var _item$onClick;
|
|
64
|
+
var item = _ref3.item,
|
|
65
|
+
_ref3$shouldCloseMenu = _ref3.shouldCloseMenu,
|
|
66
|
+
shouldCloseMenu = _ref3$shouldCloseMenu === void 0 ? true : _ref3$shouldCloseMenu;
|
|
67
|
+
(_item$onClick = item.onClick) === null || _item$onClick === void 0 || _item$onClick.call(item);
|
|
68
|
+
if (shouldCloseMenu) {
|
|
69
|
+
setIsOpen(false);
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
var handleOnOpenChange = function handleOnOpenChange(attrs) {
|
|
73
|
+
setIsOpen(!!(attrs !== null && attrs !== void 0 && attrs.isOpen));
|
|
74
|
+
};
|
|
75
|
+
var items = isOpen ? getMenuItems().map(function (menuItem, i) {
|
|
76
|
+
return {
|
|
77
|
+
key: "menu-item-".concat(i),
|
|
78
|
+
content: menuItem.label,
|
|
79
|
+
elemBefore: /*#__PURE__*/_react.default.createElement(menuItem.icon, {
|
|
80
|
+
label: menuItem.label
|
|
81
|
+
}),
|
|
82
|
+
onClick: function onClick() {
|
|
83
|
+
var _menuItem$onClick;
|
|
84
|
+
(_menuItem$onClick = menuItem.onClick) === null || _menuItem$onClick === void 0 || _menuItem$onClick.call(menuItem);
|
|
85
|
+
// NEXT PR: here we need to set the active extension so the contentComponent can render
|
|
86
|
+
// menuItem.contentComponent
|
|
87
|
+
},
|
|
88
|
+
isDisabled: menuItem.isDisabled,
|
|
89
|
+
'aria-label': menuItem.label,
|
|
90
|
+
value: {
|
|
91
|
+
name: menuItem.label
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
}) : [];
|
|
95
|
+
return /*#__PURE__*/_react.default.createElement(_uiMenu.DropdownMenuWithKeyboardNavigation, {
|
|
96
|
+
arrowKeyNavigationProviderOptions: {
|
|
97
|
+
type: _uiMenu.ArrowKeyNavigationType.MENU
|
|
98
|
+
},
|
|
99
|
+
items: [{
|
|
100
|
+
items: items
|
|
101
|
+
}],
|
|
102
|
+
isOpen: isOpen,
|
|
103
|
+
onItemActivated: handleItemActivated,
|
|
104
|
+
onOpenChange: handleOnOpenChange,
|
|
105
|
+
fitWidth: 200
|
|
106
|
+
}, /*#__PURE__*/_react.default.createElement(_uiMenu.ToolbarButton, {
|
|
107
|
+
spacing: "default",
|
|
108
|
+
disabled: isDisabled,
|
|
109
|
+
selected: isOpen,
|
|
110
|
+
title: tooltip,
|
|
111
|
+
"aria-label": tooltip,
|
|
112
|
+
"aria-expanded": isOpen,
|
|
113
|
+
"aria-haspopup": true,
|
|
114
|
+
onClick: toggleOpen,
|
|
115
|
+
onKeyDown: toggleOpenByKeyboard,
|
|
116
|
+
iconBefore: /*#__PURE__*/_react.default.createElement(Icon, {
|
|
117
|
+
label: tooltip
|
|
118
|
+
})
|
|
119
|
+
}));
|
|
120
|
+
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.getToolbarItemExtensions = exports.getMenuItemExtensions = void 0;
|
|
7
|
+
/**
|
|
8
|
+
* From the full list of extensions, extract only those that have a toolbar item configuration
|
|
9
|
+
* for the specified type (either 'primaryToolbar' or 'inlineToolbar').
|
|
10
|
+
*
|
|
11
|
+
* @param extensionList - List of all extensions
|
|
12
|
+
* @param toolbarType - Type of toolbar ('primaryToolbar' or 'inlineToolbar')
|
|
13
|
+
* @returns Array of ToolbarItemExtension objects
|
|
14
|
+
* @example
|
|
15
|
+
*/
|
|
16
|
+
var getToolbarItemExtensions = exports.getToolbarItemExtensions = function getToolbarItemExtensions(extensionList, toolbarType) {
|
|
17
|
+
return extensionList.reduce(function (acc, extension) {
|
|
18
|
+
var toolbarConfig = extension[toolbarType];
|
|
19
|
+
if (toolbarConfig !== null && toolbarConfig !== void 0 && toolbarConfig.getToolbarItem) {
|
|
20
|
+
acc.push({
|
|
21
|
+
getToolbarItem: toolbarConfig.getToolbarItem,
|
|
22
|
+
getMenuItems: toolbarConfig.getMenuItems
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
return acc;
|
|
26
|
+
}, []);
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* From the full list of extensions, extract only those that have a menu item configuration
|
|
31
|
+
* for the specified source (either 'first-party' or 'external').
|
|
32
|
+
*
|
|
33
|
+
* Map each to the legacy format for SelectionExtensionConfig.
|
|
34
|
+
*
|
|
35
|
+
* @param extensionList - List of all extensions
|
|
36
|
+
* @param targetSource - Source of the extensions ('first-party' or 'external')
|
|
37
|
+
* @returns Array of SelectionExtensionConfig objects
|
|
38
|
+
* @example
|
|
39
|
+
*/
|
|
40
|
+
var getMenuItemExtensions = exports.getMenuItemExtensions = function getMenuItemExtensions(extensionList, targetSource) {
|
|
41
|
+
return extensionList.reduce(function (acc, extension) {
|
|
42
|
+
var source = extension.source,
|
|
43
|
+
inlineToolbar = extension.inlineToolbar;
|
|
44
|
+
if (source === targetSource && inlineToolbar !== null && inlineToolbar !== void 0 && inlineToolbar.getMenuItems && !inlineToolbar.getToolbarItem) {
|
|
45
|
+
var menuItems = inlineToolbar.getMenuItems();
|
|
46
|
+
menuItems.forEach(function (menuItem) {
|
|
47
|
+
acc.push({
|
|
48
|
+
name: menuItem.label,
|
|
49
|
+
icon: menuItem.icon,
|
|
50
|
+
onClick: menuItem.onClick,
|
|
51
|
+
isDisabled: function isDisabled() {
|
|
52
|
+
return !!menuItem.isDisabled;
|
|
53
|
+
},
|
|
54
|
+
component: menuItem.contentComponent
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
return acc;
|
|
59
|
+
}, []);
|
|
60
|
+
};
|
|
@@ -1,13 +1,40 @@
|
|
|
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
7
|
exports.selectionToolbar = void 0;
|
|
7
|
-
var
|
|
8
|
+
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
|
|
9
|
+
var _react = _interopRequireDefault(require("react"));
|
|
10
|
+
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
|
|
11
|
+
var _extensions = require("./extensions");
|
|
12
|
+
var _LegacyToolbarComponent = require("./LegacyToolbarComponent");
|
|
13
|
+
var selectionToolbar = exports.selectionToolbar = function selectionToolbar(_ref) {
|
|
14
|
+
var overflowOptions = _ref.overflowOptions,
|
|
15
|
+
_ref$extensionList = _ref.extensionList,
|
|
16
|
+
extensionList = _ref$extensionList === void 0 ? [] : _ref$extensionList;
|
|
17
|
+
var inlineToolbarItemExtensions = (0, _platformFeatureFlags.fg)('platform_editor_selection_extension_api_v2') ? (0, _extensions.getToolbarItemExtensions)(extensionList, 'inlineToolbar') : [];
|
|
8
18
|
return {
|
|
9
|
-
|
|
10
|
-
|
|
19
|
+
items: [].concat((0, _toConsumableArray2.default)(inlineToolbarItemExtensions.length ? [{
|
|
20
|
+
type: 'separator',
|
|
21
|
+
fullHeight: true,
|
|
22
|
+
supportsViewMode: true
|
|
23
|
+
}].concat((0, _toConsumableArray2.default)(inlineToolbarItemExtensions.map(function (_ref2) {
|
|
24
|
+
var getToolbarItem = _ref2.getToolbarItem,
|
|
25
|
+
getMenuItems = _ref2.getMenuItems;
|
|
26
|
+
return {
|
|
27
|
+
type: 'custom',
|
|
28
|
+
render: function render() {
|
|
29
|
+
return /*#__PURE__*/_react.default.createElement(_LegacyToolbarComponent.LegacyExtensionToolbarItem, {
|
|
30
|
+
toolbarItem: getToolbarItem(),
|
|
31
|
+
getMenuItems: getMenuItems
|
|
32
|
+
});
|
|
33
|
+
},
|
|
34
|
+
fallback: [],
|
|
35
|
+
supportsViewMode: true
|
|
36
|
+
};
|
|
37
|
+
}))) : []), [{
|
|
11
38
|
type: 'separator',
|
|
12
39
|
fullHeight: true,
|
|
13
40
|
supportsViewMode: true
|
|
@@ -15,8 +42,8 @@ var selectionToolbar = exports.selectionToolbar = function selectionToolbar(opti
|
|
|
15
42
|
type: 'overflow-dropdown',
|
|
16
43
|
dropdownWidth: 240,
|
|
17
44
|
supportsViewMode: true,
|
|
18
|
-
options:
|
|
19
|
-
}],
|
|
45
|
+
options: overflowOptions
|
|
46
|
+
}]),
|
|
20
47
|
rank: -6
|
|
21
48
|
};
|
|
22
49
|
};
|
|
@@ -9,7 +9,9 @@ import { createPlugin, selectionExtensionPluginKey } from './pm-plugins/main';
|
|
|
9
9
|
import { getSelectionInfo } from './pm-plugins/utils';
|
|
10
10
|
import { SelectionExtensionActionTypes } from './types';
|
|
11
11
|
import { SelectionExtensionComponentWrapper } from './ui/extension/SelectionExtensionComponentWrapper';
|
|
12
|
+
import { getMenuItemExtensions, getToolbarItemExtensions } from './ui/extensions';
|
|
12
13
|
import { getBoundingBoxFromSelection } from './ui/getBoundingBoxFromSelection';
|
|
14
|
+
import { LegacyPrimaryToolbarComponent } from './ui/LegacyToolbarComponent';
|
|
13
15
|
import { selectionToolbar } from './ui/selectionToolbar';
|
|
14
16
|
export const selectionExtensionPlugin = ({
|
|
15
17
|
api,
|
|
@@ -20,6 +22,26 @@ export const selectionExtensionPlugin = ({
|
|
|
20
22
|
};
|
|
21
23
|
let cachedSelection;
|
|
22
24
|
let cachedOverflowMenuOptions;
|
|
25
|
+
const {
|
|
26
|
+
extensionList = [],
|
|
27
|
+
extensions = {}
|
|
28
|
+
} = config || {};
|
|
29
|
+
const {
|
|
30
|
+
firstParty = [],
|
|
31
|
+
external = []
|
|
32
|
+
} = extensions || {};
|
|
33
|
+
if (fg('platform_editor_selection_extension_api_v2')) {
|
|
34
|
+
const primaryToolbarItemExtensions = getToolbarItemExtensions(extensionList, 'primaryToolbar');
|
|
35
|
+
if (primaryToolbarItemExtensions !== null && primaryToolbarItemExtensions !== void 0 && primaryToolbarItemExtensions.length) {
|
|
36
|
+
var _api$primaryToolbar, _api$primaryToolbar$a;
|
|
37
|
+
api === null || api === void 0 ? void 0 : (_api$primaryToolbar = api.primaryToolbar) === null || _api$primaryToolbar === void 0 ? void 0 : (_api$primaryToolbar$a = _api$primaryToolbar.actions) === null || _api$primaryToolbar$a === void 0 ? void 0 : _api$primaryToolbar$a.registerComponent({
|
|
38
|
+
name: 'selectionExtension',
|
|
39
|
+
component: () => /*#__PURE__*/React.createElement(LegacyPrimaryToolbarComponent, {
|
|
40
|
+
primaryToolbarItemExtensions: primaryToolbarItemExtensions
|
|
41
|
+
})
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
}
|
|
23
45
|
return {
|
|
24
46
|
name: 'selectionExtension',
|
|
25
47
|
getSharedState(editorState) {
|
|
@@ -83,6 +105,10 @@ export const selectionExtensionPlugin = ({
|
|
|
83
105
|
} = editorViewRef.current;
|
|
84
106
|
return insertAdfAtEndOfDoc(nodeAdf)(state, dispatch);
|
|
85
107
|
}
|
|
108
|
+
// NEXT PR: Implement this to return selectedNodeAdf, selectionRanges
|
|
109
|
+
// getSelectionAdf: () => {},
|
|
110
|
+
// NEXT PR: Implement this to return text, coords
|
|
111
|
+
// getSelectionText: () => {},
|
|
86
112
|
},
|
|
87
113
|
contentComponent: ({
|
|
88
114
|
editorView
|
|
@@ -101,26 +127,18 @@ export const selectionExtensionPlugin = ({
|
|
|
101
127
|
return;
|
|
102
128
|
}
|
|
103
129
|
const {
|
|
104
|
-
pageModes
|
|
105
|
-
extensions
|
|
130
|
+
pageModes
|
|
106
131
|
} = config;
|
|
107
132
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
* Check whether plugin contains any selection extensions
|
|
112
|
-
*/
|
|
113
|
-
if ((!(extensions !== null && extensions !== void 0 && extensions.firstParty) || extensions.firstParty.length === 0) && (!(extensions !== null && extensions !== void 0 && extensions.external) || extensions.external.length === 0)) {
|
|
133
|
+
// Extensions Config Validation
|
|
134
|
+
// Check whether plugin contains any selection extensions
|
|
135
|
+
if (!(firstParty !== null && firstParty !== void 0 && firstParty.length) && !(external !== null && external !== void 0 && external.length) && !(extensionList !== null && extensionList !== void 0 && extensionList.length)) {
|
|
114
136
|
return;
|
|
115
137
|
}
|
|
116
138
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
* Check if pageModes is provided and matches against current content mode
|
|
121
|
-
*
|
|
122
|
-
* TODO: This will eventially transition from mode to contentMode
|
|
123
|
-
*/
|
|
139
|
+
// Content Mode Validation
|
|
140
|
+
// Check if pageModes is provided and matches against current content mode
|
|
141
|
+
// This will eventially transition from mode to contentMode
|
|
124
142
|
const editorContentMode = api === null || api === void 0 ? void 0 : (_api$editorViewMode = api.editorViewMode) === null || _api$editorViewMode === void 0 ? void 0 : (_api$editorViewMode$s = _api$editorViewMode.sharedState.currentState()) === null || _api$editorViewMode$s === void 0 ? void 0 : _api$editorViewMode$s.mode;
|
|
125
143
|
if (pageModes) {
|
|
126
144
|
// Early Exit: consumer has set pageModes but editorContentMode is undefined
|
|
@@ -137,11 +155,8 @@ export const selectionExtensionPlugin = ({
|
|
|
137
155
|
}
|
|
138
156
|
}
|
|
139
157
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
*
|
|
143
|
-
* Check if there is an active extension and hide the selection extension dropdown
|
|
144
|
-
*/
|
|
158
|
+
// Active Extension
|
|
159
|
+
// Check if there is an active extension and hide the selection extension dropdown
|
|
145
160
|
const selectionExtensionState = selectionExtensionPluginKey.getState(state);
|
|
146
161
|
if (selectionExtensionState !== null && selectionExtensionState !== void 0 && selectionExtensionState.activeExtension) {
|
|
147
162
|
return;
|
|
@@ -251,9 +266,7 @@ export const selectionExtensionPlugin = ({
|
|
|
251
266
|
});
|
|
252
267
|
};
|
|
253
268
|
|
|
254
|
-
|
|
255
|
-
* Add a heading to the external extensions
|
|
256
|
-
*/
|
|
269
|
+
// Add a heading to the external extensions
|
|
257
270
|
const getExternalExtensions = extensions => {
|
|
258
271
|
const prefilteredExtensions = prefilterExtensions(extensions);
|
|
259
272
|
let externalExtensions = [];
|
|
@@ -270,13 +283,28 @@ export const selectionExtensionPlugin = ({
|
|
|
270
283
|
}
|
|
271
284
|
return externalExtensions;
|
|
272
285
|
};
|
|
286
|
+
|
|
287
|
+
// NEXT PR: Make sure we cache the whole generated selection toolbar
|
|
288
|
+
// also debug this to make sure it's actually preventing unnecessary re-renders / work
|
|
273
289
|
if (cachedOverflowMenuOptions && state.selection.eq(cachedSelection) && fg('platform_editor_selection_extension_api_v2')) {
|
|
274
|
-
return selectionToolbar(
|
|
290
|
+
return selectionToolbar({
|
|
291
|
+
overflowOptions: cachedOverflowMenuOptions,
|
|
292
|
+
extensionList
|
|
293
|
+
});
|
|
275
294
|
}
|
|
276
|
-
|
|
295
|
+
let allFirstParty = [...firstParty];
|
|
296
|
+
let allExternal = [...external];
|
|
297
|
+
if (fg('platform_editor_selection_extension_api_v2')) {
|
|
298
|
+
allFirstParty = [...firstParty, ...getMenuItemExtensions(extensionList, 'first-party')];
|
|
299
|
+
allExternal = [...external, ...getMenuItemExtensions(extensionList, 'external')];
|
|
300
|
+
}
|
|
301
|
+
const groupedExtensionsArray = [...getFirstPartyExtensions(allFirstParty), ...getExternalExtensions(allExternal)];
|
|
277
302
|
cachedOverflowMenuOptions = groupedExtensionsArray;
|
|
278
303
|
cachedSelection = state.selection;
|
|
279
|
-
return selectionToolbar(
|
|
304
|
+
return selectionToolbar({
|
|
305
|
+
overflowOptions: cachedOverflowMenuOptions,
|
|
306
|
+
extensionList
|
|
307
|
+
});
|
|
280
308
|
}
|
|
281
309
|
},
|
|
282
310
|
pmPlugins: () => [{
|