@atlaskit/editor-plugin-block-type 4.0.11 → 4.0.13
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 +15 -0
- package/dist/cjs/blockTypePlugin.js +9 -4
- package/dist/cjs/pm-plugins/block-types.js +9 -2
- package/dist/cjs/pm-plugins/commands/block-type.js +64 -15
- package/dist/cjs/pm-plugins/commands/wrapSelectionIn.js +61 -0
- package/dist/cjs/pm-plugins/main.js +12 -4
- 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 +10 -6
- 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/main.js +11 -5
- 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/esm/blockTypePlugin.js +10 -5
- 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/main.js +13 -5
- 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/types/blockTypePluginType.d.ts +2 -1
- package/dist/types/pm-plugins/block-types.d.ts +1 -0
- package/dist/types/pm-plugins/commands/block-type.d.ts +6 -4
- 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/blockTypePluginType.d.ts +2 -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 -4
- 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 +5 -5
@@ -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
|
-
function setNormalText() {
|
87
|
+
export function setNormalText(fromBlockQuote) {
|
73
88
|
return function ({
|
74
89
|
tr
|
75
90
|
}) {
|
@@ -86,7 +101,15 @@ 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
|
+
}
|
@@ -3,7 +3,7 @@ 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';
|
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
7
|
import { setHeadingWithAnalytics, setNormalTextWithAnalytics } from './commands/block-type';
|
8
8
|
import { HEADING_KEYS } from './consts';
|
9
9
|
import { areBlockTypesDisabled } from './utils';
|
@@ -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
|
}
|
@@ -8,7 +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, insertBlockQuoteWithAnalytics } from './pm-plugins/commands/block-type';
|
11
|
+
import { setBlockTypeWithAnalytics, insertBlockQuoteWithAnalytics, insertBlockQuoteWithAnalyticsCommand } from './pm-plugins/commands/block-type';
|
12
12
|
import inputRulePlugin from './pm-plugins/input-rule';
|
13
13
|
import keymapPlugin from './pm-plugins/keymap';
|
14
14
|
import { createPlugin, pluginKey } from './pm-plugins/main';
|
@@ -146,7 +146,7 @@ var blockTypePlugin = function blockTypePlugin(_ref3) {
|
|
146
146
|
name: 'blockType',
|
147
147
|
plugin: function plugin(_ref5) {
|
148
148
|
var dispatch = _ref5.dispatch;
|
149
|
-
return createPlugin(api, dispatch, options && options.lastNodeMustBeParagraph);
|
149
|
+
return createPlugin(api, dispatch, options && options.lastNodeMustBeParagraph, options === null || options === void 0 ? void 0 : options.includeBlockQuoteAsTextstyleOption);
|
150
150
|
}
|
151
151
|
}, {
|
152
152
|
name: 'blockTypeInputRule',
|
@@ -178,7 +178,12 @@ var blockTypePlugin = function blockTypePlugin(_ref3) {
|
|
178
178
|
commands: {
|
179
179
|
setTextLevel: function setTextLevel(level, inputMethod) {
|
180
180
|
var _api$analytics4;
|
181
|
-
|
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);
|
182
187
|
}
|
183
188
|
},
|
184
189
|
getSharedState: function getSharedState(editorState) {
|
@@ -215,9 +220,9 @@ var blockTypePlugin = function blockTypePlugin(_ref3) {
|
|
215
220
|
}
|
216
221
|
},
|
217
222
|
quickInsert: function quickInsert(intl) {
|
218
|
-
var _api$
|
223
|
+
var _api$analytics6, _api$analytics7;
|
219
224
|
var exclude = options && options.allowBlockType && options.allowBlockType.exclude ? options.allowBlockType.exclude : [];
|
220
|
-
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)));
|
221
226
|
}
|
222
227
|
}
|
223
228
|
};
|
@@ -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;
|
@@ -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
|
-
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 @@ 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;
|