@atlaskit/editor-plugin-toolbar 3.3.3 → 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 +21 -0
- package/afm-products/tsconfig.json +60 -0
- package/dist/cjs/pm-plugins/experiences/SelectionToolbarOpenExperience.js +77 -12
- package/dist/cjs/toolbarPlugin.js +8 -3
- package/dist/cjs/ui/Section.js +10 -2
- package/dist/cjs/ui/toolbar-components.js +28 -4
- package/dist/es2019/pm-plugins/experiences/SelectionToolbarOpenExperience.js +75 -12
- package/dist/es2019/toolbarPlugin.js +7 -3
- package/dist/es2019/ui/Section.js +10 -2
- package/dist/es2019/ui/toolbar-components.js +28 -4
- package/dist/esm/pm-plugins/experiences/SelectionToolbarOpenExperience.js +76 -12
- package/dist/esm/toolbarPlugin.js +8 -3
- package/dist/esm/ui/Section.js +10 -2
- package/dist/esm/ui/toolbar-components.js +28 -4
- package/dist/types/pm-plugins/experiences/SelectionToolbarOpenExperience.d.ts +7 -0
- package/dist/types/toolbarPluginType.d.ts +13 -0
- package/dist/types/types/index.d.ts +53 -0
- package/dist/types/ui/toolbar-components.d.ts +2 -1
- package/dist/types-ts4.5/pm-plugins/experiences/SelectionToolbarOpenExperience.d.ts +7 -0
- package/dist/types-ts4.5/toolbarPluginType.d.ts +13 -0
- package/dist/types-ts4.5/types/index.d.ts +53 -0
- package/dist/types-ts4.5/ui/toolbar-components.d.ts +2 -1
- package/package.json +6 -3
- package/afm-dev-agents/tsconfig.json +0 -60
- package/afm-passionfruit/tsconfig.json +0 -60
- package/afm-rovo-extension/tsconfig.json +0 -60
- package/afm-volt/tsconfig.json +0 -36
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-toolbar
|
|
2
2
|
|
|
3
|
+
## 3.4.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`7aff1e36b43e1`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/7aff1e36b43e1) -
|
|
8
|
+
Improve editor selection toolbar experience tracking
|
|
9
|
+
- Updated dependencies
|
|
10
|
+
|
|
11
|
+
## 3.4.0
|
|
12
|
+
|
|
13
|
+
### Minor Changes
|
|
14
|
+
|
|
15
|
+
- [`301c7dd0ccdd2`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/301c7dd0ccdd2) -
|
|
16
|
+
Adds new `contextualFormattingEnabled` plugin option to editor-plugin-toolbar. This has 3 options
|
|
17
|
+
(always-inline, always-pinned and controlled) to allow direct control over toolbar placement in
|
|
18
|
+
the editor.
|
|
19
|
+
|
|
20
|
+
### Patch Changes
|
|
21
|
+
|
|
22
|
+
- Updated dependencies
|
|
23
|
+
|
|
3
24
|
## 3.3.3
|
|
4
25
|
|
|
5
26
|
### Patch Changes
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "../../../../tsconfig.entry-points.products.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"target": "es5",
|
|
5
|
+
"outDir": "../../../../../tsDist/@atlaskit__editor-plugin-toolbar/app",
|
|
6
|
+
"rootDir": "../",
|
|
7
|
+
"composite": true
|
|
8
|
+
},
|
|
9
|
+
"include": [
|
|
10
|
+
"../src/**/*.ts",
|
|
11
|
+
"../src/**/*.tsx"
|
|
12
|
+
],
|
|
13
|
+
"exclude": [
|
|
14
|
+
"../src/**/__tests__/*",
|
|
15
|
+
"../src/**/*.test.*",
|
|
16
|
+
"../src/**/test.*",
|
|
17
|
+
"../src/**/examples.*"
|
|
18
|
+
],
|
|
19
|
+
"references": [
|
|
20
|
+
{
|
|
21
|
+
"path": "../../../helpers/browser-apis/afm-products/tsconfig.json"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"path": "../../editor-plugin-analytics/afm-products/tsconfig.json"
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"path": "../../editor-plugin-connectivity/afm-products/tsconfig.json"
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"path": "../../editor-plugin-editor-viewmode/afm-products/tsconfig.json"
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"path": "../../editor-plugin-selection/afm-products/tsconfig.json"
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"path": "../../editor-plugin-user-intent/afm-products/tsconfig.json"
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"path": "../../editor-plugin-user-preferences/afm-products/tsconfig.json"
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"path": "../../editor-toolbar/afm-products/tsconfig.json"
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"path": "../../editor-toolbar-model/afm-products/tsconfig.json"
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"path": "../../../platform/feature-flags/afm-products/tsconfig.json"
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"path": "../../../platform/feature-flags-react/afm-products/tsconfig.json"
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"path": "../../tmp-editor-statsig/afm-products/tsconfig.json"
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"path": "../../editor-common/afm-products/tsconfig.json"
|
|
58
|
+
}
|
|
59
|
+
]
|
|
60
|
+
}
|
|
@@ -1,22 +1,56 @@
|
|
|
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.default = void 0;
|
|
8
|
+
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
|
|
7
9
|
var _experiences = require("@atlaskit/editor-common/experiences");
|
|
8
10
|
var _safePlugin = require("@atlaskit/editor-common/safe-plugin");
|
|
9
11
|
var _state = require("@atlaskit/editor-prosemirror/state");
|
|
10
12
|
var pluginKey = new _state.PluginKey('selectionToolbarOpenExperience');
|
|
13
|
+
var START_METHOD = {
|
|
14
|
+
MOUSE_UP: 'mouse-up',
|
|
15
|
+
KEY_DOWN: 'key-down'
|
|
16
|
+
};
|
|
17
|
+
var ABORT_REASON = {
|
|
18
|
+
SELECTION_CLEARED: 'selection-cleared',
|
|
19
|
+
BLOCK_MENU_OPENED: 'block-menu-opened',
|
|
20
|
+
EDITOR_DESTROYED: 'editor-destroyed'
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* This experience tracks when the selection toolbar is opened.
|
|
24
|
+
*
|
|
25
|
+
* Start: When user makes a selection via mouseup or shift+arrow key down
|
|
26
|
+
* Success: When the selection toolbar is added to the DOM within 500ms of start
|
|
27
|
+
* Abort: When selection transition to empty or block menu is opened
|
|
28
|
+
*/
|
|
11
29
|
var _default = exports.default = function _default(_ref) {
|
|
12
30
|
var popupsMountPointRef = _ref.popupsMountPointRef,
|
|
13
31
|
editorViewDomRef = _ref.editorViewDomRef;
|
|
32
|
+
var cachedTarget = null;
|
|
14
33
|
var getTarget = function getTarget() {
|
|
15
|
-
|
|
16
|
-
|
|
34
|
+
if (!cachedTarget) {
|
|
35
|
+
var _editorViewDomRef$cur;
|
|
36
|
+
cachedTarget = popupsMountPointRef.current || ((_editorViewDomRef$cur = editorViewDomRef.current) === null || _editorViewDomRef$cur === void 0 || (_editorViewDomRef$cur = _editorViewDomRef$cur.closest('.ak-editor-content-area')) === null || _editorViewDomRef$cur === void 0 ? void 0 : _editorViewDomRef$cur.querySelector(':scope > [data-testid="plugins-components-wrapper"]')) || null;
|
|
37
|
+
}
|
|
38
|
+
return cachedTarget;
|
|
17
39
|
};
|
|
18
40
|
var experience = new _experiences.Experience('selection-toolbar-open', {
|
|
19
|
-
checks: [new _experiences.ExperienceCheckTimeout(
|
|
41
|
+
checks: [new _experiences.ExperienceCheckTimeout({
|
|
42
|
+
durationMs: 500,
|
|
43
|
+
onTimeout: function onTimeout() {
|
|
44
|
+
if (isBlockMenuWithinNode(getTarget())) {
|
|
45
|
+
return {
|
|
46
|
+
status: 'abort',
|
|
47
|
+
metadata: {
|
|
48
|
+
reason: ABORT_REASON.BLOCK_MENU_OPENED
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}), new _experiences.ExperienceCheckDomMutation({
|
|
20
54
|
onDomMutation: function onDomMutation(_ref2) {
|
|
21
55
|
var mutations = _ref2.mutations;
|
|
22
56
|
if (mutations.some(isSelectionToolbarAddedInMutation)) {
|
|
@@ -29,8 +63,7 @@ var _default = exports.default = function _default(_ref) {
|
|
|
29
63
|
return {
|
|
30
64
|
target: getTarget(),
|
|
31
65
|
options: {
|
|
32
|
-
childList: true
|
|
33
|
-
subtree: true
|
|
66
|
+
childList: true
|
|
34
67
|
}
|
|
35
68
|
};
|
|
36
69
|
}
|
|
@@ -44,7 +77,11 @@ var _default = exports.default = function _default(_ref) {
|
|
|
44
77
|
},
|
|
45
78
|
apply: function apply(_tr, pluginState, oldState, newState) {
|
|
46
79
|
if (!oldState.selection.empty && newState.selection.empty) {
|
|
47
|
-
experience.abort(
|
|
80
|
+
experience.abort({
|
|
81
|
+
metadata: {
|
|
82
|
+
reason: ABORT_REASON.SELECTION_CLEARED
|
|
83
|
+
}
|
|
84
|
+
});
|
|
48
85
|
}
|
|
49
86
|
return pluginState;
|
|
50
87
|
}
|
|
@@ -52,15 +89,23 @@ var _default = exports.default = function _default(_ref) {
|
|
|
52
89
|
props: {
|
|
53
90
|
handleDOMEvents: {
|
|
54
91
|
mouseup: function mouseup(view) {
|
|
55
|
-
if (!view.state.selection.empty) {
|
|
56
|
-
experience.start(
|
|
92
|
+
if (!view.state.selection.empty && !isSelectionToolbarWithinNode(getTarget())) {
|
|
93
|
+
experience.start({
|
|
94
|
+
metadata: {
|
|
95
|
+
method: START_METHOD.MOUSE_UP
|
|
96
|
+
}
|
|
97
|
+
});
|
|
57
98
|
}
|
|
58
99
|
},
|
|
59
100
|
keydown: function keydown(_view, _ref3) {
|
|
60
101
|
var shiftKey = _ref3.shiftKey,
|
|
61
102
|
key = _ref3.key;
|
|
62
103
|
if (shiftKey && key.includes('Arrow') && !isSelectionToolbarWithinNode(getTarget())) {
|
|
63
|
-
experience.start(
|
|
104
|
+
experience.start({
|
|
105
|
+
metadata: {
|
|
106
|
+
method: START_METHOD.KEY_DOWN
|
|
107
|
+
}
|
|
108
|
+
});
|
|
64
109
|
}
|
|
65
110
|
}
|
|
66
111
|
}
|
|
@@ -68,7 +113,11 @@ var _default = exports.default = function _default(_ref) {
|
|
|
68
113
|
view: function view() {
|
|
69
114
|
return {
|
|
70
115
|
destroy: function destroy() {
|
|
71
|
-
experience.abort(
|
|
116
|
+
experience.abort({
|
|
117
|
+
metadata: {
|
|
118
|
+
reason: ABORT_REASON.EDITOR_DESTROYED
|
|
119
|
+
}
|
|
120
|
+
});
|
|
72
121
|
}
|
|
73
122
|
};
|
|
74
123
|
}
|
|
@@ -77,8 +126,24 @@ var _default = exports.default = function _default(_ref) {
|
|
|
77
126
|
var isSelectionToolbarAddedInMutation = function isSelectionToolbarAddedInMutation(_ref4) {
|
|
78
127
|
var type = _ref4.type,
|
|
79
128
|
addedNodes = _ref4.addedNodes;
|
|
80
|
-
return type === 'childList' &&
|
|
129
|
+
return type === 'childList' && (0, _toConsumableArray2.default)(addedNodes).some(isSelectionToolbarWithinNode);
|
|
81
130
|
};
|
|
82
131
|
var isSelectionToolbarWithinNode = function isSelectionToolbarWithinNode(node) {
|
|
83
|
-
return node
|
|
132
|
+
return containsPopupWithNestedTestId(node, 'editor-floating-toolbar');
|
|
133
|
+
};
|
|
134
|
+
var isBlockMenuWithinNode = function isBlockMenuWithinNode(node) {
|
|
135
|
+
return containsPopupWithNestedTestId(node, 'editor-block-menu');
|
|
136
|
+
};
|
|
137
|
+
var containsPopupWithNestedTestId = function containsPopupWithNestedTestId(node, testId) {
|
|
138
|
+
if (!(node instanceof HTMLElement)) {
|
|
139
|
+
return false;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Check if node itself has the popup attribute and contains the element with testId
|
|
143
|
+
if (node.matches('[data-editor-popup="true"]')) {
|
|
144
|
+
return !!node.querySelector("[data-testid=\"".concat(testId, "\"]"));
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Check if any direct child with popup attribute contains the element with testId
|
|
148
|
+
return !!node.querySelector(":scope > [data-editor-popup=\"true\"] [data-testid=\"".concat(testId, "\"]"));
|
|
84
149
|
};
|
|
@@ -78,9 +78,11 @@ var toolbarPlugin = exports.toolbarPlugin = function toolbarPlugin(_ref) {
|
|
|
78
78
|
var popupsMountPointRef = {};
|
|
79
79
|
var editorViewDomRef = {};
|
|
80
80
|
var disableSelectionToolbar = config.disableSelectionToolbar,
|
|
81
|
-
disableSelectionToolbarWhenPinned = config.disableSelectionToolbarWhenPinned
|
|
81
|
+
disableSelectionToolbarWhenPinned = config.disableSelectionToolbarWhenPinned,
|
|
82
|
+
_config$contextualFor = config.contextualFormattingEnabled,
|
|
83
|
+
contextualFormattingEnabled = _config$contextualFor === void 0 ? 'always-pinned' : _config$contextualFor;
|
|
82
84
|
var registry = (0, _editorToolbarModel.createComponentRegistry)();
|
|
83
|
-
registry.register((0, _toolbarComponents.getToolbarComponents)(api, disableSelectionToolbar));
|
|
85
|
+
registry.register((0, _toolbarComponents.getToolbarComponents)(contextualFormattingEnabled, api, disableSelectionToolbar));
|
|
84
86
|
return {
|
|
85
87
|
name: 'toolbar',
|
|
86
88
|
actions: {
|
|
@@ -94,6 +96,9 @@ var toolbarPlugin = exports.toolbarPlugin = function toolbarPlugin(_ref) {
|
|
|
94
96
|
},
|
|
95
97
|
getComponents: function getComponents() {
|
|
96
98
|
return registry.components;
|
|
99
|
+
},
|
|
100
|
+
contextualFormattingMode: function contextualFormattingMode() {
|
|
101
|
+
return contextualFormattingEnabled;
|
|
97
102
|
}
|
|
98
103
|
},
|
|
99
104
|
getSharedState: function getSharedState(editorState) {
|
|
@@ -182,7 +187,7 @@ var toolbarPlugin = exports.toolbarPlugin = function toolbarPlugin(_ref) {
|
|
|
182
187
|
}
|
|
183
188
|
});
|
|
184
189
|
}
|
|
185
|
-
}].concat((0, _toConsumableArray2.default)((0, _expValEquals.expValEquals)('platform_editor_experience_tracking', 'isEnabled', true) ? [{
|
|
190
|
+
}].concat((0, _toConsumableArray2.default)(!disableSelectionToolbar && (0, _expValEquals.expValEquals)('platform_editor_experience_tracking', 'isEnabled', true) ? [{
|
|
186
191
|
name: 'selectionToolbarOpenExperience',
|
|
187
192
|
plugin: function plugin() {
|
|
188
193
|
return (0, _SelectionToolbarOpenExperience.default)({
|
package/dist/cjs/ui/Section.js
CHANGED
|
@@ -9,14 +9,22 @@ var _react = _interopRequireDefault(require("react"));
|
|
|
9
9
|
var _toolbar = require("@atlaskit/editor-common/toolbar");
|
|
10
10
|
var _useSharedPluginStateSelector = require("@atlaskit/editor-common/use-shared-plugin-state-selector");
|
|
11
11
|
var _editorToolbar = require("@atlaskit/editor-toolbar");
|
|
12
|
+
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
|
|
12
13
|
var _platformFeatureFlagsReact = require("@atlaskit/platform-feature-flags-react");
|
|
13
14
|
var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
|
|
14
15
|
var shouldShowSection = function shouldShowSection(editMode, toolbar, toolbarDocking, disableSelectionToolbar) {
|
|
15
16
|
if (editMode === 'view') {
|
|
16
17
|
return false;
|
|
17
18
|
}
|
|
18
|
-
|
|
19
|
-
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* This check is no longer needed with plugin config changes, the selection toolbar will not be registered and so
|
|
22
|
+
* no components will render
|
|
23
|
+
*/
|
|
24
|
+
if (!(0, _platformFeatureFlags.fg)('platform_editor_toolbar_aifc_placement_config')) {
|
|
25
|
+
if (disableSelectionToolbar) {
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
20
28
|
}
|
|
21
29
|
if ((toolbar === null || toolbar === void 0 ? void 0 : toolbar.key) === _toolbar.TOOLBARS.INLINE_TEXT_TOOLBAR && toolbarDocking !== 'top') {
|
|
22
30
|
return true;
|
|
@@ -10,6 +10,7 @@ var _react = _interopRequireDefault(require("react"));
|
|
|
10
10
|
var _analytics = require("@atlaskit/editor-common/analytics");
|
|
11
11
|
var _toolbar = require("@atlaskit/editor-common/toolbar");
|
|
12
12
|
var _editorToolbar = require("@atlaskit/editor-toolbar");
|
|
13
|
+
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
|
|
13
14
|
var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
|
|
14
15
|
var _consts = require("./consts");
|
|
15
16
|
var _OverflowMenu = require("./OverflowMenu");
|
|
@@ -17,8 +18,8 @@ var _OverflowSection = require("./OverflowSection");
|
|
|
17
18
|
var _PrimaryToolbar = require("./PrimaryToolbar");
|
|
18
19
|
var _Section = require("./Section");
|
|
19
20
|
var _TextCollapsedMenu = require("./TextCollapsedMenu");
|
|
20
|
-
var
|
|
21
|
-
|
|
21
|
+
var getInlineTextToolbarComponents = function getInlineTextToolbarComponents() {
|
|
22
|
+
return [{
|
|
22
23
|
type: 'toolbar',
|
|
23
24
|
key: _toolbar.TOOLBARS.INLINE_TEXT_TOOLBAR,
|
|
24
25
|
component: function component(_ref) {
|
|
@@ -29,7 +30,10 @@ var getToolbarComponents = exports.getToolbarComponents = function getToolbarCom
|
|
|
29
30
|
testId: (0, _expValEquals.expValEquals)('platform_editor_toolbar_aifc_patch_5', 'isEnabled', true) ? 'editor-floating-toolbar' : undefined
|
|
30
31
|
}, children);
|
|
31
32
|
}
|
|
32
|
-
}
|
|
33
|
+
}];
|
|
34
|
+
};
|
|
35
|
+
var getPrimaryToolbarComponents = function getPrimaryToolbarComponents() {
|
|
36
|
+
return [{
|
|
33
37
|
type: 'toolbar',
|
|
34
38
|
key: _toolbar.TOOLBARS.PRIMARY_TOOLBAR,
|
|
35
39
|
component: (0, _expValEquals.expValEquals)('platform_editor_toolbar_aifc_responsive', 'isEnabled', true) ? _PrimaryToolbar.PrimaryToolbar : function (_ref2) {
|
|
@@ -39,7 +43,10 @@ var getToolbarComponents = exports.getToolbarComponents = function getToolbarCom
|
|
|
39
43
|
testId: "primary-toolbar"
|
|
40
44
|
}, children);
|
|
41
45
|
}
|
|
42
|
-
}
|
|
46
|
+
}];
|
|
47
|
+
};
|
|
48
|
+
var getToolbarComponents = exports.getToolbarComponents = function getToolbarComponents(contextualFormattingEnabled, api, disableSelectionToolbar) {
|
|
49
|
+
var components = [{
|
|
43
50
|
type: _toolbar.TEXT_SECTION.type,
|
|
44
51
|
key: _toolbar.TEXT_SECTION.key,
|
|
45
52
|
parents: [{
|
|
@@ -249,5 +256,22 @@ var getToolbarComponents = exports.getToolbarComponents = function getToolbarCom
|
|
|
249
256
|
}
|
|
250
257
|
});
|
|
251
258
|
}
|
|
259
|
+
if ((0, _platformFeatureFlags.fg)('platform_editor_toolbar_aifc_placement_config')) {
|
|
260
|
+
switch (contextualFormattingEnabled) {
|
|
261
|
+
case 'always-inline':
|
|
262
|
+
components.unshift.apply(components, (0, _toConsumableArray2.default)(getInlineTextToolbarComponents()));
|
|
263
|
+
break;
|
|
264
|
+
case 'always-pinned':
|
|
265
|
+
components.unshift.apply(components, (0, _toConsumableArray2.default)(getPrimaryToolbarComponents()));
|
|
266
|
+
break;
|
|
267
|
+
case 'controlled':
|
|
268
|
+
components.unshift.apply(components, (0, _toConsumableArray2.default)(getInlineTextToolbarComponents()));
|
|
269
|
+
components.unshift.apply(components, (0, _toConsumableArray2.default)(getPrimaryToolbarComponents()));
|
|
270
|
+
break;
|
|
271
|
+
}
|
|
272
|
+
} else {
|
|
273
|
+
components.unshift.apply(components, (0, _toConsumableArray2.default)(getInlineTextToolbarComponents()));
|
|
274
|
+
components.unshift.apply(components, (0, _toConsumableArray2.default)(getPrimaryToolbarComponents()));
|
|
275
|
+
}
|
|
252
276
|
return components;
|
|
253
277
|
};
|
|
@@ -2,16 +2,48 @@ import { Experience, ExperienceCheckDomMutation, ExperienceCheckTimeout } from '
|
|
|
2
2
|
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
3
3
|
import { PluginKey } from '@atlaskit/editor-prosemirror/state';
|
|
4
4
|
const pluginKey = new PluginKey('selectionToolbarOpenExperience');
|
|
5
|
+
const START_METHOD = {
|
|
6
|
+
MOUSE_UP: 'mouse-up',
|
|
7
|
+
KEY_DOWN: 'key-down'
|
|
8
|
+
};
|
|
9
|
+
const ABORT_REASON = {
|
|
10
|
+
SELECTION_CLEARED: 'selection-cleared',
|
|
11
|
+
BLOCK_MENU_OPENED: 'block-menu-opened',
|
|
12
|
+
EDITOR_DESTROYED: 'editor-destroyed'
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* This experience tracks when the selection toolbar is opened.
|
|
16
|
+
*
|
|
17
|
+
* Start: When user makes a selection via mouseup or shift+arrow key down
|
|
18
|
+
* Success: When the selection toolbar is added to the DOM within 500ms of start
|
|
19
|
+
* Abort: When selection transition to empty or block menu is opened
|
|
20
|
+
*/
|
|
5
21
|
export default (({
|
|
6
22
|
popupsMountPointRef,
|
|
7
23
|
editorViewDomRef
|
|
8
24
|
}) => {
|
|
25
|
+
let cachedTarget = null;
|
|
9
26
|
const getTarget = () => {
|
|
10
|
-
|
|
11
|
-
|
|
27
|
+
if (!cachedTarget) {
|
|
28
|
+
var _editorViewDomRef$cur, _editorViewDomRef$cur2;
|
|
29
|
+
cachedTarget = popupsMountPointRef.current || ((_editorViewDomRef$cur = editorViewDomRef.current) === null || _editorViewDomRef$cur === void 0 ? void 0 : (_editorViewDomRef$cur2 = _editorViewDomRef$cur.closest('.ak-editor-content-area')) === null || _editorViewDomRef$cur2 === void 0 ? void 0 : _editorViewDomRef$cur2.querySelector(':scope > [data-testid="plugins-components-wrapper"]')) || null;
|
|
30
|
+
}
|
|
31
|
+
return cachedTarget;
|
|
12
32
|
};
|
|
13
33
|
const experience = new Experience('selection-toolbar-open', {
|
|
14
|
-
checks: [new ExperienceCheckTimeout(
|
|
34
|
+
checks: [new ExperienceCheckTimeout({
|
|
35
|
+
durationMs: 500,
|
|
36
|
+
onTimeout: () => {
|
|
37
|
+
if (isBlockMenuWithinNode(getTarget())) {
|
|
38
|
+
return {
|
|
39
|
+
status: 'abort',
|
|
40
|
+
metadata: {
|
|
41
|
+
reason: ABORT_REASON.BLOCK_MENU_OPENED
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}), new ExperienceCheckDomMutation({
|
|
15
47
|
onDomMutation: ({
|
|
16
48
|
mutations
|
|
17
49
|
}) => {
|
|
@@ -24,8 +56,7 @@ export default (({
|
|
|
24
56
|
observeConfig: () => ({
|
|
25
57
|
target: getTarget(),
|
|
26
58
|
options: {
|
|
27
|
-
childList: true
|
|
28
|
-
subtree: true
|
|
59
|
+
childList: true
|
|
29
60
|
}
|
|
30
61
|
})
|
|
31
62
|
})]
|
|
@@ -36,7 +67,11 @@ export default (({
|
|
|
36
67
|
init: () => ({}),
|
|
37
68
|
apply: (_tr, pluginState, oldState, newState) => {
|
|
38
69
|
if (!oldState.selection.empty && newState.selection.empty) {
|
|
39
|
-
experience.abort(
|
|
70
|
+
experience.abort({
|
|
71
|
+
metadata: {
|
|
72
|
+
reason: ABORT_REASON.SELECTION_CLEARED
|
|
73
|
+
}
|
|
74
|
+
});
|
|
40
75
|
}
|
|
41
76
|
return pluginState;
|
|
42
77
|
}
|
|
@@ -44,8 +79,12 @@ export default (({
|
|
|
44
79
|
props: {
|
|
45
80
|
handleDOMEvents: {
|
|
46
81
|
mouseup: view => {
|
|
47
|
-
if (!view.state.selection.empty) {
|
|
48
|
-
experience.start(
|
|
82
|
+
if (!view.state.selection.empty && !isSelectionToolbarWithinNode(getTarget())) {
|
|
83
|
+
experience.start({
|
|
84
|
+
metadata: {
|
|
85
|
+
method: START_METHOD.MOUSE_UP
|
|
86
|
+
}
|
|
87
|
+
});
|
|
49
88
|
}
|
|
50
89
|
},
|
|
51
90
|
keydown: (_view, {
|
|
@@ -53,7 +92,11 @@ export default (({
|
|
|
53
92
|
key
|
|
54
93
|
}) => {
|
|
55
94
|
if (shiftKey && key.includes('Arrow') && !isSelectionToolbarWithinNode(getTarget())) {
|
|
56
|
-
experience.start(
|
|
95
|
+
experience.start({
|
|
96
|
+
metadata: {
|
|
97
|
+
method: START_METHOD.KEY_DOWN
|
|
98
|
+
}
|
|
99
|
+
});
|
|
57
100
|
}
|
|
58
101
|
}
|
|
59
102
|
}
|
|
@@ -61,7 +104,11 @@ export default (({
|
|
|
61
104
|
view: () => {
|
|
62
105
|
return {
|
|
63
106
|
destroy: () => {
|
|
64
|
-
experience.abort(
|
|
107
|
+
experience.abort({
|
|
108
|
+
metadata: {
|
|
109
|
+
reason: ABORT_REASON.EDITOR_DESTROYED
|
|
110
|
+
}
|
|
111
|
+
});
|
|
65
112
|
}
|
|
66
113
|
};
|
|
67
114
|
}
|
|
@@ -71,8 +118,24 @@ const isSelectionToolbarAddedInMutation = ({
|
|
|
71
118
|
type,
|
|
72
119
|
addedNodes
|
|
73
120
|
}) => {
|
|
74
|
-
return type === 'childList' &&
|
|
121
|
+
return type === 'childList' && [...addedNodes].some(isSelectionToolbarWithinNode);
|
|
75
122
|
};
|
|
76
123
|
const isSelectionToolbarWithinNode = node => {
|
|
77
|
-
return node
|
|
124
|
+
return containsPopupWithNestedTestId(node, 'editor-floating-toolbar');
|
|
125
|
+
};
|
|
126
|
+
const isBlockMenuWithinNode = node => {
|
|
127
|
+
return containsPopupWithNestedTestId(node, 'editor-block-menu');
|
|
128
|
+
};
|
|
129
|
+
const containsPopupWithNestedTestId = (node, testId) => {
|
|
130
|
+
if (!(node instanceof HTMLElement)) {
|
|
131
|
+
return false;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Check if node itself has the popup attribute and contains the element with testId
|
|
135
|
+
if (node.matches('[data-editor-popup="true"]')) {
|
|
136
|
+
return !!node.querySelector(`[data-testid="${testId}"]`);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Check if any direct child with popup attribute contains the element with testId
|
|
140
|
+
return !!node.querySelector(`:scope > [data-editor-popup="true"] [data-testid="${testId}"]`);
|
|
78
141
|
};
|
|
@@ -64,10 +64,11 @@ export const toolbarPlugin = ({
|
|
|
64
64
|
const editorViewDomRef = {};
|
|
65
65
|
const {
|
|
66
66
|
disableSelectionToolbar,
|
|
67
|
-
disableSelectionToolbarWhenPinned
|
|
67
|
+
disableSelectionToolbarWhenPinned,
|
|
68
|
+
contextualFormattingEnabled = 'always-pinned'
|
|
68
69
|
} = config;
|
|
69
70
|
const registry = createComponentRegistry();
|
|
70
|
-
registry.register(getToolbarComponents(api, disableSelectionToolbar));
|
|
71
|
+
registry.register(getToolbarComponents(contextualFormattingEnabled, api, disableSelectionToolbar));
|
|
71
72
|
return {
|
|
72
73
|
name: 'toolbar',
|
|
73
74
|
actions: {
|
|
@@ -80,6 +81,9 @@ export const toolbarPlugin = ({
|
|
|
80
81
|
},
|
|
81
82
|
getComponents: () => {
|
|
82
83
|
return registry.components;
|
|
84
|
+
},
|
|
85
|
+
contextualFormattingMode: () => {
|
|
86
|
+
return contextualFormattingEnabled;
|
|
83
87
|
}
|
|
84
88
|
},
|
|
85
89
|
getSharedState(editorState) {
|
|
@@ -173,7 +177,7 @@ export const toolbarPlugin = ({
|
|
|
173
177
|
}
|
|
174
178
|
});
|
|
175
179
|
}
|
|
176
|
-
}, ...(expValEquals('platform_editor_experience_tracking', 'isEnabled', true) ? [{
|
|
180
|
+
}, ...(!disableSelectionToolbar && expValEquals('platform_editor_experience_tracking', 'isEnabled', true) ? [{
|
|
177
181
|
name: 'selectionToolbarOpenExperience',
|
|
178
182
|
plugin: () => selectionToolbarOpenExperience({
|
|
179
183
|
popupsMountPointRef,
|
|
@@ -2,14 +2,22 @@ import React from 'react';
|
|
|
2
2
|
import { TOOLBARS, useEditorToolbar } from '@atlaskit/editor-common/toolbar';
|
|
3
3
|
import { useSharedPluginStateSelector } from '@atlaskit/editor-common/use-shared-plugin-state-selector';
|
|
4
4
|
import { ToolbarSection, SeparatorPosition } from '@atlaskit/editor-toolbar';
|
|
5
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
5
6
|
import { conditionalHooksFactory } from '@atlaskit/platform-feature-flags-react';
|
|
6
7
|
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
7
8
|
const shouldShowSection = (editMode, toolbar, toolbarDocking, disableSelectionToolbar) => {
|
|
8
9
|
if (editMode === 'view') {
|
|
9
10
|
return false;
|
|
10
11
|
}
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* This check is no longer needed with plugin config changes, the selection toolbar will not be registered and so
|
|
15
|
+
* no components will render
|
|
16
|
+
*/
|
|
17
|
+
if (!fg('platform_editor_toolbar_aifc_placement_config')) {
|
|
18
|
+
if (disableSelectionToolbar) {
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
13
21
|
}
|
|
14
22
|
if ((toolbar === null || toolbar === void 0 ? void 0 : toolbar.key) === TOOLBARS.INLINE_TEXT_TOOLBAR && toolbarDocking !== 'top') {
|
|
15
23
|
return true;
|
|
@@ -2,6 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import { ACTION_SUBJECT_ID } from '@atlaskit/editor-common/analytics';
|
|
3
3
|
import { INSERT_BLOCK_SECTION, LINKING_SECTION, OVERFLOW_GROUP, OVERFLOW_GROUP_PRIMARY_TOOLBAR, OVERFLOW_GROUP_PRIMARY_TOOLBAR_RANK, OVERFLOW_GROUP_RANK, OVERFLOW_MENU, OVERFLOW_MENU_PRIMARY_TOOLBAR, OVERFLOW_SECTION, OVERFLOW_SECTION_PRIMARY_TOOLBAR, OVERFLOW_SECTION_PRIMARY_TOOLBAR_RANK, OVERFLOW_SECTION_RANK, PIN_SECTION, TEXT_COLLAPSED_GROUP, TEXT_SECTION, TEXT_SECTION_PRIMARY_TOOLBAR, TEXT_SECTION_COLLAPSED, TEXT_COLLAPSED_MENU, TOOLBAR_RANK, TOOLBARS } from '@atlaskit/editor-common/toolbar';
|
|
4
4
|
import { PrimaryToolbar as PrimaryToolbarBase, Show, Toolbar } from '@atlaskit/editor-toolbar';
|
|
5
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
5
6
|
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
6
7
|
import { SELECTION_TOOLBAR_LABEL } from './consts';
|
|
7
8
|
import { OverflowMenu } from './OverflowMenu';
|
|
@@ -9,8 +10,8 @@ import { OverflowSection } from './OverflowSection';
|
|
|
9
10
|
import { PrimaryToolbar } from './PrimaryToolbar';
|
|
10
11
|
import { Section } from './Section';
|
|
11
12
|
import { TextCollapsedMenu } from './TextCollapsedMenu';
|
|
12
|
-
|
|
13
|
-
|
|
13
|
+
const getInlineTextToolbarComponents = () => {
|
|
14
|
+
return [{
|
|
14
15
|
type: 'toolbar',
|
|
15
16
|
key: TOOLBARS.INLINE_TEXT_TOOLBAR,
|
|
16
17
|
component: ({
|
|
@@ -22,7 +23,10 @@ export const getToolbarComponents = (api, disableSelectionToolbar) => {
|
|
|
22
23
|
testId: expValEquals('platform_editor_toolbar_aifc_patch_5', 'isEnabled', true) ? 'editor-floating-toolbar' : undefined
|
|
23
24
|
}, children);
|
|
24
25
|
}
|
|
25
|
-
}
|
|
26
|
+
}];
|
|
27
|
+
};
|
|
28
|
+
const getPrimaryToolbarComponents = () => {
|
|
29
|
+
return [{
|
|
26
30
|
type: 'toolbar',
|
|
27
31
|
key: TOOLBARS.PRIMARY_TOOLBAR,
|
|
28
32
|
component: expValEquals('platform_editor_toolbar_aifc_responsive', 'isEnabled', true) ? PrimaryToolbar : ({
|
|
@@ -31,7 +35,10 @@ export const getToolbarComponents = (api, disableSelectionToolbar) => {
|
|
|
31
35
|
label: "Primary Toolbar",
|
|
32
36
|
testId: "primary-toolbar"
|
|
33
37
|
}, children)
|
|
34
|
-
}
|
|
38
|
+
}];
|
|
39
|
+
};
|
|
40
|
+
export const getToolbarComponents = (contextualFormattingEnabled, api, disableSelectionToolbar) => {
|
|
41
|
+
const components = [{
|
|
35
42
|
type: TEXT_SECTION.type,
|
|
36
43
|
key: TEXT_SECTION.key,
|
|
37
44
|
parents: [{
|
|
@@ -245,5 +252,22 @@ export const getToolbarComponents = (api, disableSelectionToolbar) => {
|
|
|
245
252
|
}
|
|
246
253
|
});
|
|
247
254
|
}
|
|
255
|
+
if (fg('platform_editor_toolbar_aifc_placement_config')) {
|
|
256
|
+
switch (contextualFormattingEnabled) {
|
|
257
|
+
case 'always-inline':
|
|
258
|
+
components.unshift(...getInlineTextToolbarComponents());
|
|
259
|
+
break;
|
|
260
|
+
case 'always-pinned':
|
|
261
|
+
components.unshift(...getPrimaryToolbarComponents());
|
|
262
|
+
break;
|
|
263
|
+
case 'controlled':
|
|
264
|
+
components.unshift(...getInlineTextToolbarComponents());
|
|
265
|
+
components.unshift(...getPrimaryToolbarComponents());
|
|
266
|
+
break;
|
|
267
|
+
}
|
|
268
|
+
} else {
|
|
269
|
+
components.unshift(...getInlineTextToolbarComponents());
|
|
270
|
+
components.unshift(...getPrimaryToolbarComponents());
|
|
271
|
+
}
|
|
248
272
|
return components;
|
|
249
273
|
};
|