@atlaskit/editor-plugin-block-controls 2.1.11 → 2.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -0
- package/dist/cjs/commands/move-node.js +39 -14
- package/dist/cjs/commands/show-drag-handle.js +39 -6
- package/dist/cjs/consts.js +2 -0
- package/dist/cjs/pm-plugins/handle-mouse-over.js +1 -1
- package/dist/cjs/pm-plugins/keymap.js +2 -0
- package/dist/cjs/ui/drag-handle.js +20 -0
- package/dist/cjs/utils/getNestedNodePosition.js +27 -0
- package/dist/cjs/utils/index.js +8 -1
- package/dist/es2019/commands/move-node.js +33 -8
- package/dist/es2019/commands/show-drag-handle.js +38 -2
- package/dist/es2019/consts.js +2 -0
- package/dist/es2019/pm-plugins/handle-mouse-over.js +1 -1
- package/dist/es2019/pm-plugins/keymap.js +3 -1
- package/dist/es2019/ui/drag-handle.js +22 -3
- package/dist/es2019/utils/getNestedNodePosition.js +23 -0
- package/dist/es2019/utils/index.js +2 -1
- package/dist/esm/commands/move-node.js +33 -8
- package/dist/esm/commands/show-drag-handle.js +39 -6
- package/dist/esm/consts.js +2 -0
- package/dist/esm/pm-plugins/handle-mouse-over.js +1 -1
- package/dist/esm/pm-plugins/keymap.js +3 -1
- package/dist/esm/ui/drag-handle.js +22 -2
- package/dist/esm/utils/getNestedNodePosition.js +21 -0
- package/dist/esm/utils/index.js +2 -1
- package/dist/types/commands/show-drag-handle.d.ts +1 -1
- package/dist/types/consts.d.ts +3 -1
- package/dist/types/utils/getNestedNodePosition.d.ts +2 -0
- package/dist/types/utils/index.d.ts +1 -0
- package/dist/types-ts4.5/commands/show-drag-handle.d.ts +1 -1
- package/dist/types-ts4.5/consts.d.ts +3 -1
- package/dist/types-ts4.5/utils/getNestedNodePosition.d.ts +2 -0
- package/dist/types-ts4.5/utils/index.d.ts +1 -0
- package/package.json +7 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-block-controls
|
|
2
2
|
|
|
3
|
+
## 2.2.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#150591](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/150591)
|
|
8
|
+
[`13337452246bc`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/13337452246bc) -
|
|
9
|
+
support a11y to move various node types with shortcut
|
|
10
|
+
|
|
11
|
+
## 2.2.0
|
|
12
|
+
|
|
13
|
+
### Minor Changes
|
|
14
|
+
|
|
15
|
+
- [#148229](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/148229)
|
|
16
|
+
[`657f160f0cfc0`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/657f160f0cfc0) -
|
|
17
|
+
Add a11y support on moving nested elements
|
|
18
|
+
|
|
19
|
+
### Patch Changes
|
|
20
|
+
|
|
21
|
+
- [#137506](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/137506)
|
|
22
|
+
[`bc1742c9fd32e`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/bc1742c9fd32e) -
|
|
23
|
+
ED-24902: Fix to only check when to hide drag handle on doc level (behind
|
|
24
|
+
confluence_frontend_page_title_enter_improvements)
|
|
25
|
+
- Updated dependencies
|
|
26
|
+
|
|
3
27
|
## 2.1.11
|
|
4
28
|
|
|
5
29
|
### Patch Changes
|
|
@@ -11,12 +11,13 @@ var _messages = require("@atlaskit/editor-common/messages");
|
|
|
11
11
|
var _selection = require("@atlaskit/editor-common/selection");
|
|
12
12
|
var _transforms = require("@atlaskit/editor-common/transforms");
|
|
13
13
|
var _utils = require("@atlaskit/editor-common/utils");
|
|
14
|
-
var _utils2 = require("@atlaskit/editor-
|
|
14
|
+
var _utils2 = require("@atlaskit/editor-prosemirror/utils");
|
|
15
|
+
var _utils3 = require("@atlaskit/editor-tables/utils");
|
|
15
16
|
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
|
|
16
17
|
var _experiments = require("@atlaskit/tmp-editor-statsig/experiments");
|
|
17
18
|
var _consts = require("../consts");
|
|
18
19
|
var _main = require("../pm-plugins/main");
|
|
19
|
-
var
|
|
20
|
+
var _utils4 = require("../utils");
|
|
20
21
|
var _validation = require("../utils/validation");
|
|
21
22
|
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; }
|
|
22
23
|
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; }
|
|
@@ -46,7 +47,7 @@ function transformSourceSlice(nodeCopy, destType) {
|
|
|
46
47
|
*
|
|
47
48
|
* @returns the start position of a node if the node can be moved, otherwise -1
|
|
48
49
|
*/
|
|
49
|
-
var getCurrentNodePos = function getCurrentNodePos(state) {
|
|
50
|
+
var getCurrentNodePos = function getCurrentNodePos(state, isParentNodeOfTypeLayout) {
|
|
50
51
|
var _activeNode$handleOpt;
|
|
51
52
|
var selection = state.selection;
|
|
52
53
|
var _ref = _main.key.getState(state) || {},
|
|
@@ -57,32 +58,53 @@ var getCurrentNodePos = function getCurrentNodePos(state) {
|
|
|
57
58
|
if (activeNode && (_activeNode$handleOpt = activeNode.handleOptions) !== null && _activeNode$handleOpt !== void 0 && _activeNode$handleOpt.isFocused) {
|
|
58
59
|
// 1. drag handle of the node is focused
|
|
59
60
|
currentNodePos = activeNode.pos;
|
|
60
|
-
} else if ((0,
|
|
61
|
-
if ((0,
|
|
61
|
+
} else if ((0, _utils3.isInTable)(state)) {
|
|
62
|
+
if ((0, _utils3.isTableSelected)(selection)) {
|
|
62
63
|
var _findTable$pos, _findTable;
|
|
63
64
|
// We only move table node if it's fully selected
|
|
64
65
|
// to avoid shortcut collision with table drag and drop
|
|
65
|
-
currentNodePos = (_findTable$pos = (_findTable = (0,
|
|
66
|
+
currentNodePos = (_findTable$pos = (_findTable = (0, _utils3.findTable)(selection)) === null || _findTable === void 0 ? void 0 : _findTable.pos) !== null && _findTable$pos !== void 0 ? _findTable$pos : currentNodePos;
|
|
66
67
|
}
|
|
67
68
|
} else if (!(state.selection instanceof _selection.GapCursorSelection)) {
|
|
68
69
|
// 2. caret cursor is inside the node
|
|
69
70
|
// 3. the start of the selection is inside the node
|
|
70
71
|
currentNodePos = selection.$from.before(1);
|
|
72
|
+
if (selection.$from.depth > 0 && (0, _platformFeatureFlags.fg)('platform_editor_element_dnd_nested_a11y')) {
|
|
73
|
+
currentNodePos = (0, _utils4.getNestedNodePosition)(state);
|
|
74
|
+
}
|
|
71
75
|
}
|
|
72
76
|
return currentNodePos;
|
|
73
77
|
};
|
|
74
78
|
var moveNodeViaShortcut = exports.moveNodeViaShortcut = function moveNodeViaShortcut(api, direction, formatMessage) {
|
|
75
79
|
return function (state) {
|
|
76
|
-
var
|
|
80
|
+
var isParentNodeOfTypeLayout;
|
|
81
|
+
if ((0, _platformFeatureFlags.fg)('platform_editor_element_dnd_nested_a11y')) {
|
|
82
|
+
isParentNodeOfTypeLayout = !!(0, _utils2.findParentNodeOfType)([state.schema.nodes.layoutSection])(state.selection);
|
|
83
|
+
}
|
|
84
|
+
var currentNodePos = getCurrentNodePos(state, isParentNodeOfTypeLayout);
|
|
77
85
|
if (currentNodePos > -1) {
|
|
78
86
|
var _state$doc$nodeAt;
|
|
79
87
|
var $pos = state.doc.resolve(currentNodePos);
|
|
80
88
|
var moveToPos = -1;
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
if (
|
|
84
|
-
|
|
89
|
+
var nodeIndex = $pos.index();
|
|
90
|
+
if (direction === _consts.DIRECTION.LEFT && (0, _platformFeatureFlags.fg)('platform_editor_element_dnd_nested_a11y')) {
|
|
91
|
+
if ($pos.depth < 2 || !isParentNodeOfTypeLayout) {
|
|
92
|
+
return false;
|
|
85
93
|
}
|
|
94
|
+
|
|
95
|
+
// get the previous layoutSection node
|
|
96
|
+
var index = $pos.index($pos.depth - 1);
|
|
97
|
+
var grandParent = $pos.node($pos.depth - 1);
|
|
98
|
+
var previousNode = grandParent ? grandParent.maybeChild(index - 1) : null;
|
|
99
|
+
moveToPos = $pos.start() - ((previousNode === null || previousNode === void 0 ? void 0 : previousNode.nodeSize) || 1);
|
|
100
|
+
} else if (direction === _consts.DIRECTION.RIGHT && (0, _platformFeatureFlags.fg)('platform_editor_element_dnd_nested_a11y')) {
|
|
101
|
+
if ($pos.depth < 2 || !isParentNodeOfTypeLayout) {
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
moveToPos = $pos.after($pos.depth) + 1;
|
|
105
|
+
} else if (direction === _consts.DIRECTION.UP) {
|
|
106
|
+
var nodeBefore = $pos.depth > 1 && nodeIndex === 0 && (0, _platformFeatureFlags.fg)('platform_editor_element_dnd_nested_a11y') ? $pos.node($pos.depth) : $pos.nodeBefore;
|
|
107
|
+
moveToPos = $pos.depth > 1 && nodeIndex === 0 && (0, _platformFeatureFlags.fg)('platform_editor_element_dnd_nested_a11y') ? $pos.before($pos.depth) - 1 : nodeBefore ? currentNodePos - nodeBefore.nodeSize : moveToPos;
|
|
86
108
|
} else {
|
|
87
109
|
var endOfDoc = $pos.end();
|
|
88
110
|
var nodeAfterPos = $pos.posAtIndex($pos.index() + 1);
|
|
@@ -93,7 +115,10 @@ var moveNodeViaShortcut = exports.moveNodeViaShortcut = function moveNodeViaShor
|
|
|
93
115
|
}
|
|
94
116
|
}
|
|
95
117
|
var nodeType = (_state$doc$nodeAt = state.doc.nodeAt(currentNodePos)) === null || _state$doc$nodeAt === void 0 ? void 0 : _state$doc$nodeAt.type.name;
|
|
96
|
-
|
|
118
|
+
|
|
119
|
+
// only move the node if the destination is at the same depth, not support moving a nested node to a parent node
|
|
120
|
+
var shouldMoveNode = (0, _platformFeatureFlags.fg)('platform_editor_element_dnd_nested_a11y') ? moveToPos > -1 && $pos.depth === state.doc.resolve(moveToPos).depth : moveToPos > -1;
|
|
121
|
+
if (shouldMoveNode) {
|
|
97
122
|
var _api$core;
|
|
98
123
|
api === null || api === void 0 || (_api$core = api.core) === null || _api$core === void 0 || _api$core.actions.execute(function (_ref2) {
|
|
99
124
|
var tr = _ref2.tr;
|
|
@@ -109,7 +134,7 @@ var moveNodeViaShortcut = exports.moveNodeViaShortcut = function moveNodeViaShor
|
|
|
109
134
|
// If the node is first/last one, only select the node
|
|
110
135
|
api === null || api === void 0 || (_api$core2 = api.core) === null || _api$core2 === void 0 || _api$core2.actions.execute(function (_ref3) {
|
|
111
136
|
var tr = _ref3.tr;
|
|
112
|
-
(0,
|
|
137
|
+
(0, _utils4.selectNode)(tr, currentNodePos, nodeType);
|
|
113
138
|
tr.scrollIntoView();
|
|
114
139
|
return tr;
|
|
115
140
|
});
|
|
@@ -164,7 +189,7 @@ var moveNode = exports.moveNode = function moveNode(api) {
|
|
|
164
189
|
mappedTo = tr.mapping.map(to);
|
|
165
190
|
tr.insert(mappedTo, _nodeCopy); // insert the content at the new position
|
|
166
191
|
}
|
|
167
|
-
tr = (0,
|
|
192
|
+
tr = (0, _utils4.selectNode)(tr, mappedTo, node.type.name);
|
|
168
193
|
tr.setMeta(_main.key, {
|
|
169
194
|
nodeMoved: true
|
|
170
195
|
});
|
|
@@ -4,18 +4,51 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.showDragHandleAtSelection = void 0;
|
|
7
|
+
var _utils = require("@atlaskit/editor-tables/utils");
|
|
7
8
|
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
|
|
8
|
-
var
|
|
9
|
+
var _main = require("../pm-plugins/main");
|
|
10
|
+
var _utils2 = require("../utils");
|
|
11
|
+
var showDragHandleAtSelection = exports.showDragHandleAtSelection = function showDragHandleAtSelection(api, shouldFocusParentNode) {
|
|
9
12
|
return function (state, _, view) {
|
|
10
|
-
var
|
|
13
|
+
var $from = state.selection.$from;
|
|
14
|
+
var shouldFocusParentNode;
|
|
15
|
+
if ($from.depth > 1 && (0, _platformFeatureFlags.fg)('platform_editor_element_dnd_nested_a11y')) {
|
|
16
|
+
var _activeNode$handleOpt, _view$domAtPos;
|
|
17
|
+
var _ref = _main.key.getState(state) || {},
|
|
18
|
+
activeNode = _ref.activeNode;
|
|
19
|
+
|
|
20
|
+
// if the node is already focused, pressing the keymap second times should focus the parent node
|
|
21
|
+
shouldFocusParentNode = activeNode && ((_activeNode$handleOpt = activeNode.handleOptions) === null || _activeNode$handleOpt === void 0 ? void 0 : _activeNode$handleOpt.isFocused);
|
|
22
|
+
var parentPos = (0, _utils.isInTable)(state) ? $from.before(1) : shouldFocusParentNode ? $from.before(1) : (0, _utils2.getNestedNodePosition)(state) + 1;
|
|
23
|
+
var parentElement = view === null || view === void 0 || (_view$domAtPos = view.domAtPos(parentPos, 0)) === null || _view$domAtPos === void 0 ? void 0 : _view$domAtPos.node;
|
|
24
|
+
if (parentElement) {
|
|
25
|
+
var anchorName = parentElement.getAttribute('data-drag-handler-anchor-name');
|
|
26
|
+
var nodeType = parentElement.getAttribute('data-drag-handler-node-type');
|
|
27
|
+
if (!anchorName || !nodeType) {
|
|
28
|
+
// for nodes like panel and mediaSingle, the drag handle decoration is not applied to the dom node at the node position but to the parent node
|
|
29
|
+
var closestParentElement = parentElement.closest('[data-drag-handler-anchor-name]');
|
|
30
|
+
if (closestParentElement) {
|
|
31
|
+
anchorName = closestParentElement.getAttribute('data-drag-handler-anchor-name');
|
|
32
|
+
nodeType = closestParentElement.getAttribute('data-drag-handler-node-type');
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
if (api && anchorName && nodeType) {
|
|
36
|
+
api.core.actions.execute(api.blockControls.commands.showDragHandleAt(parentPos - 1, anchorName, nodeType, {
|
|
37
|
+
isFocused: true
|
|
38
|
+
}));
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
var rootPos = $from.before(1);
|
|
11
44
|
var dom = view === null || view === void 0 ? void 0 : view.domAtPos(rootPos, 0);
|
|
12
45
|
var nodeElement = dom === null || dom === void 0 ? void 0 : dom.node.childNodes[dom === null || dom === void 0 ? void 0 : dom.offset];
|
|
13
46
|
var rootNode = nodeElement && !nodeElement.hasAttribute('data-drag-handler-anchor-name') && (0, _platformFeatureFlags.fg)('platform_editor_element_drag_and_drop_ed_24321') ? nodeElement.querySelector('[data-drag-handler-anchor-name]') : nodeElement;
|
|
14
47
|
if (rootNode) {
|
|
15
|
-
var
|
|
16
|
-
var
|
|
17
|
-
if (api &&
|
|
18
|
-
api.core.actions.execute(api.blockControls.commands.showDragHandleAt(rootPos,
|
|
48
|
+
var _anchorName = rootNode.getAttribute('data-drag-handler-anchor-name');
|
|
49
|
+
var _nodeType = rootNode.getAttribute('data-drag-handler-node-type');
|
|
50
|
+
if (api && _anchorName && _nodeType) {
|
|
51
|
+
api.core.actions.execute(api.blockControls.commands.showDragHandleAt(rootPos, _anchorName, _nodeType, {
|
|
19
52
|
isFocused: true
|
|
20
53
|
}));
|
|
21
54
|
return true;
|
package/dist/cjs/consts.js
CHANGED
|
@@ -16,7 +16,7 @@ var isEmptyNestedParagraphOrHeading = function isEmptyNestedParagraphOrHeading(t
|
|
|
16
16
|
var isDocFirstChildEmptyLine = function isDocFirstChildEmptyLine(elem) {
|
|
17
17
|
var _elem$firstElementChi;
|
|
18
18
|
var parentElement = elem.parentElement;
|
|
19
|
-
return (parentElement === null || parentElement === void 0 ? void 0 : parentElement.firstElementChild) === elem && ['P', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6'].includes(elem.nodeName) && elem.childNodes.length === 1 && ((_elem$firstElementChi = elem.firstElementChild) === null || _elem$firstElementChi === void 0 ? void 0 : _elem$firstElementChi.classList.contains('ProseMirror-trailingBreak'));
|
|
19
|
+
return (parentElement === null || parentElement === void 0 ? void 0 : parentElement.classList.contains('ProseMirror')) && (parentElement === null || parentElement === void 0 ? void 0 : parentElement.firstElementChild) === elem && ['P', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6'].includes(elem.nodeName) && elem.childNodes.length === 1 && ((_elem$firstElementChi = elem.firstElementChild) === null || _elem$firstElementChi === void 0 ? void 0 : _elem$firstElementChi.classList.contains('ProseMirror-trailingBreak'));
|
|
20
20
|
};
|
|
21
21
|
var handleMouseOver = exports.handleMouseOver = function handleMouseOver(view, event, api) {
|
|
22
22
|
var _api$blockControls;
|
|
@@ -20,6 +20,8 @@ function keymapList(api, formatMessage) {
|
|
|
20
20
|
}, keymapList);
|
|
21
21
|
(0, _keymaps.bindKeymapWithCommand)(_keymaps.dragToMoveUp.common, (0, _moveNode.moveNodeViaShortcut)(api, _consts.DIRECTION.UP, formatMessage), keymapList);
|
|
22
22
|
(0, _keymaps.bindKeymapWithCommand)(_keymaps.dragToMoveDown.common, (0, _moveNode.moveNodeViaShortcut)(api, _consts.DIRECTION.DOWN, formatMessage), keymapList);
|
|
23
|
+
(0, _platformFeatureFlags.fg)('platform_editor_element_dnd_nested_a11y') && (0, _keymaps.bindKeymapWithCommand)(_keymaps.dragToMoveLeft.common, (0, _moveNode.moveNodeViaShortcut)(api, _consts.DIRECTION.LEFT, formatMessage), keymapList);
|
|
24
|
+
(0, _platformFeatureFlags.fg)('platform_editor_element_dnd_nested_a11y') && (0, _keymaps.bindKeymapWithCommand)(_keymaps.dragToMoveRight.common, (0, _moveNode.moveNodeViaShortcut)(api, _consts.DIRECTION.RIGHT, formatMessage), keymapList);
|
|
23
25
|
}
|
|
24
26
|
return keymapList;
|
|
25
27
|
}
|
|
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
value: true
|
|
6
6
|
});
|
|
7
7
|
exports.DragHandle = void 0;
|
|
8
|
+
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
|
|
8
9
|
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
9
10
|
var _react = require("react");
|
|
10
11
|
var _react2 = require("@emotion/react");
|
|
@@ -368,7 +369,26 @@ var DragHandleInternal = function DragHandleInternal(_ref) {
|
|
|
368
369
|
keymap: _keymaps.dragToMoveDown
|
|
369
370
|
}] : [{
|
|
370
371
|
description: formatMessage(_messages.blockControlsMessages.dragToMove)
|
|
372
|
+
}, {
|
|
373
|
+
description: formatMessage(_messages.blockControlsMessages.moveUp),
|
|
374
|
+
keymap: _keymaps.dragToMoveUp
|
|
375
|
+
}, {
|
|
376
|
+
description: formatMessage(_messages.blockControlsMessages.moveDown),
|
|
377
|
+
keymap: _keymaps.dragToMoveDown
|
|
371
378
|
}];
|
|
379
|
+
var isParentNodeOfTypeLayout;
|
|
380
|
+
if (!isTopLevelNode && handleOptions !== null && handleOptions !== void 0 && handleOptions.isFocused && (0, _platformFeatureFlags.fg)('platform_editor_element_dnd_nested_a11y')) {
|
|
381
|
+
isParentNodeOfTypeLayout = nodeType === 'layoutSection' || view.state.doc.resolve((0, _utils.getNestedNodePosition)(view.state)).node().type.name === 'layoutColumn';
|
|
382
|
+
if (isParentNodeOfTypeLayout) {
|
|
383
|
+
helpDescriptors = [].concat((0, _toConsumableArray2.default)(helpDescriptors), [{
|
|
384
|
+
description: formatMessage(_messages.blockControlsMessages.moveLeft),
|
|
385
|
+
keymap: _keymaps.dragToMoveLeft
|
|
386
|
+
}, {
|
|
387
|
+
description: formatMessage(_messages.blockControlsMessages.moveRight),
|
|
388
|
+
keymap: _keymaps.dragToMoveRight
|
|
389
|
+
}]);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
372
392
|
var message = helpDescriptors.map(function (descriptor) {
|
|
373
393
|
return descriptor.keymap ? [descriptor.description, (0, _keymaps.getAriaKeyshortcuts)(descriptor.keymap)] : [descriptor.description];
|
|
374
394
|
}).join('. ');
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.getNestedNodePosition = void 0;
|
|
7
|
+
var _state = require("@atlaskit/editor-prosemirror/state");
|
|
8
|
+
var _utils = require("@atlaskit/editor-prosemirror/utils");
|
|
9
|
+
var getNestedNodePosition = exports.getNestedNodePosition = function getNestedNodePosition(state) {
|
|
10
|
+
var selection = state.selection;
|
|
11
|
+
var nestedNodePos = selection.$from.before(1);
|
|
12
|
+
if (selection instanceof _state.TextSelection) {
|
|
13
|
+
nestedNodePos = selection.$from.before();
|
|
14
|
+
var $pos = state.doc.resolve(nestedNodePos);
|
|
15
|
+
if ($pos.depth < 1) {
|
|
16
|
+
return nestedNodePos;
|
|
17
|
+
}
|
|
18
|
+
var parentNodeOfSpecificTypes = (0, _utils.findParentNodeOfType)([state.schema.nodes.bulletList, state.schema.nodes.orderedList, state.schema.nodes.blockquote, state.schema.nodes.taskList])(state.selection);
|
|
19
|
+
if (parentNodeOfSpecificTypes) {
|
|
20
|
+
var parentNodeType = parentNodeOfSpecificTypes.node.type.name;
|
|
21
|
+
nestedNodePos = ['bulletList', 'orderedList'].includes(parentNodeType) ? $pos.before($pos.depth - 1) : ['blockquote', 'taskList'].includes(parentNodeType) ? $pos.before() : nestedNodePos;
|
|
22
|
+
}
|
|
23
|
+
} else {
|
|
24
|
+
nestedNodePos = selection.$from.pos;
|
|
25
|
+
}
|
|
26
|
+
return nestedNodePos;
|
|
27
|
+
};
|
package/dist/cjs/utils/index.js
CHANGED
|
@@ -3,6 +3,12 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
+
Object.defineProperty(exports, "getNestedNodePosition", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: function get() {
|
|
9
|
+
return _getNestedNodePosition.getNestedNodePosition;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
6
12
|
Object.defineProperty(exports, "getSelection", {
|
|
7
13
|
enumerable: true,
|
|
8
14
|
get: function get() {
|
|
@@ -15,4 +21,5 @@ Object.defineProperty(exports, "selectNode", {
|
|
|
15
21
|
return _getSelection.selectNode;
|
|
16
22
|
}
|
|
17
23
|
});
|
|
18
|
-
var _getSelection = require("./getSelection");
|
|
24
|
+
var _getSelection = require("./getSelection");
|
|
25
|
+
var _getNestedNodePosition = require("./getNestedNodePosition");
|
|
@@ -3,12 +3,13 @@ import { blockControlsMessages } from '@atlaskit/editor-common/messages';
|
|
|
3
3
|
import { GapCursorSelection } from '@atlaskit/editor-common/selection';
|
|
4
4
|
import { transformSliceNestedExpandToExpand } from '@atlaskit/editor-common/transforms';
|
|
5
5
|
import { isEmptyParagraph } from '@atlaskit/editor-common/utils';
|
|
6
|
+
import { findParentNodeOfType } from '@atlaskit/editor-prosemirror/utils';
|
|
6
7
|
import { findTable, isInTable, isTableSelected } from '@atlaskit/editor-tables/utils';
|
|
7
8
|
import { fg } from '@atlaskit/platform-feature-flags';
|
|
8
9
|
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
|
|
9
10
|
import { DIRECTION } from '../consts';
|
|
10
11
|
import { key } from '../pm-plugins/main';
|
|
11
|
-
import { selectNode } from '../utils';
|
|
12
|
+
import { getNestedNodePosition, selectNode } from '../utils';
|
|
12
13
|
import { canMoveNodeToIndex, isInsideTable, transformSliceExpandToNestedExpand } from '../utils/validation';
|
|
13
14
|
|
|
14
15
|
/**
|
|
@@ -38,7 +39,7 @@ function transformSourceSlice(nodeCopy, destType) {
|
|
|
38
39
|
*
|
|
39
40
|
* @returns the start position of a node if the node can be moved, otherwise -1
|
|
40
41
|
*/
|
|
41
|
-
const getCurrentNodePos = state => {
|
|
42
|
+
const getCurrentNodePos = (state, isParentNodeOfTypeLayout) => {
|
|
42
43
|
var _activeNode$handleOpt;
|
|
43
44
|
const {
|
|
44
45
|
selection
|
|
@@ -63,21 +64,42 @@ const getCurrentNodePos = state => {
|
|
|
63
64
|
// 2. caret cursor is inside the node
|
|
64
65
|
// 3. the start of the selection is inside the node
|
|
65
66
|
currentNodePos = selection.$from.before(1);
|
|
67
|
+
if (selection.$from.depth > 0 && fg('platform_editor_element_dnd_nested_a11y')) {
|
|
68
|
+
currentNodePos = getNestedNodePosition(state);
|
|
69
|
+
}
|
|
66
70
|
}
|
|
67
71
|
return currentNodePos;
|
|
68
72
|
};
|
|
69
73
|
export const moveNodeViaShortcut = (api, direction, formatMessage) => {
|
|
70
74
|
return state => {
|
|
71
|
-
|
|
75
|
+
let isParentNodeOfTypeLayout;
|
|
76
|
+
if (fg('platform_editor_element_dnd_nested_a11y')) {
|
|
77
|
+
isParentNodeOfTypeLayout = !!findParentNodeOfType([state.schema.nodes.layoutSection])(state.selection);
|
|
78
|
+
}
|
|
79
|
+
const currentNodePos = getCurrentNodePos(state, isParentNodeOfTypeLayout);
|
|
72
80
|
if (currentNodePos > -1) {
|
|
73
81
|
var _state$doc$nodeAt;
|
|
74
82
|
const $pos = state.doc.resolve(currentNodePos);
|
|
75
83
|
let moveToPos = -1;
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
if (
|
|
79
|
-
|
|
84
|
+
const nodeIndex = $pos.index();
|
|
85
|
+
if (direction === DIRECTION.LEFT && fg('platform_editor_element_dnd_nested_a11y')) {
|
|
86
|
+
if ($pos.depth < 2 || !isParentNodeOfTypeLayout) {
|
|
87
|
+
return false;
|
|
80
88
|
}
|
|
89
|
+
|
|
90
|
+
// get the previous layoutSection node
|
|
91
|
+
const index = $pos.index($pos.depth - 1);
|
|
92
|
+
const grandParent = $pos.node($pos.depth - 1);
|
|
93
|
+
const previousNode = grandParent ? grandParent.maybeChild(index - 1) : null;
|
|
94
|
+
moveToPos = $pos.start() - ((previousNode === null || previousNode === void 0 ? void 0 : previousNode.nodeSize) || 1);
|
|
95
|
+
} else if (direction === DIRECTION.RIGHT && fg('platform_editor_element_dnd_nested_a11y')) {
|
|
96
|
+
if ($pos.depth < 2 || !isParentNodeOfTypeLayout) {
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
moveToPos = $pos.after($pos.depth) + 1;
|
|
100
|
+
} else if (direction === DIRECTION.UP) {
|
|
101
|
+
const nodeBefore = $pos.depth > 1 && nodeIndex === 0 && fg('platform_editor_element_dnd_nested_a11y') ? $pos.node($pos.depth) : $pos.nodeBefore;
|
|
102
|
+
moveToPos = $pos.depth > 1 && nodeIndex === 0 && fg('platform_editor_element_dnd_nested_a11y') ? $pos.before($pos.depth) - 1 : nodeBefore ? currentNodePos - nodeBefore.nodeSize : moveToPos;
|
|
81
103
|
} else {
|
|
82
104
|
const endOfDoc = $pos.end();
|
|
83
105
|
const nodeAfterPos = $pos.posAtIndex($pos.index() + 1);
|
|
@@ -88,7 +110,10 @@ export const moveNodeViaShortcut = (api, direction, formatMessage) => {
|
|
|
88
110
|
}
|
|
89
111
|
}
|
|
90
112
|
const nodeType = (_state$doc$nodeAt = state.doc.nodeAt(currentNodePos)) === null || _state$doc$nodeAt === void 0 ? void 0 : _state$doc$nodeAt.type.name;
|
|
91
|
-
|
|
113
|
+
|
|
114
|
+
// only move the node if the destination is at the same depth, not support moving a nested node to a parent node
|
|
115
|
+
const shouldMoveNode = fg('platform_editor_element_dnd_nested_a11y') ? moveToPos > -1 && $pos.depth === state.doc.resolve(moveToPos).depth : moveToPos > -1;
|
|
116
|
+
if (shouldMoveNode) {
|
|
92
117
|
var _api$core;
|
|
93
118
|
api === null || api === void 0 ? void 0 : (_api$core = api.core) === null || _api$core === void 0 ? void 0 : _api$core.actions.execute(({
|
|
94
119
|
tr
|
|
@@ -1,6 +1,42 @@
|
|
|
1
|
+
import { isInTable } from '@atlaskit/editor-tables/utils';
|
|
1
2
|
import { fg } from '@atlaskit/platform-feature-flags';
|
|
2
|
-
|
|
3
|
-
|
|
3
|
+
import { key } from '../pm-plugins/main';
|
|
4
|
+
import { getNestedNodePosition } from '../utils';
|
|
5
|
+
export const showDragHandleAtSelection = (api, shouldFocusParentNode) => (state, _, view) => {
|
|
6
|
+
const {
|
|
7
|
+
$from
|
|
8
|
+
} = state.selection;
|
|
9
|
+
let shouldFocusParentNode;
|
|
10
|
+
if ($from.depth > 1 && fg('platform_editor_element_dnd_nested_a11y')) {
|
|
11
|
+
var _activeNode$handleOpt, _view$domAtPos;
|
|
12
|
+
const {
|
|
13
|
+
activeNode
|
|
14
|
+
} = key.getState(state) || {};
|
|
15
|
+
|
|
16
|
+
// if the node is already focused, pressing the keymap second times should focus the parent node
|
|
17
|
+
shouldFocusParentNode = activeNode && ((_activeNode$handleOpt = activeNode.handleOptions) === null || _activeNode$handleOpt === void 0 ? void 0 : _activeNode$handleOpt.isFocused);
|
|
18
|
+
const parentPos = isInTable(state) ? $from.before(1) : shouldFocusParentNode ? $from.before(1) : getNestedNodePosition(state) + 1;
|
|
19
|
+
const parentElement = view === null || view === void 0 ? void 0 : (_view$domAtPos = view.domAtPos(parentPos, 0)) === null || _view$domAtPos === void 0 ? void 0 : _view$domAtPos.node;
|
|
20
|
+
if (parentElement) {
|
|
21
|
+
let anchorName = parentElement.getAttribute('data-drag-handler-anchor-name');
|
|
22
|
+
let nodeType = parentElement.getAttribute('data-drag-handler-node-type');
|
|
23
|
+
if (!anchorName || !nodeType) {
|
|
24
|
+
// for nodes like panel and mediaSingle, the drag handle decoration is not applied to the dom node at the node position but to the parent node
|
|
25
|
+
const closestParentElement = parentElement.closest('[data-drag-handler-anchor-name]');
|
|
26
|
+
if (closestParentElement) {
|
|
27
|
+
anchorName = closestParentElement.getAttribute('data-drag-handler-anchor-name');
|
|
28
|
+
nodeType = closestParentElement.getAttribute('data-drag-handler-node-type');
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
if (api && anchorName && nodeType) {
|
|
32
|
+
api.core.actions.execute(api.blockControls.commands.showDragHandleAt(parentPos - 1, anchorName, nodeType, {
|
|
33
|
+
isFocused: true
|
|
34
|
+
}));
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
const rootPos = $from.before(1);
|
|
4
40
|
const dom = view === null || view === void 0 ? void 0 : view.domAtPos(rootPos, 0);
|
|
5
41
|
const nodeElement = dom === null || dom === void 0 ? void 0 : dom.node.childNodes[dom === null || dom === void 0 ? void 0 : dom.offset];
|
|
6
42
|
const rootNode = nodeElement && !nodeElement.hasAttribute('data-drag-handler-anchor-name') && fg('platform_editor_element_drag_and_drop_ed_24321') ? nodeElement.querySelector('[data-drag-handler-anchor-name]') : nodeElement;
|
package/dist/es2019/consts.js
CHANGED
|
@@ -10,7 +10,7 @@ const isEmptyNestedParagraphOrHeading = target => {
|
|
|
10
10
|
const isDocFirstChildEmptyLine = elem => {
|
|
11
11
|
var _elem$firstElementChi;
|
|
12
12
|
const parentElement = elem.parentElement;
|
|
13
|
-
return (parentElement === null || parentElement === void 0 ? void 0 : parentElement.firstElementChild) === elem && ['P', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6'].includes(elem.nodeName) && elem.childNodes.length === 1 && ((_elem$firstElementChi = elem.firstElementChild) === null || _elem$firstElementChi === void 0 ? void 0 : _elem$firstElementChi.classList.contains('ProseMirror-trailingBreak'));
|
|
13
|
+
return (parentElement === null || parentElement === void 0 ? void 0 : parentElement.classList.contains('ProseMirror')) && (parentElement === null || parentElement === void 0 ? void 0 : parentElement.firstElementChild) === elem && ['P', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6'].includes(elem.nodeName) && elem.childNodes.length === 1 && ((_elem$firstElementChi = elem.firstElementChild) === null || _elem$firstElementChi === void 0 ? void 0 : _elem$firstElementChi.classList.contains('ProseMirror-trailingBreak'));
|
|
14
14
|
};
|
|
15
15
|
export const handleMouseOver = (view, event, api) => {
|
|
16
16
|
var _api$blockControls;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { bindKeymapWithCommand, dragToMoveDown, dragToMoveUp, showElementDragHandle } from '@atlaskit/editor-common/keymaps';
|
|
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
4
|
import { moveNodeViaShortcut } from '../commands/move-node';
|
|
@@ -14,6 +14,8 @@ function keymapList(api, formatMessage) {
|
|
|
14
14
|
}, keymapList);
|
|
15
15
|
bindKeymapWithCommand(dragToMoveUp.common, moveNodeViaShortcut(api, DIRECTION.UP, formatMessage), keymapList);
|
|
16
16
|
bindKeymapWithCommand(dragToMoveDown.common, moveNodeViaShortcut(api, DIRECTION.DOWN, formatMessage), keymapList);
|
|
17
|
+
fg('platform_editor_element_dnd_nested_a11y') && bindKeymapWithCommand(dragToMoveLeft.common, moveNodeViaShortcut(api, DIRECTION.LEFT, formatMessage), keymapList);
|
|
18
|
+
fg('platform_editor_element_dnd_nested_a11y') && bindKeymapWithCommand(dragToMoveRight.common, moveNodeViaShortcut(api, DIRECTION.RIGHT, formatMessage), keymapList);
|
|
17
19
|
}
|
|
18
20
|
return keymapList;
|
|
19
21
|
}
|
|
@@ -9,7 +9,7 @@ import { bind } from 'bind-event-listener';
|
|
|
9
9
|
import { injectIntl } from 'react-intl-next';
|
|
10
10
|
import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
|
|
11
11
|
import { useSharedPluginState } from '@atlaskit/editor-common/hooks';
|
|
12
|
-
import { dragToMoveDown, dragToMoveUp, getAriaKeyshortcuts, TooltipContentWithMultipleShortcuts } from '@atlaskit/editor-common/keymaps';
|
|
12
|
+
import { dragToMoveDown, dragToMoveLeft, dragToMoveRight, dragToMoveUp, getAriaKeyshortcuts, TooltipContentWithMultipleShortcuts } from '@atlaskit/editor-common/keymaps';
|
|
13
13
|
import { blockControlsMessages } from '@atlaskit/editor-common/messages';
|
|
14
14
|
import { TextSelection } from '@atlaskit/editor-prosemirror/state';
|
|
15
15
|
import DragHandlerIcon from '@atlaskit/icon/glyph/drag-handler';
|
|
@@ -19,7 +19,7 @@ import { setCustomNativeDragPreview } from '@atlaskit/pragmatic-drag-and-drop/el
|
|
|
19
19
|
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
|
|
20
20
|
import Tooltip from '@atlaskit/tooltip';
|
|
21
21
|
import { key } from '../pm-plugins/main';
|
|
22
|
-
import { selectNode } from '../utils';
|
|
22
|
+
import { getNestedNodePosition, selectNode } from '../utils';
|
|
23
23
|
import { getLeftPosition, getTopPosition } from '../utils/drag-handle-positions';
|
|
24
24
|
import { DRAG_HANDLE_BORDER_RADIUS, DRAG_HANDLE_HEIGHT, DRAG_HANDLE_WIDTH, DRAG_HANDLE_ZINDEX, dragHandleGap, topPositionAdjustment } from './consts';
|
|
25
25
|
import { dragPreview } from './drag-preview';
|
|
@@ -342,7 +342,7 @@ const DragHandleInternal = ({
|
|
|
342
342
|
};
|
|
343
343
|
}
|
|
344
344
|
}, [buttonRef, handleOptions === null || handleOptions === void 0 ? void 0 : handleOptions.isFocused, view]);
|
|
345
|
-
|
|
345
|
+
let helpDescriptors = isTopLevelNode ? [{
|
|
346
346
|
description: formatMessage(blockControlsMessages.dragToMove)
|
|
347
347
|
}, {
|
|
348
348
|
description: formatMessage(blockControlsMessages.moveUp),
|
|
@@ -352,7 +352,26 @@ const DragHandleInternal = ({
|
|
|
352
352
|
keymap: dragToMoveDown
|
|
353
353
|
}] : [{
|
|
354
354
|
description: formatMessage(blockControlsMessages.dragToMove)
|
|
355
|
+
}, {
|
|
356
|
+
description: formatMessage(blockControlsMessages.moveUp),
|
|
357
|
+
keymap: dragToMoveUp
|
|
358
|
+
}, {
|
|
359
|
+
description: formatMessage(blockControlsMessages.moveDown),
|
|
360
|
+
keymap: dragToMoveDown
|
|
355
361
|
}];
|
|
362
|
+
let isParentNodeOfTypeLayout;
|
|
363
|
+
if (!isTopLevelNode && handleOptions !== null && handleOptions !== void 0 && handleOptions.isFocused && fg('platform_editor_element_dnd_nested_a11y')) {
|
|
364
|
+
isParentNodeOfTypeLayout = nodeType === 'layoutSection' || view.state.doc.resolve(getNestedNodePosition(view.state)).node().type.name === 'layoutColumn';
|
|
365
|
+
if (isParentNodeOfTypeLayout) {
|
|
366
|
+
helpDescriptors = [...helpDescriptors, {
|
|
367
|
+
description: formatMessage(blockControlsMessages.moveLeft),
|
|
368
|
+
keymap: dragToMoveLeft
|
|
369
|
+
}, {
|
|
370
|
+
description: formatMessage(blockControlsMessages.moveRight),
|
|
371
|
+
keymap: dragToMoveRight
|
|
372
|
+
}];
|
|
373
|
+
}
|
|
374
|
+
}
|
|
356
375
|
const message = helpDescriptors.map(descriptor => {
|
|
357
376
|
return descriptor.keymap ? [descriptor.description, getAriaKeyshortcuts(descriptor.keymap)] : [descriptor.description];
|
|
358
377
|
}).join('. ');
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { TextSelection } from '@atlaskit/editor-prosemirror/state';
|
|
2
|
+
import { findParentNodeOfType } from '@atlaskit/editor-prosemirror/utils';
|
|
3
|
+
export const getNestedNodePosition = state => {
|
|
4
|
+
const {
|
|
5
|
+
selection
|
|
6
|
+
} = state;
|
|
7
|
+
let nestedNodePos = selection.$from.before(1);
|
|
8
|
+
if (selection instanceof TextSelection) {
|
|
9
|
+
nestedNodePos = selection.$from.before();
|
|
10
|
+
const $pos = state.doc.resolve(nestedNodePos);
|
|
11
|
+
if ($pos.depth < 1) {
|
|
12
|
+
return nestedNodePos;
|
|
13
|
+
}
|
|
14
|
+
const parentNodeOfSpecificTypes = findParentNodeOfType([state.schema.nodes.bulletList, state.schema.nodes.orderedList, state.schema.nodes.blockquote, state.schema.nodes.taskList])(state.selection);
|
|
15
|
+
if (parentNodeOfSpecificTypes) {
|
|
16
|
+
const parentNodeType = parentNodeOfSpecificTypes.node.type.name;
|
|
17
|
+
nestedNodePos = ['bulletList', 'orderedList'].includes(parentNodeType) ? $pos.before($pos.depth - 1) : ['blockquote', 'taskList'].includes(parentNodeType) ? $pos.before() : nestedNodePos;
|
|
18
|
+
}
|
|
19
|
+
} else {
|
|
20
|
+
nestedNodePos = selection.$from.pos;
|
|
21
|
+
}
|
|
22
|
+
return nestedNodePos;
|
|
23
|
+
};
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export { getSelection, selectNode } from './getSelection';
|
|
1
|
+
export { getSelection, selectNode } from './getSelection';
|
|
2
|
+
export { getNestedNodePosition } from './getNestedNodePosition';
|
|
@@ -6,12 +6,13 @@ import { blockControlsMessages } from '@atlaskit/editor-common/messages';
|
|
|
6
6
|
import { GapCursorSelection } from '@atlaskit/editor-common/selection';
|
|
7
7
|
import { transformSliceNestedExpandToExpand } from '@atlaskit/editor-common/transforms';
|
|
8
8
|
import { isEmptyParagraph } from '@atlaskit/editor-common/utils';
|
|
9
|
+
import { findParentNodeOfType } from '@atlaskit/editor-prosemirror/utils';
|
|
9
10
|
import { findTable, isInTable, isTableSelected } from '@atlaskit/editor-tables/utils';
|
|
10
11
|
import { fg } from '@atlaskit/platform-feature-flags';
|
|
11
12
|
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
|
|
12
13
|
import { DIRECTION } from '../consts';
|
|
13
14
|
import { key } from '../pm-plugins/main';
|
|
14
|
-
import { selectNode } from '../utils';
|
|
15
|
+
import { getNestedNodePosition, selectNode } from '../utils';
|
|
15
16
|
import { canMoveNodeToIndex, isInsideTable, transformSliceExpandToNestedExpand } from '../utils/validation';
|
|
16
17
|
|
|
17
18
|
/**
|
|
@@ -40,7 +41,7 @@ function transformSourceSlice(nodeCopy, destType) {
|
|
|
40
41
|
*
|
|
41
42
|
* @returns the start position of a node if the node can be moved, otherwise -1
|
|
42
43
|
*/
|
|
43
|
-
var getCurrentNodePos = function getCurrentNodePos(state) {
|
|
44
|
+
var getCurrentNodePos = function getCurrentNodePos(state, isParentNodeOfTypeLayout) {
|
|
44
45
|
var _activeNode$handleOpt;
|
|
45
46
|
var selection = state.selection;
|
|
46
47
|
var _ref = key.getState(state) || {},
|
|
@@ -62,21 +63,42 @@ var getCurrentNodePos = function getCurrentNodePos(state) {
|
|
|
62
63
|
// 2. caret cursor is inside the node
|
|
63
64
|
// 3. the start of the selection is inside the node
|
|
64
65
|
currentNodePos = selection.$from.before(1);
|
|
66
|
+
if (selection.$from.depth > 0 && fg('platform_editor_element_dnd_nested_a11y')) {
|
|
67
|
+
currentNodePos = getNestedNodePosition(state);
|
|
68
|
+
}
|
|
65
69
|
}
|
|
66
70
|
return currentNodePos;
|
|
67
71
|
};
|
|
68
72
|
export var moveNodeViaShortcut = function moveNodeViaShortcut(api, direction, formatMessage) {
|
|
69
73
|
return function (state) {
|
|
70
|
-
var
|
|
74
|
+
var isParentNodeOfTypeLayout;
|
|
75
|
+
if (fg('platform_editor_element_dnd_nested_a11y')) {
|
|
76
|
+
isParentNodeOfTypeLayout = !!findParentNodeOfType([state.schema.nodes.layoutSection])(state.selection);
|
|
77
|
+
}
|
|
78
|
+
var currentNodePos = getCurrentNodePos(state, isParentNodeOfTypeLayout);
|
|
71
79
|
if (currentNodePos > -1) {
|
|
72
80
|
var _state$doc$nodeAt;
|
|
73
81
|
var $pos = state.doc.resolve(currentNodePos);
|
|
74
82
|
var moveToPos = -1;
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
if (
|
|
78
|
-
|
|
83
|
+
var nodeIndex = $pos.index();
|
|
84
|
+
if (direction === DIRECTION.LEFT && fg('platform_editor_element_dnd_nested_a11y')) {
|
|
85
|
+
if ($pos.depth < 2 || !isParentNodeOfTypeLayout) {
|
|
86
|
+
return false;
|
|
79
87
|
}
|
|
88
|
+
|
|
89
|
+
// get the previous layoutSection node
|
|
90
|
+
var index = $pos.index($pos.depth - 1);
|
|
91
|
+
var grandParent = $pos.node($pos.depth - 1);
|
|
92
|
+
var previousNode = grandParent ? grandParent.maybeChild(index - 1) : null;
|
|
93
|
+
moveToPos = $pos.start() - ((previousNode === null || previousNode === void 0 ? void 0 : previousNode.nodeSize) || 1);
|
|
94
|
+
} else if (direction === DIRECTION.RIGHT && fg('platform_editor_element_dnd_nested_a11y')) {
|
|
95
|
+
if ($pos.depth < 2 || !isParentNodeOfTypeLayout) {
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
moveToPos = $pos.after($pos.depth) + 1;
|
|
99
|
+
} else if (direction === DIRECTION.UP) {
|
|
100
|
+
var nodeBefore = $pos.depth > 1 && nodeIndex === 0 && fg('platform_editor_element_dnd_nested_a11y') ? $pos.node($pos.depth) : $pos.nodeBefore;
|
|
101
|
+
moveToPos = $pos.depth > 1 && nodeIndex === 0 && fg('platform_editor_element_dnd_nested_a11y') ? $pos.before($pos.depth) - 1 : nodeBefore ? currentNodePos - nodeBefore.nodeSize : moveToPos;
|
|
80
102
|
} else {
|
|
81
103
|
var endOfDoc = $pos.end();
|
|
82
104
|
var nodeAfterPos = $pos.posAtIndex($pos.index() + 1);
|
|
@@ -87,7 +109,10 @@ export var moveNodeViaShortcut = function moveNodeViaShortcut(api, direction, fo
|
|
|
87
109
|
}
|
|
88
110
|
}
|
|
89
111
|
var nodeType = (_state$doc$nodeAt = state.doc.nodeAt(currentNodePos)) === null || _state$doc$nodeAt === void 0 ? void 0 : _state$doc$nodeAt.type.name;
|
|
90
|
-
|
|
112
|
+
|
|
113
|
+
// only move the node if the destination is at the same depth, not support moving a nested node to a parent node
|
|
114
|
+
var shouldMoveNode = fg('platform_editor_element_dnd_nested_a11y') ? moveToPos > -1 && $pos.depth === state.doc.resolve(moveToPos).depth : moveToPos > -1;
|
|
115
|
+
if (shouldMoveNode) {
|
|
91
116
|
var _api$core;
|
|
92
117
|
api === null || api === void 0 || (_api$core = api.core) === null || _api$core === void 0 || _api$core.actions.execute(function (_ref2) {
|
|
93
118
|
var tr = _ref2.tr;
|
|
@@ -1,15 +1,48 @@
|
|
|
1
|
+
import { isInTable } from '@atlaskit/editor-tables/utils';
|
|
1
2
|
import { fg } from '@atlaskit/platform-feature-flags';
|
|
2
|
-
|
|
3
|
+
import { key } from '../pm-plugins/main';
|
|
4
|
+
import { getNestedNodePosition } from '../utils';
|
|
5
|
+
export var showDragHandleAtSelection = function showDragHandleAtSelection(api, shouldFocusParentNode) {
|
|
3
6
|
return function (state, _, view) {
|
|
4
|
-
var
|
|
7
|
+
var $from = state.selection.$from;
|
|
8
|
+
var shouldFocusParentNode;
|
|
9
|
+
if ($from.depth > 1 && fg('platform_editor_element_dnd_nested_a11y')) {
|
|
10
|
+
var _activeNode$handleOpt, _view$domAtPos;
|
|
11
|
+
var _ref = key.getState(state) || {},
|
|
12
|
+
activeNode = _ref.activeNode;
|
|
13
|
+
|
|
14
|
+
// if the node is already focused, pressing the keymap second times should focus the parent node
|
|
15
|
+
shouldFocusParentNode = activeNode && ((_activeNode$handleOpt = activeNode.handleOptions) === null || _activeNode$handleOpt === void 0 ? void 0 : _activeNode$handleOpt.isFocused);
|
|
16
|
+
var parentPos = isInTable(state) ? $from.before(1) : shouldFocusParentNode ? $from.before(1) : getNestedNodePosition(state) + 1;
|
|
17
|
+
var parentElement = view === null || view === void 0 || (_view$domAtPos = view.domAtPos(parentPos, 0)) === null || _view$domAtPos === void 0 ? void 0 : _view$domAtPos.node;
|
|
18
|
+
if (parentElement) {
|
|
19
|
+
var anchorName = parentElement.getAttribute('data-drag-handler-anchor-name');
|
|
20
|
+
var nodeType = parentElement.getAttribute('data-drag-handler-node-type');
|
|
21
|
+
if (!anchorName || !nodeType) {
|
|
22
|
+
// for nodes like panel and mediaSingle, the drag handle decoration is not applied to the dom node at the node position but to the parent node
|
|
23
|
+
var closestParentElement = parentElement.closest('[data-drag-handler-anchor-name]');
|
|
24
|
+
if (closestParentElement) {
|
|
25
|
+
anchorName = closestParentElement.getAttribute('data-drag-handler-anchor-name');
|
|
26
|
+
nodeType = closestParentElement.getAttribute('data-drag-handler-node-type');
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
if (api && anchorName && nodeType) {
|
|
30
|
+
api.core.actions.execute(api.blockControls.commands.showDragHandleAt(parentPos - 1, anchorName, nodeType, {
|
|
31
|
+
isFocused: true
|
|
32
|
+
}));
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
var rootPos = $from.before(1);
|
|
5
38
|
var dom = view === null || view === void 0 ? void 0 : view.domAtPos(rootPos, 0);
|
|
6
39
|
var nodeElement = dom === null || dom === void 0 ? void 0 : dom.node.childNodes[dom === null || dom === void 0 ? void 0 : dom.offset];
|
|
7
40
|
var rootNode = nodeElement && !nodeElement.hasAttribute('data-drag-handler-anchor-name') && fg('platform_editor_element_drag_and_drop_ed_24321') ? nodeElement.querySelector('[data-drag-handler-anchor-name]') : nodeElement;
|
|
8
41
|
if (rootNode) {
|
|
9
|
-
var
|
|
10
|
-
var
|
|
11
|
-
if (api &&
|
|
12
|
-
api.core.actions.execute(api.blockControls.commands.showDragHandleAt(rootPos,
|
|
42
|
+
var _anchorName = rootNode.getAttribute('data-drag-handler-anchor-name');
|
|
43
|
+
var _nodeType = rootNode.getAttribute('data-drag-handler-node-type');
|
|
44
|
+
if (api && _anchorName && _nodeType) {
|
|
45
|
+
api.core.actions.execute(api.blockControls.commands.showDragHandleAt(rootPos, _anchorName, _nodeType, {
|
|
13
46
|
isFocused: true
|
|
14
47
|
}));
|
|
15
48
|
return true;
|
package/dist/esm/consts.js
CHANGED
|
@@ -10,7 +10,7 @@ var isEmptyNestedParagraphOrHeading = function isEmptyNestedParagraphOrHeading(t
|
|
|
10
10
|
var isDocFirstChildEmptyLine = function isDocFirstChildEmptyLine(elem) {
|
|
11
11
|
var _elem$firstElementChi;
|
|
12
12
|
var parentElement = elem.parentElement;
|
|
13
|
-
return (parentElement === null || parentElement === void 0 ? void 0 : parentElement.firstElementChild) === elem && ['P', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6'].includes(elem.nodeName) && elem.childNodes.length === 1 && ((_elem$firstElementChi = elem.firstElementChild) === null || _elem$firstElementChi === void 0 ? void 0 : _elem$firstElementChi.classList.contains('ProseMirror-trailingBreak'));
|
|
13
|
+
return (parentElement === null || parentElement === void 0 ? void 0 : parentElement.classList.contains('ProseMirror')) && (parentElement === null || parentElement === void 0 ? void 0 : parentElement.firstElementChild) === elem && ['P', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6'].includes(elem.nodeName) && elem.childNodes.length === 1 && ((_elem$firstElementChi = elem.firstElementChild) === null || _elem$firstElementChi === void 0 ? void 0 : _elem$firstElementChi.classList.contains('ProseMirror-trailingBreak'));
|
|
14
14
|
};
|
|
15
15
|
export var handleMouseOver = function handleMouseOver(view, event, api) {
|
|
16
16
|
var _api$blockControls;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { bindKeymapWithCommand, dragToMoveDown, dragToMoveUp, showElementDragHandle } from '@atlaskit/editor-common/keymaps';
|
|
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
4
|
import { moveNodeViaShortcut } from '../commands/move-node';
|
|
@@ -14,6 +14,8 @@ function keymapList(api, formatMessage) {
|
|
|
14
14
|
}, keymapList);
|
|
15
15
|
bindKeymapWithCommand(dragToMoveUp.common, moveNodeViaShortcut(api, DIRECTION.UP, formatMessage), keymapList);
|
|
16
16
|
bindKeymapWithCommand(dragToMoveDown.common, moveNodeViaShortcut(api, DIRECTION.DOWN, formatMessage), keymapList);
|
|
17
|
+
fg('platform_editor_element_dnd_nested_a11y') && bindKeymapWithCommand(dragToMoveLeft.common, moveNodeViaShortcut(api, DIRECTION.LEFT, formatMessage), keymapList);
|
|
18
|
+
fg('platform_editor_element_dnd_nested_a11y') && bindKeymapWithCommand(dragToMoveRight.common, moveNodeViaShortcut(api, DIRECTION.RIGHT, formatMessage), keymapList);
|
|
17
19
|
}
|
|
18
20
|
return keymapList;
|
|
19
21
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
|
|
1
2
|
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
|
2
3
|
/**
|
|
3
4
|
* @jsxRuntime classic
|
|
@@ -10,7 +11,7 @@ import { bind } from 'bind-event-listener';
|
|
|
10
11
|
import { injectIntl } from 'react-intl-next';
|
|
11
12
|
import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
|
|
12
13
|
import { useSharedPluginState } from '@atlaskit/editor-common/hooks';
|
|
13
|
-
import { dragToMoveDown, dragToMoveUp, getAriaKeyshortcuts, TooltipContentWithMultipleShortcuts } from '@atlaskit/editor-common/keymaps';
|
|
14
|
+
import { dragToMoveDown, dragToMoveLeft, dragToMoveRight, dragToMoveUp, getAriaKeyshortcuts, TooltipContentWithMultipleShortcuts } from '@atlaskit/editor-common/keymaps';
|
|
14
15
|
import { blockControlsMessages } from '@atlaskit/editor-common/messages';
|
|
15
16
|
import { TextSelection } from '@atlaskit/editor-prosemirror/state';
|
|
16
17
|
import DragHandlerIcon from '@atlaskit/icon/glyph/drag-handler';
|
|
@@ -20,7 +21,7 @@ import { setCustomNativeDragPreview } from '@atlaskit/pragmatic-drag-and-drop/el
|
|
|
20
21
|
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
|
|
21
22
|
import Tooltip from '@atlaskit/tooltip';
|
|
22
23
|
import { key } from '../pm-plugins/main';
|
|
23
|
-
import { selectNode } from '../utils';
|
|
24
|
+
import { getNestedNodePosition, selectNode } from '../utils';
|
|
24
25
|
import { getLeftPosition, getTopPosition } from '../utils/drag-handle-positions';
|
|
25
26
|
import { DRAG_HANDLE_BORDER_RADIUS, DRAG_HANDLE_HEIGHT, DRAG_HANDLE_WIDTH, DRAG_HANDLE_ZINDEX, dragHandleGap, topPositionAdjustment } from './consts';
|
|
26
27
|
import { dragPreview } from './drag-preview';
|
|
@@ -359,7 +360,26 @@ var DragHandleInternal = function DragHandleInternal(_ref) {
|
|
|
359
360
|
keymap: dragToMoveDown
|
|
360
361
|
}] : [{
|
|
361
362
|
description: formatMessage(blockControlsMessages.dragToMove)
|
|
363
|
+
}, {
|
|
364
|
+
description: formatMessage(blockControlsMessages.moveUp),
|
|
365
|
+
keymap: dragToMoveUp
|
|
366
|
+
}, {
|
|
367
|
+
description: formatMessage(blockControlsMessages.moveDown),
|
|
368
|
+
keymap: dragToMoveDown
|
|
362
369
|
}];
|
|
370
|
+
var isParentNodeOfTypeLayout;
|
|
371
|
+
if (!isTopLevelNode && handleOptions !== null && handleOptions !== void 0 && handleOptions.isFocused && fg('platform_editor_element_dnd_nested_a11y')) {
|
|
372
|
+
isParentNodeOfTypeLayout = nodeType === 'layoutSection' || view.state.doc.resolve(getNestedNodePosition(view.state)).node().type.name === 'layoutColumn';
|
|
373
|
+
if (isParentNodeOfTypeLayout) {
|
|
374
|
+
helpDescriptors = [].concat(_toConsumableArray(helpDescriptors), [{
|
|
375
|
+
description: formatMessage(blockControlsMessages.moveLeft),
|
|
376
|
+
keymap: dragToMoveLeft
|
|
377
|
+
}, {
|
|
378
|
+
description: formatMessage(blockControlsMessages.moveRight),
|
|
379
|
+
keymap: dragToMoveRight
|
|
380
|
+
}]);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
363
383
|
var message = helpDescriptors.map(function (descriptor) {
|
|
364
384
|
return descriptor.keymap ? [descriptor.description, getAriaKeyshortcuts(descriptor.keymap)] : [descriptor.description];
|
|
365
385
|
}).join('. ');
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { TextSelection } from '@atlaskit/editor-prosemirror/state';
|
|
2
|
+
import { findParentNodeOfType } from '@atlaskit/editor-prosemirror/utils';
|
|
3
|
+
export var getNestedNodePosition = function getNestedNodePosition(state) {
|
|
4
|
+
var selection = state.selection;
|
|
5
|
+
var nestedNodePos = selection.$from.before(1);
|
|
6
|
+
if (selection instanceof TextSelection) {
|
|
7
|
+
nestedNodePos = selection.$from.before();
|
|
8
|
+
var $pos = state.doc.resolve(nestedNodePos);
|
|
9
|
+
if ($pos.depth < 1) {
|
|
10
|
+
return nestedNodePos;
|
|
11
|
+
}
|
|
12
|
+
var parentNodeOfSpecificTypes = findParentNodeOfType([state.schema.nodes.bulletList, state.schema.nodes.orderedList, state.schema.nodes.blockquote, state.schema.nodes.taskList])(state.selection);
|
|
13
|
+
if (parentNodeOfSpecificTypes) {
|
|
14
|
+
var parentNodeType = parentNodeOfSpecificTypes.node.type.name;
|
|
15
|
+
nestedNodePos = ['bulletList', 'orderedList'].includes(parentNodeType) ? $pos.before($pos.depth - 1) : ['blockquote', 'taskList'].includes(parentNodeType) ? $pos.before() : nestedNodePos;
|
|
16
|
+
}
|
|
17
|
+
} else {
|
|
18
|
+
nestedNodePos = selection.$from.pos;
|
|
19
|
+
}
|
|
20
|
+
return nestedNodePos;
|
|
21
|
+
};
|
package/dist/esm/utils/index.js
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export { getSelection, selectNode } from './getSelection';
|
|
1
|
+
export { getSelection, selectNode } from './getSelection';
|
|
2
|
+
export { getNestedNodePosition } from './getNestedNodePosition';
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { Command, ExtractInjectionAPI } from '@atlaskit/editor-common/types';
|
|
2
2
|
import type { BlockControlsPlugin } from '../types';
|
|
3
|
-
export declare const showDragHandleAtSelection: (api?: ExtractInjectionAPI<BlockControlsPlugin
|
|
3
|
+
export declare const showDragHandleAtSelection: (api?: ExtractInjectionAPI<BlockControlsPlugin>, shouldFocusParentNode?: boolean) => Command;
|
package/dist/types/consts.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { Command, ExtractInjectionAPI } from '@atlaskit/editor-common/types';
|
|
2
2
|
import type { BlockControlsPlugin } from '../types';
|
|
3
|
-
export declare const showDragHandleAtSelection: (api?: ExtractInjectionAPI<BlockControlsPlugin
|
|
3
|
+
export declare const showDragHandleAtSelection: (api?: ExtractInjectionAPI<BlockControlsPlugin>, shouldFocusParentNode?: boolean) => Command;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-block-controls",
|
|
3
|
-
"version": "2.1
|
|
3
|
+
"version": "2.2.1",
|
|
4
4
|
"description": "Block controls plugin for @atlaskit/editor-core",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@atlaskit/adf-schema": "^40.9.0",
|
|
34
|
-
"@atlaskit/editor-common": "^93.
|
|
34
|
+
"@atlaskit/editor-common": "^93.1.0",
|
|
35
35
|
"@atlaskit/editor-plugin-accessibility-utils": "^1.2.0",
|
|
36
36
|
"@atlaskit/editor-plugin-analytics": "^1.8.0",
|
|
37
37
|
"@atlaskit/editor-plugin-editor-disabled": "^1.3.0",
|
|
@@ -41,14 +41,14 @@
|
|
|
41
41
|
"@atlaskit/editor-prosemirror": "6.0.0",
|
|
42
42
|
"@atlaskit/editor-shared-styles": "^3.0.0",
|
|
43
43
|
"@atlaskit/editor-tables": "^2.8.0",
|
|
44
|
-
"@atlaskit/icon": "^22.
|
|
44
|
+
"@atlaskit/icon": "^22.22.0",
|
|
45
45
|
"@atlaskit/platform-feature-flags": "^0.3.0",
|
|
46
46
|
"@atlaskit/pragmatic-drag-and-drop": "^1.3.0",
|
|
47
47
|
"@atlaskit/pragmatic-drag-and-drop-auto-scroll": "^1.4.0",
|
|
48
48
|
"@atlaskit/pragmatic-drag-and-drop-react-drop-indicator": "^1.1.0",
|
|
49
49
|
"@atlaskit/primitives": "^12.2.0",
|
|
50
50
|
"@atlaskit/theme": "^13.0.0",
|
|
51
|
-
"@atlaskit/tmp-editor-statsig": "^2.
|
|
51
|
+
"@atlaskit/tmp-editor-statsig": "^2.3.0",
|
|
52
52
|
"@atlaskit/tokens": "^2.0.0",
|
|
53
53
|
"@atlaskit/tooltip": "^18.8.0",
|
|
54
54
|
"@babel/runtime": "^7.0.0",
|
|
@@ -147,6 +147,9 @@
|
|
|
147
147
|
},
|
|
148
148
|
"confluence_frontend_page_title_enter_improvements": {
|
|
149
149
|
"type": "boolean"
|
|
150
|
+
},
|
|
151
|
+
"platform_editor_element_dnd_nested_a11y": {
|
|
152
|
+
"type": "boolean"
|
|
150
153
|
}
|
|
151
154
|
}
|
|
152
155
|
}
|