@atlaskit/editor-plugin-block-type 4.0.13 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/dist/cjs/blockTypePlugin.js +3 -0
- package/dist/cjs/pm-plugins/block-types.js +3 -1
- package/dist/cjs/pm-plugins/commands/block-type.js +65 -11
- package/dist/cjs/pm-plugins/commands/clear-formatting.js +58 -0
- package/dist/cjs/pm-plugins/input-rule.js +18 -2
- package/dist/cjs/pm-plugins/keymap.js +26 -2
- package/dist/cjs/pm-plugins/main.js +14 -4
- package/dist/cjs/pm-plugins/ui/FloatingToolbarComponent.js +9 -1
- package/dist/cjs/pm-plugins/ui/PrimaryToolbarComponent.js +8 -0
- package/dist/cjs/pm-plugins/ui/ToolbarBlockType/blocktype-button.js +4 -1
- package/dist/cjs/pm-plugins/ui/ToolbarBlockType/index.js +83 -46
- package/dist/cjs/pm-plugins/ui/ToolbarBlockType/styled.js +15 -1
- package/dist/cjs/pm-plugins/utils.js +61 -7
- package/dist/es2019/blockTypePlugin.js +4 -1
- package/dist/es2019/pm-plugins/block-types.js +2 -0
- package/dist/es2019/pm-plugins/commands/block-type.js +57 -2
- package/dist/es2019/pm-plugins/commands/clear-formatting.js +50 -0
- package/dist/es2019/pm-plugins/input-rule.js +18 -2
- package/dist/es2019/pm-plugins/keymap.js +25 -2
- package/dist/es2019/pm-plugins/main.js +15 -5
- package/dist/es2019/pm-plugins/ui/FloatingToolbarComponent.js +9 -1
- package/dist/es2019/pm-plugins/ui/PrimaryToolbarComponent.js +8 -0
- package/dist/es2019/pm-plugins/ui/ToolbarBlockType/blocktype-button.js +4 -1
- package/dist/es2019/pm-plugins/ui/ToolbarBlockType/index.js +84 -49
- package/dist/es2019/pm-plugins/ui/ToolbarBlockType/styled.js +14 -0
- package/dist/es2019/pm-plugins/utils.js +63 -7
- package/dist/esm/blockTypePlugin.js +4 -1
- package/dist/esm/pm-plugins/block-types.js +2 -0
- package/dist/esm/pm-plugins/commands/block-type.js +62 -10
- package/dist/esm/pm-plugins/commands/clear-formatting.js +50 -0
- package/dist/esm/pm-plugins/input-rule.js +18 -2
- package/dist/esm/pm-plugins/keymap.js +25 -2
- package/dist/esm/pm-plugins/main.js +15 -5
- package/dist/esm/pm-plugins/ui/FloatingToolbarComponent.js +9 -1
- package/dist/esm/pm-plugins/ui/PrimaryToolbarComponent.js +8 -0
- package/dist/esm/pm-plugins/ui/ToolbarBlockType/blocktype-button.js +4 -1
- package/dist/esm/pm-plugins/ui/ToolbarBlockType/index.js +85 -48
- package/dist/esm/pm-plugins/ui/ToolbarBlockType/styled.js +14 -0
- package/dist/esm/pm-plugins/utils.js +61 -7
- package/dist/types/blockTypePluginType.d.ts +1 -0
- package/dist/types/pm-plugins/block-types.d.ts +2 -0
- package/dist/types/pm-plugins/commands/block-type.d.ts +1 -0
- package/dist/types/pm-plugins/commands/clear-formatting.d.ts +8 -0
- package/dist/types/pm-plugins/main.d.ts +2 -7
- package/dist/types/pm-plugins/ui/ToolbarBlockType/index.d.ts +1 -0
- package/dist/types/pm-plugins/ui/ToolbarBlockType/styled.d.ts +1 -0
- package/dist/types/pm-plugins/utils.d.ts +3 -0
- package/dist/types-ts4.5/blockTypePluginType.d.ts +1 -0
- package/dist/types-ts4.5/pm-plugins/block-types.d.ts +2 -0
- package/dist/types-ts4.5/pm-plugins/commands/block-type.d.ts +1 -0
- package/dist/types-ts4.5/pm-plugins/commands/clear-formatting.d.ts +8 -0
- package/dist/types-ts4.5/pm-plugins/main.d.ts +2 -7
- package/dist/types-ts4.5/pm-plugins/ui/ToolbarBlockType/index.d.ts +1 -0
- package/dist/types-ts4.5/pm-plugins/ui/ToolbarBlockType/styled.d.ts +1 -0
- package/dist/types-ts4.5/pm-plugins/utils.d.ts +3 -0
- package/package.json +3 -3
@@ -8,13 +8,16 @@ import React from 'react';
|
|
8
8
|
// eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
|
9
9
|
import { jsx } from '@emotion/react';
|
10
10
|
import { injectIntl } from 'react-intl-next';
|
11
|
-
import { findKeymapByDescription,
|
11
|
+
import { findKeymapByDescription, tooltip, clearFormatting } from '@atlaskit/editor-common/keymaps';
|
12
|
+
import { toolbarMessages } from '@atlaskit/editor-common/messages';
|
12
13
|
import { separatorStyles, wrapperStyle } from '@atlaskit/editor-common/styles';
|
13
14
|
import { DropdownMenuWithKeyboardNavigation as DropdownMenu } from '@atlaskit/editor-common/ui-menu';
|
14
15
|
import { akEditorMenuZIndex } from '@atlaskit/editor-shared-styles';
|
16
|
+
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
|
15
17
|
import { ThemeMutationObserver } from '@atlaskit/tokens';
|
18
|
+
import { NORMAL_TEXT } from '../../block-types';
|
16
19
|
import { BlockTypeButton } from './blocktype-button';
|
17
|
-
import { blockTypeMenuItemStyle, keyboardShortcut, keyboardShortcutSelect } from './styled';
|
20
|
+
import { blockTypeMenuItemStyle, keyboardShortcut, keyboardShortcutSelect, floatingToolbarWrapperStyle } from './styled';
|
18
21
|
// eslint-disable-next-line @repo/internal/react/no-class-components
|
19
22
|
class ToolbarBlockType extends React.PureComponent {
|
20
23
|
constructor(...args) {
|
@@ -56,23 +59,22 @@ class ToolbarBlockType extends React.PureComponent {
|
|
56
59
|
} = this.props;
|
57
60
|
const {
|
58
61
|
currentBlockType,
|
59
|
-
availableBlockTypesInDropdown
|
62
|
+
availableBlockTypesInDropdown,
|
63
|
+
formattingIsPresent
|
60
64
|
} = this.props.pluginState;
|
61
65
|
const items = availableBlockTypesInDropdown.map((blockType, index) => {
|
62
66
|
const isActive = currentBlockType === blockType;
|
63
67
|
const tagName = blockType.tagName || 'p';
|
64
68
|
const Tag = tagName;
|
65
69
|
const keyMap = findKeymapByDescription(blockType.title.defaultMessage);
|
66
|
-
|
70
|
+
const item = {
|
67
71
|
content:
|
68
72
|
// eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage, @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766
|
69
73
|
jsx("div", {
|
70
74
|
css: blockTypeMenuItemStyle(tagName, isActive, this.state.typographyTheme)
|
71
75
|
}, jsx(Tag, null, formatMessage(blockType.title))),
|
72
76
|
value: blockType,
|
73
|
-
label: formatMessage(blockType.title),
|
74
77
|
'aria-label': tooltip(keyMap, formatMessage(blockType.title)),
|
75
|
-
keyShortcuts: getAriaKeyshortcuts(keyMap),
|
76
78
|
key: `${blockType.name}-${index}`,
|
77
79
|
elemAfter:
|
78
80
|
// eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage, @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766
|
@@ -81,7 +83,30 @@ class ToolbarBlockType extends React.PureComponent {
|
|
81
83
|
}, tooltip(keyMap)),
|
82
84
|
isActive
|
83
85
|
};
|
86
|
+
return item;
|
84
87
|
});
|
88
|
+
if (availableBlockTypesInDropdown.map(blockType => blockType.name).includes('blockquote')) {
|
89
|
+
const clearFormattingItem = {
|
90
|
+
content: jsx("div", null, jsx("p", null, toolbarMessages.clearFormatting.defaultMessage)),
|
91
|
+
value: {
|
92
|
+
name: 'clearFormatting'
|
93
|
+
},
|
94
|
+
'aria-label': tooltip(clearFormatting, toolbarMessages.clearFormatting.defaultMessage),
|
95
|
+
key: 'clear-formatting',
|
96
|
+
elemAfter:
|
97
|
+
// eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage, @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766
|
98
|
+
jsx("div", {
|
99
|
+
css: [keyboardShortcut]
|
100
|
+
}, tooltip(clearFormatting)),
|
101
|
+
isActive: false,
|
102
|
+
isDisabled: currentBlockType === NORMAL_TEXT && !formattingIsPresent
|
103
|
+
};
|
104
|
+
return [{
|
105
|
+
items
|
106
|
+
}, {
|
107
|
+
items: [clearFormattingItem]
|
108
|
+
}];
|
109
|
+
}
|
85
110
|
return [{
|
86
111
|
items
|
87
112
|
}];
|
@@ -94,8 +119,12 @@ class ToolbarBlockType extends React.PureComponent {
|
|
94
119
|
if (blockType.name === 'blockquote') {
|
95
120
|
this.props.wrapBlockQuote(blockType.name);
|
96
121
|
} else {
|
97
|
-
|
98
|
-
|
122
|
+
if (blockType.name === 'clearFormatting') {
|
123
|
+
this.props.clearFormatting();
|
124
|
+
} else {
|
125
|
+
const fromBlockQuote = this.props.pluginState.currentBlockType.name === 'blockquote';
|
126
|
+
this.props.setTextLevel(blockType.name, fromBlockQuote);
|
127
|
+
}
|
99
128
|
}
|
100
129
|
if (shouldCloseMenu) {
|
101
130
|
this.setState({
|
@@ -152,50 +181,56 @@ class ToolbarBlockType extends React.PureComponent {
|
|
152
181
|
return null;
|
153
182
|
}
|
154
183
|
const blockTypeTitles = availableBlockTypesInDropdown.filter(blockType => blockType.name === currentBlockType.name).map(blockType => blockType.title);
|
155
|
-
if (!this.props.isDisabled &&
|
184
|
+
if (!this.props.isDisabled && !blockTypesDisabled) {
|
156
185
|
const items = this.createItems();
|
157
|
-
return (
|
186
|
+
return jsx("span", {
|
187
|
+
css: editorExperiment('platform_editor_blockquote_in_text_formatting_menu', true) ?
|
188
|
+
// eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage, @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766
|
189
|
+
[wrapperStyle, floatingToolbarWrapperStyle] :
|
158
190
|
// eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage, @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
191
|
+
wrapperStyle
|
192
|
+
}, jsx(DropdownMenu, {
|
193
|
+
items: items,
|
194
|
+
onOpenChange: this.onOpenChange,
|
195
|
+
onItemActivated: this.handleSelectBlockType,
|
196
|
+
isOpen: active,
|
197
|
+
mountTo: popupsMountPoint,
|
198
|
+
boundariesElement: popupsBoundariesElement,
|
199
|
+
scrollableElement: popupsScrollableElement,
|
200
|
+
zIndex: akEditorMenuZIndex,
|
201
|
+
fitHeight: 360,
|
202
|
+
fitWidth: 106,
|
203
|
+
section: {
|
204
|
+
hasSeparator: true
|
205
|
+
},
|
206
|
+
shouldUseDefaultRole: shouldUseDefaultRole
|
207
|
+
// hasSeparator={true}
|
208
|
+
,
|
209
|
+
shouldFocusFirstItem: () => {
|
210
|
+
if (isOpenedByKeyboard) {
|
211
|
+
// eslint-disable-next-line @repo/internal/react/no-set-state-inside-render
|
212
|
+
this.setState({
|
213
|
+
...this.state,
|
214
|
+
isOpenedByKeyboard: false
|
215
|
+
});
|
182
216
|
}
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
217
|
+
return isOpenedByKeyboard;
|
218
|
+
}
|
219
|
+
}, jsx(BlockTypeButton, {
|
220
|
+
isSmall: isSmall,
|
221
|
+
isReducedSpacing: isReducedSpacing,
|
222
|
+
selected: active,
|
223
|
+
disabled: false,
|
224
|
+
title: blockTypeTitles[0],
|
225
|
+
onClick: this.handleTriggerClick,
|
226
|
+
onKeyDown: this.handleTriggerByKeyboard,
|
227
|
+
formatMessage: formatMessage,
|
228
|
+
"aria-expanded": active,
|
229
|
+
blockTypeName: currentBlockType.name
|
230
|
+
})), !(api !== null && api !== void 0 && api.primaryToolbar) && jsx("span", {
|
231
|
+
// eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage, @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766
|
232
|
+
css: separatorStyles
|
233
|
+
}));
|
199
234
|
}
|
200
235
|
return (
|
201
236
|
// eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage, @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766
|
@@ -18,6 +18,12 @@ export const blockTypeMenuItemStyle = (tagName, selected, typographyTheme) => {
|
|
18
18
|
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors -- Ignored via go/DSP-18766
|
19
19
|
'h1, h2, h3, h4, h5, h6': {
|
20
20
|
marginTop: 0
|
21
|
+
},
|
22
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors -- Ignored via go/DSP-18766
|
23
|
+
blockquote: {
|
24
|
+
paddingTop: 0,
|
25
|
+
paddingBottom: 0,
|
26
|
+
marginTop: 0
|
21
27
|
}
|
22
28
|
}
|
23
29
|
},
|
@@ -45,4 +51,12 @@ export const wrapperSmallStyle = css({
|
|
45
51
|
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-exported-styles -- Ignored via go/DSP-18766
|
46
52
|
export const expandIconWrapperStyle = css({
|
47
53
|
marginLeft: "var(--ds-space-negative-100, -8px)"
|
54
|
+
});
|
55
|
+
|
56
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-exported-styles
|
57
|
+
export const floatingToolbarWrapperStyle = css({
|
58
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors
|
59
|
+
"[data-role='droplistContent']": {
|
60
|
+
maxHeight: '90vh'
|
61
|
+
}
|
48
62
|
});
|
@@ -1,7 +1,8 @@
|
|
1
|
+
import { anyMarkActive } from '@atlaskit/editor-common/mark';
|
1
2
|
import { createRule, createWrappingJoinRule } from '@atlaskit/editor-common/utils';
|
2
3
|
import { fg } from '@atlaskit/platform-feature-flags';
|
3
4
|
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
|
4
|
-
import { WRAPPER_BLOCK_TYPES } from './block-types';
|
5
|
+
import { WRAPPER_BLOCK_TYPES, FORMATTING_NODE_TYPES, FORMATTING_MARK_TYPES } from './block-types';
|
5
6
|
export const isNodeAWrappingBlockNode = node => {
|
6
7
|
if (!node) {
|
7
8
|
return false;
|
@@ -21,7 +22,10 @@ export const createWrappingTextBlockRule = ({
|
|
21
22
|
nodeType,
|
22
23
|
getAttrs
|
23
24
|
}) => {
|
24
|
-
const handler = (state, match, start, end
|
25
|
+
const handler = (state, match, start, end
|
26
|
+
// Ignored via go/ees005
|
27
|
+
// eslint-disable-next-line @typescript-eslint/max-params
|
28
|
+
) => {
|
25
29
|
const fixedStart = Math.max(start, 1);
|
26
30
|
const $start = state.doc.resolve(fixedStart);
|
27
31
|
const attrs = getAttrs instanceof Function ? getAttrs(match) : getAttrs;
|
@@ -77,19 +81,71 @@ export function areBlockTypesDisabled(state) {
|
|
77
81
|
const nodesTypes = getSelectedWrapperNodes(state);
|
78
82
|
const {
|
79
83
|
panel,
|
80
|
-
blockquote
|
84
|
+
blockquote,
|
85
|
+
bulletList,
|
86
|
+
orderedList
|
81
87
|
} = state.schema.nodes;
|
82
88
|
if (editorExperiment('platform_editor_blockquote_in_text_formatting_menu', true)) {
|
83
89
|
let hasQuote = false;
|
90
|
+
let hasNestedListInQuote = false;
|
84
91
|
const {
|
85
92
|
$from,
|
86
93
|
$to
|
87
94
|
} = state.selection;
|
88
95
|
state.doc.nodesBetween($from.pos, $to.pos, node => {
|
89
|
-
|
90
|
-
|
96
|
+
if (node.type === blockquote) {
|
97
|
+
hasQuote = true;
|
98
|
+
node.descendants(child => {
|
99
|
+
if (child.type === bulletList || child.type === orderedList) {
|
100
|
+
hasNestedListInQuote = true;
|
101
|
+
return false;
|
102
|
+
}
|
103
|
+
return true;
|
104
|
+
});
|
105
|
+
}
|
106
|
+
return !hasNestedListInQuote;
|
91
107
|
});
|
92
|
-
return nodesTypes.filter(type => type !== panel).length > 0 ||
|
108
|
+
return nodesTypes.filter(type => type !== panel).length > 0 && (!hasQuote || hasNestedListInQuote);
|
93
109
|
}
|
94
110
|
return nodesTypes.filter(type => type !== panel).length > 0;
|
95
|
-
}
|
111
|
+
}
|
112
|
+
const blockStylingIsPresent = state => {
|
113
|
+
const {
|
114
|
+
from,
|
115
|
+
to
|
116
|
+
} = state.selection;
|
117
|
+
let isBlockStyling = false;
|
118
|
+
state.doc.nodesBetween(from, to, node => {
|
119
|
+
if (FORMATTING_NODE_TYPES.indexOf(node.type.name) !== -1) {
|
120
|
+
isBlockStyling = true;
|
121
|
+
return false;
|
122
|
+
}
|
123
|
+
return true;
|
124
|
+
});
|
125
|
+
return isBlockStyling;
|
126
|
+
};
|
127
|
+
const marksArePresent = state => {
|
128
|
+
const activeMarkTypes = FORMATTING_MARK_TYPES.filter(mark => {
|
129
|
+
if (!!state.schema.marks[mark]) {
|
130
|
+
const {
|
131
|
+
$from,
|
132
|
+
empty
|
133
|
+
} = state.selection;
|
134
|
+
const {
|
135
|
+
marks
|
136
|
+
} = state.schema;
|
137
|
+
if (empty) {
|
138
|
+
return !!marks[mark].isInSet(state.storedMarks || $from.marks());
|
139
|
+
}
|
140
|
+
return anyMarkActive(state, marks[mark]);
|
141
|
+
}
|
142
|
+
return false;
|
143
|
+
});
|
144
|
+
return activeMarkTypes.length > 0;
|
145
|
+
};
|
146
|
+
export const checkFormattingIsPresent = state => {
|
147
|
+
return marksArePresent(state) || blockStylingIsPresent(state);
|
148
|
+
};
|
149
|
+
export const hasBlockQuoteInOptions = dropdownOptions => {
|
150
|
+
return !!dropdownOptions.find(blockType => blockType.name === 'blockquote');
|
151
|
+
};
|
@@ -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, insertBlockQuoteWithAnalyticsCommand } from './pm-plugins/commands/block-type';
|
11
|
+
import { setBlockTypeWithAnalytics, insertBlockQuoteWithAnalytics, insertBlockQuoteWithAnalyticsCommand, clearFormatting as _clearFormatting } 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';
|
@@ -184,6 +184,9 @@ var blockTypePlugin = function blockTypePlugin(_ref3) {
|
|
184
184
|
insertBlockQuote: function insertBlockQuote(inputMethod) {
|
185
185
|
var _api$analytics5;
|
186
186
|
return insertBlockQuoteWithAnalyticsCommand(inputMethod, api === null || api === void 0 || (_api$analytics5 = api.analytics) === null || _api$analytics5 === void 0 ? void 0 : _api$analytics5.actions);
|
187
|
+
},
|
188
|
+
clearFormatting: function clearFormatting() {
|
189
|
+
return _clearFormatting();
|
187
190
|
}
|
188
191
|
},
|
189
192
|
getSharedState: function getSharedState(editorState) {
|
@@ -70,6 +70,8 @@ export var OTHER = {
|
|
70
70
|
nodeName: ''
|
71
71
|
};
|
72
72
|
export var TEXT_BLOCK_TYPES = [NORMAL_TEXT, HEADING_1, HEADING_2, HEADING_3, HEADING_4, HEADING_5, HEADING_6];
|
73
|
+
export var FORMATTING_NODE_TYPES = ['heading', 'blockquote'];
|
74
|
+
export var FORMATTING_MARK_TYPES = ['em', 'code', 'strike', 'strong', 'underline', 'textColor', 'subsup', 'backgroundColor'];
|
73
75
|
export var WRAPPER_BLOCK_TYPES = [BLOCK_QUOTE, CODE_BLOCK, PANEL];
|
74
76
|
export var ALL_BLOCK_TYPES = TEXT_BLOCK_TYPES.concat(WRAPPER_BLOCK_TYPES);
|
75
77
|
export var getBlockTypesInDropdown = function getBlockTypesInDropdown(includeBlockQuoteAsTextstyleOption) {
|
@@ -7,6 +7,7 @@ import { filterChildrenBetween, wrapSelectionIn } from '@atlaskit/editor-common/
|
|
7
7
|
import { Slice, Fragment } from '@atlaskit/editor-prosemirror/model';
|
8
8
|
import { CellSelection } from '@atlaskit/editor-tables';
|
9
9
|
import { HEADINGS_BY_NAME, NORMAL_TEXT } from '../block-types';
|
10
|
+
import { FORMATTING_NODE_TYPES, FORMATTING_MARK_TYPES, cellSelectionNodesBetween, formatTypes, clearNodeFormattingOnSelection } from './clear-formatting';
|
10
11
|
import { wrapSelectionInBlockType } from './wrapSelectionIn';
|
11
12
|
export function setBlockType(name) {
|
12
13
|
return function (_ref) {
|
@@ -55,6 +56,9 @@ export function setHeading(level, fromBlockQuote) {
|
|
55
56
|
return tr;
|
56
57
|
};
|
57
58
|
}
|
59
|
+
|
60
|
+
// Ignored via go/ees005
|
61
|
+
// eslint-disable-next-line @typescript-eslint/max-params
|
58
62
|
export function setBlockTypeWithAnalytics(name, inputMethod, editorAnalyticsApi, fromBlockQuote) {
|
59
63
|
return function (_ref4) {
|
60
64
|
var tr = _ref4.tr;
|
@@ -95,9 +99,54 @@ export function setNormalText(fromBlockQuote) {
|
|
95
99
|
return tr;
|
96
100
|
};
|
97
101
|
}
|
98
|
-
function
|
102
|
+
export function clearFormatting() {
|
99
103
|
return function (_ref7) {
|
100
104
|
var tr = _ref7.tr;
|
105
|
+
var formattingCleared = [];
|
106
|
+
var schema = tr.doc.type.schema;
|
107
|
+
FORMATTING_MARK_TYPES.forEach(function (mark) {
|
108
|
+
var _tr$selection = tr.selection,
|
109
|
+
from = _tr$selection.from,
|
110
|
+
to = _tr$selection.to;
|
111
|
+
var markType = schema.marks[mark];
|
112
|
+
if (!markType) {
|
113
|
+
return;
|
114
|
+
}
|
115
|
+
if (tr.selection instanceof CellSelection) {
|
116
|
+
cellSelectionNodesBetween(tr.selection, tr.doc, function (node, pos) {
|
117
|
+
var isTableCell = node.type === schema.nodes.tableCell || node.type === schema.nodes.tableHeader;
|
118
|
+
if (!isTableCell) {
|
119
|
+
return true;
|
120
|
+
}
|
121
|
+
if (tr.doc.rangeHasMark(pos, pos + node.nodeSize, markType)) {
|
122
|
+
formattingCleared.push(formatTypes[mark]);
|
123
|
+
tr.removeMark(pos, pos + node.nodeSize, markType);
|
124
|
+
}
|
125
|
+
return false;
|
126
|
+
});
|
127
|
+
} else if (tr.doc.rangeHasMark(from, to, markType)) {
|
128
|
+
formattingCleared.push(formatTypes[mark]);
|
129
|
+
tr.removeMark(from, to, markType);
|
130
|
+
}
|
131
|
+
});
|
132
|
+
FORMATTING_NODE_TYPES.forEach(function (nodeName) {
|
133
|
+
var formattedNodeType = schema.nodes[nodeName];
|
134
|
+
var _tr$selection2 = tr.selection,
|
135
|
+
$from = _tr$selection2.$from,
|
136
|
+
$to = _tr$selection2.$to;
|
137
|
+
if (tr.selection instanceof CellSelection) {
|
138
|
+
cellSelectionNodesBetween(tr.selection, tr.doc, clearNodeFormattingOnSelection(schema, tr, formattedNodeType, nodeName, formattingCleared));
|
139
|
+
} else {
|
140
|
+
tr.doc.nodesBetween($from.pos, $to.pos, clearNodeFormattingOnSelection(schema, tr, formattedNodeType, nodeName, formattingCleared));
|
141
|
+
}
|
142
|
+
});
|
143
|
+
tr.setStoredMarks([]);
|
144
|
+
return tr;
|
145
|
+
};
|
146
|
+
}
|
147
|
+
function withCurrentHeadingLevel(fn) {
|
148
|
+
return function (_ref8) {
|
149
|
+
var tr = _ref8.tr;
|
101
150
|
// Find all headings and paragraphs of text
|
102
151
|
var _tr$doc$type$schema$n = tr.doc.type.schema.nodes,
|
103
152
|
heading = _tr$doc$type$schema$n.heading,
|
@@ -134,8 +183,8 @@ function withCurrentHeadingLevel(fn) {
|
|
134
183
|
}
|
135
184
|
export function setNormalTextWithAnalytics(inputMethod, editorAnalyticsApi, fromBlockQuote) {
|
136
185
|
return withCurrentHeadingLevel(function (previousHeadingLevel) {
|
137
|
-
return function (
|
138
|
-
var tr =
|
186
|
+
return function (_ref9) {
|
187
|
+
var tr = _ref9.tr;
|
139
188
|
editorAnalyticsApi === null || editorAnalyticsApi === void 0 || editorAnalyticsApi.attachAnalyticsEvent({
|
140
189
|
action: ACTION.FORMATTED,
|
141
190
|
actionSubject: ACTION_SUBJECT.TEXT,
|
@@ -153,10 +202,13 @@ export function setNormalTextWithAnalytics(inputMethod, editorAnalyticsApi, from
|
|
153
202
|
};
|
154
203
|
});
|
155
204
|
}
|
156
|
-
export var setHeadingWithAnalytics = function setHeadingWithAnalytics(newHeadingLevel, inputMethod, editorAnalyticsApi, fromBlockQuote
|
205
|
+
export var setHeadingWithAnalytics = function setHeadingWithAnalytics(newHeadingLevel, inputMethod, editorAnalyticsApi, fromBlockQuote
|
206
|
+
// Ignored via go/ees005
|
207
|
+
// eslint-disable-next-line @typescript-eslint/max-params
|
208
|
+
) {
|
157
209
|
return withCurrentHeadingLevel(function (previousHeadingLevel) {
|
158
|
-
return function (
|
159
|
-
var tr =
|
210
|
+
return function (_ref10) {
|
211
|
+
var tr = _ref10.tr;
|
160
212
|
editorAnalyticsApi === null || editorAnalyticsApi === void 0 || editorAnalyticsApi.attachAnalyticsEvent({
|
161
213
|
action: ACTION.FORMATTED,
|
162
214
|
actionSubject: ACTION_SUBJECT.TEXT,
|
@@ -205,8 +257,8 @@ export var insertBlockQuoteWithAnalytics = function insertBlockQuoteWithAnalytic
|
|
205
257
|
};
|
206
258
|
export function insertBlockQuoteWithAnalyticsCommand(inputMethod, editorAnalyticsApi) {
|
207
259
|
return withCurrentHeadingLevel(function (previousHeadingLevel) {
|
208
|
-
return function (
|
209
|
-
var tr =
|
260
|
+
return function (_ref11) {
|
261
|
+
var tr = _ref11.tr;
|
210
262
|
var nodes = tr.doc.type.schema.nodes;
|
211
263
|
|
212
264
|
// TODO: analytics event
|
@@ -228,8 +280,8 @@ export function insertBlockQuoteWithAnalyticsCommand(inputMethod, editorAnalytic
|
|
228
280
|
});
|
229
281
|
}
|
230
282
|
export var cleanUpAtTheStartOfDocument = function cleanUpAtTheStartOfDocument(state, dispatch) {
|
231
|
-
var
|
232
|
-
$cursor =
|
283
|
+
var _ref12 = state.selection,
|
284
|
+
$cursor = _ref12.$cursor;
|
233
285
|
if ($cursor && !$cursor.nodeBefore && !$cursor.nodeAfter && $cursor.pos === 1) {
|
234
286
|
var tr = state.tr,
|
235
287
|
schema = state.schema;
|
@@ -0,0 +1,50 @@
|
|
1
|
+
import { ACTION_SUBJECT_ID } from '@atlaskit/editor-common/analytics';
|
2
|
+
import { liftTarget } from '@atlaskit/editor-prosemirror/transform';
|
3
|
+
// Functions duplicated from platform/packages/editor/editor-plugin-text-formatting/src/editor-commands/clear-formatting.ts
|
4
|
+
// TODO: Refactor to avoid duplication if platform_editor_blockquote_in_text_formatting_menu experiment is productionalised
|
5
|
+
export var FORMATTING_NODE_TYPES = ['heading', 'blockquote'];
|
6
|
+
export var FORMATTING_MARK_TYPES = ['em', 'code', 'strike', 'strong', 'underline', 'textColor', 'subsup', 'backgroundColor'];
|
7
|
+
export var formatTypes = {
|
8
|
+
em: ACTION_SUBJECT_ID.FORMAT_ITALIC,
|
9
|
+
code: ACTION_SUBJECT_ID.FORMAT_CODE,
|
10
|
+
strike: ACTION_SUBJECT_ID.FORMAT_STRIKE,
|
11
|
+
strong: ACTION_SUBJECT_ID.FORMAT_STRONG,
|
12
|
+
underline: ACTION_SUBJECT_ID.FORMAT_UNDERLINE,
|
13
|
+
textColor: ACTION_SUBJECT_ID.FORMAT_COLOR,
|
14
|
+
subsup: 'subsup',
|
15
|
+
backgroundColor: ACTION_SUBJECT_ID.FORMAT_BACKGROUND_COLOR
|
16
|
+
};
|
17
|
+
export var cellSelectionNodesBetween = function cellSelectionNodesBetween(selection, doc, f, startPos
|
18
|
+
// eslint-disable-next-line @typescript-eslint/max-params
|
19
|
+
) {
|
20
|
+
selection.forEachCell(function (cell, cellPos) {
|
21
|
+
doc.nodesBetween(cellPos, cellPos + cell.nodeSize, f, startPos);
|
22
|
+
});
|
23
|
+
};
|
24
|
+
|
25
|
+
// eslint-disable-next-line @typescript-eslint/max-params
|
26
|
+
export function clearNodeFormattingOnSelection(schema, tr, formattedNodeType, nodeName, formattingCleared) {
|
27
|
+
return function (node, pos) {
|
28
|
+
if (node.type === formattedNodeType) {
|
29
|
+
if (formattedNodeType.isTextblock) {
|
30
|
+
tr.setNodeMarkup(pos, schema.nodes.paragraph);
|
31
|
+
formattingCleared.push(nodeName);
|
32
|
+
return false;
|
33
|
+
} else {
|
34
|
+
// In case of panel or blockquote
|
35
|
+
var fromPos = tr.doc.resolve(pos + 1);
|
36
|
+
var toPos = tr.doc.resolve(pos + node.nodeSize - 1);
|
37
|
+
var nodeRange = fromPos.blockRange(toPos);
|
38
|
+
if (nodeRange) {
|
39
|
+
var targetLiftDepth = liftTarget(nodeRange);
|
40
|
+
if (targetLiftDepth || targetLiftDepth === 0) {
|
41
|
+
formattingCleared.push(nodeName);
|
42
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
43
|
+
tr.lift(nodeRange, targetLiftDepth);
|
44
|
+
}
|
45
|
+
}
|
46
|
+
}
|
47
|
+
}
|
48
|
+
return true;
|
49
|
+
};
|
50
|
+
}
|
@@ -13,12 +13,16 @@ function getHeadingLevel(match) {
|
|
13
13
|
}
|
14
14
|
function headingRule(nodeType, maxLevel) {
|
15
15
|
return createWrappingTextBlockRule({
|
16
|
+
// Ignored via go/ees005
|
17
|
+
// eslint-disable-next-line require-unicode-regexp
|
16
18
|
match: new RegExp('^(#{1,' + maxLevel + '})\\s$'),
|
17
19
|
nodeType: nodeType,
|
18
20
|
getAttrs: getHeadingLevel
|
19
21
|
});
|
20
22
|
}
|
21
23
|
function blockQuoteRule(nodeType) {
|
24
|
+
// Ignored via go/ees005
|
25
|
+
// eslint-disable-next-line require-unicode-regexp
|
22
26
|
return createJoinNodesRule(/^\s*>\s$/, nodeType);
|
23
27
|
}
|
24
28
|
|
@@ -31,7 +35,13 @@ function blockQuoteRule(nodeType) {
|
|
31
35
|
function getHeadingRules(editorAnalyticsAPI, schema) {
|
32
36
|
// '# ' for h1, '## ' for h2 and etc
|
33
37
|
var hashRule = headingRule(schema.nodes.heading, MAX_HEADING_LEVEL);
|
34
|
-
var leftNodeReplacementHashRule = createRule(
|
38
|
+
var leftNodeReplacementHashRule = createRule(
|
39
|
+
// Ignored via go/ees005
|
40
|
+
// eslint-disable-next-line require-unicode-regexp
|
41
|
+
new RegExp("".concat(leafNodeReplacementCharacter, "(#{1,6})\\s$")),
|
42
|
+
// Ignored via go/ees005
|
43
|
+
// eslint-disable-next-line @typescript-eslint/max-params
|
44
|
+
function (state, match, start, end) {
|
35
45
|
var level = match[1].length;
|
36
46
|
return insertBlock(state, schema.nodes.heading, start, end, {
|
37
47
|
level: level
|
@@ -63,7 +73,13 @@ function getHeadingRules(editorAnalyticsAPI, schema) {
|
|
63
73
|
function getBlockQuoteRules(editorAnalyticsAPI, schema) {
|
64
74
|
// '> ' for blockquote
|
65
75
|
var greatherThanRule = blockQuoteRule(schema.nodes.blockquote);
|
66
|
-
var leftNodeReplacementGreatherRule = createRule(
|
76
|
+
var leftNodeReplacementGreatherRule = createRule(
|
77
|
+
// Ignored via go/ees005
|
78
|
+
// eslint-disable-next-line require-unicode-regexp
|
79
|
+
new RegExp("".concat(leafNodeReplacementCharacter, "\\s*>\\s$")),
|
80
|
+
// Ignored via go/ees005
|
81
|
+
// eslint-disable-next-line @typescript-eslint/max-params
|
82
|
+
function (state, _match, start, end) {
|
67
83
|
return insertBlock(state, schema.nodes.blockquote, start, end);
|
68
84
|
});
|
69
85
|
|
@@ -3,6 +3,8 @@ import { backspace, bindKeymapWithCommand, deleteKey, findKeyMapForBrowser, find
|
|
3
3
|
import { createNewParagraphAbove, createNewParagraphBelow, deleteEmptyParagraphAndMoveBlockUp, insertNewLineWithAnalytics } from '@atlaskit/editor-common/utils';
|
4
4
|
import { chainCommands } from '@atlaskit/editor-prosemirror/commands';
|
5
5
|
import { redo, undo } from '@atlaskit/editor-prosemirror/history';
|
6
|
+
// Ignored via go/ees005
|
7
|
+
// eslint-disable-next-line import/no-namespace
|
6
8
|
import * as blockTypes from './block-types';
|
7
9
|
import { cleanUpAtTheStartOfDocument, insertBlockQuoteWithAnalytics } from './commands/block-type';
|
8
10
|
import { deleteAndMoveCursor } from './commands/delete-and-move-cursor';
|
@@ -12,16 +14,37 @@ var backspaceCommand = chainCommands(cleanUpAtTheStartOfDocument, deleteBlockCon
|
|
12
14
|
var del = chainCommands(deleteEmptyParagraphAndMoveBlockUp(isNodeAWrappingBlockNode), deleteBlockContent(isNodeAWrappingBlockNode), deleteAndMoveCursor);
|
13
15
|
export default function keymapPlugin(editorAnalyticsApi, schema, _featureFlags) {
|
14
16
|
var list = {};
|
15
|
-
bindKeymapWithCommand(
|
17
|
+
bindKeymapWithCommand(
|
18
|
+
// Ignored via go/ees005
|
19
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
20
|
+
insertNewLine.common, insertNewLineWithAnalytics(editorAnalyticsApi), list);
|
21
|
+
// Ignored via go/ees005
|
22
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
16
23
|
bindKeymapWithCommand(moveUp.common, createNewParagraphAbove, list);
|
24
|
+
// Ignored via go/ees005
|
25
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
17
26
|
bindKeymapWithCommand(moveDown.common, createNewParagraphBelow, list);
|
27
|
+
// Ignored via go/ees005
|
28
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
18
29
|
bindKeymapWithCommand(findKeyMapForBrowser(redoKeymap), redo, list);
|
30
|
+
|
31
|
+
// Ignored via go/ees005
|
32
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
19
33
|
bindKeymapWithCommand(undoKeymap.common, undo, list);
|
34
|
+
|
35
|
+
// Ignored via go/ees005
|
36
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
20
37
|
bindKeymapWithCommand(backspace.common, backspaceCommand, list);
|
38
|
+
|
39
|
+
// Ignored via go/ees005
|
40
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
21
41
|
bindKeymapWithCommand(deleteKey.common, del, list);
|
22
42
|
bindKeymapWithCommand(forwardDelete.mac, del, list);
|
23
43
|
if (schema.nodes[blockTypes.BLOCK_QUOTE.nodeName]) {
|
24
|
-
bindKeymapWithCommand(
|
44
|
+
bindKeymapWithCommand(
|
45
|
+
// Ignored via go/ees005
|
46
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
47
|
+
findShortcutByKeymap(toggleBlockQuote), insertBlockQuoteWithAnalytics(INPUT_METHOD.KEYBOARD, editorAnalyticsApi), list);
|
25
48
|
}
|
26
49
|
return keymap(list);
|
27
50
|
}
|