@atlaskit/editor-plugin-block-controls 3.3.7 → 3.3.8
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 +9 -0
- package/dist/cjs/ui/quick-insert-button.js +35 -32
- package/dist/cjs/ui/utils/document-checks.js +41 -0
- package/dist/cjs/ui/utils/editor-commands.js +20 -0
- package/dist/es2019/ui/quick-insert-button.js +36 -34
- package/dist/es2019/ui/utils/document-checks.js +36 -0
- package/dist/es2019/ui/utils/editor-commands.js +13 -0
- package/dist/esm/ui/quick-insert-button.js +35 -32
- package/dist/esm/ui/utils/document-checks.js +35 -0
- package/dist/esm/ui/utils/editor-commands.js +14 -0
- package/dist/types/ui/utils/document-checks.d.ts +4 -0
- package/dist/types/ui/utils/editor-commands.d.ts +2 -0
- package/dist/types-ts4.5/ui/utils/document-checks.d.ts +4 -0
- package/dist/types-ts4.5/ui/utils/editor-commands.d.ts +2 -0
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-block-controls
|
|
2
2
|
|
|
3
|
+
## 3.3.8
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#124180](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/124180)
|
|
8
|
+
[`f3f332175bf17`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/f3f332175bf17) -
|
|
9
|
+
add case for quick insert button to handle block nodes which are leaf nodes, and handle media
|
|
10
|
+
- Updated dependencies
|
|
11
|
+
|
|
3
12
|
## 3.3.7
|
|
4
13
|
|
|
5
14
|
### Patch Changes
|
|
@@ -19,6 +19,8 @@ var _tooltip = _interopRequireDefault(require("@atlaskit/tooltip"));
|
|
|
19
19
|
var _dragHandlePositions = require("../pm-plugins/utils/drag-handle-positions");
|
|
20
20
|
var _widgetPositions = require("../pm-plugins/utils/widget-positions");
|
|
21
21
|
var _consts = require("./consts");
|
|
22
|
+
var _documentChecks = require("./utils/document-checks");
|
|
23
|
+
var _editorCommands = require("./utils/editor-commands");
|
|
22
24
|
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
|
|
23
25
|
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
24
26
|
var buttonStyles = (0, _primitives.xcss)({
|
|
@@ -52,18 +54,6 @@ var containerStaticStyles = (0, _primitives.xcss)({
|
|
|
52
54
|
|
|
53
55
|
// TODO: ED-26959 - Share prop types between DragHandle - generic enough to create a type for block control decoration
|
|
54
56
|
|
|
55
|
-
var isSelectionInNode = function isSelectionInNode(start, view) {
|
|
56
|
-
var node = view.state.doc.nodeAt(start);
|
|
57
|
-
if (node === null) {
|
|
58
|
-
return false;
|
|
59
|
-
}
|
|
60
|
-
var endPos = start + node.nodeSize;
|
|
61
|
-
var startPos = start;
|
|
62
|
-
var _view$state$selection = view.state.selection,
|
|
63
|
-
$from = _view$state$selection.$from,
|
|
64
|
-
$to = _view$state$selection.$to;
|
|
65
|
-
return $from.pos >= startPos && endPos >= $to.pos;
|
|
66
|
-
};
|
|
67
57
|
var TypeAheadControl = exports.TypeAheadControl = function TypeAheadControl(_ref) {
|
|
68
58
|
var view = _ref.view,
|
|
69
59
|
api = _ref.api,
|
|
@@ -143,6 +133,38 @@ var TypeAheadControl = exports.TypeAheadControl = function TypeAheadControl(_ref
|
|
|
143
133
|
(_cleanUpTransitionLis = cleanUpTransitionListener) === null || _cleanUpTransitionLis === void 0 || _cleanUpTransitionLis();
|
|
144
134
|
};
|
|
145
135
|
}, [calculatePosition, view.dom, rootAnchorName, rootNodeType]);
|
|
136
|
+
var handleQuickInsert = (0, _react.useCallback)(function () {
|
|
137
|
+
var _api$quickInsert;
|
|
138
|
+
// if the selection is not within the node this decoration is rendered at
|
|
139
|
+
// then insert a newline and trigger quick insert
|
|
140
|
+
var start = getPos();
|
|
141
|
+
if (start !== undefined) {
|
|
142
|
+
// if the selection is not within the node this decoration is rendered at
|
|
143
|
+
// or the node is non-editable, then insert a newline and trigger quick insert
|
|
144
|
+
if (!(0, _documentChecks.isSelectionInNode)(start, view) || (0, _documentChecks.isNonEditableBlock)(start, view)) {
|
|
145
|
+
api.core.actions.execute((0, _editorCommands.createNewLine)(start));
|
|
146
|
+
}
|
|
147
|
+
if ((0, _documentChecks.isSelectionInNode)(start, view) && (0, _documentChecks.isNestedNodeSelected)(view)) {
|
|
148
|
+
// if the nested selected node is non-editable, then insert a newline below the selected node
|
|
149
|
+
if ((0, _documentChecks.isNonEditableBlock)(view.state.selection.from, view)) {
|
|
150
|
+
api.core.actions.execute((0, _editorCommands.createNewLine)(view.state.selection.from));
|
|
151
|
+
} else {
|
|
152
|
+
// otherwise need to force the selection to be at the start of the node, because
|
|
153
|
+
// prosemirror is keeping it as NodeSelection for nested nodes. Do this to keep it
|
|
154
|
+
// consistent NodeSelection for root level nodes.
|
|
155
|
+
api.core.actions.execute(function (_ref2) {
|
|
156
|
+
var tr = _ref2.tr;
|
|
157
|
+
(0, _editorCommands.createNewLine)(view.state.selection.from)({
|
|
158
|
+
tr: tr
|
|
159
|
+
});
|
|
160
|
+
tr.setSelection(_state.TextSelection.create(tr.doc, view.state.selection.from));
|
|
161
|
+
return tr;
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
api === null || api === void 0 || (_api$quickInsert = api.quickInsert) === null || _api$quickInsert === void 0 || _api$quickInsert.actions.openTypeAhead('blockControl');
|
|
167
|
+
}, [api, getPos, view]);
|
|
146
168
|
return (
|
|
147
169
|
/*#__PURE__*/
|
|
148
170
|
// eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop
|
|
@@ -157,26 +179,7 @@ var TypeAheadControl = exports.TypeAheadControl = function TypeAheadControl(_ref
|
|
|
157
179
|
type: "button",
|
|
158
180
|
"aria-label": formatMessage(_messages.blockControlsMessages.insert),
|
|
159
181
|
xcss: [buttonStyles],
|
|
160
|
-
onClick:
|
|
161
|
-
var _api$quickInsert;
|
|
162
|
-
// if the selection is not within the node this decoration is rendered at
|
|
163
|
-
// then insert a newline and trigger quick insert
|
|
164
|
-
var start = getPos();
|
|
165
|
-
if (start !== undefined && !isSelectionInNode(start, view)) {
|
|
166
|
-
api.core.actions.execute(function (_ref2) {
|
|
167
|
-
var _tr$doc$nodeAt;
|
|
168
|
-
var tr = _ref2.tr;
|
|
169
|
-
var nodeSize = (_tr$doc$nodeAt = tr.doc.nodeAt(start)) === null || _tr$doc$nodeAt === void 0 ? void 0 : _tr$doc$nodeAt.nodeSize;
|
|
170
|
-
if (nodeSize === undefined) {
|
|
171
|
-
return tr;
|
|
172
|
-
}
|
|
173
|
-
var position = start + nodeSize;
|
|
174
|
-
tr.insert(position, tr.doc.type.schema.nodes.paragraph.create());
|
|
175
|
-
return tr.setSelection(_state.TextSelection.create(tr.doc, position));
|
|
176
|
-
});
|
|
177
|
-
}
|
|
178
|
-
api === null || api === void 0 || (_api$quickInsert = api.quickInsert) === null || _api$quickInsert === void 0 || _api$quickInsert.actions.openTypeAhead('blockControl');
|
|
179
|
-
}
|
|
182
|
+
onClick: handleQuickInsert
|
|
180
183
|
}, /*#__PURE__*/_react.default.createElement(_add.default, {
|
|
181
184
|
label: "add"
|
|
182
185
|
}))))
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.isSelectionInNode = exports.isNonEditableBlock = exports.isNestedNodeSelected = void 0;
|
|
7
|
+
var _state = require("@atlaskit/editor-prosemirror/state");
|
|
8
|
+
var isNestedNodeSelected = exports.isNestedNodeSelected = function isNestedNodeSelected(view) {
|
|
9
|
+
var selection = view.state.selection;
|
|
10
|
+
return selection instanceof _state.NodeSelection && selection.$from.depth > 1;
|
|
11
|
+
};
|
|
12
|
+
var isSelectionInNode = exports.isSelectionInNode = function isSelectionInNode(start, view) {
|
|
13
|
+
var node = view.state.doc.nodeAt(start);
|
|
14
|
+
if (node === null) {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
var endPos = start + node.nodeSize;
|
|
18
|
+
var startPos = start;
|
|
19
|
+
var _view$state$selection = view.state.selection,
|
|
20
|
+
$from = _view$state$selection.$from,
|
|
21
|
+
$to = _view$state$selection.$to;
|
|
22
|
+
return $from.pos >= startPos && endPos >= $to.pos;
|
|
23
|
+
};
|
|
24
|
+
var isNonEditableBlock = exports.isNonEditableBlock = function isNonEditableBlock(start, view) {
|
|
25
|
+
var node = view.state.doc.nodeAt(start);
|
|
26
|
+
if (node === null) {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// We want to treat some elements as if they are non-editable blocks for
|
|
31
|
+
// the purposes of quick insert.
|
|
32
|
+
switch (node.type.name) {
|
|
33
|
+
// mediaSingle and mediaGroup always contain a media child node, which is
|
|
34
|
+
// both a block and an atom. mediaSingle can also have a caption child node
|
|
35
|
+
// which is an editable block.
|
|
36
|
+
case 'mediaGroup':
|
|
37
|
+
case 'mediaSingle':
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
return node.isBlock && (node.isAtom || node.isLeaf);
|
|
41
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.createNewLine = void 0;
|
|
7
|
+
var _state = require("@atlaskit/editor-prosemirror/state");
|
|
8
|
+
var createNewLine = exports.createNewLine = function createNewLine(start) {
|
|
9
|
+
return function (_ref) {
|
|
10
|
+
var _tr$doc$nodeAt;
|
|
11
|
+
var tr = _ref.tr;
|
|
12
|
+
var nodeSize = (_tr$doc$nodeAt = tr.doc.nodeAt(start)) === null || _tr$doc$nodeAt === void 0 ? void 0 : _tr$doc$nodeAt.nodeSize;
|
|
13
|
+
if (nodeSize === undefined) {
|
|
14
|
+
return tr;
|
|
15
|
+
}
|
|
16
|
+
var position = start + nodeSize;
|
|
17
|
+
tr.insert(position, tr.doc.type.schema.nodes.paragraph.create());
|
|
18
|
+
return tr.setSelection(_state.TextSelection.create(tr.doc, position));
|
|
19
|
+
};
|
|
20
|
+
};
|
|
@@ -10,6 +10,8 @@ import Tooltip from '@atlaskit/tooltip';
|
|
|
10
10
|
import { getTopPosition } from '../pm-plugins/utils/drag-handle-positions';
|
|
11
11
|
import { getLeftPositionForRootElement } from '../pm-plugins/utils/widget-positions';
|
|
12
12
|
import { QUICK_INSERT_DIMENSIONS, rootElementGap, topPositionAdjustment } from './consts';
|
|
13
|
+
import { isNestedNodeSelected, isNonEditableBlock, isSelectionInNode } from './utils/document-checks';
|
|
14
|
+
import { createNewLine } from './utils/editor-commands';
|
|
13
15
|
const buttonStyles = xcss({
|
|
14
16
|
boxSizing: 'border-box',
|
|
15
17
|
display: 'flex',
|
|
@@ -41,19 +43,6 @@ const containerStaticStyles = xcss({
|
|
|
41
43
|
|
|
42
44
|
// TODO: ED-26959 - Share prop types between DragHandle - generic enough to create a type for block control decoration
|
|
43
45
|
|
|
44
|
-
const isSelectionInNode = (start, view) => {
|
|
45
|
-
const node = view.state.doc.nodeAt(start);
|
|
46
|
-
if (node === null) {
|
|
47
|
-
return false;
|
|
48
|
-
}
|
|
49
|
-
const endPos = start + node.nodeSize;
|
|
50
|
-
const startPos = start;
|
|
51
|
-
const {
|
|
52
|
-
$from,
|
|
53
|
-
$to
|
|
54
|
-
} = view.state.selection;
|
|
55
|
-
return $from.pos >= startPos && endPos >= $to.pos;
|
|
56
|
-
};
|
|
57
46
|
export const TypeAheadControl = ({
|
|
58
47
|
view,
|
|
59
48
|
api,
|
|
@@ -131,6 +120,39 @@ export const TypeAheadControl = ({
|
|
|
131
120
|
(_cleanUpTransitionLis = cleanUpTransitionListener) === null || _cleanUpTransitionLis === void 0 ? void 0 : _cleanUpTransitionLis();
|
|
132
121
|
};
|
|
133
122
|
}, [calculatePosition, view.dom, rootAnchorName, rootNodeType]);
|
|
123
|
+
const handleQuickInsert = useCallback(() => {
|
|
124
|
+
var _api$quickInsert;
|
|
125
|
+
// if the selection is not within the node this decoration is rendered at
|
|
126
|
+
// then insert a newline and trigger quick insert
|
|
127
|
+
const start = getPos();
|
|
128
|
+
if (start !== undefined) {
|
|
129
|
+
// if the selection is not within the node this decoration is rendered at
|
|
130
|
+
// or the node is non-editable, then insert a newline and trigger quick insert
|
|
131
|
+
if (!isSelectionInNode(start, view) || isNonEditableBlock(start, view)) {
|
|
132
|
+
api.core.actions.execute(createNewLine(start));
|
|
133
|
+
}
|
|
134
|
+
if (isSelectionInNode(start, view) && isNestedNodeSelected(view)) {
|
|
135
|
+
// if the nested selected node is non-editable, then insert a newline below the selected node
|
|
136
|
+
if (isNonEditableBlock(view.state.selection.from, view)) {
|
|
137
|
+
api.core.actions.execute(createNewLine(view.state.selection.from));
|
|
138
|
+
} else {
|
|
139
|
+
// otherwise need to force the selection to be at the start of the node, because
|
|
140
|
+
// prosemirror is keeping it as NodeSelection for nested nodes. Do this to keep it
|
|
141
|
+
// consistent NodeSelection for root level nodes.
|
|
142
|
+
api.core.actions.execute(({
|
|
143
|
+
tr
|
|
144
|
+
}) => {
|
|
145
|
+
createNewLine(view.state.selection.from)({
|
|
146
|
+
tr
|
|
147
|
+
});
|
|
148
|
+
tr.setSelection(TextSelection.create(tr.doc, view.state.selection.from));
|
|
149
|
+
return tr;
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
api === null || api === void 0 ? void 0 : (_api$quickInsert = api.quickInsert) === null || _api$quickInsert === void 0 ? void 0 : _api$quickInsert.actions.openTypeAhead('blockControl');
|
|
155
|
+
}, [api, getPos, view]);
|
|
134
156
|
return (
|
|
135
157
|
/*#__PURE__*/
|
|
136
158
|
// eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop
|
|
@@ -145,27 +167,7 @@ export const TypeAheadControl = ({
|
|
|
145
167
|
type: "button",
|
|
146
168
|
"aria-label": formatMessage(messages.insert),
|
|
147
169
|
xcss: [buttonStyles],
|
|
148
|
-
onClick:
|
|
149
|
-
var _api$quickInsert;
|
|
150
|
-
// if the selection is not within the node this decoration is rendered at
|
|
151
|
-
// then insert a newline and trigger quick insert
|
|
152
|
-
const start = getPos();
|
|
153
|
-
if (start !== undefined && !isSelectionInNode(start, view)) {
|
|
154
|
-
api.core.actions.execute(({
|
|
155
|
-
tr
|
|
156
|
-
}) => {
|
|
157
|
-
var _tr$doc$nodeAt;
|
|
158
|
-
const nodeSize = (_tr$doc$nodeAt = tr.doc.nodeAt(start)) === null || _tr$doc$nodeAt === void 0 ? void 0 : _tr$doc$nodeAt.nodeSize;
|
|
159
|
-
if (nodeSize === undefined) {
|
|
160
|
-
return tr;
|
|
161
|
-
}
|
|
162
|
-
const position = start + nodeSize;
|
|
163
|
-
tr.insert(position, tr.doc.type.schema.nodes.paragraph.create());
|
|
164
|
-
return tr.setSelection(TextSelection.create(tr.doc, position));
|
|
165
|
-
});
|
|
166
|
-
}
|
|
167
|
-
api === null || api === void 0 ? void 0 : (_api$quickInsert = api.quickInsert) === null || _api$quickInsert === void 0 ? void 0 : _api$quickInsert.actions.openTypeAhead('blockControl');
|
|
168
|
-
}
|
|
170
|
+
onClick: handleQuickInsert
|
|
169
171
|
}, /*#__PURE__*/React.createElement(AddIcon, {
|
|
170
172
|
label: "add"
|
|
171
173
|
}))))
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { NodeSelection } from '@atlaskit/editor-prosemirror/state';
|
|
2
|
+
export const isNestedNodeSelected = view => {
|
|
3
|
+
const selection = view.state.selection;
|
|
4
|
+
return selection instanceof NodeSelection && selection.$from.depth > 1;
|
|
5
|
+
};
|
|
6
|
+
export const isSelectionInNode = (start, view) => {
|
|
7
|
+
const node = view.state.doc.nodeAt(start);
|
|
8
|
+
if (node === null) {
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
const endPos = start + node.nodeSize;
|
|
12
|
+
const startPos = start;
|
|
13
|
+
const {
|
|
14
|
+
$from,
|
|
15
|
+
$to
|
|
16
|
+
} = view.state.selection;
|
|
17
|
+
return $from.pos >= startPos && endPos >= $to.pos;
|
|
18
|
+
};
|
|
19
|
+
export const isNonEditableBlock = (start, view) => {
|
|
20
|
+
const node = view.state.doc.nodeAt(start);
|
|
21
|
+
if (node === null) {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// We want to treat some elements as if they are non-editable blocks for
|
|
26
|
+
// the purposes of quick insert.
|
|
27
|
+
switch (node.type.name) {
|
|
28
|
+
// mediaSingle and mediaGroup always contain a media child node, which is
|
|
29
|
+
// both a block and an atom. mediaSingle can also have a caption child node
|
|
30
|
+
// which is an editable block.
|
|
31
|
+
case 'mediaGroup':
|
|
32
|
+
case 'mediaSingle':
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
return node.isBlock && (node.isAtom || node.isLeaf);
|
|
36
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { TextSelection } from '@atlaskit/editor-prosemirror/state';
|
|
2
|
+
export const createNewLine = start => ({
|
|
3
|
+
tr
|
|
4
|
+
}) => {
|
|
5
|
+
var _tr$doc$nodeAt;
|
|
6
|
+
const nodeSize = (_tr$doc$nodeAt = tr.doc.nodeAt(start)) === null || _tr$doc$nodeAt === void 0 ? void 0 : _tr$doc$nodeAt.nodeSize;
|
|
7
|
+
if (nodeSize === undefined) {
|
|
8
|
+
return tr;
|
|
9
|
+
}
|
|
10
|
+
const position = start + nodeSize;
|
|
11
|
+
tr.insert(position, tr.doc.type.schema.nodes.paragraph.create());
|
|
12
|
+
return tr.setSelection(TextSelection.create(tr.doc, position));
|
|
13
|
+
};
|
|
@@ -11,6 +11,8 @@ import Tooltip from '@atlaskit/tooltip';
|
|
|
11
11
|
import { getTopPosition } from '../pm-plugins/utils/drag-handle-positions';
|
|
12
12
|
import { getLeftPositionForRootElement } from '../pm-plugins/utils/widget-positions';
|
|
13
13
|
import { QUICK_INSERT_DIMENSIONS, rootElementGap, topPositionAdjustment } from './consts';
|
|
14
|
+
import { isNestedNodeSelected, isNonEditableBlock, isSelectionInNode } from './utils/document-checks';
|
|
15
|
+
import { createNewLine } from './utils/editor-commands';
|
|
14
16
|
var buttonStyles = xcss({
|
|
15
17
|
boxSizing: 'border-box',
|
|
16
18
|
display: 'flex',
|
|
@@ -42,18 +44,6 @@ var containerStaticStyles = xcss({
|
|
|
42
44
|
|
|
43
45
|
// TODO: ED-26959 - Share prop types between DragHandle - generic enough to create a type for block control decoration
|
|
44
46
|
|
|
45
|
-
var isSelectionInNode = function isSelectionInNode(start, view) {
|
|
46
|
-
var node = view.state.doc.nodeAt(start);
|
|
47
|
-
if (node === null) {
|
|
48
|
-
return false;
|
|
49
|
-
}
|
|
50
|
-
var endPos = start + node.nodeSize;
|
|
51
|
-
var startPos = start;
|
|
52
|
-
var _view$state$selection = view.state.selection,
|
|
53
|
-
$from = _view$state$selection.$from,
|
|
54
|
-
$to = _view$state$selection.$to;
|
|
55
|
-
return $from.pos >= startPos && endPos >= $to.pos;
|
|
56
|
-
};
|
|
57
47
|
export var TypeAheadControl = function TypeAheadControl(_ref) {
|
|
58
48
|
var view = _ref.view,
|
|
59
49
|
api = _ref.api,
|
|
@@ -133,6 +123,38 @@ export var TypeAheadControl = function TypeAheadControl(_ref) {
|
|
|
133
123
|
(_cleanUpTransitionLis = cleanUpTransitionListener) === null || _cleanUpTransitionLis === void 0 || _cleanUpTransitionLis();
|
|
134
124
|
};
|
|
135
125
|
}, [calculatePosition, view.dom, rootAnchorName, rootNodeType]);
|
|
126
|
+
var handleQuickInsert = useCallback(function () {
|
|
127
|
+
var _api$quickInsert;
|
|
128
|
+
// if the selection is not within the node this decoration is rendered at
|
|
129
|
+
// then insert a newline and trigger quick insert
|
|
130
|
+
var start = getPos();
|
|
131
|
+
if (start !== undefined) {
|
|
132
|
+
// if the selection is not within the node this decoration is rendered at
|
|
133
|
+
// or the node is non-editable, then insert a newline and trigger quick insert
|
|
134
|
+
if (!isSelectionInNode(start, view) || isNonEditableBlock(start, view)) {
|
|
135
|
+
api.core.actions.execute(createNewLine(start));
|
|
136
|
+
}
|
|
137
|
+
if (isSelectionInNode(start, view) && isNestedNodeSelected(view)) {
|
|
138
|
+
// if the nested selected node is non-editable, then insert a newline below the selected node
|
|
139
|
+
if (isNonEditableBlock(view.state.selection.from, view)) {
|
|
140
|
+
api.core.actions.execute(createNewLine(view.state.selection.from));
|
|
141
|
+
} else {
|
|
142
|
+
// otherwise need to force the selection to be at the start of the node, because
|
|
143
|
+
// prosemirror is keeping it as NodeSelection for nested nodes. Do this to keep it
|
|
144
|
+
// consistent NodeSelection for root level nodes.
|
|
145
|
+
api.core.actions.execute(function (_ref2) {
|
|
146
|
+
var tr = _ref2.tr;
|
|
147
|
+
createNewLine(view.state.selection.from)({
|
|
148
|
+
tr: tr
|
|
149
|
+
});
|
|
150
|
+
tr.setSelection(TextSelection.create(tr.doc, view.state.selection.from));
|
|
151
|
+
return tr;
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
api === null || api === void 0 || (_api$quickInsert = api.quickInsert) === null || _api$quickInsert === void 0 || _api$quickInsert.actions.openTypeAhead('blockControl');
|
|
157
|
+
}, [api, getPos, view]);
|
|
136
158
|
return (
|
|
137
159
|
/*#__PURE__*/
|
|
138
160
|
// eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop
|
|
@@ -147,26 +169,7 @@ export var TypeAheadControl = function TypeAheadControl(_ref) {
|
|
|
147
169
|
type: "button",
|
|
148
170
|
"aria-label": formatMessage(messages.insert),
|
|
149
171
|
xcss: [buttonStyles],
|
|
150
|
-
onClick:
|
|
151
|
-
var _api$quickInsert;
|
|
152
|
-
// if the selection is not within the node this decoration is rendered at
|
|
153
|
-
// then insert a newline and trigger quick insert
|
|
154
|
-
var start = getPos();
|
|
155
|
-
if (start !== undefined && !isSelectionInNode(start, view)) {
|
|
156
|
-
api.core.actions.execute(function (_ref2) {
|
|
157
|
-
var _tr$doc$nodeAt;
|
|
158
|
-
var tr = _ref2.tr;
|
|
159
|
-
var nodeSize = (_tr$doc$nodeAt = tr.doc.nodeAt(start)) === null || _tr$doc$nodeAt === void 0 ? void 0 : _tr$doc$nodeAt.nodeSize;
|
|
160
|
-
if (nodeSize === undefined) {
|
|
161
|
-
return tr;
|
|
162
|
-
}
|
|
163
|
-
var position = start + nodeSize;
|
|
164
|
-
tr.insert(position, tr.doc.type.schema.nodes.paragraph.create());
|
|
165
|
-
return tr.setSelection(TextSelection.create(tr.doc, position));
|
|
166
|
-
});
|
|
167
|
-
}
|
|
168
|
-
api === null || api === void 0 || (_api$quickInsert = api.quickInsert) === null || _api$quickInsert === void 0 || _api$quickInsert.actions.openTypeAhead('blockControl');
|
|
169
|
-
}
|
|
172
|
+
onClick: handleQuickInsert
|
|
170
173
|
}, /*#__PURE__*/React.createElement(AddIcon, {
|
|
171
174
|
label: "add"
|
|
172
175
|
}))))
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { NodeSelection } from '@atlaskit/editor-prosemirror/state';
|
|
2
|
+
export var isNestedNodeSelected = function isNestedNodeSelected(view) {
|
|
3
|
+
var selection = view.state.selection;
|
|
4
|
+
return selection instanceof NodeSelection && selection.$from.depth > 1;
|
|
5
|
+
};
|
|
6
|
+
export var isSelectionInNode = function isSelectionInNode(start, view) {
|
|
7
|
+
var node = view.state.doc.nodeAt(start);
|
|
8
|
+
if (node === null) {
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
var endPos = start + node.nodeSize;
|
|
12
|
+
var startPos = start;
|
|
13
|
+
var _view$state$selection = view.state.selection,
|
|
14
|
+
$from = _view$state$selection.$from,
|
|
15
|
+
$to = _view$state$selection.$to;
|
|
16
|
+
return $from.pos >= startPos && endPos >= $to.pos;
|
|
17
|
+
};
|
|
18
|
+
export var isNonEditableBlock = function isNonEditableBlock(start, view) {
|
|
19
|
+
var node = view.state.doc.nodeAt(start);
|
|
20
|
+
if (node === null) {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// We want to treat some elements as if they are non-editable blocks for
|
|
25
|
+
// the purposes of quick insert.
|
|
26
|
+
switch (node.type.name) {
|
|
27
|
+
// mediaSingle and mediaGroup always contain a media child node, which is
|
|
28
|
+
// both a block and an atom. mediaSingle can also have a caption child node
|
|
29
|
+
// which is an editable block.
|
|
30
|
+
case 'mediaGroup':
|
|
31
|
+
case 'mediaSingle':
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
return node.isBlock && (node.isAtom || node.isLeaf);
|
|
35
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { TextSelection } from '@atlaskit/editor-prosemirror/state';
|
|
2
|
+
export var createNewLine = function createNewLine(start) {
|
|
3
|
+
return function (_ref) {
|
|
4
|
+
var _tr$doc$nodeAt;
|
|
5
|
+
var tr = _ref.tr;
|
|
6
|
+
var nodeSize = (_tr$doc$nodeAt = tr.doc.nodeAt(start)) === null || _tr$doc$nodeAt === void 0 ? void 0 : _tr$doc$nodeAt.nodeSize;
|
|
7
|
+
if (nodeSize === undefined) {
|
|
8
|
+
return tr;
|
|
9
|
+
}
|
|
10
|
+
var position = start + nodeSize;
|
|
11
|
+
tr.insert(position, tr.doc.type.schema.nodes.paragraph.create());
|
|
12
|
+
return tr.setSelection(TextSelection.create(tr.doc, position));
|
|
13
|
+
};
|
|
14
|
+
};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { EditorView } from '@atlaskit/editor-prosemirror/view';
|
|
2
|
+
export declare const isNestedNodeSelected: (view: EditorView) => boolean;
|
|
3
|
+
export declare const isSelectionInNode: (start: number, view: EditorView) => boolean;
|
|
4
|
+
export declare const isNonEditableBlock: (start: number, view: EditorView) => boolean;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { EditorView } from '@atlaskit/editor-prosemirror/view';
|
|
2
|
+
export declare const isNestedNodeSelected: (view: EditorView) => boolean;
|
|
3
|
+
export declare const isSelectionInNode: (start: number, view: EditorView) => boolean;
|
|
4
|
+
export declare const isNonEditableBlock: (start: number, view: EditorView) => boolean;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-block-controls",
|
|
3
|
-
"version": "3.3.
|
|
3
|
+
"version": "3.3.8",
|
|
4
4
|
"description": "Block controls plugin for @atlaskit/editor-core",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"@atlaskit/primitives": "^14.1.0",
|
|
54
54
|
"@atlaskit/theme": "^18.0.0",
|
|
55
55
|
"@atlaskit/tmp-editor-statsig": "^3.5.0",
|
|
56
|
-
"@atlaskit/tokens": "^4.
|
|
56
|
+
"@atlaskit/tokens": "^4.4.0",
|
|
57
57
|
"@atlaskit/tooltip": "^20.0.0",
|
|
58
58
|
"@babel/runtime": "^7.0.0",
|
|
59
59
|
"@emotion/react": "^11.7.1",
|