@atlaskit/editor-plugin-block-controls 2.12.2 → 2.13.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 +8 -0
- package/dist/cjs/commands/move-to-layout.js +100 -63
- package/dist/cjs/ui/drop-target-layout.js +9 -3
- package/dist/cjs/ui/inline-drop-target.js +3 -1
- package/dist/es2019/commands/move-to-layout.js +90 -49
- package/dist/es2019/ui/drop-target-layout.js +11 -3
- package/dist/es2019/ui/inline-drop-target.js +3 -1
- package/dist/esm/commands/move-to-layout.js +100 -63
- package/dist/esm/ui/drop-target-layout.js +9 -3
- package/dist/esm/ui/inline-drop-target.js +3 -1
- package/dist/types/commands/move-to-layout.d.ts +3 -1
- package/dist/types/types.d.ts +9 -1
- package/dist/types-ts4.5/commands/move-to-layout.d.ts +3 -1
- package/dist/types-ts4.5/types.d.ts +9 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-block-controls
|
|
2
2
|
|
|
3
|
+
## 2.13.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#157826](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/157826)
|
|
8
|
+
[`130b9c5dcd038`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/130b9c5dcd038) -
|
|
9
|
+
[ED-25054] Support drag and drop a non layout column node in between layout columns
|
|
10
|
+
|
|
3
11
|
## 2.12.2
|
|
4
12
|
|
|
5
13
|
### Patch Changes
|
|
@@ -32,86 +32,123 @@ var createNewLayout = function createNewLayout(schema, layoutContents) {
|
|
|
32
32
|
}
|
|
33
33
|
return null;
|
|
34
34
|
};
|
|
35
|
-
var
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
if (from === to) {
|
|
41
|
-
return tr;
|
|
35
|
+
var updateColumnWidths = function updateColumnWidths(tr, layoutNode, layoutNodePos, newColumnWidth) {
|
|
36
|
+
if (newColumnWidth) {
|
|
37
|
+
layoutNode.content.forEach(function (node, offset) {
|
|
38
|
+
if (node.type.name === 'layoutColumn') {
|
|
39
|
+
tr = tr.setNodeAttribute(layoutNodePos + offset + 1, 'width', newColumnWidth);
|
|
42
40
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
var _ref4 = tr.doc.type.schema.marks || {},
|
|
48
|
-
breakout = _ref4.breakout;
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
return tr;
|
|
44
|
+
};
|
|
49
45
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
46
|
+
/**
|
|
47
|
+
* Insert a node into an existing layout at position `to` and delete the node
|
|
48
|
+
*/
|
|
49
|
+
var moveNode = function moveNode(from, to, newNode, sourceNodeSize, tr) {
|
|
50
|
+
tr.insert(to, newNode).setSelection(new _state.NodeSelection(tr.doc.resolve(to))).scrollIntoView();
|
|
51
|
+
var mappedFrom = tr.mapping.map(from);
|
|
52
|
+
var mappedFromEnd = mappedFrom + sourceNodeSize;
|
|
53
|
+
tr.delete(mappedFrom, mappedFromEnd);
|
|
54
|
+
return tr;
|
|
55
|
+
};
|
|
56
|
+
var moveToExistingLayout = function moveToExistingLayout(toLayout, toLayoutPos, sourceNode, from, to, tr) {
|
|
57
|
+
if (toLayout.childCount < _consts.MAX_LAYOUT_COLUMN_SUPPORTED) {
|
|
58
|
+
var newColumnWidth = _consts2.DEFAULT_COLUMN_DISTRIBUTIONS[toLayout.childCount + 1];
|
|
59
|
+
updateColumnWidths(tr, toLayout, toLayoutPos, newColumnWidth);
|
|
60
|
+
var _ref2 = tr.doc.type.schema.nodes || {},
|
|
61
|
+
layoutColumn = _ref2.layoutColumn;
|
|
62
|
+
moveNode(from, to, layoutColumn.create({
|
|
63
|
+
width: newColumnWidth
|
|
64
|
+
}, sourceNode), sourceNode.nodeSize, tr);
|
|
65
|
+
}
|
|
66
|
+
return tr;
|
|
67
|
+
};
|
|
55
68
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
69
|
+
/**
|
|
70
|
+
* Check if the node at `from` can be moved to node at `to` to create/expand a layout.
|
|
71
|
+
* Returns the source and destination nodes and positions if it's a valid move, otherwise, undefined
|
|
72
|
+
*/
|
|
73
|
+
var canMoveToLayout = function canMoveToLayout(from, to, tr) {
|
|
74
|
+
if (from === to) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
var _ref3 = tr.doc.type.schema.nodes || {},
|
|
78
|
+
layoutSection = _ref3.layoutSection,
|
|
79
|
+
layoutColumn = _ref3.layoutColumn,
|
|
80
|
+
doc = _ref3.doc;
|
|
61
81
|
|
|
62
|
-
|
|
63
|
-
|
|
82
|
+
// layout plugin does not exist
|
|
83
|
+
if (!layoutSection || !layoutColumn) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
var $to = tr.doc.resolve(to);
|
|
87
|
+
|
|
88
|
+
// drop at invalid position, not top level, or not a layout column
|
|
89
|
+
if (!$to.nodeAfter || ![doc, layoutSection].includes($to.parent.type)) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
var $from = tr.doc.resolve(from);
|
|
93
|
+
|
|
94
|
+
// invalid from position or dragging a layout
|
|
95
|
+
if (!$from.nodeAfter || $from.nodeAfter.type === layoutSection) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
var toNode = $to.nodeAfter;
|
|
99
|
+
var fromNode = $from.nodeAfter;
|
|
100
|
+
return {
|
|
101
|
+
toNode: toNode,
|
|
102
|
+
fromNode: fromNode,
|
|
103
|
+
$from: $from,
|
|
104
|
+
$to: $to
|
|
105
|
+
};
|
|
106
|
+
};
|
|
107
|
+
var moveToLayout = exports.moveToLayout = function moveToLayout(api) {
|
|
108
|
+
return function (from, to, options) {
|
|
109
|
+
return function (_ref4) {
|
|
110
|
+
var tr = _ref4.tr;
|
|
111
|
+
var canMove = canMoveToLayout(from, to, tr);
|
|
112
|
+
if (!canMove) {
|
|
64
113
|
return tr;
|
|
65
114
|
}
|
|
66
|
-
var toNode =
|
|
67
|
-
|
|
115
|
+
var toNode = canMove.toNode,
|
|
116
|
+
fromNode = canMove.fromNode,
|
|
117
|
+
$from = canMove.$from,
|
|
118
|
+
$to = canMove.$to;
|
|
119
|
+
var _ref5 = tr.doc.type.schema.nodes || {},
|
|
120
|
+
layoutSection = _ref5.layoutSection,
|
|
121
|
+
layoutColumn = _ref5.layoutColumn;
|
|
122
|
+
var _ref6 = tr.doc.type.schema.marks || {},
|
|
123
|
+
breakout = _ref6.breakout;
|
|
124
|
+
var fromNodeWithoutBreakout = fromNode;
|
|
68
125
|
|
|
69
126
|
// remove breakout from node;
|
|
70
127
|
if (breakout && $from.nodeAfter && $from.nodeAfter.marks.some(function (m) {
|
|
71
128
|
return m.type === breakout;
|
|
72
129
|
})) {
|
|
73
|
-
tr
|
|
130
|
+
tr.removeNodeMark(from, breakout);
|
|
131
|
+
// resolve again the source node after node updated (remove breakout marks)
|
|
132
|
+
fromNodeWithoutBreakout = tr.doc.resolve(from).nodeAfter;
|
|
74
133
|
}
|
|
75
|
-
if (
|
|
76
|
-
var existingLayoutNode = $to.nodeAfter;
|
|
77
|
-
if (existingLayoutNode.childCount < _consts.MAX_LAYOUT_COLUMN_SUPPORTED) {
|
|
78
|
-
var newColumnWidth = _consts2.DEFAULT_COLUMN_DISTRIBUTIONS[existingLayoutNode.childCount + 1];
|
|
79
|
-
if (newColumnWidth) {
|
|
80
|
-
existingLayoutNode.content.forEach(function (node, offset) {
|
|
81
|
-
if (node.type === layoutColumn) {
|
|
82
|
-
tr = tr.setNodeAttribute(to + offset + 1, 'width', newColumnWidth);
|
|
83
|
-
}
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
var toPos = position === 'left' ? to + 1 : to + existingLayoutNode.nodeSize - 1;
|
|
87
|
-
tr = tr.insert(toPos,
|
|
88
|
-
// resolve again the source node after node updated (remove breakout marks)
|
|
89
|
-
layoutColumn.create({
|
|
90
|
-
width: newColumnWidth
|
|
91
|
-
}, tr.doc.resolve(from).nodeAfter));
|
|
92
|
-
tr = tr.setSelection(new _state.NodeSelection(tr.doc.resolve(toPos)));
|
|
93
|
-
var mappedFrom = tr.mapping.map(from);
|
|
94
|
-
var mappedFromEnd = mappedFrom + fromNode.nodeSize;
|
|
95
|
-
tr = tr.delete(mappedFrom, mappedFromEnd);
|
|
96
|
-
tr = tr.scrollIntoView();
|
|
97
|
-
return tr;
|
|
98
|
-
}
|
|
134
|
+
if (!fromNodeWithoutBreakout) {
|
|
99
135
|
return tr;
|
|
136
|
+
}
|
|
137
|
+
if (toNode.type === layoutSection) {
|
|
138
|
+
var toPos = options !== null && options !== void 0 && options.moveToEnd ? to + toNode.nodeSize - 1 : to + 1;
|
|
139
|
+
return moveToExistingLayout(toNode, to, fromNodeWithoutBreakout, from, toPos, tr);
|
|
140
|
+
} else if (toNode.type === layoutColumn) {
|
|
141
|
+
var toLayout = $to.parent;
|
|
142
|
+
var toLayoutPos = to - $to.parentOffset - 1;
|
|
143
|
+
var _toPos = options !== null && options !== void 0 && options.moveToEnd ? to + toNode.nodeSize : to;
|
|
144
|
+
return moveToExistingLayout(toLayout, toLayoutPos, fromNodeWithoutBreakout, from, _toPos, tr);
|
|
100
145
|
} else {
|
|
101
|
-
|
|
102
|
-
var newFromNode = tr.doc.resolve(from).nodeAfter;
|
|
103
|
-
if (!newFromNode) {
|
|
104
|
-
return tr;
|
|
105
|
-
}
|
|
106
|
-
var layoutContents = position === 'left' ? [newFromNode, toNode] : [toNode, newFromNode];
|
|
146
|
+
var layoutContents = options !== null && options !== void 0 && options.moveToEnd ? [toNode, fromNodeWithoutBreakout] : [fromNodeWithoutBreakout, toNode];
|
|
107
147
|
var newLayout = createNewLayout(tr.doc.type.schema, layoutContents);
|
|
108
148
|
if (newLayout) {
|
|
109
|
-
tr
|
|
149
|
+
tr.delete(from, from + fromNode.nodeSize);
|
|
110
150
|
var mappedTo = tr.mapping.map(to);
|
|
111
|
-
tr
|
|
112
|
-
tr = tr.insert(mappedTo, newLayout); // insert the content at the new position
|
|
113
|
-
tr = tr.setSelection(new _state.NodeSelection(tr.doc.resolve(mappedTo)));
|
|
114
|
-
tr = tr.scrollIntoView();
|
|
151
|
+
tr.delete(mappedTo, mappedTo + toNode.nodeSize).insert(mappedTo, newLayout).setSelection(new _state.NodeSelection(tr.doc.resolve(mappedTo))).scrollIntoView();
|
|
115
152
|
}
|
|
116
153
|
return tr;
|
|
117
154
|
}
|
|
@@ -37,8 +37,8 @@ var dropTargetLayoutHintStyle = (0, _react2.css)({
|
|
|
37
37
|
width: 0
|
|
38
38
|
});
|
|
39
39
|
var DropTargetLayout = exports.DropTargetLayout = function DropTargetLayout(props) {
|
|
40
|
-
var
|
|
41
|
-
|
|
40
|
+
var api = props.api,
|
|
41
|
+
getPos = props.getPos;
|
|
42
42
|
var ref = (0, _react.useRef)(null);
|
|
43
43
|
var _useState = (0, _react.useState)(false),
|
|
44
44
|
_useState2 = (0, _slicedToArray2.default)(_useState, 2),
|
|
@@ -51,7 +51,13 @@ var DropTargetLayout = exports.DropTargetLayout = function DropTargetLayout(prop
|
|
|
51
51
|
if (!activeNode) {
|
|
52
52
|
return;
|
|
53
53
|
}
|
|
54
|
-
|
|
54
|
+
var to = getPos();
|
|
55
|
+
if (to !== undefined) {
|
|
56
|
+
var _api$core, _api$blockControls2;
|
|
57
|
+
var from = activeNode.pos;
|
|
58
|
+
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.moveToLayout(from, to));
|
|
59
|
+
}
|
|
60
|
+
}, [api, getPos]);
|
|
55
61
|
(0, _react.useEffect)(function () {
|
|
56
62
|
if (ref.current) {
|
|
57
63
|
return (0, _adapter.dropTargetForElements)({
|
|
@@ -141,7 +141,9 @@ var InlineDropTarget = exports.InlineDropTarget = function InlineDropTarget(_ref
|
|
|
141
141
|
if (activeNode && toPos !== undefined) {
|
|
142
142
|
var _api$core, _api$blockControls2;
|
|
143
143
|
var start = activeNode.pos;
|
|
144
|
-
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.moveToLayout(start, toPos,
|
|
144
|
+
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.moveToLayout(start, toPos, {
|
|
145
|
+
moveToEnd: position === 'right'
|
|
146
|
+
}));
|
|
145
147
|
}
|
|
146
148
|
}, [api, getPos, position]);
|
|
147
149
|
return (0, _react2.jsx)(_react.Fragment, null, (0, _react2.jsx)("div", {
|
|
@@ -27,85 +27,126 @@ const createNewLayout = (schema, layoutContents) => {
|
|
|
27
27
|
}
|
|
28
28
|
return null;
|
|
29
29
|
};
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
30
|
+
const updateColumnWidths = (tr, layoutNode, layoutNodePos, newColumnWidth) => {
|
|
31
|
+
if (newColumnWidth) {
|
|
32
|
+
layoutNode.content.forEach((node, offset) => {
|
|
33
|
+
if (node.type.name === 'layoutColumn') {
|
|
34
|
+
tr = tr.setNodeAttribute(layoutNodePos + offset + 1, 'width', newColumnWidth);
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
return tr;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Insert a node into an existing layout at position `to` and delete the node
|
|
43
|
+
*/
|
|
44
|
+
const moveNode = (from, to, newNode, sourceNodeSize, tr) => {
|
|
45
|
+
tr.insert(to, newNode).setSelection(new NodeSelection(tr.doc.resolve(to))).scrollIntoView();
|
|
46
|
+
const mappedFrom = tr.mapping.map(from);
|
|
47
|
+
const mappedFromEnd = mappedFrom + sourceNodeSize;
|
|
48
|
+
tr.delete(mappedFrom, mappedFromEnd);
|
|
49
|
+
return tr;
|
|
50
|
+
};
|
|
51
|
+
const moveToExistingLayout = (toLayout, toLayoutPos, sourceNode, from, to, tr) => {
|
|
52
|
+
if (toLayout.childCount < MAX_LAYOUT_COLUMN_SUPPORTED) {
|
|
53
|
+
const newColumnWidth = DEFAULT_COLUMN_DISTRIBUTIONS[toLayout.childCount + 1];
|
|
54
|
+
updateColumnWidths(tr, toLayout, toLayoutPos, newColumnWidth);
|
|
55
|
+
const {
|
|
56
|
+
layoutColumn
|
|
57
|
+
} = tr.doc.type.schema.nodes || {};
|
|
58
|
+
moveNode(from, to, layoutColumn.create({
|
|
59
|
+
width: newColumnWidth
|
|
60
|
+
}, sourceNode), sourceNode.nodeSize, tr);
|
|
61
|
+
}
|
|
62
|
+
return tr;
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Check if the node at `from` can be moved to node at `to` to create/expand a layout.
|
|
67
|
+
* Returns the source and destination nodes and positions if it's a valid move, otherwise, undefined
|
|
68
|
+
*/
|
|
69
|
+
const canMoveToLayout = (from, to, tr) => {
|
|
34
70
|
if (from === to) {
|
|
35
|
-
return
|
|
71
|
+
return;
|
|
36
72
|
}
|
|
37
73
|
const {
|
|
38
74
|
layoutSection,
|
|
39
75
|
layoutColumn,
|
|
40
76
|
doc
|
|
41
77
|
} = tr.doc.type.schema.nodes || {};
|
|
42
|
-
const {
|
|
43
|
-
breakout
|
|
44
|
-
} = tr.doc.type.schema.marks || {};
|
|
45
78
|
|
|
46
79
|
// layout plugin does not exist
|
|
47
80
|
if (!layoutSection || !layoutColumn) {
|
|
48
|
-
return
|
|
81
|
+
return;
|
|
49
82
|
}
|
|
50
83
|
const $to = tr.doc.resolve(to);
|
|
51
84
|
|
|
52
|
-
// invalid
|
|
53
|
-
if (!$to.nodeAfter || $to.parent.type
|
|
54
|
-
return
|
|
85
|
+
// drop at invalid position, not top level, or not a layout column
|
|
86
|
+
if (!$to.nodeAfter || ![doc, layoutSection].includes($to.parent.type)) {
|
|
87
|
+
return;
|
|
55
88
|
}
|
|
56
89
|
const $from = tr.doc.resolve(from);
|
|
57
90
|
|
|
58
91
|
// invalid from position or dragging a layout
|
|
59
92
|
if (!$from.nodeAfter || $from.nodeAfter.type === layoutSection) {
|
|
60
|
-
return
|
|
93
|
+
return;
|
|
61
94
|
}
|
|
62
95
|
const toNode = $to.nodeAfter;
|
|
63
96
|
const fromNode = $from.nodeAfter;
|
|
97
|
+
return {
|
|
98
|
+
toNode,
|
|
99
|
+
fromNode,
|
|
100
|
+
$from,
|
|
101
|
+
$to
|
|
102
|
+
};
|
|
103
|
+
};
|
|
104
|
+
export const moveToLayout = api => (from, to, options) => ({
|
|
105
|
+
tr
|
|
106
|
+
}) => {
|
|
107
|
+
const canMove = canMoveToLayout(from, to, tr);
|
|
108
|
+
if (!canMove) {
|
|
109
|
+
return tr;
|
|
110
|
+
}
|
|
111
|
+
const {
|
|
112
|
+
toNode,
|
|
113
|
+
fromNode,
|
|
114
|
+
$from,
|
|
115
|
+
$to
|
|
116
|
+
} = canMove;
|
|
117
|
+
const {
|
|
118
|
+
layoutSection,
|
|
119
|
+
layoutColumn
|
|
120
|
+
} = tr.doc.type.schema.nodes || {};
|
|
121
|
+
const {
|
|
122
|
+
breakout
|
|
123
|
+
} = tr.doc.type.schema.marks || {};
|
|
124
|
+
let fromNodeWithoutBreakout = fromNode;
|
|
64
125
|
|
|
65
126
|
// remove breakout from node;
|
|
66
127
|
if (breakout && $from.nodeAfter && $from.nodeAfter.marks.some(m => m.type === breakout)) {
|
|
67
|
-
tr
|
|
128
|
+
tr.removeNodeMark(from, breakout);
|
|
129
|
+
// resolve again the source node after node updated (remove breakout marks)
|
|
130
|
+
fromNodeWithoutBreakout = tr.doc.resolve(from).nodeAfter;
|
|
68
131
|
}
|
|
69
|
-
if (
|
|
70
|
-
const existingLayoutNode = $to.nodeAfter;
|
|
71
|
-
if (existingLayoutNode.childCount < MAX_LAYOUT_COLUMN_SUPPORTED) {
|
|
72
|
-
const newColumnWidth = DEFAULT_COLUMN_DISTRIBUTIONS[existingLayoutNode.childCount + 1];
|
|
73
|
-
if (newColumnWidth) {
|
|
74
|
-
existingLayoutNode.content.forEach((node, offset) => {
|
|
75
|
-
if (node.type === layoutColumn) {
|
|
76
|
-
tr = tr.setNodeAttribute(to + offset + 1, 'width', newColumnWidth);
|
|
77
|
-
}
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
|
-
const toPos = position === 'left' ? to + 1 : to + existingLayoutNode.nodeSize - 1;
|
|
81
|
-
tr = tr.insert(toPos,
|
|
82
|
-
// resolve again the source node after node updated (remove breakout marks)
|
|
83
|
-
layoutColumn.create({
|
|
84
|
-
width: newColumnWidth
|
|
85
|
-
}, tr.doc.resolve(from).nodeAfter));
|
|
86
|
-
tr = tr.setSelection(new NodeSelection(tr.doc.resolve(toPos)));
|
|
87
|
-
const mappedFrom = tr.mapping.map(from);
|
|
88
|
-
const mappedFromEnd = mappedFrom + fromNode.nodeSize;
|
|
89
|
-
tr = tr.delete(mappedFrom, mappedFromEnd);
|
|
90
|
-
tr = tr.scrollIntoView();
|
|
91
|
-
return tr;
|
|
92
|
-
}
|
|
132
|
+
if (!fromNodeWithoutBreakout) {
|
|
93
133
|
return tr;
|
|
134
|
+
}
|
|
135
|
+
if (toNode.type === layoutSection) {
|
|
136
|
+
const toPos = options !== null && options !== void 0 && options.moveToEnd ? to + toNode.nodeSize - 1 : to + 1;
|
|
137
|
+
return moveToExistingLayout(toNode, to, fromNodeWithoutBreakout, from, toPos, tr);
|
|
138
|
+
} else if (toNode.type === layoutColumn) {
|
|
139
|
+
const toLayout = $to.parent;
|
|
140
|
+
const toLayoutPos = to - $to.parentOffset - 1;
|
|
141
|
+
const toPos = options !== null && options !== void 0 && options.moveToEnd ? to + toNode.nodeSize : to;
|
|
142
|
+
return moveToExistingLayout(toLayout, toLayoutPos, fromNodeWithoutBreakout, from, toPos, tr);
|
|
94
143
|
} else {
|
|
95
|
-
|
|
96
|
-
const newFromNode = tr.doc.resolve(from).nodeAfter;
|
|
97
|
-
if (!newFromNode) {
|
|
98
|
-
return tr;
|
|
99
|
-
}
|
|
100
|
-
const layoutContents = position === 'left' ? [newFromNode, toNode] : [toNode, newFromNode];
|
|
144
|
+
const layoutContents = options !== null && options !== void 0 && options.moveToEnd ? [toNode, fromNodeWithoutBreakout] : [fromNodeWithoutBreakout, toNode];
|
|
101
145
|
const newLayout = createNewLayout(tr.doc.type.schema, layoutContents);
|
|
102
146
|
if (newLayout) {
|
|
103
|
-
tr
|
|
147
|
+
tr.delete(from, from + fromNode.nodeSize);
|
|
104
148
|
const mappedTo = tr.mapping.map(to);
|
|
105
|
-
tr
|
|
106
|
-
tr = tr.insert(mappedTo, newLayout); // insert the content at the new position
|
|
107
|
-
tr = tr.setSelection(new NodeSelection(tr.doc.resolve(mappedTo)));
|
|
108
|
-
tr = tr.scrollIntoView();
|
|
149
|
+
tr.delete(mappedTo, mappedTo + toNode.nodeSize).insert(mappedTo, newLayout).setSelection(new NodeSelection(tr.doc.resolve(mappedTo))).scrollIntoView();
|
|
109
150
|
}
|
|
110
151
|
return tr;
|
|
111
152
|
}
|
|
@@ -29,9 +29,9 @@ const dropTargetLayoutHintStyle = css({
|
|
|
29
29
|
width: 0
|
|
30
30
|
});
|
|
31
31
|
export const DropTargetLayout = props => {
|
|
32
|
-
var _api$blockControls2;
|
|
33
32
|
const {
|
|
34
|
-
api
|
|
33
|
+
api,
|
|
34
|
+
getPos
|
|
35
35
|
} = props;
|
|
36
36
|
const ref = useRef(null);
|
|
37
37
|
const [isDraggedOver, setIsDraggedOver] = useState(false);
|
|
@@ -43,7 +43,15 @@ export const DropTargetLayout = props => {
|
|
|
43
43
|
if (!activeNode) {
|
|
44
44
|
return;
|
|
45
45
|
}
|
|
46
|
-
|
|
46
|
+
const to = getPos();
|
|
47
|
+
if (to !== undefined) {
|
|
48
|
+
var _api$core, _api$blockControls2, _api$blockControls2$c;
|
|
49
|
+
const {
|
|
50
|
+
pos: from
|
|
51
|
+
} = activeNode;
|
|
52
|
+
api === null || api === void 0 ? void 0 : (_api$core = api.core) === null || _api$core === void 0 ? void 0 : _api$core.actions.execute(api === null || api === void 0 ? void 0 : (_api$blockControls2 = api.blockControls) === null || _api$blockControls2 === void 0 ? void 0 : (_api$blockControls2$c = _api$blockControls2.commands) === null || _api$blockControls2$c === void 0 ? void 0 : _api$blockControls2$c.moveToLayout(from, to));
|
|
53
|
+
}
|
|
54
|
+
}, [api, getPos]);
|
|
47
55
|
useEffect(() => {
|
|
48
56
|
if (ref.current) {
|
|
49
57
|
return dropTargetForElements({
|
|
@@ -134,7 +134,9 @@ export const InlineDropTarget = ({
|
|
|
134
134
|
const {
|
|
135
135
|
pos: start
|
|
136
136
|
} = activeNode;
|
|
137
|
-
api === null || api === void 0 ? void 0 : (_api$core = api.core) === null || _api$core === void 0 ? void 0 : _api$core.actions.execute(api === null || api === void 0 ? void 0 : (_api$blockControls2 = api.blockControls) === null || _api$blockControls2 === void 0 ? void 0 : (_api$blockControls2$c = _api$blockControls2.commands) === null || _api$blockControls2$c === void 0 ? void 0 : _api$blockControls2$c.moveToLayout(start, toPos,
|
|
137
|
+
api === null || api === void 0 ? void 0 : (_api$core = api.core) === null || _api$core === void 0 ? void 0 : _api$core.actions.execute(api === null || api === void 0 ? void 0 : (_api$blockControls2 = api.blockControls) === null || _api$blockControls2 === void 0 ? void 0 : (_api$blockControls2$c = _api$blockControls2.commands) === null || _api$blockControls2$c === void 0 ? void 0 : _api$blockControls2$c.moveToLayout(start, toPos, {
|
|
138
|
+
moveToEnd: position === 'right'
|
|
139
|
+
}));
|
|
138
140
|
}
|
|
139
141
|
}, [api, getPos, position]);
|
|
140
142
|
return jsx(Fragment, null, jsx("div", {
|
|
@@ -26,86 +26,123 @@ var createNewLayout = function createNewLayout(schema, layoutContents) {
|
|
|
26
26
|
}
|
|
27
27
|
return null;
|
|
28
28
|
};
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
if (from === to) {
|
|
35
|
-
return tr;
|
|
29
|
+
var updateColumnWidths = function updateColumnWidths(tr, layoutNode, layoutNodePos, newColumnWidth) {
|
|
30
|
+
if (newColumnWidth) {
|
|
31
|
+
layoutNode.content.forEach(function (node, offset) {
|
|
32
|
+
if (node.type.name === 'layoutColumn') {
|
|
33
|
+
tr = tr.setNodeAttribute(layoutNodePos + offset + 1, 'width', newColumnWidth);
|
|
36
34
|
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
var _ref4 = tr.doc.type.schema.marks || {},
|
|
42
|
-
breakout = _ref4.breakout;
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
return tr;
|
|
38
|
+
};
|
|
43
39
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
40
|
+
/**
|
|
41
|
+
* Insert a node into an existing layout at position `to` and delete the node
|
|
42
|
+
*/
|
|
43
|
+
var moveNode = function moveNode(from, to, newNode, sourceNodeSize, tr) {
|
|
44
|
+
tr.insert(to, newNode).setSelection(new NodeSelection(tr.doc.resolve(to))).scrollIntoView();
|
|
45
|
+
var mappedFrom = tr.mapping.map(from);
|
|
46
|
+
var mappedFromEnd = mappedFrom + sourceNodeSize;
|
|
47
|
+
tr.delete(mappedFrom, mappedFromEnd);
|
|
48
|
+
return tr;
|
|
49
|
+
};
|
|
50
|
+
var moveToExistingLayout = function moveToExistingLayout(toLayout, toLayoutPos, sourceNode, from, to, tr) {
|
|
51
|
+
if (toLayout.childCount < MAX_LAYOUT_COLUMN_SUPPORTED) {
|
|
52
|
+
var newColumnWidth = DEFAULT_COLUMN_DISTRIBUTIONS[toLayout.childCount + 1];
|
|
53
|
+
updateColumnWidths(tr, toLayout, toLayoutPos, newColumnWidth);
|
|
54
|
+
var _ref2 = tr.doc.type.schema.nodes || {},
|
|
55
|
+
layoutColumn = _ref2.layoutColumn;
|
|
56
|
+
moveNode(from, to, layoutColumn.create({
|
|
57
|
+
width: newColumnWidth
|
|
58
|
+
}, sourceNode), sourceNode.nodeSize, tr);
|
|
59
|
+
}
|
|
60
|
+
return tr;
|
|
61
|
+
};
|
|
49
62
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
63
|
+
/**
|
|
64
|
+
* Check if the node at `from` can be moved to node at `to` to create/expand a layout.
|
|
65
|
+
* Returns the source and destination nodes and positions if it's a valid move, otherwise, undefined
|
|
66
|
+
*/
|
|
67
|
+
var canMoveToLayout = function canMoveToLayout(from, to, tr) {
|
|
68
|
+
if (from === to) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
var _ref3 = tr.doc.type.schema.nodes || {},
|
|
72
|
+
layoutSection = _ref3.layoutSection,
|
|
73
|
+
layoutColumn = _ref3.layoutColumn,
|
|
74
|
+
doc = _ref3.doc;
|
|
55
75
|
|
|
56
|
-
|
|
57
|
-
|
|
76
|
+
// layout plugin does not exist
|
|
77
|
+
if (!layoutSection || !layoutColumn) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
var $to = tr.doc.resolve(to);
|
|
81
|
+
|
|
82
|
+
// drop at invalid position, not top level, or not a layout column
|
|
83
|
+
if (!$to.nodeAfter || ![doc, layoutSection].includes($to.parent.type)) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
var $from = tr.doc.resolve(from);
|
|
87
|
+
|
|
88
|
+
// invalid from position or dragging a layout
|
|
89
|
+
if (!$from.nodeAfter || $from.nodeAfter.type === layoutSection) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
var toNode = $to.nodeAfter;
|
|
93
|
+
var fromNode = $from.nodeAfter;
|
|
94
|
+
return {
|
|
95
|
+
toNode: toNode,
|
|
96
|
+
fromNode: fromNode,
|
|
97
|
+
$from: $from,
|
|
98
|
+
$to: $to
|
|
99
|
+
};
|
|
100
|
+
};
|
|
101
|
+
export var moveToLayout = function moveToLayout(api) {
|
|
102
|
+
return function (from, to, options) {
|
|
103
|
+
return function (_ref4) {
|
|
104
|
+
var tr = _ref4.tr;
|
|
105
|
+
var canMove = canMoveToLayout(from, to, tr);
|
|
106
|
+
if (!canMove) {
|
|
58
107
|
return tr;
|
|
59
108
|
}
|
|
60
|
-
var toNode =
|
|
61
|
-
|
|
109
|
+
var toNode = canMove.toNode,
|
|
110
|
+
fromNode = canMove.fromNode,
|
|
111
|
+
$from = canMove.$from,
|
|
112
|
+
$to = canMove.$to;
|
|
113
|
+
var _ref5 = tr.doc.type.schema.nodes || {},
|
|
114
|
+
layoutSection = _ref5.layoutSection,
|
|
115
|
+
layoutColumn = _ref5.layoutColumn;
|
|
116
|
+
var _ref6 = tr.doc.type.schema.marks || {},
|
|
117
|
+
breakout = _ref6.breakout;
|
|
118
|
+
var fromNodeWithoutBreakout = fromNode;
|
|
62
119
|
|
|
63
120
|
// remove breakout from node;
|
|
64
121
|
if (breakout && $from.nodeAfter && $from.nodeAfter.marks.some(function (m) {
|
|
65
122
|
return m.type === breakout;
|
|
66
123
|
})) {
|
|
67
|
-
tr
|
|
124
|
+
tr.removeNodeMark(from, breakout);
|
|
125
|
+
// resolve again the source node after node updated (remove breakout marks)
|
|
126
|
+
fromNodeWithoutBreakout = tr.doc.resolve(from).nodeAfter;
|
|
68
127
|
}
|
|
69
|
-
if (
|
|
70
|
-
var existingLayoutNode = $to.nodeAfter;
|
|
71
|
-
if (existingLayoutNode.childCount < MAX_LAYOUT_COLUMN_SUPPORTED) {
|
|
72
|
-
var newColumnWidth = DEFAULT_COLUMN_DISTRIBUTIONS[existingLayoutNode.childCount + 1];
|
|
73
|
-
if (newColumnWidth) {
|
|
74
|
-
existingLayoutNode.content.forEach(function (node, offset) {
|
|
75
|
-
if (node.type === layoutColumn) {
|
|
76
|
-
tr = tr.setNodeAttribute(to + offset + 1, 'width', newColumnWidth);
|
|
77
|
-
}
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
|
-
var toPos = position === 'left' ? to + 1 : to + existingLayoutNode.nodeSize - 1;
|
|
81
|
-
tr = tr.insert(toPos,
|
|
82
|
-
// resolve again the source node after node updated (remove breakout marks)
|
|
83
|
-
layoutColumn.create({
|
|
84
|
-
width: newColumnWidth
|
|
85
|
-
}, tr.doc.resolve(from).nodeAfter));
|
|
86
|
-
tr = tr.setSelection(new NodeSelection(tr.doc.resolve(toPos)));
|
|
87
|
-
var mappedFrom = tr.mapping.map(from);
|
|
88
|
-
var mappedFromEnd = mappedFrom + fromNode.nodeSize;
|
|
89
|
-
tr = tr.delete(mappedFrom, mappedFromEnd);
|
|
90
|
-
tr = tr.scrollIntoView();
|
|
91
|
-
return tr;
|
|
92
|
-
}
|
|
128
|
+
if (!fromNodeWithoutBreakout) {
|
|
93
129
|
return tr;
|
|
130
|
+
}
|
|
131
|
+
if (toNode.type === layoutSection) {
|
|
132
|
+
var toPos = options !== null && options !== void 0 && options.moveToEnd ? to + toNode.nodeSize - 1 : to + 1;
|
|
133
|
+
return moveToExistingLayout(toNode, to, fromNodeWithoutBreakout, from, toPos, tr);
|
|
134
|
+
} else if (toNode.type === layoutColumn) {
|
|
135
|
+
var toLayout = $to.parent;
|
|
136
|
+
var toLayoutPos = to - $to.parentOffset - 1;
|
|
137
|
+
var _toPos = options !== null && options !== void 0 && options.moveToEnd ? to + toNode.nodeSize : to;
|
|
138
|
+
return moveToExistingLayout(toLayout, toLayoutPos, fromNodeWithoutBreakout, from, _toPos, tr);
|
|
94
139
|
} else {
|
|
95
|
-
|
|
96
|
-
var newFromNode = tr.doc.resolve(from).nodeAfter;
|
|
97
|
-
if (!newFromNode) {
|
|
98
|
-
return tr;
|
|
99
|
-
}
|
|
100
|
-
var layoutContents = position === 'left' ? [newFromNode, toNode] : [toNode, newFromNode];
|
|
140
|
+
var layoutContents = options !== null && options !== void 0 && options.moveToEnd ? [toNode, fromNodeWithoutBreakout] : [fromNodeWithoutBreakout, toNode];
|
|
101
141
|
var newLayout = createNewLayout(tr.doc.type.schema, layoutContents);
|
|
102
142
|
if (newLayout) {
|
|
103
|
-
tr
|
|
143
|
+
tr.delete(from, from + fromNode.nodeSize);
|
|
104
144
|
var mappedTo = tr.mapping.map(to);
|
|
105
|
-
tr
|
|
106
|
-
tr = tr.insert(mappedTo, newLayout); // insert the content at the new position
|
|
107
|
-
tr = tr.setSelection(new NodeSelection(tr.doc.resolve(mappedTo)));
|
|
108
|
-
tr = tr.scrollIntoView();
|
|
145
|
+
tr.delete(mappedTo, mappedTo + toNode.nodeSize).insert(mappedTo, newLayout).setSelection(new NodeSelection(tr.doc.resolve(mappedTo))).scrollIntoView();
|
|
109
146
|
}
|
|
110
147
|
return tr;
|
|
111
148
|
}
|
|
@@ -30,8 +30,8 @@ var dropTargetLayoutHintStyle = css({
|
|
|
30
30
|
width: 0
|
|
31
31
|
});
|
|
32
32
|
export var DropTargetLayout = function DropTargetLayout(props) {
|
|
33
|
-
var
|
|
34
|
-
|
|
33
|
+
var api = props.api,
|
|
34
|
+
getPos = props.getPos;
|
|
35
35
|
var ref = useRef(null);
|
|
36
36
|
var _useState = useState(false),
|
|
37
37
|
_useState2 = _slicedToArray(_useState, 2),
|
|
@@ -44,7 +44,13 @@ export var DropTargetLayout = function DropTargetLayout(props) {
|
|
|
44
44
|
if (!activeNode) {
|
|
45
45
|
return;
|
|
46
46
|
}
|
|
47
|
-
|
|
47
|
+
var to = getPos();
|
|
48
|
+
if (to !== undefined) {
|
|
49
|
+
var _api$core, _api$blockControls2;
|
|
50
|
+
var from = activeNode.pos;
|
|
51
|
+
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.moveToLayout(from, to));
|
|
52
|
+
}
|
|
53
|
+
}, [api, getPos]);
|
|
48
54
|
useEffect(function () {
|
|
49
55
|
if (ref.current) {
|
|
50
56
|
return dropTargetForElements({
|
|
@@ -133,7 +133,9 @@ export var InlineDropTarget = function InlineDropTarget(_ref) {
|
|
|
133
133
|
if (activeNode && toPos !== undefined) {
|
|
134
134
|
var _api$core, _api$blockControls2;
|
|
135
135
|
var start = activeNode.pos;
|
|
136
|
-
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.moveToLayout(start, toPos,
|
|
136
|
+
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.moveToLayout(start, toPos, {
|
|
137
|
+
moveToEnd: position === 'right'
|
|
138
|
+
}));
|
|
137
139
|
}
|
|
138
140
|
}, [api, getPos, position]);
|
|
139
141
|
return jsx(Fragment, null, jsx("div", {
|
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
import type { EditorCommand, ExtractInjectionAPI } from '@atlaskit/editor-common/types';
|
|
2
2
|
import type { BlockControlsPlugin } from '../types';
|
|
3
|
-
export declare const moveToLayout: (api?: ExtractInjectionAPI<BlockControlsPlugin>) => (from: number, to: number,
|
|
3
|
+
export declare const moveToLayout: (api?: ExtractInjectionAPI<BlockControlsPlugin>) => (from: number, to: number, options?: {
|
|
4
|
+
moveToEnd?: boolean;
|
|
5
|
+
}) => EditorCommand;
|
package/dist/types/types.d.ts
CHANGED
|
@@ -58,7 +58,15 @@ export type BlockControlsPlugin = NextEditorPlugin<'blockControls', {
|
|
|
58
58
|
];
|
|
59
59
|
sharedState: BlockControlsSharedState;
|
|
60
60
|
commands: {
|
|
61
|
-
|
|
61
|
+
/**
|
|
62
|
+
* Move a node before (unless `moveToEnd` is set) another node to expand a layout or create a new layout
|
|
63
|
+
* @param from position of the node to be moved
|
|
64
|
+
* @param to position of the layout/layout column/node to move the node to
|
|
65
|
+
* @param options moveToEnd: move the node to after the layout/layout column/another node
|
|
66
|
+
*/
|
|
67
|
+
moveToLayout: (start: number, to: number, options?: {
|
|
68
|
+
moveToEnd?: boolean;
|
|
69
|
+
}) => EditorCommand;
|
|
62
70
|
moveNode: (start: number, to: number, inputMethod?: MoveNodeMethod, formatMessage?: IntlShape['formatMessage']) => EditorCommand;
|
|
63
71
|
showDragHandleAt: (pos: number, anchorName: string, nodeType: string, handleOptions?: HandleOptions) => EditorCommand;
|
|
64
72
|
setNodeDragged: (getPos: () => number | undefined, anchorName: string, nodeType: string) => EditorCommand;
|
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
import type { EditorCommand, ExtractInjectionAPI } from '@atlaskit/editor-common/types';
|
|
2
2
|
import type { BlockControlsPlugin } from '../types';
|
|
3
|
-
export declare const moveToLayout: (api?: ExtractInjectionAPI<BlockControlsPlugin>) => (from: number, to: number,
|
|
3
|
+
export declare const moveToLayout: (api?: ExtractInjectionAPI<BlockControlsPlugin>) => (from: number, to: number, options?: {
|
|
4
|
+
moveToEnd?: boolean;
|
|
5
|
+
}) => EditorCommand;
|
|
@@ -58,7 +58,15 @@ export type BlockControlsPlugin = NextEditorPlugin<'blockControls', {
|
|
|
58
58
|
];
|
|
59
59
|
sharedState: BlockControlsSharedState;
|
|
60
60
|
commands: {
|
|
61
|
-
|
|
61
|
+
/**
|
|
62
|
+
* Move a node before (unless `moveToEnd` is set) another node to expand a layout or create a new layout
|
|
63
|
+
* @param from position of the node to be moved
|
|
64
|
+
* @param to position of the layout/layout column/node to move the node to
|
|
65
|
+
* @param options moveToEnd: move the node to after the layout/layout column/another node
|
|
66
|
+
*/
|
|
67
|
+
moveToLayout: (start: number, to: number, options?: {
|
|
68
|
+
moveToEnd?: boolean;
|
|
69
|
+
}) => EditorCommand;
|
|
62
70
|
moveNode: (start: number, to: number, inputMethod?: MoveNodeMethod, formatMessage?: IntlShape['formatMessage']) => EditorCommand;
|
|
63
71
|
showDragHandleAt: (pos: number, anchorName: string, nodeType: string, handleOptions?: HandleOptions) => EditorCommand;
|
|
64
72
|
setNodeDragged: (getPos: () => number | undefined, anchorName: string, nodeType: string) => EditorCommand;
|