@atlaskit/editor-plugin-block-controls 20.0.2 → 20.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +25 -0
- package/dist/cjs/blockControlsPlugin.js +53 -17
- package/dist/cjs/editor-commands/move-node.js +1 -1
- package/dist/cjs/editor-commands/show-drag-handle.js +17 -5
- package/dist/cjs/pm-plugins/decorations-anchor.js +3 -2
- package/dist/cjs/pm-plugins/decorations-drop-target-active.js +3 -2
- package/dist/cjs/pm-plugins/decorations-drop-target.js +3 -2
- package/dist/cjs/pm-plugins/decorations-surface-anchor.js +72 -0
- package/dist/cjs/pm-plugins/handle-mouse-down.js +2 -1
- package/dist/cjs/pm-plugins/handle-mouse-over.js +4 -3
- package/dist/cjs/pm-plugins/handle-sparse-mouse-over.js +125 -0
- package/dist/cjs/pm-plugins/interaction-tracking/pm-plugin.js +1 -1
- package/dist/cjs/pm-plugins/main.js +68 -56
- package/dist/cjs/pm-plugins/sparse-surfaces.js +49 -0
- package/dist/cjs/pm-plugins/utils/drag-handle-positions.js +1 -1
- package/dist/cjs/pm-plugins/utils/sparse-surface-candidates.js +419 -0
- package/dist/cjs/pm-plugins/utils/sparse-surfaces-mapping.js +108 -0
- package/dist/cjs/pm-plugins/utils/sparse-surfaces-state.js +53 -0
- package/dist/cjs/pm-plugins/utils/sparse-surfaces-view.js +134 -0
- package/dist/cjs/pm-plugins/utils/surface-viewport.js +223 -0
- package/dist/cjs/pm-plugins/utils/transactions.js +5 -0
- package/dist/cjs/pm-plugins/utils/validation.js +1 -1
- package/dist/cjs/ui/block-controls-left-surfaces.js +31 -25
- package/dist/cjs/ui/block-controls-right-surfaces.js +31 -25
- package/dist/cjs/ui/block-controls-surface-context.js +1 -0
- package/dist/cjs/ui/block-controls-surface-drag-handle-registration.js +6 -7
- package/dist/cjs/ui/block-controls-surface-drag-handle.js +6 -2
- package/dist/cjs/ui/consts.js +1 -1
- package/dist/cjs/ui/drag-handle.js +6 -4
- package/dist/cjs/ui/drop-target-layout.js +3 -2
- package/dist/cjs/ui/drop-target.js +4 -3
- package/dist/cjs/ui/global-styles.js +70 -28
- package/dist/cjs/ui/inline-drop-target.js +6 -5
- package/dist/cjs/ui/use-block-controls-surface-drag-source.js +1 -1
- package/dist/cjs/ui/utils/anchor-name.js +2 -1
- package/dist/cjs/ui/utils/dom-attr-name.js +3 -2
- package/dist/cjs/ui/utils/get-surface-placement.js +2 -1
- package/dist/cjs/ui/utils/partition-components-by-persistence.js +1 -1
- package/dist/cjs/ui/visibility-container.js +1 -1
- package/dist/es2019/blockControlsPlugin.js +42 -8
- package/dist/es2019/editor-commands/move-node.js +1 -1
- package/dist/es2019/editor-commands/show-drag-handle.js +14 -2
- package/dist/es2019/entry-points/block-decoration-utils-anchor-name.js +1 -0
- package/dist/es2019/entry-points/block-decoration-utils-consts.js +1 -0
- package/dist/es2019/entry-points/block-decoration-utils-dom-attr-name.js +1 -0
- package/dist/es2019/entry-points/block-decoration-utils-drag-handle-positions.js +1 -0
- package/dist/es2019/entry-points/block-decoration-utils-visibility-container.js +1 -0
- package/dist/es2019/entry-points/block-decoration-utils-widget-positions.js +1 -0
- package/dist/es2019/entry-points/blockControlsPlugin.js +1 -0
- package/dist/es2019/pm-plugins/decorations-anchor.js +3 -2
- package/dist/es2019/pm-plugins/decorations-drop-target-active.js +3 -2
- package/dist/es2019/pm-plugins/decorations-drop-target.js +3 -2
- package/dist/es2019/pm-plugins/decorations-surface-anchor.js +56 -0
- package/dist/es2019/pm-plugins/handle-mouse-down.js +2 -1
- package/dist/es2019/pm-plugins/handle-mouse-over.js +4 -3
- package/dist/es2019/pm-plugins/handle-sparse-mouse-over.js +116 -0
- package/dist/es2019/pm-plugins/interaction-tracking/pm-plugin.js +1 -1
- package/dist/es2019/pm-plugins/main.js +72 -56
- package/dist/es2019/pm-plugins/sparse-surfaces.js +37 -0
- package/dist/es2019/pm-plugins/utils/drag-handle-positions.js +1 -1
- package/dist/es2019/pm-plugins/utils/sparse-surface-candidates.js +305 -0
- package/dist/es2019/pm-plugins/utils/sparse-surfaces-mapping.js +78 -0
- package/dist/es2019/pm-plugins/utils/sparse-surfaces-state.js +39 -0
- package/dist/es2019/pm-plugins/utils/sparse-surfaces-view.js +121 -0
- package/dist/es2019/pm-plugins/utils/surface-viewport.js +192 -0
- package/dist/es2019/pm-plugins/utils/transactions.js +5 -0
- package/dist/es2019/pm-plugins/utils/update-selection.js +1 -2
- package/dist/es2019/pm-plugins/utils/validation.js +1 -1
- package/dist/es2019/ui/block-controls-left-surfaces.js +21 -14
- package/dist/es2019/ui/block-controls-right-surfaces.js +21 -14
- package/dist/es2019/ui/block-controls-surface-context.js +1 -0
- package/dist/es2019/ui/block-controls-surface-drag-handle-registration.js +4 -5
- package/dist/es2019/ui/block-controls-surface-drag-handle.js +6 -2
- package/dist/es2019/ui/consts.js +1 -1
- package/dist/es2019/ui/drag-handle.js +6 -4
- package/dist/es2019/ui/drop-target-layout.js +3 -2
- package/dist/es2019/ui/drop-target.js +4 -3
- package/dist/es2019/ui/global-styles.js +68 -29
- package/dist/es2019/ui/inline-drop-target.js +7 -5
- package/dist/es2019/ui/use-block-controls-surface-drag-source.js +1 -1
- package/dist/es2019/ui/utils/anchor-name.js +2 -1
- package/dist/es2019/ui/utils/dom-attr-name.js +3 -2
- package/dist/es2019/ui/utils/get-surface-placement.js +2 -1
- package/dist/es2019/ui/utils/partition-components-by-persistence.js +1 -1
- package/dist/es2019/ui/visibility-container.js +1 -1
- package/dist/esm/blockControlsPlugin.js +53 -17
- package/dist/esm/editor-commands/move-node.js +1 -1
- package/dist/esm/editor-commands/show-drag-handle.js +17 -5
- package/dist/esm/entry-points/block-decoration-utils-anchor-name.js +1 -0
- package/dist/esm/entry-points/block-decoration-utils-consts.js +1 -0
- package/dist/esm/entry-points/block-decoration-utils-dom-attr-name.js +1 -0
- package/dist/esm/entry-points/block-decoration-utils-drag-handle-positions.js +1 -0
- package/dist/esm/entry-points/block-decoration-utils-visibility-container.js +1 -0
- package/dist/esm/entry-points/block-decoration-utils-widget-positions.js +1 -0
- package/dist/esm/entry-points/blockControlsPlugin.js +1 -0
- package/dist/esm/pm-plugins/decorations-anchor.js +3 -2
- package/dist/esm/pm-plugins/decorations-drop-target-active.js +3 -2
- package/dist/esm/pm-plugins/decorations-drop-target.js +3 -2
- package/dist/esm/pm-plugins/decorations-surface-anchor.js +65 -0
- package/dist/esm/pm-plugins/handle-mouse-down.js +2 -1
- package/dist/esm/pm-plugins/handle-mouse-over.js +4 -3
- package/dist/esm/pm-plugins/handle-sparse-mouse-over.js +119 -0
- package/dist/esm/pm-plugins/interaction-tracking/pm-plugin.js +1 -1
- package/dist/esm/pm-plugins/main.js +68 -56
- package/dist/esm/pm-plugins/sparse-surfaces.js +43 -0
- package/dist/esm/pm-plugins/utils/drag-handle-positions.js +1 -1
- package/dist/esm/pm-plugins/utils/sparse-surface-candidates.js +413 -0
- package/dist/esm/pm-plugins/utils/sparse-surfaces-mapping.js +101 -0
- package/dist/esm/pm-plugins/utils/sparse-surfaces-state.js +46 -0
- package/dist/esm/pm-plugins/utils/sparse-surfaces-view.js +127 -0
- package/dist/esm/pm-plugins/utils/surface-viewport.js +217 -0
- package/dist/esm/pm-plugins/utils/transactions.js +5 -0
- package/dist/esm/pm-plugins/utils/update-selection.js +1 -2
- package/dist/esm/pm-plugins/utils/validation.js +1 -1
- package/dist/esm/ui/block-controls-left-surfaces.js +33 -27
- package/dist/esm/ui/block-controls-right-surfaces.js +33 -27
- package/dist/esm/ui/block-controls-surface-context.js +1 -0
- package/dist/esm/ui/block-controls-surface-drag-handle-registration.js +7 -8
- package/dist/esm/ui/block-controls-surface-drag-handle.js +6 -2
- package/dist/esm/ui/consts.js +1 -1
- package/dist/esm/ui/drag-handle.js +6 -4
- package/dist/esm/ui/drop-target-layout.js +3 -2
- package/dist/esm/ui/drop-target.js +4 -3
- package/dist/esm/ui/global-styles.js +71 -29
- package/dist/esm/ui/inline-drop-target.js +7 -5
- package/dist/esm/ui/use-block-controls-surface-drag-source.js +1 -1
- package/dist/esm/ui/utils/anchor-name.js +2 -1
- package/dist/esm/ui/utils/dom-attr-name.js +3 -2
- package/dist/esm/ui/utils/get-surface-placement.js +2 -1
- package/dist/esm/ui/utils/partition-components-by-persistence.js +1 -1
- package/dist/esm/ui/visibility-container.js +1 -1
- package/dist/types/blockControlsPluginType.d.ts +11 -4
- package/dist/types/pm-plugins/decorations-surface-anchor.d.ts +22 -0
- package/dist/types/pm-plugins/handle-sparse-mouse-over.d.ts +5 -0
- package/dist/types/pm-plugins/main.d.ts +2 -9
- package/dist/types/pm-plugins/sparse-surfaces.d.ts +8 -0
- package/dist/types/pm-plugins/utils/sparse-surface-candidates.d.ts +89 -0
- package/dist/types/pm-plugins/utils/sparse-surfaces-mapping.d.ts +20 -0
- package/dist/types/pm-plugins/utils/sparse-surfaces-state.d.ts +27 -0
- package/dist/types/pm-plugins/utils/sparse-surfaces-view.d.ts +15 -0
- package/dist/types/pm-plugins/utils/surface-viewport.d.ts +10 -0
- package/dist/types/ui/inline-drop-target.d.ts +4 -0
- package/dist/types/ui/utils/get-surface-placement.d.ts +3 -2
- package/package.json +7 -7
- package/dist/cjs/pm-plugins/utils/surface-node-positions.js +0 -100
- package/dist/es2019/pm-plugins/utils/surface-node-positions.js +0 -78
- package/dist/esm/pm-plugins/utils/surface-node-positions.js +0 -93
- package/dist/types/pm-plugins/utils/surface-node-positions.d.ts +0 -14
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { findParentNodeOfType } from '@atlaskit/editor-prosemirror/utils';
|
|
2
|
+
import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
|
|
2
3
|
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
3
4
|
import { findNodeDecs } from '../pm-plugins/decorations-anchor';
|
|
5
|
+
import { getNodeTypeWithLevel } from '../pm-plugins/decorations-common';
|
|
4
6
|
import { getDecorations, key } from '../pm-plugins/main';
|
|
5
7
|
import { getNestedNodePosition, getNestedNodeStartingPosition } from '../pm-plugins/utils/getNestedNodePosition';
|
|
6
8
|
import { NODE_ANCHOR_ATTR_NAME, NODE_NODE_TYPE_ATTR_NAME } from '../ui/utils/dom-attr-name';
|
|
@@ -14,7 +16,6 @@ const findParentPosForHandle = state => {
|
|
|
14
16
|
const {
|
|
15
17
|
activeNode
|
|
16
18
|
} = key.getState(state) || {};
|
|
17
|
-
|
|
18
19
|
// if a node handle is already focused, return the parent pos of that node (with focused handle)
|
|
19
20
|
if (activeNode && (_activeNode$handleOpt = activeNode.handleOptions) !== null && _activeNode$handleOpt !== void 0 && _activeNode$handleOpt.isFocused) {
|
|
20
21
|
const $activeNodePos = state.doc.resolve(activeNode.pos);
|
|
@@ -38,7 +39,7 @@ const findParentPosForHandle = state => {
|
|
|
38
39
|
}
|
|
39
40
|
|
|
40
41
|
// else find closest parent node
|
|
41
|
-
return expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) ?
|
|
42
|
+
return expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) || isExperimentEnabled('platform_editor_block_control_migration') ?
|
|
42
43
|
// With native anchor enabled, all nodes have anchor name attribute despite no drag handle support, e.g. listItem, caption,
|
|
43
44
|
// as opposed to old approach, node decoration is only added to the node that have drag handle,
|
|
44
45
|
// hence, we need to return the exact position of the node that can have drag handle
|
|
@@ -111,6 +112,17 @@ const findNextAnchorNode = view => {
|
|
|
111
112
|
}
|
|
112
113
|
};
|
|
113
114
|
export const showDragHandleAtSelection = api => (state, _, view) => {
|
|
115
|
+
if (api && isExperimentEnabled('platform_editor_block_control_migration')) {
|
|
116
|
+
const pos = findParentPosForHandle(state);
|
|
117
|
+
const node = pos === undefined ? undefined : state.doc.nodeAt(pos);
|
|
118
|
+
const anchorName = node && pos !== undefined ? api.core.actions.getAnchorIdForNode(node, pos) : undefined;
|
|
119
|
+
if (!node || pos === undefined || !anchorName) {
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
return api.core.actions.execute(api.blockControls.commands.showDragHandleAt(pos, anchorName, getNodeTypeWithLevel(node), {
|
|
123
|
+
isFocused: true
|
|
124
|
+
}));
|
|
125
|
+
}
|
|
114
126
|
if (view && expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true)) {
|
|
115
127
|
const anchorNode = findNextAnchorNode(view);
|
|
116
128
|
if (api && anchorNode) {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Decoration } from '@atlaskit/editor-prosemirror/view';
|
|
2
|
-
import {
|
|
2
|
+
import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
|
|
3
3
|
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/editor-experiment';
|
|
4
|
+
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
4
5
|
import { getNodeAnchor, getNodeTypeWithLevel, NESTED_DEPTH, TYPE_NODE_DEC } from './decorations-common';
|
|
5
6
|
const IGNORE_NODES = ['tableCell', 'tableHeader', 'tableRow', 'listItem', 'caption', 'layoutColumn'];
|
|
6
7
|
export const IGNORE_NODES_NEXT = ['tableCell', 'tableHeader', 'tableRow', 'listItem', 'caption'];
|
|
@@ -67,7 +68,7 @@ export const findNodeDecs = (state, decorations, from, to) => {
|
|
|
67
68
|
};
|
|
68
69
|
export const nodeDecorations = (newState, from, to) => {
|
|
69
70
|
const decs = [];
|
|
70
|
-
if (expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true)) {
|
|
71
|
+
if (expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) || isExperimentEnabled('platform_editor_block_control_migration')) {
|
|
71
72
|
return [];
|
|
72
73
|
}
|
|
73
74
|
const docFrom = from === undefined || from < 0 ? 0 : from;
|
|
@@ -3,8 +3,9 @@ import { expandSelectionBounds } from '@atlaskit/editor-common/selection';
|
|
|
3
3
|
import { isEmptyParagraph } from '@atlaskit/editor-common/utils';
|
|
4
4
|
import { getBaseNodeTypeName } from '@atlaskit/editor-common/utils/node-type-utils';
|
|
5
5
|
import { findChildrenByType } from '@atlaskit/editor-prosemirror/utils';
|
|
6
|
-
import {
|
|
6
|
+
import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
|
|
7
7
|
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/editor-experiment';
|
|
8
|
+
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
8
9
|
import { getNodeAnchor } from './decorations-common';
|
|
9
10
|
import { createDropTargetDecoration, createLayoutDropTargetDecoration } from './decorations-drop-target';
|
|
10
11
|
import { findSurroundingNodes } from './decorations-find-surrounding-nodes';
|
|
@@ -236,7 +237,7 @@ export const getActiveDropTargetDecorations = (activeDropTargetNode, state, api,
|
|
|
236
237
|
}
|
|
237
238
|
}
|
|
238
239
|
}
|
|
239
|
-
defaultActiveAnchorTracker.emit(expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) ? api.core.actions.getAnchorIdForNode(anchorEmitNodeWithPos.node, anchorEmitNodeWithPos.pos) || '' : getNodeAnchor(anchorEmitNodeWithPos.node));
|
|
240
|
+
defaultActiveAnchorTracker.emit(expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) || isExperimentEnabled('platform_editor_block_control_migration') ? api.core.actions.getAnchorIdForNode(anchorEmitNodeWithPos.node, anchorEmitNodeWithPos.pos) || '' : getNodeAnchor(anchorEmitNodeWithPos.node));
|
|
240
241
|
return {
|
|
241
242
|
decsToAdd,
|
|
242
243
|
decsToRemove
|
|
@@ -6,8 +6,9 @@ import { expandSelectionBounds } from '@atlaskit/editor-common/selection';
|
|
|
6
6
|
import { isEmptyParagraph } from '@atlaskit/editor-common/utils';
|
|
7
7
|
import { getBaseNodeTypeName } from '@atlaskit/editor-common/utils/node-type-utils';
|
|
8
8
|
import { Decoration } from '@atlaskit/editor-prosemirror/view';
|
|
9
|
-
import {
|
|
9
|
+
import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
|
|
10
10
|
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/editor-experiment';
|
|
11
|
+
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
11
12
|
import { nodeMargins } from '../ui/consts';
|
|
12
13
|
import { DropTarget, EDITOR_BLOCK_CONTROLS_DROP_INDICATOR_GAP, EDITOR_BLOCK_CONTROLS_DROP_INDICATOR_OFFSET } from '../ui/drop-target';
|
|
13
14
|
import { DropTargetLayout, DropTargetLayoutNativeAnchorSupport } from '../ui/drop-target-layout';
|
|
@@ -138,7 +139,7 @@ export const createLayoutDropTargetDecoration = (pos, props, nodeViewPortalProvi
|
|
|
138
139
|
element.setAttribute('data-blocks-drop-target-container', 'true');
|
|
139
140
|
element.setAttribute('data-blocks-drop-target-key', key);
|
|
140
141
|
element.style.clear = 'unset';
|
|
141
|
-
const DropTargetLayoutComponent = expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) ? DropTargetLayoutNativeAnchorSupport : DropTargetLayout;
|
|
142
|
+
const DropTargetLayoutComponent = expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) || isExperimentEnabled('platform_editor_block_control_migration') ? DropTargetLayoutNativeAnchorSupport : DropTargetLayout;
|
|
142
143
|
nodeViewPortalProviderAPI.render(() => /*#__PURE__*/createElement(DropTargetLayoutComponent, {
|
|
143
144
|
...props,
|
|
144
145
|
getPos,
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { Decoration, DecorationSet } from '@atlaskit/editor-prosemirror/view';
|
|
2
|
+
export const TYPE_SURFACE_ANCHOR_DEC = 'block-controls-surface-anchor';
|
|
3
|
+
export const SURFACE_ANCHOR_ATTR = 'data-block-controls-surface-anchor';
|
|
4
|
+
export const SURFACE_NODE_TYPE_ATTR = 'data-block-controls-surface-node-type';
|
|
5
|
+
export const SURFACE_ANCHOR_VARIABLE = '--block-controls-surface-anchor-name';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* These node views expose the box used by the measured placement fallback rather than their
|
|
9
|
+
* ProseMirror node wrapper. The marker carries the name through a custom property so sparse CSS
|
|
10
|
+
* can name that inner box without adding a widget or changing the node view.
|
|
11
|
+
*/
|
|
12
|
+
const INNER_CONTENT_NODE_TYPES = new Set(['blockCard', 'bodiedExtension', 'embedCard', 'extension', 'mediaSingle', 'multiBodiedExtension', 'table']);
|
|
13
|
+
const getMarkerStyle = (nodeType, anchorName) => {
|
|
14
|
+
const inheritedName = `${SURFACE_ANCHOR_VARIABLE}: ${anchorName};`;
|
|
15
|
+
|
|
16
|
+
// Inner boxes get their anchor from the sparse global selector. Naming only the node wrapper
|
|
17
|
+
// would position media/table/extension controls against the wrapper instead of visible content.
|
|
18
|
+
return INNER_CONTENT_NODE_TYPES.has(nodeType) ? inheritedName : `${inheritedName} anchor-name: ${anchorName};`;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Builds sparse CSS anchor decorations from already-qualified cached positions. Anchor identity is
|
|
23
|
+
* supplied by the editor's native node-anchor provider so sparse surfaces and consumers share the
|
|
24
|
+
* same `data-node-anchor`.
|
|
25
|
+
*/
|
|
26
|
+
export const createSurfaceAnchorDecorations = (state, positions, resolveAnchorName, previousAnchors) => {
|
|
27
|
+
const anchors = new Map();
|
|
28
|
+
const decorations = [];
|
|
29
|
+
for (const position of positions) {
|
|
30
|
+
if (anchors.has(position)) {
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
const node = state.doc.nodeAt(position);
|
|
34
|
+
if (!(node !== null && node !== void 0 && node.isBlock)) {
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
const anchorName = resolveAnchorName(node, position, previousAnchors === null || previousAnchors === void 0 ? void 0 : previousAnchors.get(position));
|
|
38
|
+
if (!anchorName) {
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
anchors.set(position, anchorName);
|
|
42
|
+
decorations.push(Decoration.node(position, position + node.nodeSize, {
|
|
43
|
+
[SURFACE_ANCHOR_ATTR]: anchorName,
|
|
44
|
+
[SURFACE_NODE_TYPE_ATTR]: node.type.name,
|
|
45
|
+
style: getMarkerStyle(node.type.name, anchorName)
|
|
46
|
+
}, {
|
|
47
|
+
type: TYPE_SURFACE_ANCHOR_DEC,
|
|
48
|
+
anchorName,
|
|
49
|
+
nodeType: node.type.name
|
|
50
|
+
}));
|
|
51
|
+
}
|
|
52
|
+
return {
|
|
53
|
+
anchors,
|
|
54
|
+
decorations: DecorationSet.create(state.doc, decorations)
|
|
55
|
+
};
|
|
56
|
+
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { DRAG_HANDLE_SELECTOR } from '@atlaskit/editor-common/styles';
|
|
2
|
+
import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
|
|
2
3
|
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
3
4
|
export const handleMouseDown = api => (view, event) => {
|
|
4
5
|
if (!(event.target instanceof HTMLElement)) {
|
|
@@ -12,7 +13,7 @@ export const handleMouseDown = api => (view, event) => {
|
|
|
12
13
|
if (!rootNode) {
|
|
13
14
|
return false;
|
|
14
15
|
}
|
|
15
|
-
if (expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true)) {
|
|
16
|
+
if (expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) || isExperimentEnabled('platform_editor_block_control_migration')) {
|
|
16
17
|
var _rootNode$type$name, _rootNode$type$name2;
|
|
17
18
|
const anchorName = api === null || api === void 0 ? void 0 : api.core.actions.getAnchorIdForNode(rootNode, rootPos);
|
|
18
19
|
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import memoizeOne from 'memoize-one';
|
|
2
2
|
import { isMultiBlockSelection } from '@atlaskit/editor-common/selection';
|
|
3
3
|
import { areToolbarFlagsEnabled } from '@atlaskit/editor-common/toolbar-flag-check';
|
|
4
|
+
import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
|
|
4
5
|
import { fg } from '@atlaskit/platform-feature-flags/fg';
|
|
6
|
+
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/editor-experiment';
|
|
5
7
|
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
6
8
|
import { expValEqualsNoExposure } from '@atlaskit/tmp-editor-statsig/exp-val-equals-no-exposure';
|
|
7
|
-
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/editor-experiment';
|
|
8
9
|
import { getAnchorAttrName, getTypeNameAttrName, getTypeNameFromDom, NODE_ANCHOR_ATTR_NAME } from '../ui/utils/dom-attr-name';
|
|
9
10
|
import { IGNORE_NODE_DESCENDANTS_ADVANCED_LAYOUT, IGNORE_NODES_NEXT } from './decorations-anchor';
|
|
10
11
|
import { selectionPreservationPluginKey } from './selection-preservation/plugin-key';
|
|
@@ -132,7 +133,7 @@ export const handleMouseOver = (view, event, api) => {
|
|
|
132
133
|
// Ignored via go/ees005
|
|
133
134
|
// eslint-disable-next-line @atlaskit/editor/no-as-casting
|
|
134
135
|
const target = event.target;
|
|
135
|
-
const isNativeAnchorSupported = expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true);
|
|
136
|
+
const isNativeAnchorSupported = expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) || isExperimentEnabled('platform_editor_block_control_migration');
|
|
136
137
|
if (target !== null && target !== void 0 && (_target$classList = target.classList) !== null && _target$classList !== void 0 && _target$classList.contains('ProseMirror')) {
|
|
137
138
|
return false;
|
|
138
139
|
}
|
|
@@ -204,7 +205,7 @@ export const handleMouseOver = (view, event, api) => {
|
|
|
204
205
|
// This must happen before anchorName is read so the correct node's handle is shown.
|
|
205
206
|
rootElement = redirectParagraphToWrappedMedia(rootElement, isNativeAnchorSupported);
|
|
206
207
|
let anchorName;
|
|
207
|
-
if (expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true)) {
|
|
208
|
+
if (expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) || isExperimentEnabled('platform_editor_block_control_migration')) {
|
|
208
209
|
anchorName = rootElement.getAttribute(getAnchorAttrName());
|
|
209
210
|
|
|
210
211
|
// don't show handles if we can't find an anchor
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { fg } from '@atlaskit/platform-feature-flags/fg';
|
|
2
|
+
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
3
|
+
import { expValEqualsNoExposure } from '@atlaskit/tmp-editor-statsig/exp-val-equals-no-exposure';
|
|
4
|
+
import { getNodeTypeWithLevel } from './decorations-common';
|
|
5
|
+
const OPAQUE_BLOCKS = new Set(['table', 'bulletList', 'orderedList', 'taskList', 'decisionList', 'mediaSingle']);
|
|
6
|
+
const EXCLUDED_BLOCKS = new Set(['listItem', 'tableRow', 'tableCell', 'tableHeader', 'caption']);
|
|
7
|
+
const isPanelNodeTypeName = nodeTypeName => nodeTypeName === 'panel' || nodeTypeName === 'panel_c1' && expValEqualsNoExposure('platform_editor_controls_reliable_anchor', 'isEnabled', true) && fg('platform_editor_controls_reliable_anchor_patch_1');
|
|
8
|
+
const redirectParagraphToWrappedMedia = (view, $target, targetPosition) => {
|
|
9
|
+
const node = view.state.doc.nodeAt(targetPosition);
|
|
10
|
+
if (!node || node.type.name !== 'paragraph') {
|
|
11
|
+
return {
|
|
12
|
+
position: targetPosition,
|
|
13
|
+
node
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
const index = $target.index();
|
|
17
|
+
for (const siblingIndex of [index - 1, index + 1]) {
|
|
18
|
+
if (siblingIndex < 0 || siblingIndex >= $target.parent.childCount) {
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
const sibling = $target.parent.child(siblingIndex);
|
|
22
|
+
if ((sibling.type.name === 'mediaSingle' || sibling.type.name === 'embedCard') && (sibling.attrs.layout === 'wrap-left' || sibling.attrs.layout === 'wrap-right')) {
|
|
23
|
+
return {
|
|
24
|
+
position: siblingIndex < index ? targetPosition - sibling.nodeSize : targetPosition + node.nodeSize,
|
|
25
|
+
node: sibling
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return {
|
|
30
|
+
position: targetPosition,
|
|
31
|
+
node
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
/** Resolves hover from PM structure so the first hover can create its sparse candidate. */
|
|
36
|
+
export const handleSparseMouseOver = (view, event, api) => {
|
|
37
|
+
var _api$editorDisabled$s, _api$editorDisabled, _api$editorDisabled$s2, _api$editorViewMode, _api$editorViewMode$s, _api$showDiff$sharedS, _api$showDiff, _api$showDiff$sharedS2, _api$userIntent, _api$userIntent$share, _$pos$nodeAfter, _controls$activeNode, _anchors$get, _anchors$get2;
|
|
38
|
+
const controls = api === null || api === void 0 ? void 0 : api.blockControls.sharedState.currentState();
|
|
39
|
+
if (!api || controls !== null && controls !== void 0 && controls.isDragging || !(event.target instanceof Element) || event.target === view.dom) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
const editorDisabled = (_api$editorDisabled$s = (_api$editorDisabled = api.editorDisabled) === null || _api$editorDisabled === void 0 ? void 0 : (_api$editorDisabled$s2 = _api$editorDisabled.sharedState.currentState()) === null || _api$editorDisabled$s2 === void 0 ? void 0 : _api$editorDisabled$s2.editorDisabled) !== null && _api$editorDisabled$s !== void 0 ? _api$editorDisabled$s : false;
|
|
43
|
+
const editorViewMode = (_api$editorViewMode = api.editorViewMode) === null || _api$editorViewMode === void 0 ? void 0 : (_api$editorViewMode$s = _api$editorViewMode.sharedState.currentState()) === null || _api$editorViewMode$s === void 0 ? void 0 : _api$editorViewMode$s.mode;
|
|
44
|
+
if (editorDisabled && (editorViewMode !== 'view' || !(controls !== null && controls !== void 0 && controls.rightSideControlsEnabled))) {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
const isDisplayingDiff = (_api$showDiff$sharedS = (_api$showDiff = api.showDiff) === null || _api$showDiff === void 0 ? void 0 : (_api$showDiff$sharedS2 = _api$showDiff.sharedState.currentState()) === null || _api$showDiff$sharedS2 === void 0 ? void 0 : _api$showDiff$sharedS2.isDisplayingChanges) !== null && _api$showDiff$sharedS !== void 0 ? _api$showDiff$sharedS : false;
|
|
48
|
+
const currentUserIntent = (_api$userIntent = api.userIntent) === null || _api$userIntent === void 0 ? void 0 : (_api$userIntent$share = _api$userIntent.sharedState.currentState()) === null || _api$userIntent$share === void 0 ? void 0 : _api$userIntent$share.currentUserIntent;
|
|
49
|
+
if ((isDisplayingDiff || currentUserIntent === 'reviewing') && expValEqualsNoExposure('platform_editor_diff_plugin_extended', 'isEnabled', true)) {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
let position;
|
|
53
|
+
try {
|
|
54
|
+
position = view.posAtDOM(event.target, 0);
|
|
55
|
+
} catch {
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
const $pos = view.state.doc.resolve(position);
|
|
59
|
+
let targetPosition;
|
|
60
|
+
let opaque = false;
|
|
61
|
+
for (let depth = 1; depth <= $pos.depth; depth++) {
|
|
62
|
+
const node = $pos.node(depth);
|
|
63
|
+
if (!node.isBlock || EXCLUDED_BLOCKS.has(node.type.name)) {
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
targetPosition = $pos.before(depth);
|
|
67
|
+
if (OPAQUE_BLOCKS.has(node.type.name)) {
|
|
68
|
+
opaque = true;
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (!opaque && (_$pos$nodeAfter = $pos.nodeAfter) !== null && _$pos$nodeAfter !== void 0 && _$pos$nodeAfter.isBlock && !EXCLUDED_BLOCKS.has($pos.nodeAfter.type.name)) {
|
|
73
|
+
// Browser positions over non-editable node chrome can resolve to the first editable child.
|
|
74
|
+
// Keep the ancestor unless that child actually owns the hovered DOM target.
|
|
75
|
+
const nodeAfterDOM = view.nodeDOM(position);
|
|
76
|
+
if (nodeAfterDOM instanceof Element && nodeAfterDOM.contains(event.target)) {
|
|
77
|
+
targetPosition = position;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (targetPosition === undefined) {
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
const initialNode = view.state.doc.nodeAt(targetPosition);
|
|
84
|
+
if (!initialNode) {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
const target = redirectParagraphToWrappedMedia(view, view.state.doc.resolve(targetPosition), targetPosition);
|
|
88
|
+
targetPosition = target.position;
|
|
89
|
+
const node = target.node;
|
|
90
|
+
if (!node || (controls === null || controls === void 0 ? void 0 : (_controls$activeNode = controls.activeNode) === null || _controls$activeNode === void 0 ? void 0 : _controls$activeNode.pos) === targetPosition) {
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
const $target = view.state.doc.resolve(targetPosition);
|
|
94
|
+
if ($target.depth > 0 && (node.type.name === 'paragraph' || node.type.name === 'heading') && node.content.size === 0) {
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
const parentNode = $target.parent;
|
|
98
|
+
const parentPosition = $target.depth > 0 ? $target.before($target.depth) : undefined;
|
|
99
|
+
const parentDOM = parentPosition === undefined ? undefined : view.nodeDOM(parentPosition);
|
|
100
|
+
if (isPanelNodeTypeName(parentNode.type.name) && !(parentDOM instanceof HTMLElement && parentDOM.classList.contains('ak-editor-panel__no-icon')) && $target.index() === 0) {
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
if (node.type.name === 'layoutColumn' && parentNode.type.name === 'layoutSection' && parentNode.childCount === 1 && expValEqualsNoExposure('advanced_layouts', 'isEnabled', true) && !expValEquals('platform_editor_layout_column_menu', 'isEnabled', true)) {
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
const anchors = controls === null || controls === void 0 ? void 0 : controls.surfaceAnchors;
|
|
107
|
+
const anchorName = (_anchors$get = anchors === null || anchors === void 0 ? void 0 : anchors.get(targetPosition)) !== null && _anchors$get !== void 0 ? _anchors$get : api.core.actions.getAnchorIdForNode(node, targetPosition);
|
|
108
|
+
const rootPos = $target.depth > 0 ? $target.before(1) : targetPosition;
|
|
109
|
+
const rootNode = view.state.doc.nodeAt(rootPos);
|
|
110
|
+
const rootAnchorName = (_anchors$get2 = anchors === null || anchors === void 0 ? void 0 : anchors.get(rootPos)) !== null && _anchors$get2 !== void 0 ? _anchors$get2 : rootNode ? api.core.actions.getAnchorIdForNode(rootNode, rootPos) : undefined;
|
|
111
|
+
if (!anchorName || !rootNode) {
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
api.core.actions.execute(api.blockControls.commands.showDragHandleAt(targetPosition, anchorName, getNodeTypeWithLevel(node), undefined, rootPos, rootAnchorName !== null && rootAnchorName !== void 0 ? rootAnchorName : anchorName, getNodeTypeWithLevel(rootNode)));
|
|
115
|
+
return false;
|
|
116
|
+
};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { bind } from 'bind-event-listener';
|
|
2
2
|
import { isBlockControlsSuppressionTarget } from '@atlaskit/editor-common/block-controls-suppression';
|
|
3
3
|
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
4
|
+
import { PluginKey } from '@atlaskit/editor-prosemirror/state';
|
|
4
5
|
import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
|
|
5
6
|
import { UNSAFE_expValNoExposure } from '@atlaskit/platform-feature-experiments/unsafe-exp-val-no-exposure';
|
|
6
|
-
import { PluginKey } from '@atlaskit/editor-prosemirror/state';
|
|
7
7
|
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/editor-experiment';
|
|
8
8
|
import { RIGHT_MARGIN_ROVO_GAP_PX } from './constants';
|
|
9
9
|
import { handleKeyDown } from './handle-key-down';
|