@atlaskit/editor-plugin-block-controls 8.7.2 → 8.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -0
- package/dist/cjs/blockControlsPlugin.js +14 -3
- package/dist/cjs/pm-plugins/decorations-drag-handle.js +3 -0
- package/dist/cjs/pm-plugins/decorations-quick-insert-button.js +3 -0
- package/dist/cjs/pm-plugins/handle-mouse-over.js +27 -11
- package/dist/cjs/pm-plugins/interaction-tracking/commands.js +12 -1
- package/dist/cjs/pm-plugins/interaction-tracking/handle-mouse-move.js +96 -1
- package/dist/cjs/pm-plugins/interaction-tracking/pm-plugin.js +92 -3
- package/dist/cjs/pm-plugins/main.js +129 -25
- package/dist/cjs/pm-plugins/vanilla-quick-insert.js +36 -13
- package/dist/cjs/ui/drag-handle.js +19 -9
- package/dist/cjs/ui/global-styles.js +9 -4
- package/dist/cjs/ui/quick-insert-button.js +16 -3
- package/dist/cjs/ui/visibility-container.js +70 -9
- package/dist/es2019/blockControlsPlugin.js +12 -3
- package/dist/es2019/pm-plugins/decorations-drag-handle.js +3 -0
- package/dist/es2019/pm-plugins/decorations-quick-insert-button.js +3 -0
- package/dist/es2019/pm-plugins/handle-mouse-over.js +27 -11
- package/dist/es2019/pm-plugins/interaction-tracking/commands.js +11 -0
- package/dist/es2019/pm-plugins/interaction-tracking/handle-mouse-move.js +98 -3
- package/dist/es2019/pm-plugins/interaction-tracking/pm-plugin.js +89 -4
- package/dist/es2019/pm-plugins/main.js +73 -18
- package/dist/es2019/pm-plugins/vanilla-quick-insert.js +27 -3
- package/dist/es2019/ui/drag-handle.js +19 -9
- package/dist/es2019/ui/global-styles.js +9 -3
- package/dist/es2019/ui/quick-insert-button.js +17 -3
- package/dist/es2019/ui/visibility-container.js +65 -9
- package/dist/esm/blockControlsPlugin.js +14 -3
- package/dist/esm/pm-plugins/decorations-drag-handle.js +3 -0
- package/dist/esm/pm-plugins/decorations-quick-insert-button.js +3 -0
- package/dist/esm/pm-plugins/handle-mouse-over.js +27 -11
- package/dist/esm/pm-plugins/interaction-tracking/commands.js +11 -0
- package/dist/esm/pm-plugins/interaction-tracking/handle-mouse-move.js +98 -2
- package/dist/esm/pm-plugins/interaction-tracking/pm-plugin.js +93 -3
- package/dist/esm/pm-plugins/main.js +129 -25
- package/dist/esm/pm-plugins/vanilla-quick-insert.js +36 -13
- package/dist/esm/ui/drag-handle.js +19 -9
- package/dist/esm/ui/global-styles.js +9 -4
- package/dist/esm/ui/quick-insert-button.js +16 -3
- package/dist/esm/ui/visibility-container.js +68 -9
- package/dist/types/blockControlsPluginType.d.ts +25 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/pm-plugins/interaction-tracking/commands.d.ts +2 -0
- package/dist/types/pm-plugins/interaction-tracking/handle-mouse-move.d.ts +2 -2
- package/dist/types/pm-plugins/interaction-tracking/pm-plugin.d.ts +5 -1
- package/dist/types/pm-plugins/main.d.ts +2 -2
- package/dist/types/ui/visibility-container.d.ts +2 -1
- package/dist/types-ts4.5/blockControlsPluginType.d.ts +27 -1
- package/dist/types-ts4.5/index.d.ts +1 -1
- package/dist/types-ts4.5/pm-plugins/interaction-tracking/commands.d.ts +2 -0
- package/dist/types-ts4.5/pm-plugins/interaction-tracking/handle-mouse-move.d.ts +2 -2
- package/dist/types-ts4.5/pm-plugins/interaction-tracking/pm-plugin.d.ts +5 -1
- package/dist/types-ts4.5/pm-plugins/main.d.ts +2 -2
- package/dist/types-ts4.5/ui/visibility-container.d.ts +2 -1
- package/package.json +5 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-block-controls
|
|
2
2
|
|
|
3
|
+
## 8.8.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [`884dc5b015901`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/884dc5b015901) -
|
|
8
|
+
[ux] Update hover logic for edit mode in edit/live pages
|
|
9
|
+
|
|
10
|
+
### Patch Changes
|
|
11
|
+
|
|
12
|
+
- Updated dependencies
|
|
13
|
+
|
|
3
14
|
## 8.7.2
|
|
4
15
|
|
|
5
16
|
### Patch Changes
|
|
@@ -11,6 +11,7 @@ var _selection = require("@atlaskit/editor-common/selection");
|
|
|
11
11
|
var _toolbarFlagCheck = require("@atlaskit/editor-common/toolbar-flag-check");
|
|
12
12
|
var _state = require("@atlaskit/editor-prosemirror/state");
|
|
13
13
|
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
|
|
14
|
+
var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
|
|
14
15
|
var _expValEqualsNoExposure = require("@atlaskit/tmp-editor-statsig/exp-val-equals-no-exposure");
|
|
15
16
|
var _experiments = require("@atlaskit/tmp-editor-statsig/experiments");
|
|
16
17
|
var _handleKeyDownWithPreservedSelection = require("./editor-commands/handle-key-down-with-preserved-selection");
|
|
@@ -30,8 +31,11 @@ var _globalStyles = require("./ui/global-styles");
|
|
|
30
31
|
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
31
32
|
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
32
33
|
var blockControlsPlugin = exports.blockControlsPlugin = function blockControlsPlugin(_ref) {
|
|
33
|
-
var
|
|
34
|
+
var _config$rightSideCont;
|
|
35
|
+
var api = _ref.api,
|
|
36
|
+
config = _ref.config;
|
|
34
37
|
var nodeDecorationRegistry = [];
|
|
38
|
+
var rightSideControlsEnabled = (_config$rightSideCont = config === null || config === void 0 ? void 0 : config.rightSideControlsEnabled) !== null && _config$rightSideCont !== void 0 ? _config$rightSideCont : false;
|
|
35
39
|
return {
|
|
36
40
|
name: 'blockControls',
|
|
37
41
|
actions: {
|
|
@@ -53,13 +57,15 @@ var blockControlsPlugin = exports.blockControlsPlugin = function blockControlsPl
|
|
|
53
57
|
plugin: function plugin(_ref2) {
|
|
54
58
|
var getIntl = _ref2.getIntl,
|
|
55
59
|
nodeViewPortalProviderAPI = _ref2.nodeViewPortalProviderAPI;
|
|
56
|
-
return (0, _main.createPlugin)(api, getIntl, nodeViewPortalProviderAPI, nodeDecorationRegistry);
|
|
60
|
+
return (0, _main.createPlugin)(api, getIntl, nodeViewPortalProviderAPI, nodeDecorationRegistry, rightSideControlsEnabled && (0, _expValEquals.expValEquals)('confluence_remix_icon_right_side', 'isEnabled', true));
|
|
57
61
|
}
|
|
58
62
|
}];
|
|
59
63
|
if ((0, _experiments.editorExperiment)('platform_editor_controls', 'variant1')) {
|
|
60
64
|
pmPlugins.push({
|
|
61
65
|
name: 'blockControlsInteractionTrackingPlugin',
|
|
62
|
-
plugin:
|
|
66
|
+
plugin: function plugin() {
|
|
67
|
+
return (0, _pmPlugin.createInteractionTrackingPlugin)(rightSideControlsEnabled && (0, _expValEquals.expValEquals)('confluence_remix_icon_right_side', 'isEnabled', true));
|
|
68
|
+
}
|
|
63
69
|
});
|
|
64
70
|
}
|
|
65
71
|
if ((0, _expValEqualsNoExposure.expValEqualsNoExposure)('platform_editor_block_menu', 'isEnabled', true)) {
|
|
@@ -332,6 +338,11 @@ var blockControlsPlugin = exports.blockControlsPlugin = function blockControlsPl
|
|
|
332
338
|
if ((0, _experiments.editorExperiment)('platform_editor_controls', 'variant1')) {
|
|
333
339
|
var _interactionTrackingP2, _interactionTrackingP3;
|
|
334
340
|
sharedState.isMouseOut = (_interactionTrackingP2 = (_interactionTrackingP3 = _pmPlugin.interactionTrackingPluginKey.getState(editorState)) === null || _interactionTrackingP3 === void 0 ? void 0 : _interactionTrackingP3.isMouseOut) !== null && _interactionTrackingP2 !== void 0 ? _interactionTrackingP2 : false;
|
|
341
|
+
sharedState.rightSideControlsEnabled = rightSideControlsEnabled && (0, _expValEquals.expValEquals)('confluence_remix_icon_right_side', 'isEnabled', true);
|
|
342
|
+
if (rightSideControlsEnabled && (0, _expValEquals.expValEquals)('confluence_remix_icon_right_side', 'isEnabled', true)) {
|
|
343
|
+
var _interactionTrackingP4;
|
|
344
|
+
sharedState.hoverSide = (_interactionTrackingP4 = _pmPlugin.interactionTrackingPluginKey.getState(editorState)) === null || _interactionTrackingP4 === void 0 ? void 0 : _interactionTrackingP4.hoverSide;
|
|
345
|
+
}
|
|
335
346
|
}
|
|
336
347
|
if ((0, _expValEqualsNoExposure.expValEqualsNoExposure)('platform_editor_block_menu', 'isEnabled', true)) {
|
|
337
348
|
var _selectionPreservatio;
|
|
@@ -85,6 +85,9 @@ var dragHandleDecoration = exports.dragHandleDecoration = function dragHandleDec
|
|
|
85
85
|
var element = document.createElement('span');
|
|
86
86
|
// inline decoration causes focus issues when refocusing Editor into first line
|
|
87
87
|
element.style.display = 'block';
|
|
88
|
+
if ((0, _expValEquals.expValEquals)('confluence_remix_icon_right_side', 'isEnabled', true)) {
|
|
89
|
+
element.setAttribute('data-blocks-decorator-widget', 'true');
|
|
90
|
+
}
|
|
88
91
|
element.setAttribute('data-testid', 'block-ctrl-decorator-widget');
|
|
89
92
|
element.setAttribute('data-blocks-drag-handle-container', 'true');
|
|
90
93
|
element.setAttribute('data-blocks-drag-handle-key', key);
|
|
@@ -76,6 +76,9 @@ var quickInsertButtonDecoration = exports.quickInsertButtonDecoration = function
|
|
|
76
76
|
}
|
|
77
77
|
element.contentEditable = 'false';
|
|
78
78
|
element.setAttribute('data-blocks-quick-insert-container', 'true');
|
|
79
|
+
if ((0, _expValEquals.expValEquals)('confluence_remix_icon_right_side', 'isEnabled', true)) {
|
|
80
|
+
element.setAttribute('data-blocks-quick-insert-button', 'true');
|
|
81
|
+
}
|
|
79
82
|
element.setAttribute('data-testid', 'block-ctrl-quick-insert-button');
|
|
80
83
|
if ((0, _experiments.editorExperiment)('platform_editor_block_control_optimise_render', true, {
|
|
81
84
|
exposure: true
|
|
@@ -45,7 +45,7 @@ var getDefaultNodeSelector = (0, _memoizeOne.default)(function () {
|
|
|
45
45
|
return getNodeSelector([].concat((0, _toConsumableArray2.default)(_decorationsAnchor.IGNORE_NODES_NEXT), ['media']), [].concat((0, _toConsumableArray2.default)(_decorationsAnchor.IGNORE_NODE_DESCENDANTS_ADVANCED_LAYOUT), ['table']));
|
|
46
46
|
});
|
|
47
47
|
var handleMouseOver = exports.handleMouseOver = function handleMouseOver(view, event, api) {
|
|
48
|
-
var _api$blockControls, _api$editorDisabled, _target$classList;
|
|
48
|
+
var _api$blockControls, _api$editorDisabled, _api$editorViewMode, _api$blockControls$sh, _api$blockControls2, _target$classList;
|
|
49
49
|
var _ref = (api === null || api === void 0 || (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 ? void 0 : _api$blockControls.sharedState.currentState()) || {},
|
|
50
50
|
isDragging = _ref.isDragging,
|
|
51
51
|
activeNode = _ref.activeNode,
|
|
@@ -56,10 +56,14 @@ var handleMouseOver = exports.handleMouseOver = function handleMouseOver(view, e
|
|
|
56
56
|
editorDisabled: false
|
|
57
57
|
},
|
|
58
58
|
editorDisabled = _ref2.editorDisabled;
|
|
59
|
+
var editorViewMode = 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;
|
|
60
|
+
var isViewMode = editorViewMode === 'view';
|
|
59
61
|
var toolbarFlagsEnabled = (0, _toolbarFlagCheck.areToolbarFlagsEnabled)(Boolean(api === null || api === void 0 ? void 0 : api.toolbar));
|
|
60
62
|
|
|
61
|
-
// We shouldn't be firing mouse over transactions when the editor is disabled
|
|
62
|
-
|
|
63
|
+
// We shouldn't be firing mouse over transactions when the editor is disabled,
|
|
64
|
+
// except in view mode when right-side controls are enabled (show controls on block hover)
|
|
65
|
+
var rightSideControlsEnabled = (_api$blockControls$sh = api === null || api === void 0 || (_api$blockControls2 = api.blockControls) === null || _api$blockControls2 === void 0 || (_api$blockControls2 = _api$blockControls2.sharedState.currentState()) === null || _api$blockControls2 === void 0 ? void 0 : _api$blockControls2.rightSideControlsEnabled) !== null && _api$blockControls$sh !== void 0 ? _api$blockControls$sh : false;
|
|
66
|
+
if (editorDisabled && (!isViewMode || !(rightSideControlsEnabled && (0, _expValEquals.expValEquals)('confluence_remix_icon_right_side', 'isEnabled', true)))) {
|
|
63
67
|
return false;
|
|
64
68
|
}
|
|
65
69
|
|
|
@@ -82,6 +86,18 @@ var handleMouseOver = exports.handleMouseOver = function handleMouseOver(view, e
|
|
|
82
86
|
return false;
|
|
83
87
|
}
|
|
84
88
|
var rootElement = target === null || target === void 0 ? void 0 : target.closest(isNativeAnchorSupported ? getDefaultNodeSelector() : "[data-drag-handler-anchor-name]");
|
|
89
|
+
|
|
90
|
+
// When hovering over the right-edge button (rendered in a portal outside the block), resolve the
|
|
91
|
+
// block from the container's anchor so activeNode stays set and the button remains visible.
|
|
92
|
+
if (!rootElement && rightSideControlsEnabled && (0, _expValEquals.expValEquals)('confluence_remix_icon_right_side', 'isEnabled', true)) {
|
|
93
|
+
var rightEdgeContainer = target === null || target === void 0 ? void 0 : target.closest('[data-blocks-right-edge-button-container]');
|
|
94
|
+
if (rightEdgeContainer) {
|
|
95
|
+
var anchor = rightEdgeContainer.getAttribute('data-blocks-right-edge-button-anchor');
|
|
96
|
+
if (anchor) {
|
|
97
|
+
rootElement = view.dom.querySelector("[".concat((0, _domAttrName.getAnchorAttrName)(), "=\"").concat(CSS.escape(anchor), "\"]"));
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
85
101
|
if (rootElement) {
|
|
86
102
|
var _rootElement$parentEl;
|
|
87
103
|
// We want to exlude handles from showing for empty paragraph and heading nodes
|
|
@@ -190,22 +206,22 @@ var handleMouseOver = exports.handleMouseOver = function handleMouseOver(view, e
|
|
|
190
206
|
// as when it is a multi-selection, the showDragHandleAt command interfere with selection
|
|
191
207
|
// sometimes makes the multi-selection not continous after block menu is opened with keyboard
|
|
192
208
|
if (!(isMultipleSelected && isMenuOpen && blockMenuOptions !== null && blockMenuOptions !== void 0 && blockMenuOptions.openedViaKeyboard)) {
|
|
193
|
-
var _api$core, _api$
|
|
194
|
-
api === null || api === void 0 || (_api$core = api.core) === null || _api$core === void 0 || _api$core.actions.execute(api === null || api === void 0 || (_api$
|
|
209
|
+
var _api$core, _api$blockControls3;
|
|
210
|
+
api === null || api === void 0 || (_api$core = api.core) === null || _api$core === void 0 || _api$core.actions.execute(api === null || api === void 0 || (_api$blockControls3 = api.blockControls) === null || _api$blockControls3 === void 0 ? void 0 : _api$blockControls3.commands.showDragHandleAt(targetPos, anchorName, nodeType, undefined, rootPos !== null && rootPos !== void 0 ? rootPos : targetPos, rootAnchorName !== null && rootAnchorName !== void 0 ? rootAnchorName : anchorName, rootNodeType !== null && rootNodeType !== void 0 ? rootNodeType : nodeType));
|
|
195
211
|
}
|
|
196
212
|
} else {
|
|
197
|
-
var _api$core2, _api$
|
|
198
|
-
api === null || api === void 0 || (_api$core2 = api.core) === null || _api$core2 === void 0 || _api$core2.actions.execute(api === null || api === void 0 || (_api$
|
|
213
|
+
var _api$core2, _api$blockControls4;
|
|
214
|
+
api === null || api === void 0 || (_api$core2 = api.core) === null || _api$core2 === void 0 || _api$core2.actions.execute(api === null || api === void 0 || (_api$blockControls4 = api.blockControls) === null || _api$blockControls4 === void 0 ? void 0 : _api$blockControls4.commands.showDragHandleAt(targetPos, anchorName, nodeType, undefined, rootPos !== null && rootPos !== void 0 ? rootPos : targetPos, rootAnchorName !== null && rootAnchorName !== void 0 ? rootAnchorName : anchorName, rootNodeType !== null && rootNodeType !== void 0 ? rootNodeType : nodeType));
|
|
199
215
|
}
|
|
200
216
|
} else {
|
|
201
|
-
var _api$core3, _api$
|
|
202
|
-
api === null || api === void 0 || (_api$core3 = api.core) === null || _api$core3 === void 0 || _api$core3.actions.execute(api === null || api === void 0 || (_api$
|
|
217
|
+
var _api$core3, _api$blockControls5;
|
|
218
|
+
api === null || api === void 0 || (_api$core3 = api.core) === null || _api$core3 === void 0 || _api$core3.actions.execute(api === null || api === void 0 || (_api$blockControls5 = api.blockControls) === null || _api$blockControls5 === void 0 ? void 0 : _api$blockControls5.commands.showDragHandleAt(targetPos, anchorName, nodeType));
|
|
203
219
|
}
|
|
204
220
|
if ((0, _expValEqualsNoExposure.expValEqualsNoExposure)('platform_editor_block_menu', 'isEnabled', true)) {
|
|
205
221
|
var _api$userIntent;
|
|
206
222
|
if (isMenuOpen && originalAnchorName && (api === null || api === void 0 || (_api$userIntent = api.userIntent) === null || _api$userIntent === void 0 || (_api$userIntent = _api$userIntent.sharedState.currentState()) === null || _api$userIntent === void 0 ? void 0 : _api$userIntent.currentUserIntent) === 'blockMenuOpen') {
|
|
207
|
-
var _api$core4, _api$
|
|
208
|
-
api === null || api === void 0 || (_api$core4 = api.core) === null || _api$core4 === void 0 || _api$core4.actions.execute(api === null || api === void 0 || (_api$
|
|
223
|
+
var _api$core4, _api$blockControls6;
|
|
224
|
+
api === null || api === void 0 || (_api$core4 = api.core) === null || _api$core4 === void 0 || _api$core4.actions.execute(api === null || api === void 0 || (_api$blockControls6 = api.blockControls) === null || _api$blockControls6 === void 0 ? void 0 : _api$blockControls6.commands.toggleBlockMenu());
|
|
209
225
|
}
|
|
210
226
|
}
|
|
211
227
|
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.stopEditing = exports.startEditing = exports.mouseLeave = exports.mouseEnter = void 0;
|
|
6
|
+
exports.stopEditing = exports.startEditing = exports.setHoverSide = exports.mouseLeave = exports.mouseEnter = exports.clearHoverSide = void 0;
|
|
7
7
|
var _pmPlugin = require("./pm-plugin");
|
|
8
8
|
var stopEditing = exports.stopEditing = function stopEditing(view) {
|
|
9
9
|
view.dispatch(view.state.tr.setMeta(_pmPlugin.interactionTrackingPluginKey, {
|
|
@@ -24,4 +24,15 @@ var mouseEnter = exports.mouseEnter = function mouseEnter(view) {
|
|
|
24
24
|
view.dispatch(view.state.tr.setMeta(_pmPlugin.interactionTrackingPluginKey, {
|
|
25
25
|
type: 'mouseEnter'
|
|
26
26
|
}));
|
|
27
|
+
};
|
|
28
|
+
var setHoverSide = exports.setHoverSide = function setHoverSide(view, side) {
|
|
29
|
+
view.dispatch(view.state.tr.setMeta(_pmPlugin.interactionTrackingPluginKey, {
|
|
30
|
+
type: 'setHoverSide',
|
|
31
|
+
side: side
|
|
32
|
+
}));
|
|
33
|
+
};
|
|
34
|
+
var clearHoverSide = exports.clearHoverSide = function clearHoverSide(view) {
|
|
35
|
+
view.dispatch(view.state.tr.setMeta(_pmPlugin.interactionTrackingPluginKey, {
|
|
36
|
+
type: 'clearHoverSide'
|
|
37
|
+
}));
|
|
27
38
|
};
|
|
@@ -4,17 +4,112 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.handleMouseMove = exports.handleMouseLeave = exports.handleMouseEnter = void 0;
|
|
7
|
+
var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
|
|
7
8
|
var _commands = require("./commands");
|
|
8
9
|
var _pmPlugin = require("./pm-plugin");
|
|
9
|
-
|
|
10
|
+
/** Per-view pending hover state; avoids cross-editor singleton. */
|
|
11
|
+
var pendingByView = new WeakMap();
|
|
12
|
+
|
|
13
|
+
/** Per-view RAF handle so clearPendingHoverSide cancels only that view's callback. */
|
|
14
|
+
var rafIdByView = new WeakMap();
|
|
15
|
+
var cancelScheduledProcessForView = function cancelScheduledProcessForView(view) {
|
|
16
|
+
var id = rafIdByView.get(view);
|
|
17
|
+
if (id !== undefined) {
|
|
18
|
+
cancelAnimationFrame(id);
|
|
19
|
+
rafIdByView.delete(view);
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
var clearPendingHoverSide = function clearPendingHoverSide(view) {
|
|
23
|
+
pendingByView.delete(view);
|
|
24
|
+
cancelScheduledProcessForView(view);
|
|
25
|
+
};
|
|
26
|
+
var BLOCK_SELECTORS = '[data-node-anchor], [data-drag-handler-anchor-name]';
|
|
27
|
+
var TABLE_SELECTOR = '[data-prosemirror-node-name="table"]';
|
|
28
|
+
var RIGHT_EDGE_SELECTOR = '[data-blocks-right-edge-button-container]';
|
|
29
|
+
var isInsideTable = function isInsideTable(element) {
|
|
30
|
+
var _element$getAttribute;
|
|
31
|
+
return element.closest(TABLE_SELECTOR) !== null || ((_element$getAttribute = element.getAttribute) === null || _element$getAttribute === void 0 ? void 0 : _element$getAttribute.call(element, 'data-prosemirror-node-name')) === 'table';
|
|
32
|
+
};
|
|
33
|
+
var processHoverSide = function processHoverSide(view) {
|
|
34
|
+
var event = pendingByView.get(view);
|
|
35
|
+
if (!event) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
pendingByView.delete(view);
|
|
39
|
+
rafIdByView.delete(view);
|
|
40
|
+
var editorContentArea = view.dom.closest('.ak-editor-content-area');
|
|
41
|
+
if (!(editorContentArea instanceof HTMLElement)) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
var state = (0, _pmPlugin.getInteractionTrackingState)(view.state);
|
|
45
|
+
var target = event.target instanceof HTMLElement ? event.target : null;
|
|
46
|
+
|
|
47
|
+
// When hovering over block controls directly, infer side from which control we're over.
|
|
48
|
+
// This is more reliable than bounds when controls are in portals outside the editor DOM.
|
|
49
|
+
var rightEdgeElement = target === null || target === void 0 ? void 0 : target.closest(RIGHT_EDGE_SELECTOR);
|
|
50
|
+
if (rightEdgeElement) {
|
|
51
|
+
if ((state === null || state === void 0 ? void 0 : state.hoverSide) !== 'right') {
|
|
52
|
+
(0, _commands.setHoverSide)(view, 'right');
|
|
53
|
+
}
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
var leftControlElement = target === null || target === void 0 ? void 0 : target.closest('[data-blocks-drag-handle-container], [data-testid="block-ctrl-drag-handle"], [data-testid="block-ctrl-drag-handle-container"], [data-testid="block-ctrl-decorator-widget"], [data-testid="block-ctrl-quick-insert-button"]');
|
|
57
|
+
if (leftControlElement) {
|
|
58
|
+
if ((state === null || state === void 0 ? void 0 : state.hoverSide) !== 'left') {
|
|
59
|
+
(0, _commands.setHoverSide)(view, 'left');
|
|
60
|
+
}
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Use the hovered block's midpoint when hovering over block content.
|
|
65
|
+
var blockElement = target === null || target === void 0 ? void 0 : target.closest(BLOCK_SELECTORS);
|
|
66
|
+
var boundsElement = blockElement instanceof HTMLElement ? blockElement : editorContentArea;
|
|
67
|
+
|
|
68
|
+
// Tables show block controls at table level; don't restrict by side so drag handle
|
|
69
|
+
// stays visible when hovering anywhere in the table (e.g. paragraph in second cell).
|
|
70
|
+
if (isInsideTable(boundsElement)) {
|
|
71
|
+
if ((state === null || state === void 0 ? void 0 : state.hoverSide) !== undefined) {
|
|
72
|
+
(0, _commands.clearHoverSide)(view);
|
|
73
|
+
}
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
var _boundsElement$getBou = boundsElement.getBoundingClientRect(),
|
|
77
|
+
left = _boundsElement$getBou.left,
|
|
78
|
+
right = _boundsElement$getBou.right;
|
|
79
|
+
var midpoint = (left + right) / 2;
|
|
80
|
+
var nextHoverSide = event.clientX > midpoint ? 'right' : 'left';
|
|
81
|
+
if ((state === null || state === void 0 ? void 0 : state.hoverSide) !== nextHoverSide) {
|
|
82
|
+
(0, _commands.setHoverSide)(view, nextHoverSide);
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
var handleMouseMove = exports.handleMouseMove = function handleMouseMove(view, event) {
|
|
86
|
+
var rightSideControlsEnabled = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
10
87
|
var state = (0, _pmPlugin.getInteractionTrackingState)(view.state);
|
|
11
88
|
// if user has stopped editing and moved their mouse, show block controls again
|
|
12
89
|
if (state !== null && state !== void 0 && state.isEditing) {
|
|
13
90
|
(0, _commands.stopEditing)(view);
|
|
14
91
|
}
|
|
92
|
+
|
|
93
|
+
// Only track hover side when right-side controls are enabled and experiment is on (performance)
|
|
94
|
+
if (!rightSideControlsEnabled || !(0, _expValEquals.expValEquals)('confluence_remix_icon_right_side', 'isEnabled', true)) {
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
if (!(event instanceof MouseEvent)) {
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
pendingByView.set(view, event);
|
|
101
|
+
cancelScheduledProcessForView(view);
|
|
102
|
+
var id = requestAnimationFrame(function () {
|
|
103
|
+
processHoverSide(view);
|
|
104
|
+
});
|
|
105
|
+
rafIdByView.set(view, id);
|
|
15
106
|
return false;
|
|
16
107
|
};
|
|
17
108
|
var handleMouseLeave = exports.handleMouseLeave = function handleMouseLeave(view) {
|
|
109
|
+
var rightSideControlsEnabled = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
110
|
+
if (rightSideControlsEnabled && (0, _expValEquals.expValEquals)('confluence_remix_icon_right_side', 'isEnabled', true)) {
|
|
111
|
+
clearPendingHoverSide(view);
|
|
112
|
+
}
|
|
18
113
|
(0, _commands.mouseLeave)(view);
|
|
19
114
|
return false;
|
|
20
115
|
};
|
|
@@ -9,13 +9,21 @@ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/de
|
|
|
9
9
|
var _bindEventListener = require("bind-event-listener");
|
|
10
10
|
var _safePlugin = require("@atlaskit/editor-common/safe-plugin");
|
|
11
11
|
var _state = require("@atlaskit/editor-prosemirror/state");
|
|
12
|
+
var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
|
|
12
13
|
var _experiments = require("@atlaskit/tmp-editor-statsig/experiments");
|
|
13
14
|
var _handleKeyDown = require("./handle-key-down");
|
|
14
15
|
var _handleMouseMove = require("./handle-mouse-move");
|
|
15
16
|
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
16
17
|
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
18
|
+
/** Elements that extend the editor hover area (block controls, right-edge button, etc.) */
|
|
19
|
+
var BLOCK_CONTROLS_HOVER_AREA_SELECTOR = '[data-blocks-right-edge-button-container], [data-blocks-drag-handle-container], [data-testid="block-ctrl-drag-handle"], [data-testid="block-ctrl-drag-handle-container"], [data-testid="block-ctrl-decorator-widget"], [data-testid="block-ctrl-quick-insert-button"]';
|
|
20
|
+
var MOUSE_LEAVE_DEBOUNCE_MS = 200;
|
|
21
|
+
var isMovingToBlockControlsArea = function isMovingToBlockControlsArea(target) {
|
|
22
|
+
return target instanceof Element && !!target.closest(BLOCK_CONTROLS_HOVER_AREA_SELECTOR);
|
|
23
|
+
};
|
|
17
24
|
var interactionTrackingPluginKey = exports.interactionTrackingPluginKey = new _state.PluginKey('interactionTrackingPlugin');
|
|
18
25
|
var createInteractionTrackingPlugin = exports.createInteractionTrackingPlugin = function createInteractionTrackingPlugin() {
|
|
26
|
+
var rightSideControlsEnabled = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
|
19
27
|
return new _safePlugin.SafePlugin({
|
|
20
28
|
key: interactionTrackingPluginKey,
|
|
21
29
|
state: {
|
|
@@ -40,10 +48,17 @@ var createInteractionTrackingPlugin = exports.createInteractionTrackingPlugin =
|
|
|
40
48
|
break;
|
|
41
49
|
case 'mouseLeave':
|
|
42
50
|
newState.isMouseOut = true;
|
|
51
|
+
newState.hoverSide = undefined;
|
|
43
52
|
break;
|
|
44
53
|
case 'mouseEnter':
|
|
45
54
|
newState.isMouseOut = false;
|
|
46
55
|
break;
|
|
56
|
+
case 'setHoverSide':
|
|
57
|
+
newState.hoverSide = meta.side;
|
|
58
|
+
break;
|
|
59
|
+
case 'clearHoverSide':
|
|
60
|
+
newState.hoverSide = undefined;
|
|
61
|
+
break;
|
|
47
62
|
}
|
|
48
63
|
return _objectSpread(_objectSpread({}, pluginState), newState);
|
|
49
64
|
}
|
|
@@ -51,30 +66,104 @@ var createInteractionTrackingPlugin = exports.createInteractionTrackingPlugin =
|
|
|
51
66
|
props: {
|
|
52
67
|
handleKeyDown: _handleKeyDown.handleKeyDown,
|
|
53
68
|
handleDOMEvents: {
|
|
54
|
-
mousemove:
|
|
69
|
+
mousemove: function mousemove(view, event) {
|
|
70
|
+
return (0, _handleMouseMove.handleMouseMove)(view, event, rightSideControlsEnabled && (0, _expValEquals.expValEquals)('confluence_remix_icon_right_side', 'isEnabled', true));
|
|
71
|
+
}
|
|
55
72
|
}
|
|
56
73
|
},
|
|
57
74
|
view: (0, _experiments.editorExperiment)('platform_editor_controls', 'variant1') ? function (view) {
|
|
58
75
|
var editorContentArea = view.dom.closest('.ak-editor-content-area');
|
|
76
|
+
var remixRightSideEnabled = rightSideControlsEnabled && (0, _expValEquals.expValEquals)('confluence_remix_icon_right_side', 'isEnabled', true);
|
|
59
77
|
var unbindMouseEnter;
|
|
60
78
|
var unbindMouseLeave;
|
|
79
|
+
var unbindDocumentMouseMove;
|
|
80
|
+
var mouseLeaveTimeoutId = null;
|
|
81
|
+
var lastMousePosition = {
|
|
82
|
+
x: 0,
|
|
83
|
+
y: 0
|
|
84
|
+
};
|
|
85
|
+
var scheduleMouseLeave = function scheduleMouseLeave(event) {
|
|
86
|
+
if (mouseLeaveTimeoutId) {
|
|
87
|
+
clearTimeout(mouseLeaveTimeoutId);
|
|
88
|
+
mouseLeaveTimeoutId = null;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Don't set isMouseOut when moving to block controls (right-edge button, drag handle, etc.)
|
|
92
|
+
if (rightSideControlsEnabled && (0, _expValEquals.expValEquals)('confluence_remix_icon_right_side', 'isEnabled', true) && isMovingToBlockControlsArea(event.relatedTarget)) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
mouseLeaveTimeoutId = setTimeout(function () {
|
|
96
|
+
mouseLeaveTimeoutId = null;
|
|
97
|
+
// Before dispatching, check if mouse has moved to block controls (e.g. through empty space)
|
|
98
|
+
if (rightSideControlsEnabled && (0, _expValEquals.expValEquals)('confluence_remix_icon_right_side', 'isEnabled', true) && typeof document !== 'undefined') {
|
|
99
|
+
var el = document.elementFromPoint(lastMousePosition.x, lastMousePosition.y);
|
|
100
|
+
if (el && isMovingToBlockControlsArea(el)) {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
(0, _handleMouseMove.handleMouseLeave)(view, rightSideControlsEnabled && (0, _expValEquals.expValEquals)('confluence_remix_icon_right_side', 'isEnabled', true));
|
|
105
|
+
}, MOUSE_LEAVE_DEBOUNCE_MS);
|
|
106
|
+
};
|
|
107
|
+
var cancelScheduledMouseLeave = function cancelScheduledMouseLeave() {
|
|
108
|
+
if (mouseLeaveTimeoutId) {
|
|
109
|
+
clearTimeout(mouseLeaveTimeoutId);
|
|
110
|
+
mouseLeaveTimeoutId = null;
|
|
111
|
+
}
|
|
112
|
+
};
|
|
61
113
|
if (editorContentArea) {
|
|
114
|
+
if (remixRightSideEnabled && typeof document !== 'undefined') {
|
|
115
|
+
unbindDocumentMouseMove = (0, _bindEventListener.bind)(document, {
|
|
116
|
+
type: 'mousemove',
|
|
117
|
+
listener: function listener(event) {
|
|
118
|
+
lastMousePosition = {
|
|
119
|
+
x: event.clientX,
|
|
120
|
+
y: event.clientY
|
|
121
|
+
};
|
|
122
|
+
// Use document-level mousemove so we get events when hovering over block
|
|
123
|
+
// controls (which may be in portals outside the editor DOM). Without this,
|
|
124
|
+
// handleDOMEvents.mousemove only fires when over the editor content.
|
|
125
|
+
if (editorContentArea.contains(event.target) || isMovingToBlockControlsArea(event.target)) {
|
|
126
|
+
(0, _handleMouseMove.handleMouseMove)(view, event, rightSideControlsEnabled && (0, _expValEquals.expValEquals)('confluence_remix_icon_right_side', 'isEnabled', true));
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
options: {
|
|
130
|
+
passive: true
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
}
|
|
62
134
|
unbindMouseEnter = (0, _bindEventListener.bind)(editorContentArea, {
|
|
63
135
|
type: 'mouseenter',
|
|
64
136
|
listener: function listener() {
|
|
137
|
+
if (remixRightSideEnabled) {
|
|
138
|
+
cancelScheduledMouseLeave();
|
|
139
|
+
}
|
|
65
140
|
(0, _handleMouseMove.handleMouseEnter)(view);
|
|
66
141
|
}
|
|
67
142
|
});
|
|
68
143
|
unbindMouseLeave = (0, _bindEventListener.bind)(editorContentArea, {
|
|
69
144
|
type: 'mouseleave',
|
|
70
|
-
listener: function listener() {
|
|
71
|
-
|
|
145
|
+
listener: function listener(event) {
|
|
146
|
+
var e = event;
|
|
147
|
+
lastMousePosition = {
|
|
148
|
+
x: e.clientX,
|
|
149
|
+
y: e.clientY
|
|
150
|
+
};
|
|
151
|
+
if (remixRightSideEnabled) {
|
|
152
|
+
scheduleMouseLeave(e);
|
|
153
|
+
} else {
|
|
154
|
+
(0, _handleMouseMove.handleMouseLeave)(view, false);
|
|
155
|
+
}
|
|
72
156
|
}
|
|
73
157
|
});
|
|
74
158
|
}
|
|
75
159
|
return {
|
|
76
160
|
destroy: function destroy() {
|
|
77
161
|
var _unbindMouseEnter, _unbindMouseLeave;
|
|
162
|
+
if (remixRightSideEnabled) {
|
|
163
|
+
var _unbindDocumentMouseM;
|
|
164
|
+
cancelScheduledMouseLeave();
|
|
165
|
+
(_unbindDocumentMouseM = unbindDocumentMouseMove) === null || _unbindDocumentMouseM === void 0 || _unbindDocumentMouseM();
|
|
166
|
+
}
|
|
78
167
|
(_unbindMouseEnter = unbindMouseEnter) === null || _unbindMouseEnter === void 0 || _unbindMouseEnter();
|
|
79
168
|
(_unbindMouseLeave = unbindMouseLeave) === null || _unbindMouseLeave === void 0 || _unbindMouseLeave();
|
|
80
169
|
}
|