@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
@@ -7,6 +7,7 @@ exports.areBlockTypesDisabled = areBlockTypesDisabled;
|
|
7
7
|
exports.isNodeAWrappingBlockNode = exports.createWrappingTextBlockRule = exports.createJoinNodesRule = void 0;
|
8
8
|
var _utils = require("@atlaskit/editor-common/utils");
|
9
9
|
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
|
10
|
+
var _experiments = require("@atlaskit/tmp-editor-statsig/experiments");
|
10
11
|
var _blockTypes = require("./block-types");
|
11
12
|
var isNodeAWrappingBlockNode = exports.isNodeAWrappingBlockNode = function isNodeAWrappingBlockNode(node) {
|
12
13
|
if (!node) {
|
@@ -82,7 +83,22 @@ function getSelectedWrapperNodes(state) {
|
|
82
83
|
*/
|
83
84
|
function areBlockTypesDisabled(state) {
|
84
85
|
var nodesTypes = getSelectedWrapperNodes(state);
|
85
|
-
var
|
86
|
+
var _state$schema$nodes2 = state.schema.nodes,
|
87
|
+
panel = _state$schema$nodes2.panel,
|
88
|
+
blockquote = _state$schema$nodes2.blockquote;
|
89
|
+
if ((0, _experiments.editorExperiment)('platform_editor_blockquote_in_text_formatting_menu', true)) {
|
90
|
+
var hasQuote = false;
|
91
|
+
var _state$selection2 = state.selection,
|
92
|
+
$from = _state$selection2.$from,
|
93
|
+
$to = _state$selection2.$to;
|
94
|
+
state.doc.nodesBetween($from.pos, $to.pos, function (node) {
|
95
|
+
hasQuote = node.type === blockquote;
|
96
|
+
return !hasQuote;
|
97
|
+
});
|
98
|
+
return nodesTypes.filter(function (type) {
|
99
|
+
return type !== panel;
|
100
|
+
}).length > 0 || hasQuote;
|
101
|
+
}
|
86
102
|
return nodesTypes.filter(function (type) {
|
87
103
|
return type !== panel;
|
88
104
|
}).length > 0;
|
@@ -7,8 +7,7 @@ import { IconHeading, IconQuote } from '@atlaskit/editor-common/quick-insert';
|
|
7
7
|
import { ToolbarSize } from '@atlaskit/editor-common/types';
|
8
8
|
import { fg } from '@atlaskit/platform-feature-flags';
|
9
9
|
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
|
10
|
-
import { setBlockTypeWithAnalytics } from './pm-plugins/commands';
|
11
|
-
import { insertBlockQuoteWithAnalytics } from './pm-plugins/commands/block-type';
|
10
|
+
import { setBlockTypeWithAnalytics, insertBlockQuoteWithAnalytics, insertBlockQuoteWithAnalyticsCommand } from './pm-plugins/commands/block-type';
|
12
11
|
import inputRulePlugin from './pm-plugins/input-rule';
|
13
12
|
import keymapPlugin from './pm-plugins/keymap';
|
14
13
|
import { createPlugin, pluginKey } from './pm-plugins/main';
|
@@ -144,7 +143,7 @@ const blockTypePlugin = ({
|
|
144
143
|
name: 'blockType',
|
145
144
|
plugin: ({
|
146
145
|
dispatch
|
147
|
-
}) => createPlugin(api, dispatch, options && options.lastNodeMustBeParagraph)
|
146
|
+
}) => createPlugin(api, dispatch, options && options.lastNodeMustBeParagraph, options === null || options === void 0 ? void 0 : options.includeBlockQuoteAsTextstyleOption)
|
148
147
|
}, {
|
149
148
|
name: 'blockTypeInputRule',
|
150
149
|
plugin: ({
|
@@ -175,9 +174,13 @@ const blockTypePlugin = ({
|
|
175
174
|
}
|
176
175
|
},
|
177
176
|
commands: {
|
178
|
-
setTextLevel(level, inputMethod) {
|
177
|
+
setTextLevel(level, inputMethod, fromBlockQuote = false) {
|
179
178
|
var _api$analytics4;
|
180
|
-
return setBlockTypeWithAnalytics(level, inputMethod, api === null || api === void 0 ? void 0 : (_api$analytics4 = api.analytics) === null || _api$analytics4 === void 0 ? void 0 : _api$analytics4.actions);
|
179
|
+
return setBlockTypeWithAnalytics(level, inputMethod, api === null || api === void 0 ? void 0 : (_api$analytics4 = api.analytics) === null || _api$analytics4 === void 0 ? void 0 : _api$analytics4.actions, fromBlockQuote);
|
180
|
+
},
|
181
|
+
insertBlockQuote(inputMethod) {
|
182
|
+
var _api$analytics5;
|
183
|
+
return insertBlockQuoteWithAnalyticsCommand(inputMethod, api === null || api === void 0 ? void 0 : (_api$analytics5 = api.analytics) === null || _api$analytics5 === void 0 ? void 0 : _api$analytics5.actions);
|
181
184
|
}
|
182
185
|
},
|
183
186
|
getSharedState(editorState) {
|
@@ -214,12 +217,11 @@ const blockTypePlugin = ({
|
|
214
217
|
}
|
215
218
|
},
|
216
219
|
quickInsert: intl => {
|
217
|
-
var _api$
|
220
|
+
var _api$analytics6, _api$analytics7;
|
218
221
|
const exclude = options && options.allowBlockType && options.allowBlockType.exclude ? options.allowBlockType.exclude : [];
|
219
|
-
return [...blockquotePluginOptions(intl, exclude.indexOf('blockquote') === -1, api === null || api === void 0 ? void 0 : (_api$
|
222
|
+
return [...blockquotePluginOptions(intl, exclude.indexOf('blockquote') === -1, api === null || api === void 0 ? void 0 : (_api$analytics6 = api.analytics) === null || _api$analytics6 === void 0 ? void 0 : _api$analytics6.actions), ...headingPluginOptions(intl, exclude.indexOf('heading') === -1, api === null || api === void 0 ? void 0 : (_api$analytics7 = api.analytics) === null || _api$analytics7 === void 0 ? void 0 : _api$analytics7.actions)];
|
220
223
|
}
|
221
224
|
}
|
222
225
|
};
|
223
226
|
};
|
224
|
-
export { blockTypePlugin };
|
225
|
-
export { pluginKey } from './pm-plugins/main';
|
227
|
+
export { blockTypePlugin };
|
package/dist/es2019/index.js
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
import { blockTypeMessages as messages } from '@atlaskit/editor-common/messages';
|
2
|
+
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
|
2
3
|
export const NORMAL_TEXT = {
|
3
4
|
name: 'normal',
|
4
5
|
title: messages.normal,
|
@@ -50,7 +51,8 @@ export const HEADING_6 = {
|
|
50
51
|
export const BLOCK_QUOTE = {
|
51
52
|
name: 'blockquote',
|
52
53
|
title: messages.blockquote,
|
53
|
-
nodeName: 'blockquote'
|
54
|
+
nodeName: 'blockquote',
|
55
|
+
tagName: 'blockquote'
|
54
56
|
};
|
55
57
|
export const CODE_BLOCK = {
|
56
58
|
name: 'codeblock',
|
@@ -70,6 +72,11 @@ export const OTHER = {
|
|
70
72
|
export const TEXT_BLOCK_TYPES = [NORMAL_TEXT, HEADING_1, HEADING_2, HEADING_3, HEADING_4, HEADING_5, HEADING_6];
|
71
73
|
export const WRAPPER_BLOCK_TYPES = [BLOCK_QUOTE, CODE_BLOCK, PANEL];
|
72
74
|
export const ALL_BLOCK_TYPES = TEXT_BLOCK_TYPES.concat(WRAPPER_BLOCK_TYPES);
|
75
|
+
export const getBlockTypesInDropdown = includeBlockQuoteAsTextstyleOption => {
|
76
|
+
return editorExperiment('platform_editor_blockquote_in_text_formatting_menu', true, {
|
77
|
+
exposure: true
|
78
|
+
}) && includeBlockQuoteAsTextstyleOption ? [...TEXT_BLOCK_TYPES, BLOCK_QUOTE] : TEXT_BLOCK_TYPES;
|
79
|
+
};
|
73
80
|
export const HEADINGS_BY_LEVEL = TEXT_BLOCK_TYPES.reduce((acc, blockType) => {
|
74
81
|
if (blockType.level && blockType.nodeName === 'heading') {
|
75
82
|
acc[blockType.level] = blockType;
|
@@ -1,8 +1,10 @@
|
|
1
1
|
import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
|
2
2
|
import { withAnalytics } from '@atlaskit/editor-common/editor-analytics';
|
3
3
|
import { filterChildrenBetween, wrapSelectionIn } from '@atlaskit/editor-common/utils';
|
4
|
+
import { Slice, Fragment } from '@atlaskit/editor-prosemirror/model';
|
4
5
|
import { CellSelection } from '@atlaskit/editor-tables';
|
5
6
|
import { HEADINGS_BY_NAME, NORMAL_TEXT } from '../block-types';
|
7
|
+
import { wrapSelectionInBlockType } from './wrapSelectionIn';
|
6
8
|
export function setBlockType(name) {
|
7
9
|
return ({
|
8
10
|
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 ({
|
29
31
|
tr
|
30
32
|
}) {
|
@@ -41,14 +43,27 @@ export function setHeading(level) {
|
|
41
43
|
$from,
|
42
44
|
$to
|
43
45
|
}) => {
|
44
|
-
|
45
|
-
|
46
|
-
|
46
|
+
if (fromBlockQuote) {
|
47
|
+
const range = $from.blockRange($to);
|
48
|
+
if (!range) {
|
49
|
+
return;
|
50
|
+
}
|
51
|
+
const content = $from.node().content;
|
52
|
+
const headingNode = schema.nodes.heading.createChecked({
|
53
|
+
level
|
54
|
+
}, content);
|
55
|
+
const slice = new Slice(Fragment.from(headingNode), 0, 0);
|
56
|
+
tr.replaceRange(range.start, range.end, slice);
|
57
|
+
} else {
|
58
|
+
tr.setBlockType($from.pos, $to.pos, schema.nodes.heading, {
|
59
|
+
level
|
60
|
+
});
|
61
|
+
}
|
47
62
|
});
|
48
63
|
return tr;
|
49
64
|
};
|
50
65
|
}
|
51
|
-
export function setBlockTypeWithAnalytics(name, inputMethod, editorAnalyticsApi) {
|
66
|
+
export function setBlockTypeWithAnalytics(name, inputMethod, editorAnalyticsApi, fromBlockQuote) {
|
52
67
|
return ({
|
53
68
|
tr
|
54
69
|
}) => {
|
@@ -56,20 +71,20 @@ export function setBlockTypeWithAnalytics(name, inputMethod, editorAnalyticsApi)
|
|
56
71
|
nodes
|
57
72
|
} = tr.doc.type.schema;
|
58
73
|
if (name === 'normal' && nodes.paragraph) {
|
59
|
-
return setNormalTextWithAnalytics(inputMethod, editorAnalyticsApi)({
|
74
|
+
return setNormalTextWithAnalytics(inputMethod, editorAnalyticsApi, fromBlockQuote)({
|
60
75
|
tr
|
61
76
|
});
|
62
77
|
}
|
63
78
|
const headingBlockType = HEADINGS_BY_NAME[name];
|
64
79
|
if (headingBlockType && nodes.heading && headingBlockType.level) {
|
65
|
-
return setHeadingWithAnalytics(headingBlockType.level, inputMethod, editorAnalyticsApi)({
|
80
|
+
return setHeadingWithAnalytics(headingBlockType.level, inputMethod, editorAnalyticsApi, fromBlockQuote)({
|
66
81
|
tr
|
67
82
|
});
|
68
83
|
}
|
69
84
|
return null;
|
70
85
|
};
|
71
86
|
}
|
72
|
-
export function setNormalText() {
|
87
|
+
export function setNormalText(fromBlockQuote) {
|
73
88
|
return function ({
|
74
89
|
tr
|
75
90
|
}) {
|
@@ -86,7 +101,15 @@ export function setNormalText() {
|
|
86
101
|
$from,
|
87
102
|
$to
|
88
103
|
}) => {
|
89
|
-
|
104
|
+
if (fromBlockQuote) {
|
105
|
+
const range = $from.blockRange($to);
|
106
|
+
if (!range) {
|
107
|
+
return;
|
108
|
+
}
|
109
|
+
tr.lift(range, 0);
|
110
|
+
} else {
|
111
|
+
tr.setBlockType($from.pos, $to.pos, schema.nodes.paragraph);
|
112
|
+
}
|
90
113
|
});
|
91
114
|
return tr;
|
92
115
|
};
|
@@ -121,7 +144,7 @@ function withCurrentHeadingLevel(fn) {
|
|
121
144
|
});
|
122
145
|
};
|
123
146
|
}
|
124
|
-
export function setNormalTextWithAnalytics(inputMethod, editorAnalyticsApi) {
|
147
|
+
export function setNormalTextWithAnalytics(inputMethod, editorAnalyticsApi, fromBlockQuote) {
|
125
148
|
return withCurrentHeadingLevel(previousHeadingLevel => ({
|
126
149
|
tr
|
127
150
|
}) => {
|
@@ -136,12 +159,12 @@ export function setNormalTextWithAnalytics(inputMethod, editorAnalyticsApi) {
|
|
136
159
|
previousHeadingLevel
|
137
160
|
}
|
138
161
|
})(tr);
|
139
|
-
return setNormalText()({
|
162
|
+
return setNormalText(fromBlockQuote)({
|
140
163
|
tr
|
141
164
|
});
|
142
165
|
});
|
143
166
|
}
|
144
|
-
export const setHeadingWithAnalytics = (newHeadingLevel, inputMethod, editorAnalyticsApi) => {
|
167
|
+
export const setHeadingWithAnalytics = (newHeadingLevel, inputMethod, editorAnalyticsApi, fromBlockQuote) => {
|
145
168
|
return withCurrentHeadingLevel(previousHeadingLevel => ({
|
146
169
|
tr
|
147
170
|
}) => {
|
@@ -156,7 +179,7 @@ export const setHeadingWithAnalytics = (newHeadingLevel, inputMethod, editorAnal
|
|
156
179
|
previousHeadingLevel
|
157
180
|
}
|
158
181
|
})(tr);
|
159
|
-
return setHeading(newHeadingLevel)({
|
182
|
+
return setHeading(newHeadingLevel, fromBlockQuote)({
|
160
183
|
tr
|
161
184
|
});
|
162
185
|
});
|
@@ -192,6 +215,31 @@ export const insertBlockQuoteWithAnalytics = (inputMethod, editorAnalyticsApi) =
|
|
192
215
|
}
|
193
216
|
})(insertBlockQuote());
|
194
217
|
};
|
218
|
+
export function insertBlockQuoteWithAnalyticsCommand(inputMethod, editorAnalyticsApi) {
|
219
|
+
return withCurrentHeadingLevel(previousHeadingLevel => ({
|
220
|
+
tr
|
221
|
+
}) => {
|
222
|
+
const {
|
223
|
+
nodes
|
224
|
+
} = tr.doc.type.schema;
|
225
|
+
|
226
|
+
// TODO: analytics event
|
227
|
+
|
228
|
+
// editorAnalyticsApi?.attachAnalyticsEvent({
|
229
|
+
// action: ACTION.FORMATTED,
|
230
|
+
// actionSubject: ACTION_SUBJECT.TEXT,
|
231
|
+
// eventType: EVENT_TYPE.TRACK,
|
232
|
+
// actionSubjectId: ACTION_SUBJECT_ID.FORMAT_BLOCK_QUOTE,
|
233
|
+
// attributes: {
|
234
|
+
// inputMethod: inputMethod,
|
235
|
+
// },
|
236
|
+
// })(tr);
|
237
|
+
|
238
|
+
return wrapSelectionInBlockType(nodes.blockquote)({
|
239
|
+
tr
|
240
|
+
});
|
241
|
+
});
|
242
|
+
}
|
195
243
|
export const cleanUpAtTheStartOfDocument = (state, dispatch) => {
|
196
244
|
const {
|
197
245
|
$cursor
|
@@ -0,0 +1,54 @@
|
|
1
|
+
import { Slice, Fragment } from '@atlaskit/editor-prosemirror/model';
|
2
|
+
import { findWrapping } from '@atlaskit/editor-prosemirror/transform';
|
3
|
+
export function wrapSelectionInBlockType(nodeType) {
|
4
|
+
return ({
|
5
|
+
tr
|
6
|
+
}) => {
|
7
|
+
const {
|
8
|
+
nodes
|
9
|
+
} = tr.doc.type.schema;
|
10
|
+
const {
|
11
|
+
alignment,
|
12
|
+
indentation
|
13
|
+
} = tr.doc.type.schema.marks;
|
14
|
+
if (nodes.paragraph && nodes.blockquote) {
|
15
|
+
/**Remove alignment and indentation marks from the selection */
|
16
|
+
const marksToRemove = [alignment, indentation];
|
17
|
+
const hasMark = mark => marksToRemove.indexOf(mark.type) > -1;
|
18
|
+
const not = fn => arg => !fn(arg);
|
19
|
+
|
20
|
+
/**
|
21
|
+
* When you need to toggle the selection
|
22
|
+
* when another type which does not allow alignment is applied
|
23
|
+
*/
|
24
|
+
tr.doc.nodesBetween(tr.selection.from, tr.selection.to, (node, pos) => {
|
25
|
+
if (node.type === nodes.paragraph && node.marks.some(hasMark)) {
|
26
|
+
const resolvedPos = tr.doc.resolve(pos);
|
27
|
+
const withoutBlockMarks = node.marks.filter(not(hasMark));
|
28
|
+
tr = tr.setNodeMarkup(resolvedPos.pos, undefined, node.attrs, withoutBlockMarks);
|
29
|
+
}
|
30
|
+
});
|
31
|
+
|
32
|
+
/** Get range and wrapping needed for the selection */
|
33
|
+
const {
|
34
|
+
$from,
|
35
|
+
$to
|
36
|
+
} = tr.selection;
|
37
|
+
const range = $from.blockRange($to);
|
38
|
+
const wrapping = range && findWrapping(range, nodes.blockquote);
|
39
|
+
if (wrapping) {
|
40
|
+
/** Wrap the selection */
|
41
|
+
tr.wrap(range, wrapping).scrollIntoView();
|
42
|
+
} else {
|
43
|
+
/** If wrapping is not possible, replace with a blockquote */
|
44
|
+
const start = $from.start();
|
45
|
+
const end = $to.end();
|
46
|
+
const content = $from.node().content;
|
47
|
+
const blockquote = nodes.blockquote.create({}, nodes.paragraph.create({}, content));
|
48
|
+
const slice = new Slice(Fragment.from(blockquote), 0, 0);
|
49
|
+
tr.replaceRange(start, end, slice).scrollIntoView();
|
50
|
+
}
|
51
|
+
}
|
52
|
+
return tr;
|
53
|
+
};
|
54
|
+
}
|
@@ -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
|
const backspaceCommand = chainCommands(cleanUpAtTheStartOfDocument, deleteBlockContent(isNodeAWrappingBlockNode), deleteAndMoveCursor);
|
10
12
|
const del = chainCommands(deleteEmptyParagraphAndMoveBlockUp(isNodeAWrappingBlockNode), deleteBlockContent(isNodeAWrappingBlockNode), deleteAndMoveCursor);
|
@@ -3,8 +3,8 @@ import { browser } from '@atlaskit/editor-common/browser';
|
|
3
3
|
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
4
4
|
import { PluginKey } from '@atlaskit/editor-prosemirror/state';
|
5
5
|
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
|
6
|
-
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';
|
7
|
-
import { setHeadingWithAnalytics, setNormalTextWithAnalytics } from './commands';
|
6
|
+
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';
|
7
|
+
import { setHeadingWithAnalytics, setNormalTextWithAnalytics } from './commands/block-type';
|
8
8
|
import { HEADING_KEYS } from './consts';
|
9
9
|
import { areBlockTypesDisabled } from './utils';
|
10
10
|
const blockTypeForNode = (node, schema) => {
|
@@ -15,6 +15,8 @@ const blockTypeForNode = (node, schema) => {
|
|
15
15
|
}
|
16
16
|
} else if (node.type === schema.nodes.paragraph) {
|
17
17
|
return NORMAL_TEXT;
|
18
|
+
} else if (node.type === schema.nodes.blockquote) {
|
19
|
+
return BLOCK_QUOTE;
|
18
20
|
}
|
19
21
|
return OTHER;
|
20
22
|
};
|
@@ -56,6 +58,7 @@ const detectBlockType = (availableBlockTypes, state) => {
|
|
56
58
|
} else if (blockType !== OTHER && blockType !== nodeBlockType[0]) {
|
57
59
|
blockType = OTHER;
|
58
60
|
}
|
61
|
+
return false;
|
59
62
|
}
|
60
63
|
});
|
61
64
|
return blockType || OTHER;
|
@@ -67,7 +70,7 @@ const autoformatHeading = (headingLevel, editorAnalyticsApi) => {
|
|
67
70
|
return setHeadingWithAnalytics(headingLevel, INPUT_METHOD.FORMATTING, editorAnalyticsApi);
|
68
71
|
};
|
69
72
|
export const pluginKey = new PluginKey('blockTypePlugin');
|
70
|
-
export const createPlugin = (editorAPI, dispatch, lastNodeMustBeParagraph) => {
|
73
|
+
export const createPlugin = (editorAPI, dispatch, lastNodeMustBeParagraph, includeBlockQuoteAsTextstyleOption) => {
|
71
74
|
var _editorAPI$analytics;
|
72
75
|
const editorAnalyticsApi = editorAPI === null || editorAPI === void 0 ? void 0 : (_editorAPI$analytics = editorAPI.analytics) === null || _editorAPI$analytics === void 0 ? void 0 : _editorAPI$analytics.actions;
|
73
76
|
let altKeyLocation = 0;
|
@@ -88,17 +91,20 @@ export const createPlugin = (editorAPI, dispatch, lastNodeMustBeParagraph) => {
|
|
88
91
|
init(_config, state) {
|
89
92
|
const availableBlockTypes = TEXT_BLOCK_TYPES.filter(blockType => isBlockTypeSchemaSupported(blockType, state));
|
90
93
|
const availableWrapperBlockTypes = WRAPPER_BLOCK_TYPES.filter(blockType => isBlockTypeSchemaSupported(blockType, state));
|
94
|
+
const BLOCK_TYPES_IN_DROPDOWN = getBlockTypesInDropdown(includeBlockQuoteAsTextstyleOption);
|
95
|
+
const availableBlockTypesInDropdown = BLOCK_TYPES_IN_DROPDOWN.filter(blockType => isBlockTypeSchemaSupported(blockType, state));
|
91
96
|
return {
|
92
|
-
currentBlockType: detectBlockType(
|
97
|
+
currentBlockType: detectBlockType(availableBlockTypesInDropdown, state),
|
93
98
|
blockTypesDisabled: areBlockTypesDisabled(state),
|
94
99
|
availableBlockTypes,
|
95
|
-
availableWrapperBlockTypes
|
100
|
+
availableWrapperBlockTypes,
|
101
|
+
availableBlockTypesInDropdown
|
96
102
|
};
|
97
103
|
},
|
98
104
|
apply(_tr, oldPluginState, _oldState, newState) {
|
99
105
|
const newPluginState = {
|
100
106
|
...oldPluginState,
|
101
|
-
currentBlockType: detectBlockType(oldPluginState.
|
107
|
+
currentBlockType: detectBlockType(oldPluginState.availableBlockTypesInDropdown, newState),
|
102
108
|
blockTypesDisabled: areBlockTypesDisabled(newState)
|
103
109
|
};
|
104
110
|
if (newPluginState.currentBlockType !== oldPluginState.currentBlockType || newPluginState.blockTypesDisabled !== oldPluginState.blockTypesDisabled) {
|
@@ -18,12 +18,17 @@ export function FloatingToolbarComponent({
|
|
18
18
|
var _api$core, _api$blockType, _api$blockType$comman;
|
19
19
|
return 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$blockType = api.blockType) === null || _api$blockType === void 0 ? void 0 : (_api$blockType$comman = _api$blockType.commands) === null || _api$blockType$comman === void 0 ? void 0 : _api$blockType$comman.setTextLevel(name, INPUT_METHOD.FLOATING_TB));
|
20
20
|
}, [api]);
|
21
|
+
const wrapBlockQuote = useCallback(() => {
|
22
|
+
var _api$core2, _api$blockType2, _api$blockType2$comma;
|
23
|
+
return api === null || api === void 0 ? void 0 : (_api$core2 = api.core) === null || _api$core2 === void 0 ? void 0 : _api$core2.actions.execute(api === null || api === void 0 ? void 0 : (_api$blockType2 = api.blockType) === null || _api$blockType2 === void 0 ? void 0 : (_api$blockType2$comma = _api$blockType2.commands) === null || _api$blockType2$comma === void 0 ? void 0 : _api$blockType2$comma.insertBlockQuote(INPUT_METHOD.TOOLBAR));
|
24
|
+
}, [api]);
|
21
25
|
return /*#__PURE__*/React.createElement(ToolbarBlockType, {
|
22
26
|
isSmall: FloatingToolbarSettings.isSmall,
|
23
27
|
isDisabled: FloatingToolbarSettings.disabled,
|
24
28
|
isReducedSpacing: FloatingToolbarSettings.isToolbarReducedSpacing,
|
25
29
|
setTextLevel: boundSetBlockType,
|
26
30
|
pluginState: blockTypeState,
|
31
|
+
wrapBlockQuote: wrapBlockQuote,
|
27
32
|
shouldUseDefaultRole: FloatingToolbarSettings.shouldUseDefaultRole,
|
28
33
|
api: api
|
29
34
|
});
|
@@ -15,15 +15,20 @@ export function PrimaryToolbarComponent({
|
|
15
15
|
const {
|
16
16
|
blockTypeState
|
17
17
|
} = useSharedPluginState(api, ['blockType']);
|
18
|
-
const boundSetBlockType = name => {
|
18
|
+
const boundSetBlockType = (name, fromBlockQuote) => {
|
19
19
|
var _api$core, _api$blockType, _api$blockType$comman;
|
20
|
-
return 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$blockType = api.blockType) === null || _api$blockType === void 0 ? void 0 : (_api$blockType$comman = _api$blockType.commands) === null || _api$blockType$comman === void 0 ? void 0 : _api$blockType$comman.setTextLevel(name, INPUT_METHOD.TOOLBAR));
|
20
|
+
return 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$blockType = api.blockType) === null || _api$blockType === void 0 ? void 0 : (_api$blockType$comman = _api$blockType.commands) === null || _api$blockType$comman === void 0 ? void 0 : _api$blockType$comman.setTextLevel(name, INPUT_METHOD.TOOLBAR, fromBlockQuote));
|
21
|
+
};
|
22
|
+
const wrapBlockQuote = () => {
|
23
|
+
var _api$core2, _api$blockType2, _api$blockType2$comma;
|
24
|
+
return api === null || api === void 0 ? void 0 : (_api$core2 = api.core) === null || _api$core2 === void 0 ? void 0 : _api$core2.actions.execute(api === null || api === void 0 ? void 0 : (_api$blockType2 = api.blockType) === null || _api$blockType2 === void 0 ? void 0 : (_api$blockType2$comma = _api$blockType2.commands) === null || _api$blockType2$comma === void 0 ? void 0 : _api$blockType2$comma.insertBlockQuote(INPUT_METHOD.TOOLBAR));
|
21
25
|
};
|
22
26
|
return /*#__PURE__*/React.createElement(ToolbarBlockType, {
|
23
27
|
isSmall: isSmall,
|
24
28
|
isDisabled: disabled,
|
25
29
|
isReducedSpacing: isToolbarReducedSpacing,
|
26
30
|
setTextLevel: boundSetBlockType,
|
31
|
+
wrapBlockQuote: wrapBlockQuote,
|
27
32
|
pluginState: blockTypeState,
|
28
33
|
popupsMountPoint: popupsMountPoint,
|
29
34
|
popupsBoundariesElement: popupsBoundariesElement,
|
@@ -56,9 +56,9 @@ class ToolbarBlockType extends React.PureComponent {
|
|
56
56
|
} = this.props;
|
57
57
|
const {
|
58
58
|
currentBlockType,
|
59
|
-
|
59
|
+
availableBlockTypesInDropdown
|
60
60
|
} = this.props.pluginState;
|
61
|
-
const items =
|
61
|
+
const items = availableBlockTypesInDropdown.map((blockType, index) => {
|
62
62
|
const isActive = currentBlockType === blockType;
|
63
63
|
const tagName = blockType.tagName || 'p';
|
64
64
|
const Tag = tagName;
|
@@ -91,7 +91,12 @@ class ToolbarBlockType extends React.PureComponent {
|
|
91
91
|
shouldCloseMenu = true
|
92
92
|
}) => {
|
93
93
|
const blockType = item.value;
|
94
|
-
|
94
|
+
if (blockType.name === 'blockquote') {
|
95
|
+
this.props.wrapBlockQuote(blockType.name);
|
96
|
+
} else {
|
97
|
+
const fromBlockQuote = this.props.pluginState.currentBlockType.name === 'blockquote';
|
98
|
+
this.props.setTextLevel(blockType.name, fromBlockQuote);
|
99
|
+
}
|
95
100
|
if (shouldCloseMenu) {
|
96
101
|
this.setState({
|
97
102
|
...this.state,
|
@@ -133,7 +138,8 @@ class ToolbarBlockType extends React.PureComponent {
|
|
133
138
|
pluginState: {
|
134
139
|
currentBlockType,
|
135
140
|
blockTypesDisabled,
|
136
|
-
availableBlockTypes
|
141
|
+
availableBlockTypes,
|
142
|
+
availableBlockTypesInDropdown
|
137
143
|
},
|
138
144
|
shouldUseDefaultRole,
|
139
145
|
intl: {
|
@@ -145,8 +151,8 @@ class ToolbarBlockType extends React.PureComponent {
|
|
145
151
|
if (isHeadingDisabled) {
|
146
152
|
return null;
|
147
153
|
}
|
148
|
-
const blockTypeTitles =
|
149
|
-
if (!this.props.isDisabled && !blockTypesDisabled) {
|
154
|
+
const blockTypeTitles = availableBlockTypesInDropdown.filter(blockType => blockType.name === currentBlockType.name).map(blockType => blockType.title);
|
155
|
+
if (!this.props.isDisabled && (!blockTypesDisabled || currentBlockType.name === 'blockquote')) {
|
150
156
|
const items = this.createItems();
|
151
157
|
return (
|
152
158
|
// eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage, @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766
|
@@ -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 const blockTypeMenuItemStyle = (tagName, selected, typographyTheme) => {
|
@@ -12,7 +12,7 @@ export const blockTypeMenuItemStyle = (tagName, selected, typographyTheme) => {
|
|
12
12
|
const selectedStyle = selected ? `${tagName} { color: ${"var(--ds-text, white)"} !important; }` : '';
|
13
13
|
return () => css(
|
14
14
|
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values -- Ignored via go/DSP-18766
|
15
|
-
headingsSharedStyles(typographyTheme), {
|
15
|
+
tagName === 'blockquote' ? blockquoteSharedStyles : headingsSharedStyles(typographyTheme), {
|
16
16
|
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors -- Ignored via go/DSP-18766
|
17
17
|
'>': {
|
18
18
|
// 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 const isNodeAWrappingBlockNode = node => {
|
5
6
|
if (!node) {
|
@@ -75,7 +76,20 @@ function getSelectedWrapperNodes(state) {
|
|
75
76
|
export function areBlockTypesDisabled(state) {
|
76
77
|
const nodesTypes = getSelectedWrapperNodes(state);
|
77
78
|
const {
|
78
|
-
panel
|
79
|
+
panel,
|
80
|
+
blockquote
|
79
81
|
} = state.schema.nodes;
|
82
|
+
if (editorExperiment('platform_editor_blockquote_in_text_formatting_menu', true)) {
|
83
|
+
let hasQuote = false;
|
84
|
+
const {
|
85
|
+
$from,
|
86
|
+
$to
|
87
|
+
} = state.selection;
|
88
|
+
state.doc.nodesBetween($from.pos, $to.pos, node => {
|
89
|
+
hasQuote = node.type === blockquote;
|
90
|
+
return !hasQuote;
|
91
|
+
});
|
92
|
+
return nodesTypes.filter(type => type !== panel).length > 0 || hasQuote;
|
93
|
+
}
|
80
94
|
return nodesTypes.filter(type => type !== panel).length > 0;
|
81
95
|
}
|
package/dist/es2019/ui/consts.js
CHANGED
@@ -8,8 +8,7 @@ import { IconHeading, IconQuote } from '@atlaskit/editor-common/quick-insert';
|
|
8
8
|
import { ToolbarSize } from '@atlaskit/editor-common/types';
|
9
9
|
import { fg } from '@atlaskit/platform-feature-flags';
|
10
10
|
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
|
11
|
-
import { setBlockTypeWithAnalytics } from './pm-plugins/commands';
|
12
|
-
import { insertBlockQuoteWithAnalytics } from './pm-plugins/commands/block-type';
|
11
|
+
import { setBlockTypeWithAnalytics, insertBlockQuoteWithAnalytics, insertBlockQuoteWithAnalyticsCommand } from './pm-plugins/commands/block-type';
|
13
12
|
import inputRulePlugin from './pm-plugins/input-rule';
|
14
13
|
import keymapPlugin from './pm-plugins/keymap';
|
15
14
|
import { createPlugin, pluginKey } from './pm-plugins/main';
|
@@ -147,7 +146,7 @@ var blockTypePlugin = function blockTypePlugin(_ref3) {
|
|
147
146
|
name: 'blockType',
|
148
147
|
plugin: function plugin(_ref5) {
|
149
148
|
var dispatch = _ref5.dispatch;
|
150
|
-
return createPlugin(api, dispatch, options && options.lastNodeMustBeParagraph);
|
149
|
+
return createPlugin(api, dispatch, options && options.lastNodeMustBeParagraph, options === null || options === void 0 ? void 0 : options.includeBlockQuoteAsTextstyleOption);
|
151
150
|
}
|
152
151
|
}, {
|
153
152
|
name: 'blockTypeInputRule',
|
@@ -179,7 +178,12 @@ var blockTypePlugin = function blockTypePlugin(_ref3) {
|
|
179
178
|
commands: {
|
180
179
|
setTextLevel: function setTextLevel(level, inputMethod) {
|
181
180
|
var _api$analytics4;
|
182
|
-
|
181
|
+
var fromBlockQuote = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
182
|
+
return setBlockTypeWithAnalytics(level, inputMethod, api === null || api === void 0 || (_api$analytics4 = api.analytics) === null || _api$analytics4 === void 0 ? void 0 : _api$analytics4.actions, fromBlockQuote);
|
183
|
+
},
|
184
|
+
insertBlockQuote: function insertBlockQuote(inputMethod) {
|
185
|
+
var _api$analytics5;
|
186
|
+
return insertBlockQuoteWithAnalyticsCommand(inputMethod, api === null || api === void 0 || (_api$analytics5 = api.analytics) === null || _api$analytics5 === void 0 ? void 0 : _api$analytics5.actions);
|
183
187
|
}
|
184
188
|
},
|
185
189
|
getSharedState: function getSharedState(editorState) {
|
@@ -216,12 +220,11 @@ var blockTypePlugin = function blockTypePlugin(_ref3) {
|
|
216
220
|
}
|
217
221
|
},
|
218
222
|
quickInsert: function quickInsert(intl) {
|
219
|
-
var _api$
|
223
|
+
var _api$analytics6, _api$analytics7;
|
220
224
|
var exclude = options && options.allowBlockType && options.allowBlockType.exclude ? options.allowBlockType.exclude : [];
|
221
|
-
return [].concat(_toConsumableArray(blockquotePluginOptions(intl, exclude.indexOf('blockquote') === -1, api === null || api === void 0 || (_api$
|
225
|
+
return [].concat(_toConsumableArray(blockquotePluginOptions(intl, exclude.indexOf('blockquote') === -1, api === null || api === void 0 || (_api$analytics6 = api.analytics) === null || _api$analytics6 === void 0 ? void 0 : _api$analytics6.actions)), _toConsumableArray(headingPluginOptions(intl, exclude.indexOf('heading') === -1, api === null || api === void 0 || (_api$analytics7 = api.analytics) === null || _api$analytics7 === void 0 ? void 0 : _api$analytics7.actions)));
|
222
226
|
}
|
223
227
|
}
|
224
228
|
};
|
225
229
|
};
|
226
|
-
export { blockTypePlugin };
|
227
|
-
export { pluginKey } from './pm-plugins/main';
|
230
|
+
export { blockTypePlugin };
|
package/dist/esm/index.js
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
import { blockTypeMessages as messages } from '@atlaskit/editor-common/messages';
|
2
|
+
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
|
2
3
|
export var NORMAL_TEXT = {
|
3
4
|
name: 'normal',
|
4
5
|
title: messages.normal,
|
@@ -50,7 +51,8 @@ export var HEADING_6 = {
|
|
50
51
|
export var BLOCK_QUOTE = {
|
51
52
|
name: 'blockquote',
|
52
53
|
title: messages.blockquote,
|
53
|
-
nodeName: 'blockquote'
|
54
|
+
nodeName: 'blockquote',
|
55
|
+
tagName: 'blockquote'
|
54
56
|
};
|
55
57
|
export var CODE_BLOCK = {
|
56
58
|
name: 'codeblock',
|
@@ -70,6 +72,11 @@ export var OTHER = {
|
|
70
72
|
export var TEXT_BLOCK_TYPES = [NORMAL_TEXT, HEADING_1, HEADING_2, HEADING_3, HEADING_4, HEADING_5, HEADING_6];
|
71
73
|
export var WRAPPER_BLOCK_TYPES = [BLOCK_QUOTE, CODE_BLOCK, PANEL];
|
72
74
|
export var ALL_BLOCK_TYPES = TEXT_BLOCK_TYPES.concat(WRAPPER_BLOCK_TYPES);
|
75
|
+
export var getBlockTypesInDropdown = function getBlockTypesInDropdown(includeBlockQuoteAsTextstyleOption) {
|
76
|
+
return editorExperiment('platform_editor_blockquote_in_text_formatting_menu', true, {
|
77
|
+
exposure: true
|
78
|
+
}) && includeBlockQuoteAsTextstyleOption ? [].concat(TEXT_BLOCK_TYPES, [BLOCK_QUOTE]) : TEXT_BLOCK_TYPES;
|
79
|
+
};
|
73
80
|
export var HEADINGS_BY_LEVEL = TEXT_BLOCK_TYPES.reduce(function (acc, blockType) {
|
74
81
|
if (blockType.level && blockType.nodeName === 'heading') {
|
75
82
|
acc[blockType.level] = blockType;
|