@atlaskit/editor-plugin-block-menu 6.0.25 → 6.0.27
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 +16 -0
- package/dist/cjs/blockMenuPlugin.js +14 -0
- package/dist/cjs/editor-commands/transformNode.js +1 -0
- package/dist/cjs/pm-plugins/experiences/block-menu-experiences.js +147 -0
- package/dist/cjs/ui/block-menu.js +18 -55
- package/dist/cjs/ui/delete-button.js +24 -1
- package/dist/es2019/blockMenuPlugin.js +12 -0
- package/dist/es2019/editor-commands/transformNode.js +1 -0
- package/dist/es2019/pm-plugins/experiences/block-menu-experiences.js +140 -0
- package/dist/es2019/ui/block-menu.js +6 -42
- package/dist/es2019/ui/delete-button.js +26 -3
- package/dist/esm/blockMenuPlugin.js +14 -0
- package/dist/esm/editor-commands/transformNode.js +1 -0
- package/dist/esm/pm-plugins/experiences/block-menu-experiences.js +140 -0
- package/dist/esm/ui/block-menu.js +18 -55
- package/dist/esm/ui/delete-button.js +26 -3
- package/dist/types/pm-plugins/experiences/block-menu-experiences.d.ts +10 -0
- package/dist/types-ts4.5/pm-plugins/experiences/block-menu-experiences.d.ts +10 -0
- package/package.json +6 -8
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-block-menu
|
|
2
2
|
|
|
3
|
+
## 6.0.27
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`4cafa94a73e1e`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/4cafa94a73e1e) -
|
|
8
|
+
Add delete track event for block menu
|
|
9
|
+
- Updated dependencies
|
|
10
|
+
|
|
11
|
+
## 6.0.26
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- [`e00b363b9fa30`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/e00b363b9fa30) -
|
|
16
|
+
[ux] EDITOR-4481 Clean up platform_editor_toolbar_aifc_user_intent_fix
|
|
17
|
+
- Updated dependencies
|
|
18
|
+
|
|
3
19
|
## 6.0.25
|
|
4
20
|
|
|
5
21
|
### Patch Changes
|
|
@@ -10,6 +10,7 @@ var _editorActions = require("./editor-actions");
|
|
|
10
10
|
var _isTransformToTargetDisabled = require("./editor-actions/isTransformToTargetDisabled");
|
|
11
11
|
var _formatNode2 = require("./editor-commands/formatNode");
|
|
12
12
|
var _transformNode2 = require("./editor-commands/transformNode");
|
|
13
|
+
var _blockMenuExperiences = require("./pm-plugins/experiences/block-menu-experiences");
|
|
13
14
|
var _keymap = require("./pm-plugins/keymap");
|
|
14
15
|
var _main = require("./pm-plugins/main");
|
|
15
16
|
var _blockMenu = _interopRequireDefault(require("./ui/block-menu"));
|
|
@@ -24,6 +25,7 @@ var blockMenuPlugin = exports.blockMenuPlugin = function blockMenuPlugin(_ref) {
|
|
|
24
25
|
api: api,
|
|
25
26
|
config: config
|
|
26
27
|
}));
|
|
28
|
+
var refs = {};
|
|
27
29
|
return {
|
|
28
30
|
name: 'blockMenu',
|
|
29
31
|
pmPlugins: function pmPlugins() {
|
|
@@ -37,6 +39,17 @@ var blockMenuPlugin = exports.blockMenuPlugin = function blockMenuPlugin(_ref) {
|
|
|
37
39
|
plugin: function plugin() {
|
|
38
40
|
return (0, _keymap.keymapPlugin)(api, config);
|
|
39
41
|
}
|
|
42
|
+
}, {
|
|
43
|
+
name: 'blockMenuExperiences',
|
|
44
|
+
plugin: function plugin() {
|
|
45
|
+
return (0, _blockMenuExperiences.getBlockMenuExperiencesPlugin)({
|
|
46
|
+
refs: refs,
|
|
47
|
+
dispatchAnalyticsEvent: function dispatchAnalyticsEvent(payload) {
|
|
48
|
+
var _api$analytics;
|
|
49
|
+
return api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 || (_api$analytics = _api$analytics.actions) === null || _api$analytics === void 0 ? void 0 : _api$analytics.fireAnalyticsEvent(payload);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
}
|
|
40
53
|
}];
|
|
41
54
|
},
|
|
42
55
|
actions: {
|
|
@@ -94,6 +107,7 @@ var blockMenuPlugin = exports.blockMenuPlugin = function blockMenuPlugin(_ref) {
|
|
|
94
107
|
popupsMountPoint = _ref2.popupsMountPoint,
|
|
95
108
|
popupsBoundariesElement = _ref2.popupsBoundariesElement,
|
|
96
109
|
popupsScrollableElement = _ref2.popupsScrollableElement;
|
|
110
|
+
refs.popupsMountPoint = popupsMountPoint || undefined;
|
|
97
111
|
return /*#__PURE__*/_react.default.createElement(_blockMenuProvider.BlockMenuProvider, {
|
|
98
112
|
api: api,
|
|
99
113
|
editorView: editorView
|
|
@@ -84,6 +84,7 @@ var transformNode = exports.transformNode = function transformNode(api) {
|
|
|
84
84
|
isNested: isNested,
|
|
85
85
|
sourceNodesCount: sourceNodes.length,
|
|
86
86
|
sourceNodesCountByType: sourceNodeTypes,
|
|
87
|
+
sourceNodeType: sourceNodes.length === 1 ? sourceNodes[0].type.name : 'multiple',
|
|
87
88
|
startTime: startTime,
|
|
88
89
|
targetNodeType: targetType.name,
|
|
89
90
|
outputNodesCount: content.length,
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.getBlockMenuExperiencesPlugin = void 0;
|
|
8
|
+
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
|
|
9
|
+
var _bindEventListener = require("bind-event-listener");
|
|
10
|
+
var _analytics = require("@atlaskit/editor-common/analytics");
|
|
11
|
+
var _experiences = require("@atlaskit/editor-common/experiences");
|
|
12
|
+
var _safePlugin = require("@atlaskit/editor-common/safe-plugin");
|
|
13
|
+
var _state = require("@atlaskit/editor-prosemirror/state");
|
|
14
|
+
var TIMEOUT_DURATION = 1000;
|
|
15
|
+
var pluginKey = new _state.PluginKey('blockMenuExperiences');
|
|
16
|
+
var START_METHOD = {
|
|
17
|
+
DRAG_HANDLE_CLICK: 'dragHandleClick',
|
|
18
|
+
KEYBOARD: 'keyboard'
|
|
19
|
+
};
|
|
20
|
+
var ABORT_REASON = {
|
|
21
|
+
USER_CANCELED: 'userCanceled',
|
|
22
|
+
EDITOR_DESTROYED: 'editorDestroyed'
|
|
23
|
+
};
|
|
24
|
+
var getBlockMenuExperiencesPlugin = exports.getBlockMenuExperiencesPlugin = function getBlockMenuExperiencesPlugin(_ref) {
|
|
25
|
+
var refs = _ref.refs,
|
|
26
|
+
dispatchAnalyticsEvent = _ref.dispatchAnalyticsEvent;
|
|
27
|
+
var targetEl;
|
|
28
|
+
var editorViewEl;
|
|
29
|
+
var getPopupsTarget = function getPopupsTarget() {
|
|
30
|
+
if (!targetEl) {
|
|
31
|
+
targetEl = refs.popupsMountPoint || (0, _experiences.getPopupContainerFromEditorView)(editorViewEl);
|
|
32
|
+
}
|
|
33
|
+
return targetEl;
|
|
34
|
+
};
|
|
35
|
+
var blockMenuOpenExperience = new _experiences.Experience(_experiences.EXPERIENCE_ID.MENU_OPEN, {
|
|
36
|
+
actionSubjectId: _analytics.ACTION_SUBJECT_ID.BLOCK_MENU,
|
|
37
|
+
dispatchAnalyticsEvent: dispatchAnalyticsEvent,
|
|
38
|
+
checks: [new _experiences.ExperienceCheckTimeout({
|
|
39
|
+
durationMs: TIMEOUT_DURATION
|
|
40
|
+
}), new _experiences.ExperienceCheckDomMutation({
|
|
41
|
+
onDomMutation: function onDomMutation(_ref2) {
|
|
42
|
+
var mutations = _ref2.mutations;
|
|
43
|
+
if (mutations.some(isBlockMenuAddedInMutation)) {
|
|
44
|
+
return {
|
|
45
|
+
status: 'success'
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
return undefined;
|
|
49
|
+
},
|
|
50
|
+
observeConfig: function observeConfig() {
|
|
51
|
+
return {
|
|
52
|
+
target: getPopupsTarget(),
|
|
53
|
+
options: {
|
|
54
|
+
childList: true
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
})]
|
|
59
|
+
});
|
|
60
|
+
var unbindClickListener = (0, _bindEventListener.bind)(document, {
|
|
61
|
+
type: 'click',
|
|
62
|
+
listener: function listener(event) {
|
|
63
|
+
if (!(event.target instanceof Element)) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
var target = event.target;
|
|
67
|
+
|
|
68
|
+
// Check if the click is on a drag handle
|
|
69
|
+
if (!isDragHandleElement(target)) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Don't start if block menu is already visible
|
|
74
|
+
if (isBlockMenuVisible(getPopupsTarget())) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
blockMenuOpenExperience.start({
|
|
78
|
+
method: START_METHOD.DRAG_HANDLE_CLICK
|
|
79
|
+
});
|
|
80
|
+
},
|
|
81
|
+
options: {
|
|
82
|
+
capture: true
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
var unbindKeydownListener = (0, _bindEventListener.bind)(document, {
|
|
86
|
+
type: 'keydown',
|
|
87
|
+
listener: function listener(event) {
|
|
88
|
+
if (!(event.target instanceof Element)) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
var target = event.target;
|
|
92
|
+
|
|
93
|
+
// Check if Enter or Space is pressed on a drag handle
|
|
94
|
+
if ((event.key === 'Enter' || event.key === ' ') && isDragHandleElement(target)) {
|
|
95
|
+
// Don't start if block menu is already visible
|
|
96
|
+
if (isBlockMenuVisible(getPopupsTarget())) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
blockMenuOpenExperience.start({
|
|
100
|
+
method: START_METHOD.KEYBOARD
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Abort on Escape key if block menu is not yet visible
|
|
105
|
+
if (event.key === 'Escape' && !isBlockMenuVisible(getPopupsTarget())) {
|
|
106
|
+
blockMenuOpenExperience.abort({
|
|
107
|
+
reason: ABORT_REASON.USER_CANCELED
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
options: {
|
|
112
|
+
capture: true
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
return new _safePlugin.SafePlugin({
|
|
116
|
+
key: pluginKey,
|
|
117
|
+
view: function view(editorView) {
|
|
118
|
+
editorViewEl = editorView.dom;
|
|
119
|
+
return {
|
|
120
|
+
destroy: function destroy() {
|
|
121
|
+
blockMenuOpenExperience.abort({
|
|
122
|
+
reason: ABORT_REASON.EDITOR_DESTROYED
|
|
123
|
+
});
|
|
124
|
+
unbindClickListener();
|
|
125
|
+
unbindKeydownListener();
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
};
|
|
131
|
+
var isBlockMenuAddedInMutation = function isBlockMenuAddedInMutation(_ref3) {
|
|
132
|
+
var type = _ref3.type,
|
|
133
|
+
addedNodes = _ref3.addedNodes;
|
|
134
|
+
return type === 'childList' && (0, _toConsumableArray2.default)(addedNodes).some(isBlockMenuWithinNode);
|
|
135
|
+
};
|
|
136
|
+
var isBlockMenuWithinNode = function isBlockMenuWithinNode(node) {
|
|
137
|
+
return (0, _experiences.popupWithNestedElement)(node, '[data-testid="editor-block-menu"]') !== null;
|
|
138
|
+
};
|
|
139
|
+
var isDragHandleElement = function isDragHandleElement(element) {
|
|
140
|
+
return !!(element !== null && element !== void 0 && element.closest('[data-editor-block-ctrl-drag-handle]'));
|
|
141
|
+
};
|
|
142
|
+
var isBlockMenuVisible = function isBlockMenuVisible(popupsTarget) {
|
|
143
|
+
if (!popupsTarget) {
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
return (0, _experiences.popupWithNestedElement)(popupsTarget, '[data-testid="editor-block-menu"]') !== null;
|
|
147
|
+
};
|
|
@@ -21,8 +21,6 @@ var _ui = require("@atlaskit/editor-common/ui");
|
|
|
21
21
|
var _uiMenu = require("@atlaskit/editor-common/ui-menu");
|
|
22
22
|
var _uiReact = require("@atlaskit/editor-common/ui-react");
|
|
23
23
|
var _editorSharedStyles = require("@atlaskit/editor-shared-styles");
|
|
24
|
-
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
|
|
25
|
-
var _platformFeatureFlagsReact = require("@atlaskit/platform-feature-flags-react");
|
|
26
24
|
var _compiled = require("@atlaskit/primitives/compiled");
|
|
27
25
|
var _prosemirrorHistory = require("@atlaskit/prosemirror-history");
|
|
28
26
|
var _experiments = require("@atlaskit/tmp-editor-statsig/experiments");
|
|
@@ -37,9 +35,7 @@ var DEFAULT_MENU_WIDTH = 230;
|
|
|
37
35
|
var DRAG_HANDLE_OFFSET_PADDING = 5;
|
|
38
36
|
var FALLBACK_MENU_HEIGHT = 300;
|
|
39
37
|
var PopupWithListeners = (0, _uiReact.withReactEditorViewOuterListeners)(_ui.Popup);
|
|
40
|
-
var useConditionalBlockMenuEffect =
|
|
41
|
-
return (0, _platformFeatureFlags.fg)('platform_editor_toolbar_aifc_user_intent_fix');
|
|
42
|
-
}, function (_ref) {
|
|
38
|
+
var useConditionalBlockMenuEffect = function useConditionalBlockMenuEffect(_ref) {
|
|
43
39
|
var api = _ref.api,
|
|
44
40
|
isMenuOpen = _ref.isMenuOpen,
|
|
45
41
|
menuTriggerBy = _ref.menuTriggerBy,
|
|
@@ -73,49 +69,17 @@ var useConditionalBlockMenuEffect = (0, _platformFeatureFlagsReact.conditionalHo
|
|
|
73
69
|
prevIsMenuOpenRef.current = isMenuOpen;
|
|
74
70
|
api === null || api === void 0 || api.core.actions.execute(api === null || api === void 0 || (_api$userIntent = api.userIntent) === null || _api$userIntent === void 0 ? void 0 : _api$userIntent.commands.setCurrentUserIntent('blockMenuOpen'));
|
|
75
71
|
}, [api, isMenuOpen, menuTriggerBy, selectedByShortcutOrDragHandle, hasFocus, openedViaKeyboard, prevIsMenuOpenRef]);
|
|
76
|
-
}
|
|
77
|
-
var api = _ref2.api,
|
|
78
|
-
isMenuOpen = _ref2.isMenuOpen,
|
|
79
|
-
menuTriggerBy = _ref2.menuTriggerBy,
|
|
80
|
-
selectedByShortcutOrDragHandle = _ref2.selectedByShortcutOrDragHandle,
|
|
81
|
-
hasFocus = _ref2.hasFocus,
|
|
82
|
-
currentUserIntent = _ref2.currentUserIntent,
|
|
83
|
-
openedViaKeyboard = _ref2.openedViaKeyboard,
|
|
84
|
-
prevIsMenuOpenRef = _ref2.prevIsMenuOpenRef;
|
|
85
|
-
(0, _react.useEffect)(function () {
|
|
86
|
-
var _api$userIntent2;
|
|
87
|
-
if (!isMenuOpen || !menuTriggerBy || !selectedByShortcutOrDragHandle || !hasFocus || ['resizing', 'dragging'].includes(currentUserIntent || '')) {
|
|
88
|
-
return;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// Fire analytics event when block menu opens (only on first transition from closed to open)
|
|
92
|
-
if (!prevIsMenuOpenRef.current && isMenuOpen) {
|
|
93
|
-
var _api$analytics2;
|
|
94
|
-
api === null || api === void 0 || (_api$analytics2 = api.analytics) === null || _api$analytics2 === void 0 || _api$analytics2.actions.fireAnalyticsEvent({
|
|
95
|
-
action: _analytics.ACTION.OPENED,
|
|
96
|
-
actionSubject: _analytics.ACTION_SUBJECT.BLOCK_MENU,
|
|
97
|
-
eventType: _analytics.EVENT_TYPE.UI,
|
|
98
|
-
attributes: {
|
|
99
|
-
inputMethod: openedViaKeyboard ? _analytics.INPUT_METHOD.KEYBOARD : _analytics.INPUT_METHOD.MOUSE
|
|
100
|
-
}
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
// Update the previous state
|
|
105
|
-
prevIsMenuOpenRef.current = isMenuOpen;
|
|
106
|
-
api === null || api === void 0 || api.core.actions.execute(api === null || api === void 0 || (_api$userIntent2 = api.userIntent) === null || _api$userIntent2 === void 0 ? void 0 : _api$userIntent2.commands.setCurrentUserIntent('blockMenuOpen'));
|
|
107
|
-
}, [api, isMenuOpen, menuTriggerBy, selectedByShortcutOrDragHandle, hasFocus, currentUserIntent, openedViaKeyboard, prevIsMenuOpenRef]);
|
|
108
|
-
});
|
|
72
|
+
};
|
|
109
73
|
var isSelectionWithinCodeBlock = function isSelectionWithinCodeBlock(state) {
|
|
110
74
|
var _state$selection = state.selection,
|
|
111
75
|
$from = _state$selection.$from,
|
|
112
76
|
$to = _state$selection.$to;
|
|
113
77
|
return $from.sameParent($to) && $from.parent.type === state.schema.nodes.codeBlock;
|
|
114
78
|
};
|
|
115
|
-
var BlockMenuContent = function BlockMenuContent(
|
|
79
|
+
var BlockMenuContent = function BlockMenuContent(_ref2) {
|
|
116
80
|
var _api$blockMenu;
|
|
117
|
-
var api =
|
|
118
|
-
setRef =
|
|
81
|
+
var api = _ref2.api,
|
|
82
|
+
setRef = _ref2.setRef;
|
|
119
83
|
var blockMenuComponents = api === null || api === void 0 || (_api$blockMenu = api.blockMenu) === null || _api$blockMenu === void 0 ? void 0 : _api$blockMenu.actions.getBlockMenuComponents();
|
|
120
84
|
var setOutsideClickTargetRef = (0, _react.useContext)(_uiReact.OutsideClickTargetRefContext);
|
|
121
85
|
var ref = function ref(el) {
|
|
@@ -135,13 +99,13 @@ var BlockMenuContent = function BlockMenuContent(_ref3) {
|
|
|
135
99
|
allRegisteredComponents: blockMenuComponents || []
|
|
136
100
|
})));
|
|
137
101
|
};
|
|
138
|
-
var BlockMenu = function BlockMenu(
|
|
139
|
-
var _editorView$dom,
|
|
140
|
-
var editorView =
|
|
141
|
-
api =
|
|
142
|
-
mountTo =
|
|
143
|
-
boundariesElement =
|
|
144
|
-
scrollableElement =
|
|
102
|
+
var BlockMenu = function BlockMenu(_ref3) {
|
|
103
|
+
var _editorView$dom, _ref4, _api$analytics2;
|
|
104
|
+
var editorView = _ref3.editorView,
|
|
105
|
+
api = _ref3.api,
|
|
106
|
+
mountTo = _ref3.mountTo,
|
|
107
|
+
boundariesElement = _ref3.boundariesElement,
|
|
108
|
+
scrollableElement = _ref3.scrollableElement;
|
|
145
109
|
var _useSharedPluginState = (0, _hooks.useSharedPluginStateWithSelector)(api, ['blockControls', 'userIntent'], function (states) {
|
|
146
110
|
var _states$blockControls, _states$blockControls2, _states$blockControls3, _states$userIntentSta, _states$blockControls4;
|
|
147
111
|
return {
|
|
@@ -174,7 +138,7 @@ var BlockMenu = function BlockMenu(_ref4) {
|
|
|
174
138
|
}
|
|
175
139
|
setMenuHeight(((_popupRef$current = popupRef.current) === null || _popupRef$current === void 0 ? void 0 : _popupRef$current.clientHeight) || FALLBACK_MENU_HEIGHT);
|
|
176
140
|
}, [isMenuOpen]);
|
|
177
|
-
var hasFocus = (
|
|
141
|
+
var hasFocus = (_ref4 = (editorView === null || editorView === void 0 ? void 0 : editorView.hasFocus()) || document.activeElement === targetHandleRef || popupRef.current && (popupRef.current.contains(document.activeElement) || popupRef.current === document.activeElement)) !== null && _ref4 !== void 0 ? _ref4 : false;
|
|
178
142
|
var selectedByShortcutOrDragHandle = !!isSelectedViaDragHandle || !!openedViaKeyboard;
|
|
179
143
|
|
|
180
144
|
// Use conditional hook based on feature flag
|
|
@@ -184,7 +148,6 @@ var BlockMenu = function BlockMenu(_ref4) {
|
|
|
184
148
|
menuTriggerBy: menuTriggerBy,
|
|
185
149
|
selectedByShortcutOrDragHandle: selectedByShortcutOrDragHandle,
|
|
186
150
|
hasFocus: hasFocus,
|
|
187
|
-
currentUserIntent: (0, _platformFeatureFlags.fg)('platform_editor_toolbar_aifc_user_intent_fix') ? undefined : currentUserIntent,
|
|
188
151
|
openedViaKeyboard: openedViaKeyboard,
|
|
189
152
|
prevIsMenuOpenRef: prevIsMenuOpenRef
|
|
190
153
|
});
|
|
@@ -225,16 +188,16 @@ var BlockMenu = function BlockMenu(_ref4) {
|
|
|
225
188
|
closeMenu();
|
|
226
189
|
};
|
|
227
190
|
var closeMenu = function closeMenu() {
|
|
228
|
-
api === null || api === void 0 || api.core.actions.execute(function (
|
|
229
|
-
var _api$blockControls2, _api$
|
|
230
|
-
var tr =
|
|
191
|
+
api === null || api === void 0 || api.core.actions.execute(function (_ref5) {
|
|
192
|
+
var _api$blockControls2, _api$userIntent2;
|
|
193
|
+
var tr = _ref5.tr;
|
|
231
194
|
api === null || api === void 0 || (_api$blockControls2 = api.blockControls) === null || _api$blockControls2 === void 0 || _api$blockControls2.commands.toggleBlockMenu({
|
|
232
195
|
closeMenu: true
|
|
233
196
|
})({
|
|
234
197
|
tr: tr
|
|
235
198
|
});
|
|
236
199
|
onDropdownOpenChanged(false);
|
|
237
|
-
api === null || api === void 0 || (_api$
|
|
200
|
+
api === null || api === void 0 || (_api$userIntent2 = api.userIntent) === null || _api$userIntent2 === void 0 || _api$userIntent2.commands.setCurrentUserIntent(currentUserIntent === 'blockMenuOpen' ? 'default' : currentUserIntent || 'default')({
|
|
238
201
|
tr: tr
|
|
239
202
|
});
|
|
240
203
|
return tr;
|
|
@@ -254,7 +217,7 @@ var BlockMenu = function BlockMenu(_ref4) {
|
|
|
254
217
|
}
|
|
255
218
|
return /*#__PURE__*/_react.default.createElement(_errorBoundary.ErrorBoundary, {
|
|
256
219
|
component: _analytics.ACTION_SUBJECT.BLOCK_MENU,
|
|
257
|
-
dispatchAnalyticsEvent: api === null || api === void 0 || (_api$
|
|
220
|
+
dispatchAnalyticsEvent: api === null || api === void 0 || (_api$analytics2 = api.analytics) === null || _api$analytics2 === void 0 ? void 0 : _api$analytics2.actions.fireAnalyticsEvent,
|
|
258
221
|
fallbackComponent: null
|
|
259
222
|
}, /*#__PURE__*/_react.default.createElement(PopupWithListeners, {
|
|
260
223
|
alignX: 'right',
|
|
@@ -34,7 +34,30 @@ var DeleteDropdownItemContent = function DeleteDropdownItemContent(_ref) {
|
|
|
34
34
|
eventType: _analytics.EVENT_TYPE.UI
|
|
35
35
|
};
|
|
36
36
|
api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 || (_api$analytics = _api$analytics.actions) === null || _api$analytics === void 0 || _api$analytics.attachAnalyticsEvent(payload)(tr);
|
|
37
|
-
|
|
37
|
+
|
|
38
|
+
// Extract node information before deletion
|
|
39
|
+
var preservedSelection = api === null || api === void 0 || (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 || (_api$blockControls = _api$blockControls.sharedState.currentState()) === null || _api$blockControls === void 0 ? void 0 : _api$blockControls.preservedSelection;
|
|
40
|
+
var selection = preservedSelection || tr.selection;
|
|
41
|
+
var sourceNodes = (0, _selection.getSourceNodesFromSelectionRange)(tr, selection);
|
|
42
|
+
var nodeCount = sourceNodes.length;
|
|
43
|
+
|
|
44
|
+
// Fire node deletion analytics event if nodes are being deleted
|
|
45
|
+
if (nodeCount > 0) {
|
|
46
|
+
var _api$analytics2;
|
|
47
|
+
var nodeType = sourceNodes.length === 1 ? sourceNodes[0].type.name : 'multiple';
|
|
48
|
+
var nodeDeletedPayload = {
|
|
49
|
+
action: _analytics.ACTION.DELETED,
|
|
50
|
+
actionSubject: _analytics.ACTION_SUBJECT.ELEMENT,
|
|
51
|
+
attributes: {
|
|
52
|
+
inputMethod: _analytics.INPUT_METHOD.BLOCK_MENU,
|
|
53
|
+
nodeType: nodeType,
|
|
54
|
+
nodeCount: nodeCount
|
|
55
|
+
},
|
|
56
|
+
eventType: _analytics.EVENT_TYPE.TRACK
|
|
57
|
+
};
|
|
58
|
+
api === null || api === void 0 || (_api$analytics2 = api.analytics) === null || _api$analytics2 === void 0 || (_api$analytics2 = _api$analytics2.actions) === null || _api$analytics2 === void 0 || _api$analytics2.attachAnalyticsEvent(nodeDeletedPayload)(tr);
|
|
59
|
+
}
|
|
60
|
+
(0, _selection.deleteSelectedRange)(tr, preservedSelection);
|
|
38
61
|
api === null || api === void 0 || (_api$blockControls2 = api.blockControls) === null || _api$blockControls2 === void 0 || (_api$blockControls2 = _api$blockControls2.commands) === null || _api$blockControls2 === void 0 || _api$blockControls2.toggleBlockMenu({
|
|
39
62
|
closeMenu: true
|
|
40
63
|
})({
|
|
@@ -3,6 +3,7 @@ import { createBlockMenuRegistry } from './editor-actions';
|
|
|
3
3
|
import { isTransformToTargetDisabled } from './editor-actions/isTransformToTargetDisabled';
|
|
4
4
|
import { formatNode } from './editor-commands/formatNode';
|
|
5
5
|
import { transformNode } from './editor-commands/transformNode';
|
|
6
|
+
import { getBlockMenuExperiencesPlugin } from './pm-plugins/experiences/block-menu-experiences';
|
|
6
7
|
import { keymapPlugin } from './pm-plugins/keymap';
|
|
7
8
|
import { blockMenuPluginKey, createPlugin } from './pm-plugins/main';
|
|
8
9
|
import BlockMenu from './ui/block-menu';
|
|
@@ -18,6 +19,7 @@ export const blockMenuPlugin = ({
|
|
|
18
19
|
api,
|
|
19
20
|
config
|
|
20
21
|
}));
|
|
22
|
+
const refs = {};
|
|
21
23
|
return {
|
|
22
24
|
name: 'blockMenu',
|
|
23
25
|
pmPlugins() {
|
|
@@ -27,6 +29,15 @@ export const blockMenuPlugin = ({
|
|
|
27
29
|
}, {
|
|
28
30
|
name: 'blockMenuKeymap',
|
|
29
31
|
plugin: () => keymapPlugin(api, config)
|
|
32
|
+
}, {
|
|
33
|
+
name: 'blockMenuExperiences',
|
|
34
|
+
plugin: () => getBlockMenuExperiencesPlugin({
|
|
35
|
+
refs,
|
|
36
|
+
dispatchAnalyticsEvent: payload => {
|
|
37
|
+
var _api$analytics, _api$analytics$action;
|
|
38
|
+
return api === null || api === void 0 ? void 0 : (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : (_api$analytics$action = _api$analytics.actions) === null || _api$analytics$action === void 0 ? void 0 : _api$analytics$action.fireAnalyticsEvent(payload);
|
|
39
|
+
}
|
|
40
|
+
})
|
|
30
41
|
}];
|
|
31
42
|
},
|
|
32
43
|
actions: {
|
|
@@ -85,6 +96,7 @@ export const blockMenuPlugin = ({
|
|
|
85
96
|
popupsBoundariesElement,
|
|
86
97
|
popupsScrollableElement
|
|
87
98
|
}) {
|
|
99
|
+
refs.popupsMountPoint = popupsMountPoint || undefined;
|
|
88
100
|
return /*#__PURE__*/React.createElement(BlockMenuProvider, {
|
|
89
101
|
api: api,
|
|
90
102
|
editorView: editorView
|
|
@@ -76,6 +76,7 @@ export const transformNode = api => (targetType, metadata) => ({
|
|
|
76
76
|
isNested,
|
|
77
77
|
sourceNodesCount: sourceNodes.length,
|
|
78
78
|
sourceNodesCountByType: sourceNodeTypes,
|
|
79
|
+
sourceNodeType: sourceNodes.length === 1 ? sourceNodes[0].type.name : 'multiple',
|
|
79
80
|
startTime,
|
|
80
81
|
targetNodeType: targetType.name,
|
|
81
82
|
outputNodesCount: content.length,
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { bind } from 'bind-event-listener';
|
|
2
|
+
import { ACTION_SUBJECT_ID } from '@atlaskit/editor-common/analytics';
|
|
3
|
+
import { Experience, EXPERIENCE_ID, ExperienceCheckDomMutation, ExperienceCheckTimeout, getPopupContainerFromEditorView, popupWithNestedElement } from '@atlaskit/editor-common/experiences';
|
|
4
|
+
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
5
|
+
import { PluginKey } from '@atlaskit/editor-prosemirror/state';
|
|
6
|
+
const TIMEOUT_DURATION = 1000;
|
|
7
|
+
const pluginKey = new PluginKey('blockMenuExperiences');
|
|
8
|
+
const START_METHOD = {
|
|
9
|
+
DRAG_HANDLE_CLICK: 'dragHandleClick',
|
|
10
|
+
KEYBOARD: 'keyboard'
|
|
11
|
+
};
|
|
12
|
+
const ABORT_REASON = {
|
|
13
|
+
USER_CANCELED: 'userCanceled',
|
|
14
|
+
EDITOR_DESTROYED: 'editorDestroyed'
|
|
15
|
+
};
|
|
16
|
+
export const getBlockMenuExperiencesPlugin = ({
|
|
17
|
+
refs,
|
|
18
|
+
dispatchAnalyticsEvent
|
|
19
|
+
}) => {
|
|
20
|
+
let targetEl;
|
|
21
|
+
let editorViewEl;
|
|
22
|
+
const getPopupsTarget = () => {
|
|
23
|
+
if (!targetEl) {
|
|
24
|
+
targetEl = refs.popupsMountPoint || getPopupContainerFromEditorView(editorViewEl);
|
|
25
|
+
}
|
|
26
|
+
return targetEl;
|
|
27
|
+
};
|
|
28
|
+
const blockMenuOpenExperience = new Experience(EXPERIENCE_ID.MENU_OPEN, {
|
|
29
|
+
actionSubjectId: ACTION_SUBJECT_ID.BLOCK_MENU,
|
|
30
|
+
dispatchAnalyticsEvent,
|
|
31
|
+
checks: [new ExperienceCheckTimeout({
|
|
32
|
+
durationMs: TIMEOUT_DURATION
|
|
33
|
+
}), new ExperienceCheckDomMutation({
|
|
34
|
+
onDomMutation: ({
|
|
35
|
+
mutations
|
|
36
|
+
}) => {
|
|
37
|
+
if (mutations.some(isBlockMenuAddedInMutation)) {
|
|
38
|
+
return {
|
|
39
|
+
status: 'success'
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
return undefined;
|
|
43
|
+
},
|
|
44
|
+
observeConfig: () => ({
|
|
45
|
+
target: getPopupsTarget(),
|
|
46
|
+
options: {
|
|
47
|
+
childList: true
|
|
48
|
+
}
|
|
49
|
+
})
|
|
50
|
+
})]
|
|
51
|
+
});
|
|
52
|
+
const unbindClickListener = bind(document, {
|
|
53
|
+
type: 'click',
|
|
54
|
+
listener: event => {
|
|
55
|
+
if (!(event.target instanceof Element)) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
const target = event.target;
|
|
59
|
+
|
|
60
|
+
// Check if the click is on a drag handle
|
|
61
|
+
if (!isDragHandleElement(target)) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Don't start if block menu is already visible
|
|
66
|
+
if (isBlockMenuVisible(getPopupsTarget())) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
blockMenuOpenExperience.start({
|
|
70
|
+
method: START_METHOD.DRAG_HANDLE_CLICK
|
|
71
|
+
});
|
|
72
|
+
},
|
|
73
|
+
options: {
|
|
74
|
+
capture: true
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
const unbindKeydownListener = bind(document, {
|
|
78
|
+
type: 'keydown',
|
|
79
|
+
listener: event => {
|
|
80
|
+
if (!(event.target instanceof Element)) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
const target = event.target;
|
|
84
|
+
|
|
85
|
+
// Check if Enter or Space is pressed on a drag handle
|
|
86
|
+
if ((event.key === 'Enter' || event.key === ' ') && isDragHandleElement(target)) {
|
|
87
|
+
// Don't start if block menu is already visible
|
|
88
|
+
if (isBlockMenuVisible(getPopupsTarget())) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
blockMenuOpenExperience.start({
|
|
92
|
+
method: START_METHOD.KEYBOARD
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Abort on Escape key if block menu is not yet visible
|
|
97
|
+
if (event.key === 'Escape' && !isBlockMenuVisible(getPopupsTarget())) {
|
|
98
|
+
blockMenuOpenExperience.abort({
|
|
99
|
+
reason: ABORT_REASON.USER_CANCELED
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
options: {
|
|
104
|
+
capture: true
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
return new SafePlugin({
|
|
108
|
+
key: pluginKey,
|
|
109
|
+
view: editorView => {
|
|
110
|
+
editorViewEl = editorView.dom;
|
|
111
|
+
return {
|
|
112
|
+
destroy: () => {
|
|
113
|
+
blockMenuOpenExperience.abort({
|
|
114
|
+
reason: ABORT_REASON.EDITOR_DESTROYED
|
|
115
|
+
});
|
|
116
|
+
unbindClickListener();
|
|
117
|
+
unbindKeydownListener();
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
};
|
|
123
|
+
const isBlockMenuAddedInMutation = ({
|
|
124
|
+
type,
|
|
125
|
+
addedNodes
|
|
126
|
+
}) => {
|
|
127
|
+
return type === 'childList' && [...addedNodes].some(isBlockMenuWithinNode);
|
|
128
|
+
};
|
|
129
|
+
const isBlockMenuWithinNode = node => {
|
|
130
|
+
return popupWithNestedElement(node, '[data-testid="editor-block-menu"]') !== null;
|
|
131
|
+
};
|
|
132
|
+
const isDragHandleElement = element => {
|
|
133
|
+
return !!(element !== null && element !== void 0 && element.closest('[data-editor-block-ctrl-drag-handle]'));
|
|
134
|
+
};
|
|
135
|
+
const isBlockMenuVisible = popupsTarget => {
|
|
136
|
+
if (!popupsTarget) {
|
|
137
|
+
return false;
|
|
138
|
+
}
|
|
139
|
+
return popupWithNestedElement(popupsTarget, '[data-testid="editor-block-menu"]') !== null;
|
|
140
|
+
};
|
|
@@ -12,8 +12,6 @@ import { Popup } from '@atlaskit/editor-common/ui';
|
|
|
12
12
|
import { ArrowKeyNavigationProvider, ArrowKeyNavigationType } from '@atlaskit/editor-common/ui-menu';
|
|
13
13
|
import { OutsideClickTargetRefContext, withReactEditorViewOuterListeners } from '@atlaskit/editor-common/ui-react';
|
|
14
14
|
import { akEditorFloatingOverlapPanelZIndex } from '@atlaskit/editor-shared-styles';
|
|
15
|
-
import { fg } from '@atlaskit/platform-feature-flags';
|
|
16
|
-
import { conditionalHooksFactory } from '@atlaskit/platform-feature-flags-react';
|
|
17
15
|
import { Box } from '@atlaskit/primitives/compiled';
|
|
18
16
|
import { redo, undo } from '@atlaskit/prosemirror-history';
|
|
19
17
|
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
|
|
@@ -27,7 +25,7 @@ const DEFAULT_MENU_WIDTH = 230;
|
|
|
27
25
|
const DRAG_HANDLE_OFFSET_PADDING = 5;
|
|
28
26
|
const FALLBACK_MENU_HEIGHT = 300;
|
|
29
27
|
const PopupWithListeners = withReactEditorViewOuterListeners(Popup);
|
|
30
|
-
const useConditionalBlockMenuEffect =
|
|
28
|
+
const useConditionalBlockMenuEffect = ({
|
|
31
29
|
api,
|
|
32
30
|
isMenuOpen,
|
|
33
31
|
menuTriggerBy,
|
|
@@ -62,40 +60,7 @@ const useConditionalBlockMenuEffect = conditionalHooksFactory(() => fg('platform
|
|
|
62
60
|
prevIsMenuOpenRef.current = isMenuOpen;
|
|
63
61
|
api === null || api === void 0 ? void 0 : api.core.actions.execute(api === null || api === void 0 ? void 0 : (_api$userIntent = api.userIntent) === null || _api$userIntent === void 0 ? void 0 : _api$userIntent.commands.setCurrentUserIntent('blockMenuOpen'));
|
|
64
62
|
}, [api, isMenuOpen, menuTriggerBy, selectedByShortcutOrDragHandle, hasFocus, openedViaKeyboard, prevIsMenuOpenRef]);
|
|
65
|
-
}
|
|
66
|
-
api,
|
|
67
|
-
isMenuOpen,
|
|
68
|
-
menuTriggerBy,
|
|
69
|
-
selectedByShortcutOrDragHandle,
|
|
70
|
-
hasFocus,
|
|
71
|
-
currentUserIntent,
|
|
72
|
-
openedViaKeyboard,
|
|
73
|
-
prevIsMenuOpenRef
|
|
74
|
-
}) => {
|
|
75
|
-
useEffect(() => {
|
|
76
|
-
var _api$userIntent2;
|
|
77
|
-
if (!isMenuOpen || !menuTriggerBy || !selectedByShortcutOrDragHandle || !hasFocus || ['resizing', 'dragging'].includes(currentUserIntent || '')) {
|
|
78
|
-
return;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// Fire analytics event when block menu opens (only on first transition from closed to open)
|
|
82
|
-
if (!prevIsMenuOpenRef.current && isMenuOpen) {
|
|
83
|
-
var _api$analytics2;
|
|
84
|
-
api === null || api === void 0 ? void 0 : (_api$analytics2 = api.analytics) === null || _api$analytics2 === void 0 ? void 0 : _api$analytics2.actions.fireAnalyticsEvent({
|
|
85
|
-
action: ACTION.OPENED,
|
|
86
|
-
actionSubject: ACTION_SUBJECT.BLOCK_MENU,
|
|
87
|
-
eventType: EVENT_TYPE.UI,
|
|
88
|
-
attributes: {
|
|
89
|
-
inputMethod: openedViaKeyboard ? INPUT_METHOD.KEYBOARD : INPUT_METHOD.MOUSE
|
|
90
|
-
}
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
// Update the previous state
|
|
95
|
-
prevIsMenuOpenRef.current = isMenuOpen;
|
|
96
|
-
api === null || api === void 0 ? void 0 : api.core.actions.execute(api === null || api === void 0 ? void 0 : (_api$userIntent2 = api.userIntent) === null || _api$userIntent2 === void 0 ? void 0 : _api$userIntent2.commands.setCurrentUserIntent('blockMenuOpen'));
|
|
97
|
-
}, [api, isMenuOpen, menuTriggerBy, selectedByShortcutOrDragHandle, hasFocus, currentUserIntent, openedViaKeyboard, prevIsMenuOpenRef]);
|
|
98
|
-
});
|
|
63
|
+
};
|
|
99
64
|
const isSelectionWithinCodeBlock = state => {
|
|
100
65
|
const {
|
|
101
66
|
$from,
|
|
@@ -132,7 +97,7 @@ const BlockMenu = ({
|
|
|
132
97
|
boundariesElement,
|
|
133
98
|
scrollableElement
|
|
134
99
|
}) => {
|
|
135
|
-
var _editorView$dom, _ref, _api$
|
|
100
|
+
var _editorView$dom, _ref, _api$analytics2;
|
|
136
101
|
const {
|
|
137
102
|
menuTriggerBy,
|
|
138
103
|
isSelectedViaDragHandle,
|
|
@@ -174,7 +139,6 @@ const BlockMenu = ({
|
|
|
174
139
|
menuTriggerBy,
|
|
175
140
|
selectedByShortcutOrDragHandle,
|
|
176
141
|
hasFocus,
|
|
177
|
-
currentUserIntent: fg('platform_editor_toolbar_aifc_user_intent_fix') ? undefined : currentUserIntent,
|
|
178
142
|
openedViaKeyboard,
|
|
179
143
|
prevIsMenuOpenRef
|
|
180
144
|
});
|
|
@@ -218,14 +182,14 @@ const BlockMenu = ({
|
|
|
218
182
|
api === null || api === void 0 ? void 0 : api.core.actions.execute(({
|
|
219
183
|
tr
|
|
220
184
|
}) => {
|
|
221
|
-
var _api$blockControls2, _api$
|
|
185
|
+
var _api$blockControls2, _api$userIntent2;
|
|
222
186
|
api === null || api === void 0 ? void 0 : (_api$blockControls2 = api.blockControls) === null || _api$blockControls2 === void 0 ? void 0 : _api$blockControls2.commands.toggleBlockMenu({
|
|
223
187
|
closeMenu: true
|
|
224
188
|
})({
|
|
225
189
|
tr
|
|
226
190
|
});
|
|
227
191
|
onDropdownOpenChanged(false);
|
|
228
|
-
api === null || api === void 0 ? void 0 : (_api$
|
|
192
|
+
api === null || api === void 0 ? void 0 : (_api$userIntent2 = api.userIntent) === null || _api$userIntent2 === void 0 ? void 0 : _api$userIntent2.commands.setCurrentUserIntent(currentUserIntent === 'blockMenuOpen' ? 'default' : currentUserIntent || 'default')({
|
|
229
193
|
tr
|
|
230
194
|
});
|
|
231
195
|
return tr;
|
|
@@ -245,7 +209,7 @@ const BlockMenu = ({
|
|
|
245
209
|
}
|
|
246
210
|
return /*#__PURE__*/React.createElement(ErrorBoundary, {
|
|
247
211
|
component: ACTION_SUBJECT.BLOCK_MENU,
|
|
248
|
-
dispatchAnalyticsEvent: api === null || api === void 0 ? void 0 : (_api$
|
|
212
|
+
dispatchAnalyticsEvent: api === null || api === void 0 ? void 0 : (_api$analytics2 = api.analytics) === null || _api$analytics2 === void 0 ? void 0 : _api$analytics2.actions.fireAnalyticsEvent,
|
|
249
213
|
fallbackComponent: null
|
|
250
214
|
}, /*#__PURE__*/React.createElement(PopupWithListeners, {
|
|
251
215
|
alignX: 'right',
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import React, { useCallback, useEffect } from 'react';
|
|
2
2
|
import { injectIntl, useIntl } from 'react-intl-next';
|
|
3
|
-
import { ACTION, ACTION_SUBJECT, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
|
|
3
|
+
import { ACTION, ACTION_SUBJECT, EVENT_TYPE, INPUT_METHOD } from '@atlaskit/editor-common/analytics';
|
|
4
4
|
import { blockMenuMessages } from '@atlaskit/editor-common/messages';
|
|
5
|
-
import { deleteSelectedRange } from '@atlaskit/editor-common/selection';
|
|
5
|
+
import { deleteSelectedRange, getSourceNodesFromSelectionRange } from '@atlaskit/editor-common/selection';
|
|
6
6
|
import { ToolbarDropdownItem } from '@atlaskit/editor-toolbar';
|
|
7
7
|
import DeleteIcon from '@atlaskit/icon/core/delete';
|
|
8
8
|
import { Box } from '@atlaskit/primitives/box';
|
|
@@ -28,7 +28,30 @@ const DeleteDropdownItemContent = ({
|
|
|
28
28
|
eventType: EVENT_TYPE.UI
|
|
29
29
|
};
|
|
30
30
|
api === null || api === void 0 ? void 0 : (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : (_api$analytics$action = _api$analytics.actions) === null || _api$analytics$action === void 0 ? void 0 : _api$analytics$action.attachAnalyticsEvent(payload)(tr);
|
|
31
|
-
|
|
31
|
+
|
|
32
|
+
// Extract node information before deletion
|
|
33
|
+
const preservedSelection = api === null || api === void 0 ? void 0 : (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 ? void 0 : (_api$blockControls$sh = _api$blockControls.sharedState.currentState()) === null || _api$blockControls$sh === void 0 ? void 0 : _api$blockControls$sh.preservedSelection;
|
|
34
|
+
const selection = preservedSelection || tr.selection;
|
|
35
|
+
const sourceNodes = getSourceNodesFromSelectionRange(tr, selection);
|
|
36
|
+
const nodeCount = sourceNodes.length;
|
|
37
|
+
|
|
38
|
+
// Fire node deletion analytics event if nodes are being deleted
|
|
39
|
+
if (nodeCount > 0) {
|
|
40
|
+
var _api$analytics2, _api$analytics2$actio;
|
|
41
|
+
const nodeType = sourceNodes.length === 1 ? sourceNodes[0].type.name : 'multiple';
|
|
42
|
+
const nodeDeletedPayload = {
|
|
43
|
+
action: ACTION.DELETED,
|
|
44
|
+
actionSubject: ACTION_SUBJECT.ELEMENT,
|
|
45
|
+
attributes: {
|
|
46
|
+
inputMethod: INPUT_METHOD.BLOCK_MENU,
|
|
47
|
+
nodeType,
|
|
48
|
+
nodeCount
|
|
49
|
+
},
|
|
50
|
+
eventType: EVENT_TYPE.TRACK
|
|
51
|
+
};
|
|
52
|
+
api === null || api === void 0 ? void 0 : (_api$analytics2 = api.analytics) === null || _api$analytics2 === void 0 ? void 0 : (_api$analytics2$actio = _api$analytics2.actions) === null || _api$analytics2$actio === void 0 ? void 0 : _api$analytics2$actio.attachAnalyticsEvent(nodeDeletedPayload)(tr);
|
|
53
|
+
}
|
|
54
|
+
deleteSelectedRange(tr, preservedSelection);
|
|
32
55
|
api === null || api === void 0 ? void 0 : (_api$blockControls2 = api.blockControls) === null || _api$blockControls2 === void 0 ? void 0 : (_api$blockControls2$c = _api$blockControls2.commands) === null || _api$blockControls2$c === void 0 ? void 0 : _api$blockControls2$c.toggleBlockMenu({
|
|
33
56
|
closeMenu: true
|
|
34
57
|
})({
|
|
@@ -3,6 +3,7 @@ import { createBlockMenuRegistry } from './editor-actions';
|
|
|
3
3
|
import { isTransformToTargetDisabled } from './editor-actions/isTransformToTargetDisabled';
|
|
4
4
|
import { formatNode as _formatNode } from './editor-commands/formatNode';
|
|
5
5
|
import { transformNode as _transformNode } from './editor-commands/transformNode';
|
|
6
|
+
import { getBlockMenuExperiencesPlugin } from './pm-plugins/experiences/block-menu-experiences';
|
|
6
7
|
import { keymapPlugin } from './pm-plugins/keymap';
|
|
7
8
|
import { blockMenuPluginKey, createPlugin } from './pm-plugins/main';
|
|
8
9
|
import BlockMenu from './ui/block-menu';
|
|
@@ -17,6 +18,7 @@ export var blockMenuPlugin = function blockMenuPlugin(_ref) {
|
|
|
17
18
|
api: api,
|
|
18
19
|
config: config
|
|
19
20
|
}));
|
|
21
|
+
var refs = {};
|
|
20
22
|
return {
|
|
21
23
|
name: 'blockMenu',
|
|
22
24
|
pmPlugins: function pmPlugins() {
|
|
@@ -30,6 +32,17 @@ export var blockMenuPlugin = function blockMenuPlugin(_ref) {
|
|
|
30
32
|
plugin: function plugin() {
|
|
31
33
|
return keymapPlugin(api, config);
|
|
32
34
|
}
|
|
35
|
+
}, {
|
|
36
|
+
name: 'blockMenuExperiences',
|
|
37
|
+
plugin: function plugin() {
|
|
38
|
+
return getBlockMenuExperiencesPlugin({
|
|
39
|
+
refs: refs,
|
|
40
|
+
dispatchAnalyticsEvent: function dispatchAnalyticsEvent(payload) {
|
|
41
|
+
var _api$analytics;
|
|
42
|
+
return api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 || (_api$analytics = _api$analytics.actions) === null || _api$analytics === void 0 ? void 0 : _api$analytics.fireAnalyticsEvent(payload);
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
}
|
|
33
46
|
}];
|
|
34
47
|
},
|
|
35
48
|
actions: {
|
|
@@ -87,6 +100,7 @@ export var blockMenuPlugin = function blockMenuPlugin(_ref) {
|
|
|
87
100
|
popupsMountPoint = _ref2.popupsMountPoint,
|
|
88
101
|
popupsBoundariesElement = _ref2.popupsBoundariesElement,
|
|
89
102
|
popupsScrollableElement = _ref2.popupsScrollableElement;
|
|
103
|
+
refs.popupsMountPoint = popupsMountPoint || undefined;
|
|
90
104
|
return /*#__PURE__*/React.createElement(BlockMenuProvider, {
|
|
91
105
|
api: api,
|
|
92
106
|
editorView: editorView
|
|
@@ -78,6 +78,7 @@ export var transformNode = function transformNode(api) {
|
|
|
78
78
|
isNested: isNested,
|
|
79
79
|
sourceNodesCount: sourceNodes.length,
|
|
80
80
|
sourceNodesCountByType: sourceNodeTypes,
|
|
81
|
+
sourceNodeType: sourceNodes.length === 1 ? sourceNodes[0].type.name : 'multiple',
|
|
81
82
|
startTime: startTime,
|
|
82
83
|
targetNodeType: targetType.name,
|
|
83
84
|
outputNodesCount: content.length,
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
|
|
2
|
+
import { bind } from 'bind-event-listener';
|
|
3
|
+
import { ACTION_SUBJECT_ID } from '@atlaskit/editor-common/analytics';
|
|
4
|
+
import { Experience, EXPERIENCE_ID, ExperienceCheckDomMutation, ExperienceCheckTimeout, getPopupContainerFromEditorView, popupWithNestedElement } from '@atlaskit/editor-common/experiences';
|
|
5
|
+
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
6
|
+
import { PluginKey } from '@atlaskit/editor-prosemirror/state';
|
|
7
|
+
var TIMEOUT_DURATION = 1000;
|
|
8
|
+
var pluginKey = new PluginKey('blockMenuExperiences');
|
|
9
|
+
var START_METHOD = {
|
|
10
|
+
DRAG_HANDLE_CLICK: 'dragHandleClick',
|
|
11
|
+
KEYBOARD: 'keyboard'
|
|
12
|
+
};
|
|
13
|
+
var ABORT_REASON = {
|
|
14
|
+
USER_CANCELED: 'userCanceled',
|
|
15
|
+
EDITOR_DESTROYED: 'editorDestroyed'
|
|
16
|
+
};
|
|
17
|
+
export var getBlockMenuExperiencesPlugin = function getBlockMenuExperiencesPlugin(_ref) {
|
|
18
|
+
var refs = _ref.refs,
|
|
19
|
+
dispatchAnalyticsEvent = _ref.dispatchAnalyticsEvent;
|
|
20
|
+
var targetEl;
|
|
21
|
+
var editorViewEl;
|
|
22
|
+
var getPopupsTarget = function getPopupsTarget() {
|
|
23
|
+
if (!targetEl) {
|
|
24
|
+
targetEl = refs.popupsMountPoint || getPopupContainerFromEditorView(editorViewEl);
|
|
25
|
+
}
|
|
26
|
+
return targetEl;
|
|
27
|
+
};
|
|
28
|
+
var blockMenuOpenExperience = new Experience(EXPERIENCE_ID.MENU_OPEN, {
|
|
29
|
+
actionSubjectId: ACTION_SUBJECT_ID.BLOCK_MENU,
|
|
30
|
+
dispatchAnalyticsEvent: dispatchAnalyticsEvent,
|
|
31
|
+
checks: [new ExperienceCheckTimeout({
|
|
32
|
+
durationMs: TIMEOUT_DURATION
|
|
33
|
+
}), new ExperienceCheckDomMutation({
|
|
34
|
+
onDomMutation: function onDomMutation(_ref2) {
|
|
35
|
+
var mutations = _ref2.mutations;
|
|
36
|
+
if (mutations.some(isBlockMenuAddedInMutation)) {
|
|
37
|
+
return {
|
|
38
|
+
status: 'success'
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
return undefined;
|
|
42
|
+
},
|
|
43
|
+
observeConfig: function observeConfig() {
|
|
44
|
+
return {
|
|
45
|
+
target: getPopupsTarget(),
|
|
46
|
+
options: {
|
|
47
|
+
childList: true
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
})]
|
|
52
|
+
});
|
|
53
|
+
var unbindClickListener = bind(document, {
|
|
54
|
+
type: 'click',
|
|
55
|
+
listener: function listener(event) {
|
|
56
|
+
if (!(event.target instanceof Element)) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
var target = event.target;
|
|
60
|
+
|
|
61
|
+
// Check if the click is on a drag handle
|
|
62
|
+
if (!isDragHandleElement(target)) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Don't start if block menu is already visible
|
|
67
|
+
if (isBlockMenuVisible(getPopupsTarget())) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
blockMenuOpenExperience.start({
|
|
71
|
+
method: START_METHOD.DRAG_HANDLE_CLICK
|
|
72
|
+
});
|
|
73
|
+
},
|
|
74
|
+
options: {
|
|
75
|
+
capture: true
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
var unbindKeydownListener = bind(document, {
|
|
79
|
+
type: 'keydown',
|
|
80
|
+
listener: function listener(event) {
|
|
81
|
+
if (!(event.target instanceof Element)) {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
var target = event.target;
|
|
85
|
+
|
|
86
|
+
// Check if Enter or Space is pressed on a drag handle
|
|
87
|
+
if ((event.key === 'Enter' || event.key === ' ') && isDragHandleElement(target)) {
|
|
88
|
+
// Don't start if block menu is already visible
|
|
89
|
+
if (isBlockMenuVisible(getPopupsTarget())) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
blockMenuOpenExperience.start({
|
|
93
|
+
method: START_METHOD.KEYBOARD
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Abort on Escape key if block menu is not yet visible
|
|
98
|
+
if (event.key === 'Escape' && !isBlockMenuVisible(getPopupsTarget())) {
|
|
99
|
+
blockMenuOpenExperience.abort({
|
|
100
|
+
reason: ABORT_REASON.USER_CANCELED
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
options: {
|
|
105
|
+
capture: true
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
return new SafePlugin({
|
|
109
|
+
key: pluginKey,
|
|
110
|
+
view: function view(editorView) {
|
|
111
|
+
editorViewEl = editorView.dom;
|
|
112
|
+
return {
|
|
113
|
+
destroy: function destroy() {
|
|
114
|
+
blockMenuOpenExperience.abort({
|
|
115
|
+
reason: ABORT_REASON.EDITOR_DESTROYED
|
|
116
|
+
});
|
|
117
|
+
unbindClickListener();
|
|
118
|
+
unbindKeydownListener();
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
};
|
|
124
|
+
var isBlockMenuAddedInMutation = function isBlockMenuAddedInMutation(_ref3) {
|
|
125
|
+
var type = _ref3.type,
|
|
126
|
+
addedNodes = _ref3.addedNodes;
|
|
127
|
+
return type === 'childList' && _toConsumableArray(addedNodes).some(isBlockMenuWithinNode);
|
|
128
|
+
};
|
|
129
|
+
var isBlockMenuWithinNode = function isBlockMenuWithinNode(node) {
|
|
130
|
+
return popupWithNestedElement(node, '[data-testid="editor-block-menu"]') !== null;
|
|
131
|
+
};
|
|
132
|
+
var isDragHandleElement = function isDragHandleElement(element) {
|
|
133
|
+
return !!(element !== null && element !== void 0 && element.closest('[data-editor-block-ctrl-drag-handle]'));
|
|
134
|
+
};
|
|
135
|
+
var isBlockMenuVisible = function isBlockMenuVisible(popupsTarget) {
|
|
136
|
+
if (!popupsTarget) {
|
|
137
|
+
return false;
|
|
138
|
+
}
|
|
139
|
+
return popupWithNestedElement(popupsTarget, '[data-testid="editor-block-menu"]') !== null;
|
|
140
|
+
};
|
|
@@ -13,8 +13,6 @@ import { Popup } from '@atlaskit/editor-common/ui';
|
|
|
13
13
|
import { ArrowKeyNavigationProvider, ArrowKeyNavigationType } from '@atlaskit/editor-common/ui-menu';
|
|
14
14
|
import { OutsideClickTargetRefContext, withReactEditorViewOuterListeners } from '@atlaskit/editor-common/ui-react';
|
|
15
15
|
import { akEditorFloatingOverlapPanelZIndex } from '@atlaskit/editor-shared-styles';
|
|
16
|
-
import { fg } from '@atlaskit/platform-feature-flags';
|
|
17
|
-
import { conditionalHooksFactory } from '@atlaskit/platform-feature-flags-react';
|
|
18
16
|
import { Box } from '@atlaskit/primitives/compiled';
|
|
19
17
|
import { redo, undo } from '@atlaskit/prosemirror-history';
|
|
20
18
|
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
|
|
@@ -28,9 +26,7 @@ var DEFAULT_MENU_WIDTH = 230;
|
|
|
28
26
|
var DRAG_HANDLE_OFFSET_PADDING = 5;
|
|
29
27
|
var FALLBACK_MENU_HEIGHT = 300;
|
|
30
28
|
var PopupWithListeners = withReactEditorViewOuterListeners(Popup);
|
|
31
|
-
var useConditionalBlockMenuEffect =
|
|
32
|
-
return fg('platform_editor_toolbar_aifc_user_intent_fix');
|
|
33
|
-
}, function (_ref) {
|
|
29
|
+
var useConditionalBlockMenuEffect = function useConditionalBlockMenuEffect(_ref) {
|
|
34
30
|
var api = _ref.api,
|
|
35
31
|
isMenuOpen = _ref.isMenuOpen,
|
|
36
32
|
menuTriggerBy = _ref.menuTriggerBy,
|
|
@@ -64,49 +60,17 @@ var useConditionalBlockMenuEffect = conditionalHooksFactory(function () {
|
|
|
64
60
|
prevIsMenuOpenRef.current = isMenuOpen;
|
|
65
61
|
api === null || api === void 0 || api.core.actions.execute(api === null || api === void 0 || (_api$userIntent = api.userIntent) === null || _api$userIntent === void 0 ? void 0 : _api$userIntent.commands.setCurrentUserIntent('blockMenuOpen'));
|
|
66
62
|
}, [api, isMenuOpen, menuTriggerBy, selectedByShortcutOrDragHandle, hasFocus, openedViaKeyboard, prevIsMenuOpenRef]);
|
|
67
|
-
}
|
|
68
|
-
var api = _ref2.api,
|
|
69
|
-
isMenuOpen = _ref2.isMenuOpen,
|
|
70
|
-
menuTriggerBy = _ref2.menuTriggerBy,
|
|
71
|
-
selectedByShortcutOrDragHandle = _ref2.selectedByShortcutOrDragHandle,
|
|
72
|
-
hasFocus = _ref2.hasFocus,
|
|
73
|
-
currentUserIntent = _ref2.currentUserIntent,
|
|
74
|
-
openedViaKeyboard = _ref2.openedViaKeyboard,
|
|
75
|
-
prevIsMenuOpenRef = _ref2.prevIsMenuOpenRef;
|
|
76
|
-
useEffect(function () {
|
|
77
|
-
var _api$userIntent2;
|
|
78
|
-
if (!isMenuOpen || !menuTriggerBy || !selectedByShortcutOrDragHandle || !hasFocus || ['resizing', 'dragging'].includes(currentUserIntent || '')) {
|
|
79
|
-
return;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
// Fire analytics event when block menu opens (only on first transition from closed to open)
|
|
83
|
-
if (!prevIsMenuOpenRef.current && isMenuOpen) {
|
|
84
|
-
var _api$analytics2;
|
|
85
|
-
api === null || api === void 0 || (_api$analytics2 = api.analytics) === null || _api$analytics2 === void 0 || _api$analytics2.actions.fireAnalyticsEvent({
|
|
86
|
-
action: ACTION.OPENED,
|
|
87
|
-
actionSubject: ACTION_SUBJECT.BLOCK_MENU,
|
|
88
|
-
eventType: EVENT_TYPE.UI,
|
|
89
|
-
attributes: {
|
|
90
|
-
inputMethod: openedViaKeyboard ? INPUT_METHOD.KEYBOARD : INPUT_METHOD.MOUSE
|
|
91
|
-
}
|
|
92
|
-
});
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// Update the previous state
|
|
96
|
-
prevIsMenuOpenRef.current = isMenuOpen;
|
|
97
|
-
api === null || api === void 0 || api.core.actions.execute(api === null || api === void 0 || (_api$userIntent2 = api.userIntent) === null || _api$userIntent2 === void 0 ? void 0 : _api$userIntent2.commands.setCurrentUserIntent('blockMenuOpen'));
|
|
98
|
-
}, [api, isMenuOpen, menuTriggerBy, selectedByShortcutOrDragHandle, hasFocus, currentUserIntent, openedViaKeyboard, prevIsMenuOpenRef]);
|
|
99
|
-
});
|
|
63
|
+
};
|
|
100
64
|
var isSelectionWithinCodeBlock = function isSelectionWithinCodeBlock(state) {
|
|
101
65
|
var _state$selection = state.selection,
|
|
102
66
|
$from = _state$selection.$from,
|
|
103
67
|
$to = _state$selection.$to;
|
|
104
68
|
return $from.sameParent($to) && $from.parent.type === state.schema.nodes.codeBlock;
|
|
105
69
|
};
|
|
106
|
-
var BlockMenuContent = function BlockMenuContent(
|
|
70
|
+
var BlockMenuContent = function BlockMenuContent(_ref2) {
|
|
107
71
|
var _api$blockMenu;
|
|
108
|
-
var api =
|
|
109
|
-
setRef =
|
|
72
|
+
var api = _ref2.api,
|
|
73
|
+
setRef = _ref2.setRef;
|
|
110
74
|
var blockMenuComponents = api === null || api === void 0 || (_api$blockMenu = api.blockMenu) === null || _api$blockMenu === void 0 ? void 0 : _api$blockMenu.actions.getBlockMenuComponents();
|
|
111
75
|
var setOutsideClickTargetRef = useContext(OutsideClickTargetRefContext);
|
|
112
76
|
var ref = function ref(el) {
|
|
@@ -126,13 +90,13 @@ var BlockMenuContent = function BlockMenuContent(_ref3) {
|
|
|
126
90
|
allRegisteredComponents: blockMenuComponents || []
|
|
127
91
|
})));
|
|
128
92
|
};
|
|
129
|
-
var BlockMenu = function BlockMenu(
|
|
130
|
-
var _editorView$dom,
|
|
131
|
-
var editorView =
|
|
132
|
-
api =
|
|
133
|
-
mountTo =
|
|
134
|
-
boundariesElement =
|
|
135
|
-
scrollableElement =
|
|
93
|
+
var BlockMenu = function BlockMenu(_ref3) {
|
|
94
|
+
var _editorView$dom, _ref4, _api$analytics2;
|
|
95
|
+
var editorView = _ref3.editorView,
|
|
96
|
+
api = _ref3.api,
|
|
97
|
+
mountTo = _ref3.mountTo,
|
|
98
|
+
boundariesElement = _ref3.boundariesElement,
|
|
99
|
+
scrollableElement = _ref3.scrollableElement;
|
|
136
100
|
var _useSharedPluginState = useSharedPluginStateWithSelector(api, ['blockControls', 'userIntent'], function (states) {
|
|
137
101
|
var _states$blockControls, _states$blockControls2, _states$blockControls3, _states$userIntentSta, _states$blockControls4;
|
|
138
102
|
return {
|
|
@@ -165,7 +129,7 @@ var BlockMenu = function BlockMenu(_ref4) {
|
|
|
165
129
|
}
|
|
166
130
|
setMenuHeight(((_popupRef$current = popupRef.current) === null || _popupRef$current === void 0 ? void 0 : _popupRef$current.clientHeight) || FALLBACK_MENU_HEIGHT);
|
|
167
131
|
}, [isMenuOpen]);
|
|
168
|
-
var hasFocus = (
|
|
132
|
+
var hasFocus = (_ref4 = (editorView === null || editorView === void 0 ? void 0 : editorView.hasFocus()) || document.activeElement === targetHandleRef || popupRef.current && (popupRef.current.contains(document.activeElement) || popupRef.current === document.activeElement)) !== null && _ref4 !== void 0 ? _ref4 : false;
|
|
169
133
|
var selectedByShortcutOrDragHandle = !!isSelectedViaDragHandle || !!openedViaKeyboard;
|
|
170
134
|
|
|
171
135
|
// Use conditional hook based on feature flag
|
|
@@ -175,7 +139,6 @@ var BlockMenu = function BlockMenu(_ref4) {
|
|
|
175
139
|
menuTriggerBy: menuTriggerBy,
|
|
176
140
|
selectedByShortcutOrDragHandle: selectedByShortcutOrDragHandle,
|
|
177
141
|
hasFocus: hasFocus,
|
|
178
|
-
currentUserIntent: fg('platform_editor_toolbar_aifc_user_intent_fix') ? undefined : currentUserIntent,
|
|
179
142
|
openedViaKeyboard: openedViaKeyboard,
|
|
180
143
|
prevIsMenuOpenRef: prevIsMenuOpenRef
|
|
181
144
|
});
|
|
@@ -216,16 +179,16 @@ var BlockMenu = function BlockMenu(_ref4) {
|
|
|
216
179
|
closeMenu();
|
|
217
180
|
};
|
|
218
181
|
var closeMenu = function closeMenu() {
|
|
219
|
-
api === null || api === void 0 || api.core.actions.execute(function (
|
|
220
|
-
var _api$blockControls2, _api$
|
|
221
|
-
var tr =
|
|
182
|
+
api === null || api === void 0 || api.core.actions.execute(function (_ref5) {
|
|
183
|
+
var _api$blockControls2, _api$userIntent2;
|
|
184
|
+
var tr = _ref5.tr;
|
|
222
185
|
api === null || api === void 0 || (_api$blockControls2 = api.blockControls) === null || _api$blockControls2 === void 0 || _api$blockControls2.commands.toggleBlockMenu({
|
|
223
186
|
closeMenu: true
|
|
224
187
|
})({
|
|
225
188
|
tr: tr
|
|
226
189
|
});
|
|
227
190
|
onDropdownOpenChanged(false);
|
|
228
|
-
api === null || api === void 0 || (_api$
|
|
191
|
+
api === null || api === void 0 || (_api$userIntent2 = api.userIntent) === null || _api$userIntent2 === void 0 || _api$userIntent2.commands.setCurrentUserIntent(currentUserIntent === 'blockMenuOpen' ? 'default' : currentUserIntent || 'default')({
|
|
229
192
|
tr: tr
|
|
230
193
|
});
|
|
231
194
|
return tr;
|
|
@@ -245,7 +208,7 @@ var BlockMenu = function BlockMenu(_ref4) {
|
|
|
245
208
|
}
|
|
246
209
|
return /*#__PURE__*/React.createElement(ErrorBoundary, {
|
|
247
210
|
component: ACTION_SUBJECT.BLOCK_MENU,
|
|
248
|
-
dispatchAnalyticsEvent: api === null || api === void 0 || (_api$
|
|
211
|
+
dispatchAnalyticsEvent: api === null || api === void 0 || (_api$analytics2 = api.analytics) === null || _api$analytics2 === void 0 ? void 0 : _api$analytics2.actions.fireAnalyticsEvent,
|
|
249
212
|
fallbackComponent: null
|
|
250
213
|
}, /*#__PURE__*/React.createElement(PopupWithListeners, {
|
|
251
214
|
alignX: 'right',
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import React, { useCallback, useEffect } from 'react';
|
|
2
2
|
import { injectIntl, useIntl } from 'react-intl-next';
|
|
3
|
-
import { ACTION, ACTION_SUBJECT, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
|
|
3
|
+
import { ACTION, ACTION_SUBJECT, EVENT_TYPE, INPUT_METHOD } from '@atlaskit/editor-common/analytics';
|
|
4
4
|
import { blockMenuMessages } from '@atlaskit/editor-common/messages';
|
|
5
|
-
import { deleteSelectedRange } from '@atlaskit/editor-common/selection';
|
|
5
|
+
import { deleteSelectedRange, getSourceNodesFromSelectionRange } from '@atlaskit/editor-common/selection';
|
|
6
6
|
import { ToolbarDropdownItem } from '@atlaskit/editor-toolbar';
|
|
7
7
|
import DeleteIcon from '@atlaskit/icon/core/delete';
|
|
8
8
|
import { Box } from '@atlaskit/primitives/box';
|
|
@@ -25,7 +25,30 @@ var DeleteDropdownItemContent = function DeleteDropdownItemContent(_ref) {
|
|
|
25
25
|
eventType: EVENT_TYPE.UI
|
|
26
26
|
};
|
|
27
27
|
api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 || (_api$analytics = _api$analytics.actions) === null || _api$analytics === void 0 || _api$analytics.attachAnalyticsEvent(payload)(tr);
|
|
28
|
-
|
|
28
|
+
|
|
29
|
+
// Extract node information before deletion
|
|
30
|
+
var preservedSelection = api === null || api === void 0 || (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 || (_api$blockControls = _api$blockControls.sharedState.currentState()) === null || _api$blockControls === void 0 ? void 0 : _api$blockControls.preservedSelection;
|
|
31
|
+
var selection = preservedSelection || tr.selection;
|
|
32
|
+
var sourceNodes = getSourceNodesFromSelectionRange(tr, selection);
|
|
33
|
+
var nodeCount = sourceNodes.length;
|
|
34
|
+
|
|
35
|
+
// Fire node deletion analytics event if nodes are being deleted
|
|
36
|
+
if (nodeCount > 0) {
|
|
37
|
+
var _api$analytics2;
|
|
38
|
+
var nodeType = sourceNodes.length === 1 ? sourceNodes[0].type.name : 'multiple';
|
|
39
|
+
var nodeDeletedPayload = {
|
|
40
|
+
action: ACTION.DELETED,
|
|
41
|
+
actionSubject: ACTION_SUBJECT.ELEMENT,
|
|
42
|
+
attributes: {
|
|
43
|
+
inputMethod: INPUT_METHOD.BLOCK_MENU,
|
|
44
|
+
nodeType: nodeType,
|
|
45
|
+
nodeCount: nodeCount
|
|
46
|
+
},
|
|
47
|
+
eventType: EVENT_TYPE.TRACK
|
|
48
|
+
};
|
|
49
|
+
api === null || api === void 0 || (_api$analytics2 = api.analytics) === null || _api$analytics2 === void 0 || (_api$analytics2 = _api$analytics2.actions) === null || _api$analytics2 === void 0 || _api$analytics2.attachAnalyticsEvent(nodeDeletedPayload)(tr);
|
|
50
|
+
}
|
|
51
|
+
deleteSelectedRange(tr, preservedSelection);
|
|
29
52
|
api === null || api === void 0 || (_api$blockControls2 = api.blockControls) === null || _api$blockControls2 === void 0 || (_api$blockControls2 = _api$blockControls2.commands) === null || _api$blockControls2 === void 0 || _api$blockControls2.toggleBlockMenu({
|
|
30
53
|
closeMenu: true
|
|
31
54
|
})({
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type DispatchAnalyticsEvent } from '@atlaskit/editor-common/analytics';
|
|
2
|
+
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
3
|
+
type ExperienceOptions = {
|
|
4
|
+
dispatchAnalyticsEvent: DispatchAnalyticsEvent;
|
|
5
|
+
refs: {
|
|
6
|
+
popupsMountPoint?: HTMLElement;
|
|
7
|
+
};
|
|
8
|
+
};
|
|
9
|
+
export declare const getBlockMenuExperiencesPlugin: ({ refs, dispatchAnalyticsEvent, }: ExperienceOptions) => SafePlugin<any>;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type DispatchAnalyticsEvent } from '@atlaskit/editor-common/analytics';
|
|
2
|
+
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
3
|
+
type ExperienceOptions = {
|
|
4
|
+
dispatchAnalyticsEvent: DispatchAnalyticsEvent;
|
|
5
|
+
refs: {
|
|
6
|
+
popupsMountPoint?: HTMLElement;
|
|
7
|
+
};
|
|
8
|
+
};
|
|
9
|
+
export declare const getBlockMenuExperiencesPlugin: ({ refs, dispatchAnalyticsEvent, }: ExperienceOptions) => SafePlugin<any>;
|
|
10
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-block-menu",
|
|
3
|
-
"version": "6.0.
|
|
3
|
+
"version": "6.0.27",
|
|
4
4
|
"description": "BlockMenu plugin for @atlaskit/editor-core",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"@atlaskit/css": "^0.19.0",
|
|
33
33
|
"@atlaskit/dropdown-menu": "^16.4.0",
|
|
34
34
|
"@atlaskit/editor-plugin-analytics": "^7.0.0",
|
|
35
|
-
"@atlaskit/editor-plugin-block-controls": "^8.
|
|
35
|
+
"@atlaskit/editor-plugin-block-controls": "^8.1.0",
|
|
36
36
|
"@atlaskit/editor-plugin-decorations": "^7.0.0",
|
|
37
37
|
"@atlaskit/editor-plugin-selection": "^7.0.0",
|
|
38
38
|
"@atlaskit/editor-plugin-user-intent": "^5.0.0",
|
|
@@ -46,12 +46,13 @@
|
|
|
46
46
|
"@atlaskit/platform-feature-flags-react": "^0.4.0",
|
|
47
47
|
"@atlaskit/primitives": "^17.1.0",
|
|
48
48
|
"@atlaskit/prosemirror-history": "^0.2.0",
|
|
49
|
-
"@atlaskit/tmp-editor-statsig": "^
|
|
49
|
+
"@atlaskit/tmp-editor-statsig": "^17.2.0",
|
|
50
50
|
"@atlaskit/tokens": "^10.1.0",
|
|
51
|
-
"@babel/runtime": "^7.0.0"
|
|
51
|
+
"@babel/runtime": "^7.0.0",
|
|
52
|
+
"bind-event-listener": "^3.0.0"
|
|
52
53
|
},
|
|
53
54
|
"peerDependencies": {
|
|
54
|
-
"@atlaskit/editor-common": "^111.
|
|
55
|
+
"@atlaskit/editor-common": "^111.9.0",
|
|
55
56
|
"react": "^18.2.0",
|
|
56
57
|
"react-intl-next": "npm:react-intl@^5.18.1"
|
|
57
58
|
},
|
|
@@ -94,9 +95,6 @@
|
|
|
94
95
|
"platform-feature-flags": {
|
|
95
96
|
"platform_editor_adf_with_localid": {
|
|
96
97
|
"type": "boolean"
|
|
97
|
-
},
|
|
98
|
-
"platform_editor_toolbar_aifc_user_intent_fix": {
|
|
99
|
-
"type": "boolean"
|
|
100
98
|
}
|
|
101
99
|
}
|
|
102
100
|
}
|