@atlaskit/editor-plugin-block-controls 2.4.1 → 2.6.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 +33 -0
- package/dist/cjs/commands/move-node.js +7 -6
- package/dist/cjs/commands/show-drag-handle.js +2 -1
- package/dist/cjs/pm-plugins/decorations.js +93 -32
- package/dist/cjs/pm-plugins/keymap.js +5 -2
- package/dist/cjs/pm-plugins/main.js +349 -203
- package/dist/cjs/ui/drag-handle.js +4 -6
- package/dist/cjs/ui/drop-target-v2.js +32 -6
- package/dist/cjs/ui/drop-target.js +2 -0
- package/dist/cjs/ui/global-styles.js +1 -7
- package/dist/cjs/utils/transactions.js +63 -0
- package/dist/cjs/utils/validation.js +17 -0
- package/dist/es2019/commands/move-node.js +7 -6
- package/dist/es2019/commands/show-drag-handle.js +2 -1
- package/dist/es2019/pm-plugins/decorations.js +86 -31
- package/dist/es2019/pm-plugins/keymap.js +5 -2
- package/dist/es2019/pm-plugins/main.js +332 -179
- package/dist/es2019/ui/drag-handle.js +4 -8
- package/dist/es2019/ui/drop-target-v2.js +32 -6
- package/dist/es2019/ui/drop-target.js +2 -0
- package/dist/es2019/ui/global-styles.js +1 -7
- package/dist/es2019/utils/transactions.js +57 -0
- package/dist/es2019/utils/validation.js +17 -0
- package/dist/esm/commands/move-node.js +7 -6
- package/dist/esm/commands/show-drag-handle.js +2 -1
- package/dist/esm/pm-plugins/decorations.js +92 -31
- package/dist/esm/pm-plugins/keymap.js +5 -2
- package/dist/esm/pm-plugins/main.js +350 -204
- package/dist/esm/ui/drag-handle.js +4 -6
- package/dist/esm/ui/drop-target-v2.js +32 -6
- package/dist/esm/ui/drop-target.js +2 -0
- package/dist/esm/ui/global-styles.js +1 -7
- package/dist/esm/utils/transactions.js +57 -0
- package/dist/esm/utils/validation.js +17 -0
- package/dist/types/pm-plugins/decorations.d.ts +24 -4
- package/dist/types/pm-plugins/main.d.ts +32 -0
- package/dist/types/ui/drag-handle.d.ts +5 -14
- package/dist/types/ui/drop-target-v2.d.ts +1 -1
- package/dist/types/ui/drop-target.d.ts +2 -0
- package/dist/types/utils/transactions.d.ts +29 -0
- package/dist/types-ts4.5/pm-plugins/decorations.d.ts +24 -4
- package/dist/types-ts4.5/pm-plugins/main.d.ts +32 -0
- package/dist/types-ts4.5/ui/drag-handle.d.ts +5 -14
- package/dist/types-ts4.5/ui/drop-target-v2.d.ts +1 -1
- package/dist/types-ts4.5/ui/drop-target.d.ts +2 -0
- package/dist/types-ts4.5/utils/transactions.d.ts +29 -0
- package/package.json +5 -8
|
@@ -10,7 +10,6 @@ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/sli
|
|
|
10
10
|
var _react = require("react");
|
|
11
11
|
var _react2 = require("@emotion/react");
|
|
12
12
|
var _bindEventListener = require("bind-event-listener");
|
|
13
|
-
var _reactIntlNext = require("react-intl-next");
|
|
14
13
|
var _analytics = require("@atlaskit/editor-common/analytics");
|
|
15
14
|
var _hooks = require("@atlaskit/editor-common/hooks");
|
|
16
15
|
var _keymaps = require("@atlaskit/editor-common/keymaps");
|
|
@@ -69,14 +68,14 @@ var selectedStyles = (0, _react2.css)({
|
|
|
69
68
|
backgroundColor: "var(--ds-background-selected, #E9F2FF)",
|
|
70
69
|
color: "var(--ds-icon-selected, #0C66E4)"
|
|
71
70
|
});
|
|
72
|
-
var
|
|
71
|
+
var DragHandle = exports.DragHandle = function DragHandle(_ref) {
|
|
73
72
|
var _api$core2, _api$analytics2, _api$core4, _api$core6;
|
|
74
73
|
var view = _ref.view,
|
|
75
74
|
api = _ref.api,
|
|
75
|
+
formatMessage = _ref.formatMessage,
|
|
76
76
|
getPos = _ref.getPos,
|
|
77
77
|
anchorName = _ref.anchorName,
|
|
78
78
|
nodeType = _ref.nodeType,
|
|
79
|
-
formatMessage = _ref.intl.formatMessage,
|
|
80
79
|
handleOptions = _ref.handleOptions,
|
|
81
80
|
_ref$isTopLevelNode = _ref.isTopLevelNode,
|
|
82
81
|
isTopLevelNode = _ref$isTopLevelNode === void 0 ? true : _ref$isTopLevelNode;
|
|
@@ -377,7 +376,7 @@ var DragHandleInternal = function DragHandleInternal(_ref) {
|
|
|
377
376
|
keymap: _keymaps.dragToMoveDown
|
|
378
377
|
}];
|
|
379
378
|
var isParentNodeOfTypeLayout;
|
|
380
|
-
if (!isTopLevelNode && handleOptions !== null && handleOptions !== void 0 && handleOptions.isFocused && (0, _platformFeatureFlags.fg)('platform_editor_element_dnd_nested_a11y')) {
|
|
379
|
+
if (!isTopLevelNode && handleOptions !== null && handleOptions !== void 0 && handleOptions.isFocused && (0, _experiments.editorExperiment)('nested-dnd', true) && (0, _platformFeatureFlags.fg)('platform_editor_element_dnd_nested_a11y')) {
|
|
381
380
|
isParentNodeOfTypeLayout = nodeType === 'layoutSection' || view.state.doc.resolve((0, _utils.getNestedNodePosition)(view.state)).node().type.name === 'layoutColumn';
|
|
382
381
|
if (isParentNodeOfTypeLayout) {
|
|
383
382
|
helpDescriptors = [].concat((0, _toConsumableArray2.default)(helpDescriptors), [{
|
|
@@ -424,5 +423,4 @@ var DragHandleInternal = function DragHandleInternal(_ref) {
|
|
|
424
423
|
});
|
|
425
424
|
}
|
|
426
425
|
}, renderButton()) : renderButton();
|
|
427
|
-
};
|
|
428
|
-
var DragHandle = exports.DragHandle = (0, _reactIntlNext.injectIntl)(DragHandleInternal);
|
|
426
|
+
};
|
|
@@ -62,15 +62,28 @@ var nestedDropZoneStyle = (0, _react2.css)({
|
|
|
62
62
|
width: 'unset'
|
|
63
63
|
});
|
|
64
64
|
var enableDropZone = ['paragraph', 'mediaSingle', 'heading', 'codeBlock', 'decisionList', 'bulletList', 'orderedList', 'taskList', 'extension', 'blockCard'];
|
|
65
|
+
var fullHeightStyle = (0, _react2.css)({
|
|
66
|
+
top: '4px',
|
|
67
|
+
bottom: '4px',
|
|
68
|
+
height: 'unset',
|
|
69
|
+
zIndex: 10
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
// This z index is used in container like layout
|
|
73
|
+
var fullHeightStyleAdjustZIndexStyle = (0, _react2.css)({
|
|
74
|
+
zIndex: 0
|
|
75
|
+
});
|
|
65
76
|
var HoverZone = function HoverZone(_ref) {
|
|
66
77
|
var onDragEnter = _ref.onDragEnter,
|
|
67
78
|
onDragLeave = _ref.onDragLeave,
|
|
68
79
|
onDrop = _ref.onDrop,
|
|
69
80
|
node = _ref.node,
|
|
81
|
+
parent = _ref.parent,
|
|
70
82
|
editorWidth = _ref.editorWidth,
|
|
71
83
|
anchorHeightsCache = _ref.anchorHeightsCache,
|
|
72
84
|
position = _ref.position,
|
|
73
|
-
isNestedDropTarget = _ref.isNestedDropTarget
|
|
85
|
+
isNestedDropTarget = _ref.isNestedDropTarget,
|
|
86
|
+
dropTargetStyle = _ref.dropTargetStyle;
|
|
74
87
|
var ref = (0, _react.useRef)(null);
|
|
75
88
|
(0, _react.useEffect)(function () {
|
|
76
89
|
if (ref.current) {
|
|
@@ -97,14 +110,23 @@ var HoverZone = function HoverZone(_ref) {
|
|
|
97
110
|
maxWidth: "".concat(editorWidth || 0, "px")
|
|
98
111
|
});
|
|
99
112
|
}, [anchorHeightsCache, editorWidth, node, position]);
|
|
113
|
+
var isFullHeight = (0, _react.useMemo)(function () {
|
|
114
|
+
return dropTargetStyle === 'fullHeight';
|
|
115
|
+
}, [dropTargetStyle]);
|
|
116
|
+
var isFullHeightInLayout = (0, _react.useMemo)(function () {
|
|
117
|
+
return isFullHeight && (parent === null || parent === void 0 ? void 0 : parent.type.name) === 'layoutColumn';
|
|
118
|
+
}, [isFullHeight, parent === null || parent === void 0 ? void 0 : parent.type.name]);
|
|
100
119
|
return (0, _react2.jsx)("div", {
|
|
101
120
|
ref: ref
|
|
102
121
|
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop
|
|
103
122
|
,
|
|
104
|
-
className: "drop-target-hover-zone-".concat(position)
|
|
123
|
+
className: "drop-target-hover-zone-".concat(position),
|
|
124
|
+
"data-testid": "drop-target-zone-".concat(position)
|
|
105
125
|
// eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage
|
|
106
126
|
,
|
|
107
|
-
css: [dropZoneStyles, isNestedDropTarget && nestedDropZoneStyle,
|
|
127
|
+
css: [dropZoneStyles, isNestedDropTarget && nestedDropZoneStyle,
|
|
128
|
+
// eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage
|
|
129
|
+
hoverZoneUpperStyle, isFullHeight && fullHeightStyle, isFullHeightInLayout && fullHeightStyleAdjustZIndexStyle]
|
|
108
130
|
});
|
|
109
131
|
};
|
|
110
132
|
var DropTargetV2 = exports.DropTargetV2 = function DropTargetV2(_ref2) {
|
|
@@ -115,7 +137,8 @@ var DropTargetV2 = exports.DropTargetV2 = function DropTargetV2(_ref2) {
|
|
|
115
137
|
nextNode = _ref2.nextNode,
|
|
116
138
|
parentNode = _ref2.parentNode,
|
|
117
139
|
formatMessage = _ref2.formatMessage,
|
|
118
|
-
anchorHeightsCache = _ref2.anchorHeightsCache
|
|
140
|
+
anchorHeightsCache = _ref2.anchorHeightsCache,
|
|
141
|
+
dropTargetStyle = _ref2.dropTargetStyle;
|
|
119
142
|
var _useState = (0, _react.useState)(false),
|
|
120
143
|
_useState2 = (0, _slicedToArray2.default)(_useState, 2),
|
|
121
144
|
isDraggedOver = _useState2[0],
|
|
@@ -137,10 +160,11 @@ var DropTargetV2 = exports.DropTargetV2 = function DropTargetV2(_ref2) {
|
|
|
137
160
|
api === null || api === void 0 || (_api$core = api.core) === null || _api$core === void 0 || _api$core.actions.execute(api === null || api === void 0 || (_api$blockControls2 = api.blockControls) === null || _api$blockControls2 === void 0 || (_api$blockControls2 = _api$blockControls2.commands) === null || _api$blockControls2 === void 0 ? void 0 : _api$blockControls2.moveNode(start, pos, undefined, formatMessage));
|
|
138
161
|
}
|
|
139
162
|
};
|
|
163
|
+
var isFullHeight = dropTargetStyle === 'fullHeight';
|
|
140
164
|
var dynamicStyle = (_dynamicStyle = {
|
|
141
165
|
width: isNestedDropTarget ? 'unset' : '100%'
|
|
142
166
|
}, (0, _defineProperty2.default)(_dynamicStyle, EDITOR_BLOCK_CONTROLS_DROP_INDICATOR_WIDTH, isNestedDropTarget ? '100%' : "".concat((widthState === null || widthState === void 0 ? void 0 : widthState.lineLength) || DEFAULT_DROP_INDICATOR_WIDTH, "px")), (0, _defineProperty2.default)(_dynamicStyle, EDITOR_BLOCK_CONTROLS_DROP_TARGET_LEFT_MARGIN, isNestedDropTarget ? (0, _consts.getNestedNodeLeftPaddingMargin)(parentNode === null || parentNode === void 0 ? void 0 : parentNode.type.name) : '0'), (0, _defineProperty2.default)(_dynamicStyle, EDITOR_BLOCK_CONTROLS_DROP_TARGET_ZINDEX, (0, _experiments.editorExperiment)('nested-dnd', true) ? _constants.layers.navigation() : _constants.layers.card()), _dynamicStyle);
|
|
143
|
-
return (0, _react2.jsx)(_react.Fragment, null, (0, _react2.jsx)(HoverZone, {
|
|
167
|
+
return (0, _react2.jsx)(_react.Fragment, null, !isFullHeight && (0, _react2.jsx)(HoverZone, {
|
|
144
168
|
onDragEnter: function onDragEnter() {
|
|
145
169
|
return setIsDraggedOver(true);
|
|
146
170
|
},
|
|
@@ -176,9 +200,11 @@ var DropTargetV2 = exports.DropTargetV2 = function DropTargetV2(_ref2) {
|
|
|
176
200
|
},
|
|
177
201
|
onDrop: onDrop,
|
|
178
202
|
node: nextNode,
|
|
203
|
+
parent: parentNode,
|
|
179
204
|
editorWidth: widthState === null || widthState === void 0 ? void 0 : widthState.lineLength,
|
|
180
205
|
anchorHeightsCache: anchorHeightsCache,
|
|
181
206
|
position: "lower",
|
|
182
|
-
isNestedDropTarget: isNestedDropTarget
|
|
207
|
+
isNestedDropTarget: isNestedDropTarget,
|
|
208
|
+
dropTargetStyle: dropTargetStyle
|
|
183
209
|
}));
|
|
184
210
|
};
|
|
@@ -120,6 +120,8 @@ var DropTarget = exports.DropTarget = function DropTarget(_ref3) {
|
|
|
120
120
|
return;
|
|
121
121
|
}
|
|
122
122
|
|
|
123
|
+
// This should be moved to platform/packages/editor/editor-plugin-block-controls/src/utils/validation.ts
|
|
124
|
+
// Since we are moved to drop-target-v2
|
|
123
125
|
// Place experiments here instead of just inside move-node.ts as it stops the drag marker from appearing.
|
|
124
126
|
if ((0, _experiments.editorExperiment)('nest-media-and-codeblock-in-quote', false)) {
|
|
125
127
|
var _api$blockControls;
|
|
@@ -128,18 +128,12 @@ var withFormatInLayoutStyleFixSelectors = ["".concat(dragHandleContainer, ":firs
|
|
|
128
128
|
var withInlineNodeStyleWithChromeFix = (0, _react.css)((0, _defineProperty2.default)({}, withInlineNodeStyleWithChromeFixSelectors, {
|
|
129
129
|
transform: 'scale(0)'
|
|
130
130
|
}));
|
|
131
|
-
var globalStyles = (0,
|
|
131
|
+
var globalStyles = (0, _react.css)({
|
|
132
132
|
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Ignored via go/DSP-18766
|
|
133
133
|
'.ProseMirror-widget:first-child + *:not([data-panel-type], .code-block, [data-node-type="nestedExpand"])': {
|
|
134
134
|
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-important-styles -- Ignored via go/DSP-18766
|
|
135
135
|
marginTop: '0 !important'
|
|
136
136
|
}
|
|
137
|
-
}) : (0, _react.css)({
|
|
138
|
-
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Ignored via go/DSP-18766
|
|
139
|
-
'.ProseMirror-widget:first-child + *': {
|
|
140
|
-
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-important-styles -- Ignored via go/DSP-18766
|
|
141
|
-
marginTop: '0 !important'
|
|
142
|
-
}
|
|
143
137
|
});
|
|
144
138
|
var withDividerInPanelStyleFix = (0, _react.css)((0, _defineProperty2.default)({}, "".concat(dividerBodiedInCustomPanelWithNoIconSelector), {
|
|
145
139
|
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-important-styles
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.isStepText = exports.isStepDelete = exports.getTrMetadata = void 0;
|
|
7
|
+
var _transform = require("@atlaskit/editor-prosemirror/transform");
|
|
8
|
+
/**
|
|
9
|
+
* Checks if step adds inline char
|
|
10
|
+
* @param s
|
|
11
|
+
* @returns True if step adds inline char
|
|
12
|
+
*/
|
|
13
|
+
var isStepText = exports.isStepText = function isStepText(s) {
|
|
14
|
+
var content = s.slice.content.firstChild;
|
|
15
|
+
return s.from === s.to && s.slice.content.childCount === 1 && !!content && !!content.text;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Checks if step is an inline delete/backspace (replace range from -> from + 1 with empty content)
|
|
20
|
+
* @param s
|
|
21
|
+
* @returns True if delete/backspace
|
|
22
|
+
*/
|
|
23
|
+
var isStepDelete = exports.isStepDelete = function isStepDelete(s) {
|
|
24
|
+
var content = s.slice.content;
|
|
25
|
+
return s.to === s.from + 1 && content.size === 0;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Get metadata from the transaction.
|
|
30
|
+
* @param tr
|
|
31
|
+
* @returns Min 'from', max 'to' (from + slice size). If no steps, returns pos range of entire doc.
|
|
32
|
+
* Number of ReplaceStep and ReplaceAroundStep steps 'numReplaceSteps'.
|
|
33
|
+
* 'isAllText' if all steps are represent adding inline text or a backspace/delete or no-op
|
|
34
|
+
*/
|
|
35
|
+
var getTrMetadata = exports.getTrMetadata = function getTrMetadata(tr) {
|
|
36
|
+
var from;
|
|
37
|
+
var to;
|
|
38
|
+
var numReplaceSteps = 0;
|
|
39
|
+
var isAllText = true;
|
|
40
|
+
tr.steps.forEach(function (s) {
|
|
41
|
+
if (s instanceof _transform.ReplaceStep || s instanceof _transform.ReplaceAroundStep) {
|
|
42
|
+
if (s instanceof _transform.ReplaceAroundStep || s instanceof _transform.ReplaceStep && !isStepText(s) && !isStepDelete(s)) {
|
|
43
|
+
isAllText = false;
|
|
44
|
+
}
|
|
45
|
+
var $to = s.from + s.slice.size;
|
|
46
|
+
from = from === undefined || from > s.from ? s.from : from;
|
|
47
|
+
to = to === undefined || to < $to ? $to : to;
|
|
48
|
+
numReplaceSteps++;
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
if (from === undefined) {
|
|
52
|
+
from = 0;
|
|
53
|
+
}
|
|
54
|
+
if (to === undefined || to > tr.doc.nodeSize - 2) {
|
|
55
|
+
to = tr.doc.nodeSize - 2;
|
|
56
|
+
}
|
|
57
|
+
return {
|
|
58
|
+
from: from,
|
|
59
|
+
to: to,
|
|
60
|
+
numReplaceSteps: numReplaceSteps,
|
|
61
|
+
isAllText: isAllText
|
|
62
|
+
};
|
|
63
|
+
};
|
|
@@ -8,6 +8,7 @@ exports.canMoveNodeToIndex = canMoveNodeToIndex;
|
|
|
8
8
|
exports.transformSliceExpandToNestedExpand = exports.transformExpandToNestedExpand = exports.memoizedTransformExpandToNestedExpand = exports.isNestedExpand = exports.isLayoutColumn = exports.isInsideTable = exports.isExpand = exports.isDoc = void 0;
|
|
9
9
|
var _memoizeOne = _interopRequireDefault(require("memoize-one"));
|
|
10
10
|
var _model = require("@atlaskit/editor-prosemirror/model");
|
|
11
|
+
var _experiments = require("@atlaskit/tmp-editor-statsig/experiments");
|
|
11
12
|
var isInsideTable = exports.isInsideTable = function isInsideTable(nodeType) {
|
|
12
13
|
var _nodeType$schema$node = nodeType.schema.nodes,
|
|
13
14
|
tableCell = _nodeType$schema$node.tableCell,
|
|
@@ -70,6 +71,22 @@ var memoizedTransformExpandToNestedExpand = exports.memoizedTransformExpandToNes
|
|
|
70
71
|
});
|
|
71
72
|
function canMoveNodeToIndex(destParent, indexIntoParent, srcNode) {
|
|
72
73
|
var srcNodeType = srcNode.type;
|
|
74
|
+
var parentNodeType = destParent === null || destParent === void 0 ? void 0 : destParent.type.name;
|
|
75
|
+
var activeNodeType = srcNode === null || srcNode === void 0 ? void 0 : srcNode.type.name;
|
|
76
|
+
|
|
77
|
+
// Place experiments here instead of just inside move-node.ts as it stops the drag marker from appearing.
|
|
78
|
+
if ((0, _experiments.editorExperiment)('nest-media-and-codeblock-in-quote', false)) {
|
|
79
|
+
if (parentNodeType === 'blockquote' && (activeNodeType === 'mediaGroup' || activeNodeType === 'mediaSingle' || activeNodeType === 'codeBlock')) {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Place experiments here instead of just inside move-node.ts as it stops the drag marker from appearing.
|
|
85
|
+
if ((0, _experiments.editorExperiment)('nested-expand-in-expand', false)) {
|
|
86
|
+
if (parentNodeType === 'expand' && (activeNodeType === 'expand' || activeNodeType === 'nestedExpand')) {
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
73
90
|
if (isInsideTable(destParent.type) && isExpand(srcNodeType)) {
|
|
74
91
|
if (memoizedTransformExpandToNestedExpand(srcNode)) {
|
|
75
92
|
srcNodeType = srcNodeType.schema.nodes.nestedExpand;
|
|
@@ -65,7 +65,7 @@ const getCurrentNodePos = (state, isParentNodeOfTypeLayout) => {
|
|
|
65
65
|
// 2. caret cursor is inside the node
|
|
66
66
|
// 3. the start of the selection is inside the node
|
|
67
67
|
currentNodePos = selection.$from.before(1);
|
|
68
|
-
if (selection.$from.depth > 0 && fg('platform_editor_element_dnd_nested_a11y')) {
|
|
68
|
+
if (selection.$from.depth > 0 && editorExperiment('nested-dnd', true) && fg('platform_editor_element_dnd_nested_a11y')) {
|
|
69
69
|
currentNodePos = getNestedNodePosition(state);
|
|
70
70
|
}
|
|
71
71
|
}
|
|
@@ -74,7 +74,8 @@ const getCurrentNodePos = (state, isParentNodeOfTypeLayout) => {
|
|
|
74
74
|
export const moveNodeViaShortcut = (api, direction, formatMessage) => {
|
|
75
75
|
return state => {
|
|
76
76
|
let isParentNodeOfTypeLayout;
|
|
77
|
-
|
|
77
|
+
const shouldEnableNestedDndA11y = editorExperiment('nested-dnd', true) && fg('platform_editor_element_dnd_nested_a11y');
|
|
78
|
+
if (shouldEnableNestedDndA11y) {
|
|
78
79
|
isParentNodeOfTypeLayout = !!findParentNodeOfType([state.schema.nodes.layoutSection])(state.selection);
|
|
79
80
|
}
|
|
80
81
|
const currentNodePos = getCurrentNodePos(state, isParentNodeOfTypeLayout);
|
|
@@ -83,7 +84,7 @@ export const moveNodeViaShortcut = (api, direction, formatMessage) => {
|
|
|
83
84
|
const $pos = state.doc.resolve(currentNodePos);
|
|
84
85
|
let moveToPos = -1;
|
|
85
86
|
const nodeIndex = $pos.index();
|
|
86
|
-
if (direction === DIRECTION.LEFT &&
|
|
87
|
+
if (direction === DIRECTION.LEFT && shouldEnableNestedDndA11y) {
|
|
87
88
|
if ($pos.depth < 2 || !isParentNodeOfTypeLayout) {
|
|
88
89
|
return false;
|
|
89
90
|
}
|
|
@@ -93,13 +94,13 @@ export const moveNodeViaShortcut = (api, direction, formatMessage) => {
|
|
|
93
94
|
const grandParent = $pos.node($pos.depth - 1);
|
|
94
95
|
const previousNode = grandParent ? grandParent.maybeChild(index - 1) : null;
|
|
95
96
|
moveToPos = $pos.start() - ((previousNode === null || previousNode === void 0 ? void 0 : previousNode.nodeSize) || 1);
|
|
96
|
-
} else if (direction === DIRECTION.RIGHT &&
|
|
97
|
+
} else if (direction === DIRECTION.RIGHT && shouldEnableNestedDndA11y) {
|
|
97
98
|
if ($pos.depth < 2 || !isParentNodeOfTypeLayout) {
|
|
98
99
|
return false;
|
|
99
100
|
}
|
|
100
101
|
moveToPos = $pos.after($pos.depth) + 1;
|
|
101
102
|
} else if (direction === DIRECTION.UP) {
|
|
102
|
-
const nodeBefore = $pos.depth > 1 && nodeIndex === 0 &&
|
|
103
|
+
const nodeBefore = $pos.depth > 1 && nodeIndex === 0 && shouldEnableNestedDndA11y ? $pos.node($pos.depth) : $pos.nodeBefore;
|
|
103
104
|
if (nodeBefore) {
|
|
104
105
|
moveToPos = currentNodePos - nodeBefore.nodeSize;
|
|
105
106
|
}
|
|
@@ -115,7 +116,7 @@ export const moveNodeViaShortcut = (api, direction, formatMessage) => {
|
|
|
115
116
|
const nodeType = (_state$doc$nodeAt = state.doc.nodeAt(currentNodePos)) === null || _state$doc$nodeAt === void 0 ? void 0 : _state$doc$nodeAt.type.name;
|
|
116
117
|
|
|
117
118
|
// only move the node if the destination is at the same depth, not support moving a nested node to a parent node
|
|
118
|
-
const shouldMoveNode =
|
|
119
|
+
const shouldMoveNode = shouldEnableNestedDndA11y ? moveToPos > -1 && $pos.depth === state.doc.resolve(moveToPos).depth : moveToPos > -1;
|
|
119
120
|
if (shouldMoveNode) {
|
|
120
121
|
var _api$core;
|
|
121
122
|
api === null || api === void 0 ? void 0 : (_api$core = api.core) === null || _api$core === void 0 ? void 0 : _api$core.actions.execute(({
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { isInTable } from '@atlaskit/editor-tables/utils';
|
|
2
2
|
import { fg } from '@atlaskit/platform-feature-flags';
|
|
3
|
+
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
|
|
3
4
|
import { key } from '../pm-plugins/main';
|
|
4
5
|
import { getNestedNodePosition } from '../utils';
|
|
5
6
|
export const showDragHandleAtSelection = (api, shouldFocusParentNode) => (state, _, view) => {
|
|
@@ -7,7 +8,7 @@ export const showDragHandleAtSelection = (api, shouldFocusParentNode) => (state,
|
|
|
7
8
|
$from
|
|
8
9
|
} = state.selection;
|
|
9
10
|
let shouldFocusParentNode;
|
|
10
|
-
if ($from.depth > 1 && fg('platform_editor_element_dnd_nested_a11y')) {
|
|
11
|
+
if ($from.depth > 1 && editorExperiment('nested-dnd', true) && fg('platform_editor_element_dnd_nested_a11y')) {
|
|
11
12
|
var _activeNode$handleOpt, _view$domAtPos;
|
|
12
13
|
const {
|
|
13
14
|
activeNode
|
|
@@ -2,7 +2,6 @@ import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
|
2
2
|
import { createElement } from 'react';
|
|
3
3
|
import { bind } from 'bind-event-listener';
|
|
4
4
|
import ReactDOM from 'react-dom';
|
|
5
|
-
import { RawIntlProvider } from 'react-intl-next';
|
|
6
5
|
import uuid from 'uuid';
|
|
7
6
|
import { isEmptyParagraph } from '@atlaskit/editor-common/utils';
|
|
8
7
|
import { Decoration } from '@atlaskit/editor-prosemirror/view';
|
|
@@ -18,6 +17,9 @@ const IGNORE_NODES = ['tableCell', 'tableHeader', 'tableRow', 'layoutColumn', 'l
|
|
|
18
17
|
const IGNORE_NODE_DESCENDANTS = ['listItem', 'taskList', 'decisionList', 'mediaSingle'];
|
|
19
18
|
const PARENT_WITH_END_DROP_TARGET = ['tableCell', 'tableHeader', 'panel', 'layoutColumn', 'expand', 'nestedExpand', 'bodiedExtension'];
|
|
20
19
|
const DISABLE_CHILD_DROP_TARGET = ['orderedList', 'bulletList'];
|
|
20
|
+
export const TYPE_DROP_TARGET_DEC = 'drop-target-decoration';
|
|
21
|
+
export const TYPE_HANDLE_DEC = 'drag-handle';
|
|
22
|
+
export const TYPE_NODE_DEC = 'node-decoration';
|
|
21
23
|
const getNestedDepth = () => editorExperiment('nested-dnd', true) ? 100 : 0;
|
|
22
24
|
export const getNodeAnchor = node => {
|
|
23
25
|
const handleId = ObjHash.getForNode(node);
|
|
@@ -66,6 +68,48 @@ const shouldDescend = node => {
|
|
|
66
68
|
}
|
|
67
69
|
return true;
|
|
68
70
|
};
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Find drop target decorations in the pos range between from and to
|
|
74
|
+
* @param decorations
|
|
75
|
+
* @param from
|
|
76
|
+
* @param to
|
|
77
|
+
* @returns
|
|
78
|
+
*/
|
|
79
|
+
export const findDropTargetDecs = (decorations, from, to) => {
|
|
80
|
+
return decorations.find(from, to, spec => spec.type === TYPE_DROP_TARGET_DEC);
|
|
81
|
+
};
|
|
82
|
+
export const findHandleDec = (decorations, from, to) => {
|
|
83
|
+
return decorations.find(from, to, spec => spec.type === TYPE_HANDLE_DEC);
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Find node decorations in the pos range between from and to (non-inclusive)
|
|
88
|
+
* @param decorations
|
|
89
|
+
* @param from
|
|
90
|
+
* @param to
|
|
91
|
+
* @returns
|
|
92
|
+
*/
|
|
93
|
+
export const findNodeDecs = (decorations, from, to) => {
|
|
94
|
+
let newfrom = from;
|
|
95
|
+
let newTo = to;
|
|
96
|
+
|
|
97
|
+
// make it non-inclusive
|
|
98
|
+
if (newfrom !== undefined) {
|
|
99
|
+
newfrom++;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// make it non-inclusive
|
|
103
|
+
if (newTo !== undefined) {
|
|
104
|
+
newTo--;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// return empty array if range reversed
|
|
108
|
+
if (newfrom !== undefined && newTo !== undefined && newfrom > newTo) {
|
|
109
|
+
return new Array();
|
|
110
|
+
}
|
|
111
|
+
return decorations.find(newfrom, newTo, spec => spec.type === TYPE_NODE_DEC);
|
|
112
|
+
};
|
|
69
113
|
export const createDropTargetDecoration = (pos, props, side, anchorHeightsCache) => {
|
|
70
114
|
return Decoration.widget(pos, (_, getPos) => {
|
|
71
115
|
const element = document.createElement('div');
|
|
@@ -93,13 +137,16 @@ export const createDropTargetDecoration = (pos, props, side, anchorHeightsCache)
|
|
|
93
137
|
}
|
|
94
138
|
return element;
|
|
95
139
|
}, {
|
|
96
|
-
type:
|
|
140
|
+
type: TYPE_DROP_TARGET_DEC,
|
|
97
141
|
side
|
|
98
142
|
});
|
|
99
143
|
};
|
|
100
|
-
export const dropTargetDecorations = (newState, api, formatMessage, activeNode, anchorHeightsCache) => {
|
|
101
|
-
const decs = [];
|
|
144
|
+
export const dropTargetDecorations = (newState, api, formatMessage, activeNode, anchorHeightsCache, from, to) => {
|
|
102
145
|
unmountDecorations('data-blocks-drop-target-container');
|
|
146
|
+
const decs = [];
|
|
147
|
+
const POS_END_OF_DOC = newState.doc.nodeSize - 2;
|
|
148
|
+
const docFrom = from === undefined || from < 0 ? 0 : from;
|
|
149
|
+
const docTo = to === undefined || to > POS_END_OF_DOC ? POS_END_OF_DOC : to;
|
|
103
150
|
let prevNode;
|
|
104
151
|
const activeNodePos = activeNode === null || activeNode === void 0 ? void 0 : activeNode.pos;
|
|
105
152
|
const activePMNode = typeof activeNodePos === 'number' && newState.doc.resolve(activeNodePos).nodeAfter;
|
|
@@ -117,7 +164,7 @@ export const dropTargetDecorations = (newState, api, formatMessage, activeNode,
|
|
|
117
164
|
popNodeStack(depth);
|
|
118
165
|
prevNodeStack.push(node);
|
|
119
166
|
};
|
|
120
|
-
newState.doc.
|
|
167
|
+
newState.doc.nodesBetween(docFrom, docTo, (node, pos, parent, index) => {
|
|
121
168
|
let depth = 0;
|
|
122
169
|
// drop target deco at the end position
|
|
123
170
|
let endPos;
|
|
@@ -155,19 +202,27 @@ export const dropTargetDecorations = (newState, api, formatMessage, activeNode,
|
|
|
155
202
|
}
|
|
156
203
|
}
|
|
157
204
|
const previousNode = fg('platform_editor_drag_and_drop_target_v2') ? popNodeStack(depth) : prevNode; // created scoped variable
|
|
205
|
+
|
|
206
|
+
// only table and layout need to render full height drop target
|
|
207
|
+
const isInSupportedContainer = fg('platform_editor_drag_and_drop_target_v2') && ['tableCell', 'tableHeader', 'layoutColumn'].includes((parent === null || parent === void 0 ? void 0 : parent.type.name) || '');
|
|
208
|
+
|
|
209
|
+
// container with only an empty paragrah
|
|
210
|
+
const shouldShowFullHeight = isInSupportedContainer && (parent === null || parent === void 0 ? void 0 : parent.lastChild) === node && (parent === null || parent === void 0 ? void 0 : parent.childCount) === 1 && isEmptyParagraph(node) && fg('platform_editor_drag_and_drop_target_v2');
|
|
158
211
|
decs.push(createDropTargetDecoration(pos, {
|
|
159
212
|
api,
|
|
160
213
|
prevNode: previousNode,
|
|
161
214
|
nextNode: node,
|
|
162
215
|
parentNode: parent || undefined,
|
|
163
|
-
formatMessage
|
|
216
|
+
formatMessage,
|
|
217
|
+
dropTargetStyle: shouldShowFullHeight ? 'fullHeight' : 'default'
|
|
164
218
|
}, -1, anchorHeightsCache));
|
|
165
219
|
if (endPos !== undefined) {
|
|
166
220
|
decs.push(createDropTargetDecoration(endPos, {
|
|
167
221
|
api,
|
|
168
222
|
prevNode: fg('platform_editor_drag_and_drop_target_v2') ? node : undefined,
|
|
169
223
|
parentNode: parent || undefined,
|
|
170
|
-
formatMessage
|
|
224
|
+
formatMessage,
|
|
225
|
+
dropTargetStyle: isInSupportedContainer ? 'fullHeight' : 'default'
|
|
171
226
|
}, -1, anchorHeightsCache));
|
|
172
227
|
}
|
|
173
228
|
if (fg('platform_editor_drag_and_drop_target_v2')) {
|
|
@@ -177,12 +232,14 @@ export const dropTargetDecorations = (newState, api, formatMessage, activeNode,
|
|
|
177
232
|
}
|
|
178
233
|
return depth < getNestedDepth() && shouldDescend(node);
|
|
179
234
|
});
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
235
|
+
if (docTo === POS_END_OF_DOC) {
|
|
236
|
+
decs.push(createDropTargetDecoration(POS_END_OF_DOC, {
|
|
237
|
+
api,
|
|
238
|
+
formatMessage,
|
|
239
|
+
prevNode: newState.doc.lastChild || undefined,
|
|
240
|
+
parentNode: newState.doc
|
|
241
|
+
}, undefined, anchorHeightsCache));
|
|
242
|
+
}
|
|
186
243
|
return decs;
|
|
187
244
|
};
|
|
188
245
|
export const emptyParagraphNodeDecorations = () => {
|
|
@@ -192,7 +249,7 @@ export const emptyParagraphNodeDecorations = () => {
|
|
|
192
249
|
style,
|
|
193
250
|
['data-drag-handler-anchor-name']: anchorName
|
|
194
251
|
}, {
|
|
195
|
-
type:
|
|
252
|
+
type: TYPE_NODE_DEC
|
|
196
253
|
});
|
|
197
254
|
};
|
|
198
255
|
class ObjHash {
|
|
@@ -214,18 +271,16 @@ const shouldIgnoreNode = node => {
|
|
|
214
271
|
}
|
|
215
272
|
return IGNORE_NODES.includes(node.type.name);
|
|
216
273
|
};
|
|
217
|
-
export const nodeDecorations = newState => {
|
|
274
|
+
export const nodeDecorations = (newState, from, to) => {
|
|
218
275
|
const decs = [];
|
|
219
|
-
|
|
276
|
+
const docFrom = from === undefined || from < 0 ? 0 : from;
|
|
277
|
+
const docTo = to === undefined || to > newState.doc.nodeSize - 2 ? newState.doc.nodeSize - 2 : to;
|
|
278
|
+
newState.doc.nodesBetween(docFrom, docTo, (node, pos, _parent, index) => {
|
|
220
279
|
let depth = 0;
|
|
221
280
|
let anchorName;
|
|
222
281
|
const shouldDescend = !IGNORE_NODE_DESCENDANTS.includes(node.type.name);
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
}) || editorExperiment('nested-dnd', true)) {
|
|
226
|
-
const handleId = ObjHash.getForNode(node);
|
|
227
|
-
anchorName = `--node-anchor-${node.type.name}-${handleId}`;
|
|
228
|
-
}
|
|
282
|
+
const handleId = ObjHash.getForNode(node);
|
|
283
|
+
anchorName = `--node-anchor-${node.type.name}-${handleId}`;
|
|
229
284
|
if (editorExperiment('nested-dnd', true)) {
|
|
230
285
|
var _anchorName;
|
|
231
286
|
// Doesn't descend into a node
|
|
@@ -247,7 +302,7 @@ export const nodeDecorations = newState => {
|
|
|
247
302
|
['data-drag-handler-node-type']: node.type.name,
|
|
248
303
|
['data-drag-handler-anchor-depth']: `${depth}`
|
|
249
304
|
}, {
|
|
250
|
-
type:
|
|
305
|
+
type: TYPE_NODE_DEC,
|
|
251
306
|
anchorName,
|
|
252
307
|
nodeType: node.type.name
|
|
253
308
|
}));
|
|
@@ -255,7 +310,8 @@ export const nodeDecorations = newState => {
|
|
|
255
310
|
});
|
|
256
311
|
return decs;
|
|
257
312
|
};
|
|
258
|
-
export const dragHandleDecoration = (api,
|
|
313
|
+
export const dragHandleDecoration = (api, formatMessage, pos, anchorName, nodeType, handleOptions) => {
|
|
314
|
+
unmountDecorations('data-blocks-drag-handle-container');
|
|
259
315
|
let unbind;
|
|
260
316
|
return Decoration.widget(pos, (view, getPos) => {
|
|
261
317
|
const element = document.createElement('span');
|
|
@@ -269,7 +325,7 @@ export const dragHandleDecoration = (api, getIntl, pos, anchorName, nodeType, ha
|
|
|
269
325
|
isTopLevelNode = ($pos === null || $pos === void 0 ? void 0 : $pos.parent.type.name) === 'doc';
|
|
270
326
|
/*
|
|
271
327
|
* We disable mouseover event to fix flickering issue on hover
|
|
272
|
-
* However, the tooltip for nested drag handle is
|
|
328
|
+
* However, the tooltip for nested drag handle is no long working.
|
|
273
329
|
*/
|
|
274
330
|
if (!isTopLevelNode) {
|
|
275
331
|
// This will also hide the tooltip.
|
|
@@ -281,26 +337,25 @@ export const dragHandleDecoration = (api, getIntl, pos, anchorName, nodeType, ha
|
|
|
281
337
|
});
|
|
282
338
|
}
|
|
283
339
|
}
|
|
284
|
-
unmountDecorations('data-blocks-drag-handle-container');
|
|
285
340
|
|
|
286
341
|
// There are times when global clear: "both" styles are applied to this decoration causing jumpiness
|
|
287
342
|
// due to margins applied to other nodes eg. Headings
|
|
288
343
|
element.style.clear = 'unset';
|
|
289
|
-
ReactDOM.render( /*#__PURE__*/createElement(
|
|
290
|
-
value: getIntl()
|
|
291
|
-
}, /*#__PURE__*/createElement(DragHandle, {
|
|
344
|
+
ReactDOM.render( /*#__PURE__*/createElement(DragHandle, {
|
|
292
345
|
view,
|
|
293
346
|
api,
|
|
347
|
+
formatMessage,
|
|
294
348
|
getPos,
|
|
295
349
|
anchorName,
|
|
296
350
|
nodeType,
|
|
297
351
|
handleOptions,
|
|
298
352
|
isTopLevelNode
|
|
299
|
-
})
|
|
353
|
+
}), element);
|
|
300
354
|
return element;
|
|
301
355
|
}, {
|
|
302
356
|
side: -1,
|
|
303
|
-
|
|
357
|
+
type: TYPE_HANDLE_DEC,
|
|
358
|
+
testid: `${TYPE_HANDLE_DEC}-${uuid()}`,
|
|
304
359
|
destroy: () => {
|
|
305
360
|
if (editorExperiment('nested-dnd', true)) {
|
|
306
361
|
unbind && unbind();
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { bindKeymapWithCommand, dragToMoveDown, dragToMoveLeft, dragToMoveRight, dragToMoveUp, showElementDragHandle } from '@atlaskit/editor-common/keymaps';
|
|
2
2
|
import { keydownHandler } from '@atlaskit/editor-prosemirror/keymap';
|
|
3
3
|
import { fg } from '@atlaskit/platform-feature-flags';
|
|
4
|
+
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
|
|
4
5
|
import { moveNodeViaShortcut } from '../commands/move-node';
|
|
5
6
|
import { showDragHandleAtSelection } from '../commands/show-drag-handle';
|
|
6
7
|
import { DIRECTION } from '../consts';
|
|
@@ -14,8 +15,10 @@ function keymapList(api, formatMessage) {
|
|
|
14
15
|
}, keymapList);
|
|
15
16
|
bindKeymapWithCommand(dragToMoveUp.common, moveNodeViaShortcut(api, DIRECTION.UP, formatMessage), keymapList);
|
|
16
17
|
bindKeymapWithCommand(dragToMoveDown.common, moveNodeViaShortcut(api, DIRECTION.DOWN, formatMessage), keymapList);
|
|
17
|
-
|
|
18
|
-
|
|
18
|
+
if (editorExperiment('nested-dnd', true) && fg('platform_editor_element_dnd_nested_a11y')) {
|
|
19
|
+
bindKeymapWithCommand(dragToMoveLeft.common, moveNodeViaShortcut(api, DIRECTION.LEFT, formatMessage), keymapList);
|
|
20
|
+
bindKeymapWithCommand(dragToMoveRight.common, moveNodeViaShortcut(api, DIRECTION.RIGHT, formatMessage), keymapList);
|
|
21
|
+
}
|
|
19
22
|
}
|
|
20
23
|
return keymapList;
|
|
21
24
|
}
|