@atlaskit/editor-plugin-block-type 4.0.10 → 4.0.12
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 +18 -0
- package/dist/cjs/blockTypePlugin.js +9 -11
- package/dist/cjs/pm-plugins/block-types.js +9 -2
- package/dist/cjs/pm-plugins/commands/block-type.js +63 -15
- package/dist/cjs/pm-plugins/commands/wrapSelectionIn.js +61 -0
- package/dist/cjs/pm-plugins/keymap.js +6 -4
- package/dist/cjs/pm-plugins/main.js +15 -7
- package/dist/cjs/pm-plugins/ui/FloatingToolbarComponent.js +5 -0
- package/dist/cjs/pm-plugins/ui/PrimaryToolbarComponent.js +7 -2
- package/dist/cjs/pm-plugins/ui/ToolbarBlockType/index.js +22 -19
- package/dist/cjs/pm-plugins/ui/ToolbarBlockType/styled.js +1 -1
- package/dist/cjs/pm-plugins/utils.js +17 -1
- package/dist/es2019/blockTypePlugin.js +11 -9
- package/dist/es2019/index.js +3 -0
- package/dist/es2019/pm-plugins/block-types.js +8 -1
- package/dist/es2019/pm-plugins/commands/block-type.js +61 -13
- package/dist/es2019/pm-plugins/commands/wrapSelectionIn.js +54 -0
- package/dist/es2019/pm-plugins/keymap.js +3 -1
- package/dist/es2019/pm-plugins/main.js +12 -6
- package/dist/es2019/pm-plugins/ui/FloatingToolbarComponent.js +5 -0
- package/dist/es2019/pm-plugins/ui/PrimaryToolbarComponent.js +7 -2
- package/dist/es2019/pm-plugins/ui/ToolbarBlockType/index.js +12 -6
- package/dist/es2019/pm-plugins/ui/ToolbarBlockType/styled.js +2 -2
- package/dist/es2019/pm-plugins/utils.js +15 -1
- package/dist/es2019/ui/consts.js +3 -0
- package/dist/esm/blockTypePlugin.js +11 -8
- package/dist/esm/index.js +3 -0
- package/dist/esm/pm-plugins/block-types.js +8 -1
- package/dist/esm/pm-plugins/commands/block-type.js +62 -15
- package/dist/esm/pm-plugins/commands/wrapSelectionIn.js +55 -0
- package/dist/esm/pm-plugins/keymap.js +3 -1
- package/dist/esm/pm-plugins/main.js +14 -6
- package/dist/esm/pm-plugins/ui/FloatingToolbarComponent.js +5 -0
- package/dist/esm/pm-plugins/ui/PrimaryToolbarComponent.js +7 -2
- package/dist/esm/pm-plugins/ui/ToolbarBlockType/index.js +22 -19
- package/dist/esm/pm-plugins/ui/ToolbarBlockType/styled.js +2 -2
- package/dist/esm/pm-plugins/utils.js +17 -1
- package/dist/esm/ui/consts.js +3 -0
- package/dist/types/blockTypePlugin.d.ts +0 -2
- package/dist/types/blockTypePluginType.d.ts +2 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/pm-plugins/block-types.d.ts +1 -0
- package/dist/types/pm-plugins/commands/block-type.d.ts +6 -5
- package/dist/types/pm-plugins/commands/wrapSelectionIn.d.ts +3 -0
- package/dist/types/pm-plugins/main.d.ts +3 -1
- package/dist/types/pm-plugins/types.d.ts +1 -0
- package/dist/types/pm-plugins/ui/ToolbarBlockType/index.d.ts +2 -1
- package/dist/types-ts4.5/blockTypePlugin.d.ts +0 -2
- package/dist/types-ts4.5/blockTypePluginType.d.ts +2 -1
- package/dist/types-ts4.5/index.d.ts +1 -1
- package/dist/types-ts4.5/pm-plugins/block-types.d.ts +1 -0
- package/dist/types-ts4.5/pm-plugins/commands/block-type.d.ts +6 -5
- package/dist/types-ts4.5/pm-plugins/commands/wrapSelectionIn.d.ts +3 -0
- package/dist/types-ts4.5/pm-plugins/main.d.ts +3 -1
- package/dist/types-ts4.5/pm-plugins/types.d.ts +1 -0
- package/dist/types-ts4.5/pm-plugins/ui/ToolbarBlockType/index.d.ts +2 -1
- package/package.json +6 -6
- package/dist/cjs/pm-plugins/commands/index.js +0 -62
- package/dist/es2019/pm-plugins/commands/index.js +0 -3
- package/dist/esm/pm-plugins/commands/index.js +0 -3
- package/dist/types/pm-plugins/commands/index.d.ts +0 -4
- package/dist/types-ts4.5/pm-plugins/commands/index.d.ts +0 -4
@@ -4,8 +4,10 @@ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length)
|
|
4
4
|
import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
|
5
5
|
import { withAnalytics } from '@atlaskit/editor-common/editor-analytics';
|
6
6
|
import { filterChildrenBetween, wrapSelectionIn } from '@atlaskit/editor-common/utils';
|
7
|
+
import { Slice, Fragment } from '@atlaskit/editor-prosemirror/model';
|
7
8
|
import { CellSelection } from '@atlaskit/editor-tables';
|
8
9
|
import { HEADINGS_BY_NAME, NORMAL_TEXT } from '../block-types';
|
10
|
+
import { wrapSelectionInBlockType } from './wrapSelectionIn';
|
9
11
|
export function setBlockType(name) {
|
10
12
|
return function (_ref) {
|
11
13
|
var tr = _ref.tr;
|
@@ -24,7 +26,7 @@ export function setBlockType(name) {
|
|
24
26
|
return null;
|
25
27
|
};
|
26
28
|
}
|
27
|
-
export function setHeading(level) {
|
29
|
+
export function setHeading(level, fromBlockQuote) {
|
28
30
|
return function (_ref2) {
|
29
31
|
var tr = _ref2.tr;
|
30
32
|
var selection = tr.selection,
|
@@ -33,32 +35,45 @@ export function setHeading(level) {
|
|
33
35
|
ranges.forEach(function (_ref3) {
|
34
36
|
var $from = _ref3.$from,
|
35
37
|
$to = _ref3.$to;
|
36
|
-
|
37
|
-
|
38
|
-
|
38
|
+
if (fromBlockQuote) {
|
39
|
+
var range = $from.blockRange($to);
|
40
|
+
if (!range) {
|
41
|
+
return;
|
42
|
+
}
|
43
|
+
var content = $from.node().content;
|
44
|
+
var headingNode = schema.nodes.heading.createChecked({
|
45
|
+
level: level
|
46
|
+
}, content);
|
47
|
+
var slice = new Slice(Fragment.from(headingNode), 0, 0);
|
48
|
+
tr.replaceRange(range.start, range.end, slice);
|
49
|
+
} else {
|
50
|
+
tr.setBlockType($from.pos, $to.pos, schema.nodes.heading, {
|
51
|
+
level: level
|
52
|
+
});
|
53
|
+
}
|
39
54
|
});
|
40
55
|
return tr;
|
41
56
|
};
|
42
57
|
}
|
43
|
-
export function setBlockTypeWithAnalytics(name, inputMethod, editorAnalyticsApi) {
|
58
|
+
export function setBlockTypeWithAnalytics(name, inputMethod, editorAnalyticsApi, fromBlockQuote) {
|
44
59
|
return function (_ref4) {
|
45
60
|
var tr = _ref4.tr;
|
46
61
|
var nodes = tr.doc.type.schema.nodes;
|
47
62
|
if (name === 'normal' && nodes.paragraph) {
|
48
|
-
return setNormalTextWithAnalytics(inputMethod, editorAnalyticsApi)({
|
63
|
+
return setNormalTextWithAnalytics(inputMethod, editorAnalyticsApi, fromBlockQuote)({
|
49
64
|
tr: tr
|
50
65
|
});
|
51
66
|
}
|
52
67
|
var headingBlockType = HEADINGS_BY_NAME[name];
|
53
68
|
if (headingBlockType && nodes.heading && headingBlockType.level) {
|
54
|
-
return setHeadingWithAnalytics(headingBlockType.level, inputMethod, editorAnalyticsApi)({
|
69
|
+
return setHeadingWithAnalytics(headingBlockType.level, inputMethod, editorAnalyticsApi, fromBlockQuote)({
|
55
70
|
tr: tr
|
56
71
|
});
|
57
72
|
}
|
58
73
|
return null;
|
59
74
|
};
|
60
75
|
}
|
61
|
-
export function setNormalText() {
|
76
|
+
export function setNormalText(fromBlockQuote) {
|
62
77
|
return function (_ref5) {
|
63
78
|
var tr = _ref5.tr;
|
64
79
|
var selection = tr.selection,
|
@@ -67,7 +82,15 @@ export function setNormalText() {
|
|
67
82
|
ranges.forEach(function (_ref6) {
|
68
83
|
var $from = _ref6.$from,
|
69
84
|
$to = _ref6.$to;
|
70
|
-
|
85
|
+
if (fromBlockQuote) {
|
86
|
+
var range = $from.blockRange($to);
|
87
|
+
if (!range) {
|
88
|
+
return;
|
89
|
+
}
|
90
|
+
tr.lift(range, 0);
|
91
|
+
} else {
|
92
|
+
tr.setBlockType($from.pos, $to.pos, schema.nodes.paragraph);
|
93
|
+
}
|
71
94
|
});
|
72
95
|
return tr;
|
73
96
|
};
|
@@ -109,7 +132,7 @@ function withCurrentHeadingLevel(fn) {
|
|
109
132
|
});
|
110
133
|
};
|
111
134
|
}
|
112
|
-
export function setNormalTextWithAnalytics(inputMethod, editorAnalyticsApi) {
|
135
|
+
export function setNormalTextWithAnalytics(inputMethod, editorAnalyticsApi, fromBlockQuote) {
|
113
136
|
return withCurrentHeadingLevel(function (previousHeadingLevel) {
|
114
137
|
return function (_ref8) {
|
115
138
|
var tr = _ref8.tr;
|
@@ -124,13 +147,13 @@ export function setNormalTextWithAnalytics(inputMethod, editorAnalyticsApi) {
|
|
124
147
|
previousHeadingLevel: previousHeadingLevel
|
125
148
|
}
|
126
149
|
})(tr);
|
127
|
-
return setNormalText()({
|
150
|
+
return setNormalText(fromBlockQuote)({
|
128
151
|
tr: tr
|
129
152
|
});
|
130
153
|
};
|
131
154
|
});
|
132
155
|
}
|
133
|
-
export var setHeadingWithAnalytics = function setHeadingWithAnalytics(newHeadingLevel, inputMethod, editorAnalyticsApi) {
|
156
|
+
export var setHeadingWithAnalytics = function setHeadingWithAnalytics(newHeadingLevel, inputMethod, editorAnalyticsApi, fromBlockQuote) {
|
134
157
|
return withCurrentHeadingLevel(function (previousHeadingLevel) {
|
135
158
|
return function (_ref9) {
|
136
159
|
var tr = _ref9.tr;
|
@@ -145,7 +168,7 @@ export var setHeadingWithAnalytics = function setHeadingWithAnalytics(newHeading
|
|
145
168
|
previousHeadingLevel: previousHeadingLevel
|
146
169
|
}
|
147
170
|
})(tr);
|
148
|
-
return setHeading(newHeadingLevel)({
|
171
|
+
return setHeading(newHeadingLevel, fromBlockQuote)({
|
149
172
|
tr: tr
|
150
173
|
});
|
151
174
|
};
|
@@ -180,9 +203,33 @@ export var insertBlockQuoteWithAnalytics = function insertBlockQuoteWithAnalytic
|
|
180
203
|
}
|
181
204
|
})(insertBlockQuote());
|
182
205
|
};
|
206
|
+
export function insertBlockQuoteWithAnalyticsCommand(inputMethod, editorAnalyticsApi) {
|
207
|
+
return withCurrentHeadingLevel(function (previousHeadingLevel) {
|
208
|
+
return function (_ref10) {
|
209
|
+
var tr = _ref10.tr;
|
210
|
+
var nodes = tr.doc.type.schema.nodes;
|
211
|
+
|
212
|
+
// TODO: analytics event
|
213
|
+
|
214
|
+
// editorAnalyticsApi?.attachAnalyticsEvent({
|
215
|
+
// action: ACTION.FORMATTED,
|
216
|
+
// actionSubject: ACTION_SUBJECT.TEXT,
|
217
|
+
// eventType: EVENT_TYPE.TRACK,
|
218
|
+
// actionSubjectId: ACTION_SUBJECT_ID.FORMAT_BLOCK_QUOTE,
|
219
|
+
// attributes: {
|
220
|
+
// inputMethod: inputMethod,
|
221
|
+
// },
|
222
|
+
// })(tr);
|
223
|
+
|
224
|
+
return wrapSelectionInBlockType(nodes.blockquote)({
|
225
|
+
tr: tr
|
226
|
+
});
|
227
|
+
};
|
228
|
+
});
|
229
|
+
}
|
183
230
|
export var cleanUpAtTheStartOfDocument = function cleanUpAtTheStartOfDocument(state, dispatch) {
|
184
|
-
var
|
185
|
-
$cursor =
|
231
|
+
var _ref11 = state.selection,
|
232
|
+
$cursor = _ref11.$cursor;
|
186
233
|
if ($cursor && !$cursor.nodeBefore && !$cursor.nodeAfter && $cursor.pos === 1) {
|
187
234
|
var tr = state.tr,
|
188
235
|
schema = state.schema;
|
@@ -0,0 +1,55 @@
|
|
1
|
+
import { Slice, Fragment } from '@atlaskit/editor-prosemirror/model';
|
2
|
+
import { findWrapping } from '@atlaskit/editor-prosemirror/transform';
|
3
|
+
export function wrapSelectionInBlockType(nodeType) {
|
4
|
+
return function (_ref) {
|
5
|
+
var tr = _ref.tr;
|
6
|
+
var nodes = tr.doc.type.schema.nodes;
|
7
|
+
var _tr$doc$type$schema$m = tr.doc.type.schema.marks,
|
8
|
+
alignment = _tr$doc$type$schema$m.alignment,
|
9
|
+
indentation = _tr$doc$type$schema$m.indentation;
|
10
|
+
if (nodes.paragraph && nodes.blockquote) {
|
11
|
+
/**Remove alignment and indentation marks from the selection */
|
12
|
+
var marksToRemove = [alignment, indentation];
|
13
|
+
var hasMark = function hasMark(mark) {
|
14
|
+
return marksToRemove.indexOf(mark.type) > -1;
|
15
|
+
};
|
16
|
+
var not = function not(fn) {
|
17
|
+
return function (arg) {
|
18
|
+
return !fn(arg);
|
19
|
+
};
|
20
|
+
};
|
21
|
+
|
22
|
+
/**
|
23
|
+
* When you need to toggle the selection
|
24
|
+
* when another type which does not allow alignment is applied
|
25
|
+
*/
|
26
|
+
tr.doc.nodesBetween(tr.selection.from, tr.selection.to, function (node, pos) {
|
27
|
+
if (node.type === nodes.paragraph && node.marks.some(hasMark)) {
|
28
|
+
var resolvedPos = tr.doc.resolve(pos);
|
29
|
+
var withoutBlockMarks = node.marks.filter(not(hasMark));
|
30
|
+
tr = tr.setNodeMarkup(resolvedPos.pos, undefined, node.attrs, withoutBlockMarks);
|
31
|
+
}
|
32
|
+
});
|
33
|
+
|
34
|
+
/** Get range and wrapping needed for the selection */
|
35
|
+
var _tr$selection = tr.selection,
|
36
|
+
$from = _tr$selection.$from,
|
37
|
+
$to = _tr$selection.$to;
|
38
|
+
var range = $from.blockRange($to);
|
39
|
+
var wrapping = range && findWrapping(range, nodes.blockquote);
|
40
|
+
if (wrapping) {
|
41
|
+
/** Wrap the selection */
|
42
|
+
tr.wrap(range, wrapping).scrollIntoView();
|
43
|
+
} else {
|
44
|
+
/** If wrapping is not possible, replace with a blockquote */
|
45
|
+
var start = $from.start();
|
46
|
+
var end = $to.end();
|
47
|
+
var content = $from.node().content;
|
48
|
+
var blockquote = nodes.blockquote.create({}, nodes.paragraph.create({}, content));
|
49
|
+
var slice = new Slice(Fragment.from(blockquote), 0, 0);
|
50
|
+
tr.replaceRange(start, end, slice).scrollIntoView();
|
51
|
+
}
|
52
|
+
}
|
53
|
+
return tr;
|
54
|
+
};
|
55
|
+
}
|
@@ -4,7 +4,9 @@ import { createNewParagraphAbove, createNewParagraphBelow, deleteEmptyParagraphA
|
|
4
4
|
import { chainCommands } from '@atlaskit/editor-prosemirror/commands';
|
5
5
|
import { redo, undo } from '@atlaskit/editor-prosemirror/history';
|
6
6
|
import * as blockTypes from './block-types';
|
7
|
-
import { cleanUpAtTheStartOfDocument,
|
7
|
+
import { cleanUpAtTheStartOfDocument, insertBlockQuoteWithAnalytics } from './commands/block-type';
|
8
|
+
import { deleteAndMoveCursor } from './commands/delete-and-move-cursor';
|
9
|
+
import { deleteBlockContent } from './commands/delete-block-content';
|
8
10
|
import { isNodeAWrappingBlockNode } from './utils';
|
9
11
|
var backspaceCommand = chainCommands(cleanUpAtTheStartOfDocument, deleteBlockContent(isNodeAWrappingBlockNode), deleteAndMoveCursor);
|
10
12
|
var del = chainCommands(deleteEmptyParagraphAndMoveBlockUp(isNodeAWrappingBlockNode), deleteBlockContent(isNodeAWrappingBlockNode), deleteAndMoveCursor);
|
@@ -6,8 +6,8 @@ import { browser } from '@atlaskit/editor-common/browser';
|
|
6
6
|
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
7
7
|
import { PluginKey } from '@atlaskit/editor-prosemirror/state';
|
8
8
|
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
|
9
|
-
import { BLOCK_QUOTE, CODE_BLOCK, HEADING_1, HEADING_2, HEADING_3, HEADING_4, HEADING_5, HEADING_6, HEADINGS_BY_LEVEL, NORMAL_TEXT, OTHER, PANEL, TEXT_BLOCK_TYPES, WRAPPER_BLOCK_TYPES } from './block-types';
|
10
|
-
import { setHeadingWithAnalytics, setNormalTextWithAnalytics } from './commands';
|
9
|
+
import { BLOCK_QUOTE, CODE_BLOCK, HEADING_1, HEADING_2, HEADING_3, HEADING_4, HEADING_5, HEADING_6, HEADINGS_BY_LEVEL, NORMAL_TEXT, OTHER, PANEL, TEXT_BLOCK_TYPES, WRAPPER_BLOCK_TYPES, getBlockTypesInDropdown } from './block-types';
|
10
|
+
import { setHeadingWithAnalytics, setNormalTextWithAnalytics } from './commands/block-type';
|
11
11
|
import { HEADING_KEYS } from './consts';
|
12
12
|
import { areBlockTypesDisabled } from './utils';
|
13
13
|
var blockTypeForNode = function blockTypeForNode(node, schema) {
|
@@ -18,6 +18,8 @@ var blockTypeForNode = function blockTypeForNode(node, schema) {
|
|
18
18
|
}
|
19
19
|
} else if (node.type === schema.nodes.paragraph) {
|
20
20
|
return NORMAL_TEXT;
|
21
|
+
} else if (node.type === schema.nodes.blockquote) {
|
22
|
+
return BLOCK_QUOTE;
|
21
23
|
}
|
22
24
|
return OTHER;
|
23
25
|
};
|
@@ -60,6 +62,7 @@ var detectBlockType = function detectBlockType(availableBlockTypes, state) {
|
|
60
62
|
} else if (blockType !== OTHER && blockType !== nodeBlockType[0]) {
|
61
63
|
blockType = OTHER;
|
62
64
|
}
|
65
|
+
return false;
|
63
66
|
}
|
64
67
|
});
|
65
68
|
return blockType || OTHER;
|
@@ -71,7 +74,7 @@ var autoformatHeading = function autoformatHeading(headingLevel, editorAnalytics
|
|
71
74
|
return setHeadingWithAnalytics(headingLevel, INPUT_METHOD.FORMATTING, editorAnalyticsApi);
|
72
75
|
};
|
73
76
|
export var pluginKey = new PluginKey('blockTypePlugin');
|
74
|
-
export var createPlugin = function createPlugin(editorAPI, dispatch, lastNodeMustBeParagraph) {
|
77
|
+
export var createPlugin = function createPlugin(editorAPI, dispatch, lastNodeMustBeParagraph, includeBlockQuoteAsTextstyleOption) {
|
75
78
|
var _editorAPI$analytics;
|
76
79
|
var editorAnalyticsApi = editorAPI === null || editorAPI === void 0 || (_editorAPI$analytics = editorAPI.analytics) === null || _editorAPI$analytics === void 0 ? void 0 : _editorAPI$analytics.actions;
|
77
80
|
var altKeyLocation = 0;
|
@@ -94,16 +97,21 @@ export var createPlugin = function createPlugin(editorAPI, dispatch, lastNodeMus
|
|
94
97
|
var availableWrapperBlockTypes = WRAPPER_BLOCK_TYPES.filter(function (blockType) {
|
95
98
|
return isBlockTypeSchemaSupported(blockType, state);
|
96
99
|
});
|
100
|
+
var BLOCK_TYPES_IN_DROPDOWN = getBlockTypesInDropdown(includeBlockQuoteAsTextstyleOption);
|
101
|
+
var availableBlockTypesInDropdown = BLOCK_TYPES_IN_DROPDOWN.filter(function (blockType) {
|
102
|
+
return isBlockTypeSchemaSupported(blockType, state);
|
103
|
+
});
|
97
104
|
return {
|
98
|
-
currentBlockType: detectBlockType(
|
105
|
+
currentBlockType: detectBlockType(availableBlockTypesInDropdown, state),
|
99
106
|
blockTypesDisabled: areBlockTypesDisabled(state),
|
100
107
|
availableBlockTypes: availableBlockTypes,
|
101
|
-
availableWrapperBlockTypes: availableWrapperBlockTypes
|
108
|
+
availableWrapperBlockTypes: availableWrapperBlockTypes,
|
109
|
+
availableBlockTypesInDropdown: availableBlockTypesInDropdown
|
102
110
|
};
|
103
111
|
},
|
104
112
|
apply: function apply(_tr, oldPluginState, _oldState, newState) {
|
105
113
|
var newPluginState = _objectSpread(_objectSpread({}, oldPluginState), {}, {
|
106
|
-
currentBlockType: detectBlockType(oldPluginState.
|
114
|
+
currentBlockType: detectBlockType(oldPluginState.availableBlockTypesInDropdown, newState),
|
107
115
|
blockTypesDisabled: areBlockTypesDisabled(newState)
|
108
116
|
});
|
109
117
|
if (newPluginState.currentBlockType !== oldPluginState.currentBlockType || newPluginState.blockTypesDisabled !== oldPluginState.blockTypesDisabled) {
|
@@ -16,12 +16,17 @@ export function FloatingToolbarComponent(_ref) {
|
|
16
16
|
var _api$core, _api$blockType;
|
17
17
|
return api === null || api === void 0 || (_api$core = api.core) === null || _api$core === void 0 ? void 0 : _api$core.actions.execute(api === null || api === void 0 || (_api$blockType = api.blockType) === null || _api$blockType === void 0 || (_api$blockType = _api$blockType.commands) === null || _api$blockType === void 0 ? void 0 : _api$blockType.setTextLevel(name, INPUT_METHOD.FLOATING_TB));
|
18
18
|
}, [api]);
|
19
|
+
var wrapBlockQuote = useCallback(function () {
|
20
|
+
var _api$core2, _api$blockType2;
|
21
|
+
return api === null || api === void 0 || (_api$core2 = api.core) === null || _api$core2 === void 0 ? void 0 : _api$core2.actions.execute(api === null || api === void 0 || (_api$blockType2 = api.blockType) === null || _api$blockType2 === void 0 || (_api$blockType2 = _api$blockType2.commands) === null || _api$blockType2 === void 0 ? void 0 : _api$blockType2.insertBlockQuote(INPUT_METHOD.TOOLBAR));
|
22
|
+
}, [api]);
|
19
23
|
return /*#__PURE__*/React.createElement(ToolbarBlockType, {
|
20
24
|
isSmall: FloatingToolbarSettings.isSmall,
|
21
25
|
isDisabled: FloatingToolbarSettings.disabled,
|
22
26
|
isReducedSpacing: FloatingToolbarSettings.isToolbarReducedSpacing,
|
23
27
|
setTextLevel: boundSetBlockType,
|
24
28
|
pluginState: blockTypeState,
|
29
|
+
wrapBlockQuote: wrapBlockQuote,
|
25
30
|
shouldUseDefaultRole: FloatingToolbarSettings.shouldUseDefaultRole,
|
26
31
|
api: api
|
27
32
|
});
|
@@ -13,15 +13,20 @@ export function PrimaryToolbarComponent(_ref) {
|
|
13
13
|
shouldUseDefaultRole = _ref.shouldUseDefaultRole;
|
14
14
|
var _useSharedPluginState = useSharedPluginState(api, ['blockType']),
|
15
15
|
blockTypeState = _useSharedPluginState.blockTypeState;
|
16
|
-
var boundSetBlockType = function boundSetBlockType(name) {
|
16
|
+
var boundSetBlockType = function boundSetBlockType(name, fromBlockQuote) {
|
17
17
|
var _api$core, _api$blockType;
|
18
|
-
return api === null || api === void 0 || (_api$core = api.core) === null || _api$core === void 0 ? void 0 : _api$core.actions.execute(api === null || api === void 0 || (_api$blockType = api.blockType) === null || _api$blockType === void 0 || (_api$blockType = _api$blockType.commands) === null || _api$blockType === void 0 ? void 0 : _api$blockType.setTextLevel(name, INPUT_METHOD.TOOLBAR));
|
18
|
+
return api === null || api === void 0 || (_api$core = api.core) === null || _api$core === void 0 ? void 0 : _api$core.actions.execute(api === null || api === void 0 || (_api$blockType = api.blockType) === null || _api$blockType === void 0 || (_api$blockType = _api$blockType.commands) === null || _api$blockType === void 0 ? void 0 : _api$blockType.setTextLevel(name, INPUT_METHOD.TOOLBAR, fromBlockQuote));
|
19
|
+
};
|
20
|
+
var wrapBlockQuote = function wrapBlockQuote() {
|
21
|
+
var _api$core2, _api$blockType2;
|
22
|
+
return api === null || api === void 0 || (_api$core2 = api.core) === null || _api$core2 === void 0 ? void 0 : _api$core2.actions.execute(api === null || api === void 0 || (_api$blockType2 = api.blockType) === null || _api$blockType2 === void 0 || (_api$blockType2 = _api$blockType2.commands) === null || _api$blockType2 === void 0 ? void 0 : _api$blockType2.insertBlockQuote(INPUT_METHOD.TOOLBAR));
|
19
23
|
};
|
20
24
|
return /*#__PURE__*/React.createElement(ToolbarBlockType, {
|
21
25
|
isSmall: isSmall,
|
22
26
|
isDisabled: disabled,
|
23
27
|
isReducedSpacing: isToolbarReducedSpacing,
|
24
28
|
setTextLevel: boundSetBlockType,
|
29
|
+
wrapBlockQuote: wrapBlockQuote,
|
25
30
|
pluginState: blockTypeState,
|
26
31
|
popupsMountPoint: popupsMountPoint,
|
27
32
|
popupsBoundariesElement: popupsBoundariesElement,
|
@@ -1,13 +1,12 @@
|
|
1
1
|
import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
|
2
2
|
import _createClass from "@babel/runtime/helpers/createClass";
|
3
|
-
import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized";
|
4
|
-
import _inherits from "@babel/runtime/helpers/inherits";
|
5
3
|
import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn";
|
6
4
|
import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
|
5
|
+
import _inherits from "@babel/runtime/helpers/inherits";
|
7
6
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
8
7
|
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; }
|
9
8
|
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) { _defineProperty(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; }
|
10
|
-
function
|
9
|
+
function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
|
11
10
|
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
|
12
11
|
/**
|
13
12
|
* @jsxRuntime classic
|
@@ -27,35 +26,33 @@ import { BlockTypeButton } from './blocktype-button';
|
|
27
26
|
import { blockTypeMenuItemStyle, keyboardShortcut, keyboardShortcutSelect } from './styled';
|
28
27
|
// eslint-disable-next-line @repo/internal/react/no-class-components
|
29
28
|
var ToolbarBlockType = /*#__PURE__*/function (_React$PureComponent) {
|
30
|
-
_inherits(ToolbarBlockType, _React$PureComponent);
|
31
|
-
var _super = _createSuper(ToolbarBlockType);
|
32
29
|
function ToolbarBlockType() {
|
33
30
|
var _this;
|
34
31
|
_classCallCheck(this, ToolbarBlockType);
|
35
32
|
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
36
33
|
args[_key] = arguments[_key];
|
37
34
|
}
|
38
|
-
_this =
|
39
|
-
_defineProperty(
|
35
|
+
_this = _callSuper(this, ToolbarBlockType, [].concat(args));
|
36
|
+
_defineProperty(_this, "state", {
|
40
37
|
active: false,
|
41
38
|
isOpenedByKeyboard: false,
|
42
39
|
typographyTheme: undefined,
|
43
40
|
observer: null
|
44
41
|
});
|
45
42
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
46
|
-
_defineProperty(
|
43
|
+
_defineProperty(_this, "onOpenChange", function (attrs) {
|
47
44
|
_this.setState(_objectSpread(_objectSpread({}, _this.state), {}, {
|
48
45
|
active: attrs.isOpen,
|
49
46
|
isOpenedByKeyboard: attrs.isOpenedByKeyboard
|
50
47
|
}));
|
51
48
|
});
|
52
|
-
_defineProperty(
|
49
|
+
_defineProperty(_this, "handleTriggerClick", function () {
|
53
50
|
_this.onOpenChange({
|
54
51
|
isOpen: !_this.state.active,
|
55
52
|
isOpenedByKeyboard: false
|
56
53
|
});
|
57
54
|
});
|
58
|
-
_defineProperty(
|
55
|
+
_defineProperty(_this, "handleTriggerByKeyboard", function (event) {
|
59
56
|
if (event.key === 'Enter' || event.key === ' ') {
|
60
57
|
event.preventDefault();
|
61
58
|
_this.onOpenChange({
|
@@ -64,12 +61,12 @@ var ToolbarBlockType = /*#__PURE__*/function (_React$PureComponent) {
|
|
64
61
|
});
|
65
62
|
}
|
66
63
|
});
|
67
|
-
_defineProperty(
|
64
|
+
_defineProperty(_this, "createItems", function () {
|
68
65
|
var formatMessage = _this.props.intl.formatMessage;
|
69
66
|
var _this$props$pluginSta = _this.props.pluginState,
|
70
67
|
currentBlockType = _this$props$pluginSta.currentBlockType,
|
71
|
-
|
72
|
-
var items =
|
68
|
+
availableBlockTypesInDropdown = _this$props$pluginSta.availableBlockTypesInDropdown;
|
69
|
+
var items = availableBlockTypesInDropdown.map(function (blockType, index) {
|
73
70
|
var isActive = currentBlockType === blockType;
|
74
71
|
var tagName = blockType.tagName || 'p';
|
75
72
|
var Tag = tagName;
|
@@ -97,12 +94,17 @@ var ToolbarBlockType = /*#__PURE__*/function (_React$PureComponent) {
|
|
97
94
|
items: items
|
98
95
|
}];
|
99
96
|
});
|
100
|
-
_defineProperty(
|
97
|
+
_defineProperty(_this, "handleSelectBlockType", function (_ref) {
|
101
98
|
var item = _ref.item,
|
102
99
|
_ref$shouldCloseMenu = _ref.shouldCloseMenu,
|
103
100
|
shouldCloseMenu = _ref$shouldCloseMenu === void 0 ? true : _ref$shouldCloseMenu;
|
104
101
|
var blockType = item.value;
|
105
|
-
|
102
|
+
if (blockType.name === 'blockquote') {
|
103
|
+
_this.props.wrapBlockQuote(blockType.name);
|
104
|
+
} else {
|
105
|
+
var fromBlockQuote = _this.props.pluginState.currentBlockType.name === 'blockquote';
|
106
|
+
_this.props.setTextLevel(blockType.name, fromBlockQuote);
|
107
|
+
}
|
106
108
|
if (shouldCloseMenu) {
|
107
109
|
_this.setState(_objectSpread(_objectSpread({}, _this.state), {}, {
|
108
110
|
active: false
|
@@ -111,7 +113,8 @@ var ToolbarBlockType = /*#__PURE__*/function (_React$PureComponent) {
|
|
111
113
|
});
|
112
114
|
return _this;
|
113
115
|
}
|
114
|
-
|
116
|
+
_inherits(ToolbarBlockType, _React$PureComponent);
|
117
|
+
return _createClass(ToolbarBlockType, [{
|
115
118
|
key: "componentDidMount",
|
116
119
|
value: function componentDidMount() {
|
117
120
|
var _this2 = this;
|
@@ -151,6 +154,7 @@ var ToolbarBlockType = /*#__PURE__*/function (_React$PureComponent) {
|
|
151
154
|
currentBlockType = _this$props$pluginSta2.currentBlockType,
|
152
155
|
blockTypesDisabled = _this$props$pluginSta2.blockTypesDisabled,
|
153
156
|
availableBlockTypes = _this$props$pluginSta2.availableBlockTypes,
|
157
|
+
availableBlockTypesInDropdown = _this$props$pluginSta2.availableBlockTypesInDropdown,
|
154
158
|
shouldUseDefaultRole = _this$props.shouldUseDefaultRole,
|
155
159
|
formatMessage = _this$props.intl.formatMessage,
|
156
160
|
api = _this$props.api;
|
@@ -160,12 +164,12 @@ var ToolbarBlockType = /*#__PURE__*/function (_React$PureComponent) {
|
|
160
164
|
if (isHeadingDisabled) {
|
161
165
|
return null;
|
162
166
|
}
|
163
|
-
var blockTypeTitles =
|
167
|
+
var blockTypeTitles = availableBlockTypesInDropdown.filter(function (blockType) {
|
164
168
|
return blockType.name === currentBlockType.name;
|
165
169
|
}).map(function (blockType) {
|
166
170
|
return blockType.title;
|
167
171
|
});
|
168
|
-
if (!this.props.isDisabled && !blockTypesDisabled) {
|
172
|
+
if (!this.props.isDisabled && (!blockTypesDisabled || currentBlockType.name === 'blockquote')) {
|
169
173
|
var items = this.createItems();
|
170
174
|
return (
|
171
175
|
// eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage, @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766
|
@@ -231,6 +235,5 @@ var ToolbarBlockType = /*#__PURE__*/function (_React$PureComponent) {
|
|
231
235
|
);
|
232
236
|
}
|
233
237
|
}]);
|
234
|
-
return ToolbarBlockType;
|
235
238
|
}(React.PureComponent);
|
236
239
|
export default injectIntl(ToolbarBlockType);
|
@@ -4,7 +4,7 @@
|
|
4
4
|
*/
|
5
5
|
// eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
|
6
6
|
import { css } from '@emotion/react';
|
7
|
-
import { headingsSharedStyles } from '@atlaskit/editor-common/styles';
|
7
|
+
import { headingsSharedStyles, blockquoteSharedStyles } from '@atlaskit/editor-common/styles';
|
8
8
|
import { shortcutStyle } from '@atlaskit/editor-shared-styles/shortcut';
|
9
9
|
import { N400 } from '@atlaskit/theme/colors';
|
10
10
|
export var blockTypeMenuItemStyle = function blockTypeMenuItemStyle(tagName, selected, typographyTheme) {
|
@@ -13,7 +13,7 @@ export var blockTypeMenuItemStyle = function blockTypeMenuItemStyle(tagName, sel
|
|
13
13
|
return function () {
|
14
14
|
return css(
|
15
15
|
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values -- Ignored via go/DSP-18766
|
16
|
-
headingsSharedStyles(typographyTheme), {
|
16
|
+
tagName === 'blockquote' ? blockquoteSharedStyles : headingsSharedStyles(typographyTheme), {
|
17
17
|
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors -- Ignored via go/DSP-18766
|
18
18
|
'>': {
|
19
19
|
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors -- Ignored via go/DSP-18766
|
@@ -1,5 +1,6 @@
|
|
1
1
|
import { createRule, createWrappingJoinRule } from '@atlaskit/editor-common/utils';
|
2
2
|
import { fg } from '@atlaskit/platform-feature-flags';
|
3
|
+
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
|
3
4
|
import { WRAPPER_BLOCK_TYPES } from './block-types';
|
4
5
|
export var isNodeAWrappingBlockNode = function isNodeAWrappingBlockNode(node) {
|
5
6
|
if (!node) {
|
@@ -75,7 +76,22 @@ function getSelectedWrapperNodes(state) {
|
|
75
76
|
*/
|
76
77
|
export function areBlockTypesDisabled(state) {
|
77
78
|
var nodesTypes = getSelectedWrapperNodes(state);
|
78
|
-
var
|
79
|
+
var _state$schema$nodes2 = state.schema.nodes,
|
80
|
+
panel = _state$schema$nodes2.panel,
|
81
|
+
blockquote = _state$schema$nodes2.blockquote;
|
82
|
+
if (editorExperiment('platform_editor_blockquote_in_text_formatting_menu', true)) {
|
83
|
+
var hasQuote = false;
|
84
|
+
var _state$selection2 = state.selection,
|
85
|
+
$from = _state$selection2.$from,
|
86
|
+
$to = _state$selection2.$to;
|
87
|
+
state.doc.nodesBetween($from.pos, $to.pos, function (node) {
|
88
|
+
hasQuote = node.type === blockquote;
|
89
|
+
return !hasQuote;
|
90
|
+
});
|
91
|
+
return nodesTypes.filter(function (type) {
|
92
|
+
return type !== panel;
|
93
|
+
}).length > 0 || hasQuote;
|
94
|
+
}
|
79
95
|
return nodesTypes.filter(function (type) {
|
80
96
|
return type !== panel;
|
81
97
|
}).length > 0;
|
package/dist/esm/ui/consts.js
CHANGED
@@ -13,6 +13,7 @@ export type BlockTypePlugin = NextEditorPlugin<'blockType', {
|
|
13
13
|
insertBlockQuote: (inputMethod: InputMethod) => Command;
|
14
14
|
};
|
15
15
|
commands: {
|
16
|
-
setTextLevel: (level: TextBlockTypes, inputMethod: InputMethod) => EditorCommand;
|
16
|
+
setTextLevel: (level: TextBlockTypes, inputMethod: InputMethod, fromBlockQuote?: boolean) => EditorCommand;
|
17
|
+
insertBlockQuote: (inputMethod: InputMethod) => EditorCommand;
|
17
18
|
};
|
18
19
|
}>;
|
package/dist/types/index.d.ts
CHANGED
@@ -2,6 +2,6 @@ export { blockTypePlugin } from './blockTypePlugin';
|
|
2
2
|
export type { BlockTypePlugin } from './blockTypePluginType';
|
3
3
|
export type { BlockTypePluginOptions, BlockType } from './pm-plugins/types';
|
4
4
|
export type { BlockTypeState } from './pm-plugins/main';
|
5
|
-
export type { InputMethod } from './pm-plugins/commands';
|
5
|
+
export type { InputMethod } from './pm-plugins/commands/block-type';
|
6
6
|
export type { DropdownItem } from './pm-plugins/ui/ToolbarBlockType';
|
7
7
|
export type { TextBlockTypes } from './pm-plugins/block-types';
|
@@ -14,6 +14,7 @@ export declare const TEXT_BLOCK_TYPES: BlockType[];
|
|
14
14
|
export type TextBlockTypes = 'normal' | 'heading1' | 'heading2' | 'heading3' | 'heading4' | 'heading5' | 'heading6';
|
15
15
|
export declare const WRAPPER_BLOCK_TYPES: BlockType[];
|
16
16
|
export declare const ALL_BLOCK_TYPES: BlockType[];
|
17
|
+
export declare const getBlockTypesInDropdown: (includeBlockQuoteAsTextstyleOption?: boolean) => BlockType[];
|
17
18
|
export declare const HEADINGS_BY_LEVEL: Record<number, BlockType>;
|
18
19
|
export declare const HEADINGS_BY_NAME: {
|
19
20
|
[blockType: string]: BlockType;
|
@@ -3,11 +3,11 @@ import type { Command, EditorCommand, HeadingLevelsAndNormalText } from '@atlask
|
|
3
3
|
import type { TextBlockTypes } from '../block-types';
|
4
4
|
export type InputMethod = INPUT_METHOD.TOOLBAR | INPUT_METHOD.INSERT_MENU | INPUT_METHOD.SHORTCUT | INPUT_METHOD.FORMATTING | INPUT_METHOD.KEYBOARD | INPUT_METHOD.FLOATING_TB;
|
5
5
|
export declare function setBlockType(name: TextBlockTypes): EditorCommand;
|
6
|
-
export declare function setHeading(level: HeadingLevelsAndNormalText): EditorCommand;
|
7
|
-
export declare function setBlockTypeWithAnalytics(name: TextBlockTypes, inputMethod: InputMethod, editorAnalyticsApi: EditorAnalyticsAPI | undefined): EditorCommand;
|
8
|
-
export declare function setNormalText(): EditorCommand;
|
9
|
-
export declare function setNormalTextWithAnalytics(inputMethod: InputMethod, editorAnalyticsApi: EditorAnalyticsAPI | undefined): EditorCommand;
|
10
|
-
export declare const setHeadingWithAnalytics: (newHeadingLevel: HeadingLevelsAndNormalText, inputMethod: InputMethod, editorAnalyticsApi: EditorAnalyticsAPI | undefined) => EditorCommand;
|
6
|
+
export declare function setHeading(level: HeadingLevelsAndNormalText, fromBlockQuote?: boolean): EditorCommand;
|
7
|
+
export declare function setBlockTypeWithAnalytics(name: TextBlockTypes, inputMethod: InputMethod, editorAnalyticsApi: EditorAnalyticsAPI | undefined, fromBlockQuote?: boolean): EditorCommand;
|
8
|
+
export declare function setNormalText(fromBlockQuote?: boolean): EditorCommand;
|
9
|
+
export declare function setNormalTextWithAnalytics(inputMethod: InputMethod, editorAnalyticsApi: EditorAnalyticsAPI | undefined, fromBlockQuote?: boolean): EditorCommand;
|
10
|
+
export declare const setHeadingWithAnalytics: (newHeadingLevel: HeadingLevelsAndNormalText, inputMethod: InputMethod, editorAnalyticsApi: EditorAnalyticsAPI | undefined, fromBlockQuote?: boolean) => EditorCommand;
|
11
11
|
/**
|
12
12
|
*
|
13
13
|
* @param name - block type name
|
@@ -17,4 +17,5 @@ export declare const setHeadingWithAnalytics: (newHeadingLevel: HeadingLevelsAnd
|
|
17
17
|
* @returns - command that inserts block type
|
18
18
|
*/
|
19
19
|
export declare const insertBlockQuoteWithAnalytics: (inputMethod: InputMethod, editorAnalyticsApi: EditorAnalyticsAPI | undefined) => Command;
|
20
|
+
export declare function insertBlockQuoteWithAnalyticsCommand(inputMethod: InputMethod, editorAnalyticsApi: EditorAnalyticsAPI | undefined): EditorCommand;
|
20
21
|
export declare const cleanUpAtTheStartOfDocument: Command;
|
@@ -10,12 +10,14 @@ export type BlockTypeState = {
|
|
10
10
|
blockTypesDisabled: boolean;
|
11
11
|
availableBlockTypes: BlockType[];
|
12
12
|
availableWrapperBlockTypes: BlockType[];
|
13
|
+
availableBlockTypesInDropdown: BlockType[];
|
13
14
|
};
|
14
15
|
export declare const pluginKey: PluginKey<BlockTypeState>;
|
15
|
-
export declare const createPlugin: (editorAPI: ExtractInjectionAPI<BlockTypePlugin> | undefined, dispatch: (eventName: string | PluginKey, data: any) => void, lastNodeMustBeParagraph?: boolean) => SafePlugin<{
|
16
|
+
export declare const createPlugin: (editorAPI: ExtractInjectionAPI<BlockTypePlugin> | undefined, dispatch: (eventName: string | PluginKey, data: any) => void, lastNodeMustBeParagraph?: boolean, includeBlockQuoteAsTextstyleOption?: boolean) => SafePlugin<{
|
16
17
|
currentBlockType: BlockType;
|
17
18
|
blockTypesDisabled: boolean;
|
18
19
|
availableBlockTypes: BlockType[];
|
19
20
|
availableWrapperBlockTypes: BlockType[];
|
21
|
+
availableBlockTypesInDropdown: BlockType[];
|
20
22
|
}>;
|
21
23
|
export declare const handleBlockQuoteDND: (view: EditorView, event: DragEvent, slice: Slice) => boolean;
|
@@ -24,7 +24,8 @@ export interface Props {
|
|
24
24
|
popupsBoundariesElement?: HTMLElement;
|
25
25
|
popupsScrollableElement?: HTMLElement;
|
26
26
|
editorView?: EditorView;
|
27
|
-
setTextLevel: (type: TextBlockTypes) => void;
|
27
|
+
setTextLevel: (type: TextBlockTypes, fromBlockQuote?: boolean) => void;
|
28
|
+
wrapBlockQuote: (type: TextBlockTypes) => void;
|
28
29
|
shouldUseDefaultRole?: boolean;
|
29
30
|
api: ExtractInjectionAPI<BlockTypePlugin> | undefined;
|
30
31
|
}
|
@@ -16,6 +16,7 @@ export type BlockTypePlugin = NextEditorPlugin<'blockType', {
|
|
16
16
|
insertBlockQuote: (inputMethod: InputMethod) => Command;
|
17
17
|
};
|
18
18
|
commands: {
|
19
|
-
setTextLevel: (level: TextBlockTypes, inputMethod: InputMethod) => EditorCommand;
|
19
|
+
setTextLevel: (level: TextBlockTypes, inputMethod: InputMethod, fromBlockQuote?: boolean) => EditorCommand;
|
20
|
+
insertBlockQuote: (inputMethod: InputMethod) => EditorCommand;
|
20
21
|
};
|
21
22
|
}>;
|