@atlaskit/editor-plugin-text-formatting 0.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/.eslintrc.js +7 -0
- package/CHANGELOG.md +1 -0
- package/LICENSE.md +13 -0
- package/README.md +9 -0
- package/dist/cjs/actions.js +188 -0
- package/dist/cjs/commands/clear-formatting.js +111 -0
- package/dist/cjs/commands/text-formatting.js +143 -0
- package/dist/cjs/commands/transform-to-code.js +68 -0
- package/dist/cjs/index.js +12 -0
- package/dist/cjs/plugin.js +133 -0
- package/dist/cjs/pm-plugins/clear-formatting-keymap.js +21 -0
- package/dist/cjs/pm-plugins/clear-formatting.js +36 -0
- package/dist/cjs/pm-plugins/cursor.js +55 -0
- package/dist/cjs/pm-plugins/input-rule.js +274 -0
- package/dist/cjs/pm-plugins/keymap.js +52 -0
- package/dist/cjs/pm-plugins/main.js +113 -0
- package/dist/cjs/pm-plugins/plugin-key.js +9 -0
- package/dist/cjs/pm-plugins/smart-input-rule.js +176 -0
- package/dist/cjs/ui/Toolbar/constants.js +19 -0
- package/dist/cjs/ui/Toolbar/dropdown-menu.js +86 -0
- package/dist/cjs/ui/Toolbar/hooks/clear-formatting-icon.js +55 -0
- package/dist/cjs/ui/Toolbar/hooks/formatting-icons.js +227 -0
- package/dist/cjs/ui/Toolbar/hooks/menu-state.js +23 -0
- package/dist/cjs/ui/Toolbar/hooks/responsive-toolbar-buttons.js +60 -0
- package/dist/cjs/ui/Toolbar/index.js +183 -0
- package/dist/cjs/ui/Toolbar/more-button.js +42 -0
- package/dist/cjs/ui/Toolbar/single-toolbar-buttons.js +49 -0
- package/dist/cjs/ui/Toolbar/types.js +17 -0
- package/dist/cjs/utils/cell-selection.js +12 -0
- package/dist/cjs/utils.js +86 -0
- package/dist/cjs/version.json +5 -0
- package/dist/es2019/actions.js +161 -0
- package/dist/es2019/commands/clear-formatting.js +105 -0
- package/dist/es2019/commands/text-formatting.js +144 -0
- package/dist/es2019/commands/transform-to-code.js +71 -0
- package/dist/es2019/index.js +1 -0
- package/dist/es2019/plugin.js +124 -0
- package/dist/es2019/pm-plugins/clear-formatting-keymap.js +10 -0
- package/dist/es2019/pm-plugins/clear-formatting.js +26 -0
- package/dist/es2019/pm-plugins/cursor.js +52 -0
- package/dist/es2019/pm-plugins/input-rule.js +242 -0
- package/dist/es2019/pm-plugins/keymap.js +43 -0
- package/dist/es2019/pm-plugins/main.js +110 -0
- package/dist/es2019/pm-plugins/plugin-key.js +2 -0
- package/dist/es2019/pm-plugins/smart-input-rule.js +155 -0
- package/dist/es2019/ui/Toolbar/constants.js +20 -0
- package/dist/es2019/ui/Toolbar/dropdown-menu.js +66 -0
- package/dist/es2019/ui/Toolbar/hooks/clear-formatting-icon.js +44 -0
- package/dist/es2019/ui/Toolbar/hooks/formatting-icons.js +212 -0
- package/dist/es2019/ui/Toolbar/hooks/menu-state.js +11 -0
- package/dist/es2019/ui/Toolbar/hooks/responsive-toolbar-buttons.js +48 -0
- package/dist/es2019/ui/Toolbar/index.js +168 -0
- package/dist/es2019/ui/Toolbar/more-button.js +34 -0
- package/dist/es2019/ui/Toolbar/single-toolbar-buttons.js +39 -0
- package/dist/es2019/ui/Toolbar/types.js +10 -0
- package/dist/es2019/utils/cell-selection.js +5 -0
- package/dist/es2019/utils.js +74 -0
- package/dist/es2019/version.json +5 -0
- package/dist/esm/actions.js +168 -0
- package/dist/esm/commands/clear-formatting.js +101 -0
- package/dist/esm/commands/text-formatting.js +134 -0
- package/dist/esm/commands/transform-to-code.js +61 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/plugin.js +125 -0
- package/dist/esm/pm-plugins/clear-formatting-keymap.js +10 -0
- package/dist/esm/pm-plugins/clear-formatting.js +28 -0
- package/dist/esm/pm-plugins/cursor.js +48 -0
- package/dist/esm/pm-plugins/input-rule.js +257 -0
- package/dist/esm/pm-plugins/keymap.js +43 -0
- package/dist/esm/pm-plugins/main.js +99 -0
- package/dist/esm/pm-plugins/plugin-key.js +2 -0
- package/dist/esm/pm-plugins/smart-input-rule.js +169 -0
- package/dist/esm/ui/Toolbar/constants.js +8 -0
- package/dist/esm/ui/Toolbar/dropdown-menu.js +75 -0
- package/dist/esm/ui/Toolbar/hooks/clear-formatting-icon.js +47 -0
- package/dist/esm/ui/Toolbar/hooks/formatting-icons.js +215 -0
- package/dist/esm/ui/Toolbar/hooks/menu-state.js +15 -0
- package/dist/esm/ui/Toolbar/hooks/responsive-toolbar-buttons.js +50 -0
- package/dist/esm/ui/Toolbar/index.js +174 -0
- package/dist/esm/ui/Toolbar/more-button.js +33 -0
- package/dist/esm/ui/Toolbar/single-toolbar-buttons.js +38 -0
- package/dist/esm/ui/Toolbar/types.js +10 -0
- package/dist/esm/utils/cell-selection.js +5 -0
- package/dist/esm/utils.js +75 -0
- package/dist/esm/version.json +5 -0
- package/dist/types/actions.d.ts +22 -0
- package/dist/types/commands/clear-formatting.d.ts +6 -0
- package/dist/types/commands/text-formatting.d.ts +5 -0
- package/dist/types/commands/transform-to-code.d.ts +2 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/plugin.d.ts +17 -0
- package/dist/types/pm-plugins/clear-formatting-keymap.d.ts +4 -0
- package/dist/types/pm-plugins/clear-formatting.d.ts +8 -0
- package/dist/types/pm-plugins/cursor.d.ts +3 -0
- package/dist/types/pm-plugins/input-rule.d.ts +23 -0
- package/dist/types/pm-plugins/keymap.d.ts +4 -0
- package/dist/types/pm-plugins/main.d.ts +7 -0
- package/dist/types/pm-plugins/plugin-key.d.ts +3 -0
- package/dist/types/pm-plugins/smart-input-rule.d.ts +3 -0
- package/dist/types/ui/Toolbar/constants.d.ts +6 -0
- package/dist/types/ui/Toolbar/dropdown-menu.d.ts +15 -0
- package/dist/types/ui/Toolbar/hooks/clear-formatting-icon.d.ts +7 -0
- package/dist/types/ui/Toolbar/hooks/formatting-icons.d.ts +14 -0
- package/dist/types/ui/Toolbar/hooks/menu-state.d.ts +1 -0
- package/dist/types/ui/Toolbar/hooks/responsive-toolbar-buttons.d.ts +20 -0
- package/dist/types/ui/Toolbar/index.d.ts +25 -0
- package/dist/types/ui/Toolbar/more-button.d.ts +14 -0
- package/dist/types/ui/Toolbar/single-toolbar-buttons.d.ts +10 -0
- package/dist/types/ui/Toolbar/types.d.ts +32 -0
- package/dist/types/utils/cell-selection.d.ts +3 -0
- package/dist/types/utils.d.ts +11 -0
- package/dist/types-ts4.5/actions.d.ts +22 -0
- package/dist/types-ts4.5/commands/clear-formatting.d.ts +6 -0
- package/dist/types-ts4.5/commands/text-formatting.d.ts +5 -0
- package/dist/types-ts4.5/commands/transform-to-code.d.ts +2 -0
- package/dist/types-ts4.5/index.d.ts +3 -0
- package/dist/types-ts4.5/plugin.d.ts +19 -0
- package/dist/types-ts4.5/pm-plugins/clear-formatting-keymap.d.ts +4 -0
- package/dist/types-ts4.5/pm-plugins/clear-formatting.d.ts +8 -0
- package/dist/types-ts4.5/pm-plugins/cursor.d.ts +3 -0
- package/dist/types-ts4.5/pm-plugins/input-rule.d.ts +23 -0
- package/dist/types-ts4.5/pm-plugins/keymap.d.ts +4 -0
- package/dist/types-ts4.5/pm-plugins/main.d.ts +7 -0
- package/dist/types-ts4.5/pm-plugins/plugin-key.d.ts +3 -0
- package/dist/types-ts4.5/pm-plugins/smart-input-rule.d.ts +3 -0
- package/dist/types-ts4.5/ui/Toolbar/constants.d.ts +6 -0
- package/dist/types-ts4.5/ui/Toolbar/dropdown-menu.d.ts +15 -0
- package/dist/types-ts4.5/ui/Toolbar/hooks/clear-formatting-icon.d.ts +7 -0
- package/dist/types-ts4.5/ui/Toolbar/hooks/formatting-icons.d.ts +14 -0
- package/dist/types-ts4.5/ui/Toolbar/hooks/menu-state.d.ts +5 -0
- package/dist/types-ts4.5/ui/Toolbar/hooks/responsive-toolbar-buttons.d.ts +20 -0
- package/dist/types-ts4.5/ui/Toolbar/index.d.ts +25 -0
- package/dist/types-ts4.5/ui/Toolbar/more-button.d.ts +14 -0
- package/dist/types-ts4.5/ui/Toolbar/single-toolbar-buttons.d.ts +10 -0
- package/dist/types-ts4.5/ui/Toolbar/types.d.ts +32 -0
- package/dist/types-ts4.5/utils/cell-selection.d.ts +3 -0
- package/dist/types-ts4.5/utils.d.ts +11 -0
- package/package.json +93 -0
- package/report.api.md +66 -0
- package/tmp/api-report-tmp.d.ts +39 -0
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { code, em, strike, strong, subsup, underline } from '@atlaskit/adf-schema';
|
|
3
|
+
import { WithPluginState } from '@atlaskit/editor-common/with-plugin-state';
|
|
4
|
+
import { toggleCodeWithAnalytics, toggleEmWithAnalytics, toggleStrikeWithAnalytics, toggleStrongWithAnalytics, toggleSubscriptWithAnalytics, toggleSuperscriptWithAnalytics, toggleUnderlineWithAnalytics } from './actions';
|
|
5
|
+
import { plugin as clearFormattingPlugin, pluginKey as clearFormattingPluginKey } from './pm-plugins/clear-formatting';
|
|
6
|
+
import clearFormattingKeymapPlugin from './pm-plugins/clear-formatting-keymap';
|
|
7
|
+
import textFormattingCursorPlugin from './pm-plugins/cursor';
|
|
8
|
+
import textFormattingInputRulePlugin from './pm-plugins/input-rule';
|
|
9
|
+
import keymapPlugin from './pm-plugins/keymap';
|
|
10
|
+
import { plugin as pmPlugin, pluginKey as textFormattingPluginKey } from './pm-plugins/main';
|
|
11
|
+
import textFormattingSmartInputRulePlugin from './pm-plugins/smart-input-rule';
|
|
12
|
+
import Toolbar from './ui/Toolbar';
|
|
13
|
+
export const textFormattingPlugin = (options = {}, api) => {
|
|
14
|
+
var _api$dependencies$ana7, _api$dependencies$ana8, _api$dependencies$ana9, _api$dependencies$ana10, _api$dependencies$ana11, _api$dependencies$ana12, _api$dependencies$ana13;
|
|
15
|
+
return {
|
|
16
|
+
name: 'textFormatting',
|
|
17
|
+
marks() {
|
|
18
|
+
return [{
|
|
19
|
+
name: 'em',
|
|
20
|
+
mark: em
|
|
21
|
+
}, {
|
|
22
|
+
name: 'strong',
|
|
23
|
+
mark: strong
|
|
24
|
+
}, {
|
|
25
|
+
name: 'strike',
|
|
26
|
+
mark: strike
|
|
27
|
+
}].concat(options.disableCode ? [] : {
|
|
28
|
+
name: 'code',
|
|
29
|
+
mark: code
|
|
30
|
+
}).concat(options.disableSuperscriptAndSubscript ? [] : {
|
|
31
|
+
name: 'subsup',
|
|
32
|
+
mark: subsup
|
|
33
|
+
}).concat(options.disableUnderline ? [] : {
|
|
34
|
+
name: 'underline',
|
|
35
|
+
mark: underline
|
|
36
|
+
});
|
|
37
|
+
},
|
|
38
|
+
pmPlugins() {
|
|
39
|
+
return [{
|
|
40
|
+
name: 'textFormatting',
|
|
41
|
+
plugin: ({
|
|
42
|
+
dispatch
|
|
43
|
+
}) => {
|
|
44
|
+
var _api$dependencies$ana;
|
|
45
|
+
return pmPlugin(dispatch, api === null || api === void 0 ? void 0 : (_api$dependencies$ana = api.dependencies.analytics) === null || _api$dependencies$ana === void 0 ? void 0 : _api$dependencies$ana.actions);
|
|
46
|
+
}
|
|
47
|
+
}, {
|
|
48
|
+
name: 'textFormattingCursor',
|
|
49
|
+
plugin: () => textFormattingCursorPlugin
|
|
50
|
+
}, {
|
|
51
|
+
name: 'textFormattingInputRule',
|
|
52
|
+
plugin: ({
|
|
53
|
+
schema
|
|
54
|
+
}) => {
|
|
55
|
+
var _api$dependencies$ana2;
|
|
56
|
+
return textFormattingInputRulePlugin(schema, api === null || api === void 0 ? void 0 : (_api$dependencies$ana2 = api.dependencies.analytics) === null || _api$dependencies$ana2 === void 0 ? void 0 : _api$dependencies$ana2.actions);
|
|
57
|
+
}
|
|
58
|
+
}, {
|
|
59
|
+
name: 'textFormattingSmartRule',
|
|
60
|
+
plugin: () => {
|
|
61
|
+
var _api$dependencies$ana3;
|
|
62
|
+
return !options.disableSmartTextCompletion ? textFormattingSmartInputRulePlugin(api === null || api === void 0 ? void 0 : (_api$dependencies$ana3 = api.dependencies.analytics) === null || _api$dependencies$ana3 === void 0 ? void 0 : _api$dependencies$ana3.actions) : undefined;
|
|
63
|
+
}
|
|
64
|
+
}, {
|
|
65
|
+
name: 'textFormattingClear',
|
|
66
|
+
plugin: ({
|
|
67
|
+
dispatch
|
|
68
|
+
}) => clearFormattingPlugin(dispatch)
|
|
69
|
+
}, {
|
|
70
|
+
name: 'textFormattingClearKeymap',
|
|
71
|
+
plugin: () => {
|
|
72
|
+
var _api$dependencies$ana4;
|
|
73
|
+
return clearFormattingKeymapPlugin(api === null || api === void 0 ? void 0 : (_api$dependencies$ana4 = api.dependencies.analytics) === null || _api$dependencies$ana4 === void 0 ? void 0 : _api$dependencies$ana4.actions);
|
|
74
|
+
}
|
|
75
|
+
}, {
|
|
76
|
+
name: 'textFormattingKeymap',
|
|
77
|
+
plugin: ({
|
|
78
|
+
schema
|
|
79
|
+
}) => {
|
|
80
|
+
var _api$dependencies$ana5;
|
|
81
|
+
return keymapPlugin(schema, api === null || api === void 0 ? void 0 : (_api$dependencies$ana5 = api.dependencies.analytics) === null || _api$dependencies$ana5 === void 0 ? void 0 : _api$dependencies$ana5.actions);
|
|
82
|
+
}
|
|
83
|
+
}];
|
|
84
|
+
},
|
|
85
|
+
primaryToolbarComponent({
|
|
86
|
+
editorView,
|
|
87
|
+
popupsMountPoint,
|
|
88
|
+
popupsScrollableElement,
|
|
89
|
+
isToolbarReducedSpacing,
|
|
90
|
+
toolbarSize,
|
|
91
|
+
disabled
|
|
92
|
+
}) {
|
|
93
|
+
return /*#__PURE__*/React.createElement(WithPluginState, {
|
|
94
|
+
plugins: {
|
|
95
|
+
textFormattingState: textFormattingPluginKey,
|
|
96
|
+
clearFormattingPluginState: clearFormattingPluginKey
|
|
97
|
+
},
|
|
98
|
+
render: () => {
|
|
99
|
+
var _api$dependencies$ana6;
|
|
100
|
+
return /*#__PURE__*/React.createElement(Toolbar, {
|
|
101
|
+
editorState: editorView.state,
|
|
102
|
+
popupsMountPoint: popupsMountPoint,
|
|
103
|
+
popupsScrollableElement: popupsScrollableElement,
|
|
104
|
+
toolbarSize: toolbarSize,
|
|
105
|
+
isReducedSpacing: isToolbarReducedSpacing,
|
|
106
|
+
editorView: editorView,
|
|
107
|
+
isToolbarDisabled: disabled,
|
|
108
|
+
shouldUseResponsiveToolbar: Boolean(options.responsiveToolbarMenu),
|
|
109
|
+
editorAnalyticsAPI: api === null || api === void 0 ? void 0 : (_api$dependencies$ana6 = api.dependencies.analytics) === null || _api$dependencies$ana6 === void 0 ? void 0 : _api$dependencies$ana6.actions
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
},
|
|
114
|
+
actions: {
|
|
115
|
+
toggleSuperscript: toggleSuperscriptWithAnalytics(api === null || api === void 0 ? void 0 : (_api$dependencies$ana7 = api.dependencies.analytics) === null || _api$dependencies$ana7 === void 0 ? void 0 : _api$dependencies$ana7.actions),
|
|
116
|
+
toggleSubscript: toggleSubscriptWithAnalytics(api === null || api === void 0 ? void 0 : (_api$dependencies$ana8 = api.dependencies.analytics) === null || _api$dependencies$ana8 === void 0 ? void 0 : _api$dependencies$ana8.actions),
|
|
117
|
+
toggleStrike: toggleStrikeWithAnalytics(api === null || api === void 0 ? void 0 : (_api$dependencies$ana9 = api.dependencies.analytics) === null || _api$dependencies$ana9 === void 0 ? void 0 : _api$dependencies$ana9.actions),
|
|
118
|
+
toggleCode: toggleCodeWithAnalytics(api === null || api === void 0 ? void 0 : (_api$dependencies$ana10 = api.dependencies.analytics) === null || _api$dependencies$ana10 === void 0 ? void 0 : _api$dependencies$ana10.actions),
|
|
119
|
+
toggleUnderline: toggleUnderlineWithAnalytics(api === null || api === void 0 ? void 0 : (_api$dependencies$ana11 = api.dependencies.analytics) === null || _api$dependencies$ana11 === void 0 ? void 0 : _api$dependencies$ana11.actions),
|
|
120
|
+
toggleEm: toggleEmWithAnalytics(api === null || api === void 0 ? void 0 : (_api$dependencies$ana12 = api.dependencies.analytics) === null || _api$dependencies$ana12 === void 0 ? void 0 : _api$dependencies$ana12.actions),
|
|
121
|
+
toggleStrong: toggleStrongWithAnalytics(api === null || api === void 0 ? void 0 : (_api$dependencies$ana13 = api.dependencies.analytics) === null || _api$dependencies$ana13 === void 0 ? void 0 : _api$dependencies$ana13.actions)
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { INPUT_METHOD } from '@atlaskit/editor-common/analytics';
|
|
2
|
+
import * as keymaps from '@atlaskit/editor-common/keymaps';
|
|
3
|
+
import { keymap } from '@atlaskit/editor-prosemirror/keymap';
|
|
4
|
+
import { clearFormattingWithAnalytics } from '../commands/clear-formatting';
|
|
5
|
+
export function keymapPlugin(editorAnalyticsAPI) {
|
|
6
|
+
const list = {};
|
|
7
|
+
keymaps.bindKeymapWithCommand(keymaps.clearFormatting.common, clearFormattingWithAnalytics(INPUT_METHOD.SHORTCUT, editorAnalyticsAPI), list);
|
|
8
|
+
return keymap(list);
|
|
9
|
+
}
|
|
10
|
+
export default keymapPlugin;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
2
|
+
import { PluginKey } from '@atlaskit/editor-prosemirror/state';
|
|
3
|
+
import { checkFormattingIsPresent } from '../utils';
|
|
4
|
+
export const pluginKey = new PluginKey('clearFormattingPlugin');
|
|
5
|
+
export const plugin = dispatch => new SafePlugin({
|
|
6
|
+
state: {
|
|
7
|
+
init(_config, state) {
|
|
8
|
+
return {
|
|
9
|
+
formattingIsPresent: checkFormattingIsPresent(state)
|
|
10
|
+
};
|
|
11
|
+
},
|
|
12
|
+
apply(_tr, pluginState, _oldState, newState) {
|
|
13
|
+
const formattingIsPresent = checkFormattingIsPresent(newState);
|
|
14
|
+
if (formattingIsPresent !== pluginState.formattingIsPresent) {
|
|
15
|
+
dispatch(pluginKey, {
|
|
16
|
+
formattingIsPresent
|
|
17
|
+
});
|
|
18
|
+
return {
|
|
19
|
+
formattingIsPresent
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
return pluginState;
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
key: pluginKey
|
|
26
|
+
});
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
2
|
+
import { TextSelection } from '@atlaskit/editor-prosemirror/state';
|
|
3
|
+
export default new SafePlugin({
|
|
4
|
+
props: {
|
|
5
|
+
handleClick(view, clickPos, event) {
|
|
6
|
+
// Don't apply in Edge as per ED-4546
|
|
7
|
+
if (navigator && /Edge\/\d/.test(navigator.userAgent)) {
|
|
8
|
+
return false;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// @see ED-6231
|
|
12
|
+
if (clickPos > view.state.doc.content.size) {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
const {
|
|
16
|
+
code
|
|
17
|
+
} = view.state.schema.marks;
|
|
18
|
+
const {
|
|
19
|
+
paragraph
|
|
20
|
+
} = view.state.schema.nodes;
|
|
21
|
+
const $click = view.state.doc.resolve(clickPos);
|
|
22
|
+
const clickWasAtEdgeOfATextNode = ($click.nodeBefore ? $click.nodeBefore.isInline : $click.nodeAfter) && ($click.nodeAfter ? $click.nodeAfter.isInline : $click.nodeBefore) && $click.textOffset === 0;
|
|
23
|
+
const clickWasNearACodeMark = code && ($click.nodeBefore && code.isInSet($click.nodeBefore.marks) || $click.nodeAfter && code.isInSet($click.nodeAfter.marks));
|
|
24
|
+
|
|
25
|
+
// Find the starting position of the clicked dom-element
|
|
26
|
+
// TODO: Remove calls to private API
|
|
27
|
+
const clickedDOMElementPosition = event.target && event.target instanceof Node && view.posAtDOM(event.target);
|
|
28
|
+
const clickNode = view.state.doc.nodeAt(clickPos);
|
|
29
|
+
const clickWasAtTextNode = !!(clickNode && clickNode.isText);
|
|
30
|
+
const clickWasAtEndOfAParagraphNode = $click.parent.type === paragraph && $click.textOffset === 0 && $click.nodeAfter === null;
|
|
31
|
+
if (clickWasAtEdgeOfATextNode && clickWasNearACodeMark && clickedDOMElementPosition && (
|
|
32
|
+
// if click did not occur at a text node or end of paragraph, then
|
|
33
|
+
// it was at a directly adjacent non-text node, so we skip this manual
|
|
34
|
+
// text selection logic to preserve that non-text node's selection
|
|
35
|
+
clickWasAtTextNode || clickWasAtEndOfAParagraphNode)) {
|
|
36
|
+
const clickWasInsideNodeDOM = event.target.parentNode === view.domAtPos(clickedDOMElementPosition).node && code.isInSet(view.state.doc.resolve(clickedDOMElementPosition).nodeAfter.marks);
|
|
37
|
+
const nodeNextToClick = $click.nodeBefore && code.isInSet($click.nodeBefore.marks) ? $click.nodeAfter : $click.nodeBefore;
|
|
38
|
+
|
|
39
|
+
// Need to set the selection here to allow clicking between [code('text'),{<>},emoji()]
|
|
40
|
+
const tr = view.state.tr.setSelection(TextSelection.near($click));
|
|
41
|
+
if (clickWasInsideNodeDOM) {
|
|
42
|
+
tr.setStoredMarks([code.create()]);
|
|
43
|
+
} else {
|
|
44
|
+
tr.setStoredMarks(nodeNextToClick ? nodeNextToClick.marks : []);
|
|
45
|
+
}
|
|
46
|
+
view.dispatch(tr);
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
});
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE, INPUT_METHOD } from '@atlaskit/editor-common/analytics';
|
|
2
|
+
import { transformSmartCharsMentionsAndEmojis } from '@atlaskit/editor-common/mark';
|
|
3
|
+
import { inputRuleWithAnalytics } from '@atlaskit/editor-common/utils';
|
|
4
|
+
import { createPlugin, createRule, leafNodeReplacementCharacter } from '@atlaskit/prosemirror-input-rules';
|
|
5
|
+
var ValidAutoformatChars = /*#__PURE__*/function (ValidAutoformatChars) {
|
|
6
|
+
ValidAutoformatChars["STRONG"] = "__";
|
|
7
|
+
ValidAutoformatChars["STRIKE"] = "~~";
|
|
8
|
+
ValidAutoformatChars["STRONG_MARKDOWN"] = "**";
|
|
9
|
+
ValidAutoformatChars["ITALIC_MARKDOWN"] = "*";
|
|
10
|
+
ValidAutoformatChars["ITALIC"] = "_";
|
|
11
|
+
ValidAutoformatChars["CODE"] = "`";
|
|
12
|
+
return ValidAutoformatChars;
|
|
13
|
+
}(ValidAutoformatChars || {});
|
|
14
|
+
export const ValidCombinations = {
|
|
15
|
+
[ValidAutoformatChars.STRIKE]: [
|
|
16
|
+
// e.g: _~~lol~~_
|
|
17
|
+
ValidAutoformatChars.ITALIC,
|
|
18
|
+
// e.g: __~~lol~~__
|
|
19
|
+
ValidAutoformatChars.STRONG,
|
|
20
|
+
// e.g: **~~lol~~**
|
|
21
|
+
ValidAutoformatChars.STRONG_MARKDOWN,
|
|
22
|
+
// e.g: *~~lol~~*
|
|
23
|
+
ValidAutoformatChars.ITALIC_MARKDOWN],
|
|
24
|
+
[ValidAutoformatChars.STRONG]: [
|
|
25
|
+
// e.g: ~~__lol__~~
|
|
26
|
+
ValidAutoformatChars.STRIKE,
|
|
27
|
+
// e.g: *__lol__*
|
|
28
|
+
ValidAutoformatChars.ITALIC_MARKDOWN],
|
|
29
|
+
[ValidAutoformatChars.STRONG_MARKDOWN]: [
|
|
30
|
+
// e.g: _**lol**_
|
|
31
|
+
ValidAutoformatChars.ITALIC,
|
|
32
|
+
// e.g: ~~**lol**~~
|
|
33
|
+
ValidAutoformatChars.STRIKE],
|
|
34
|
+
[ValidAutoformatChars.ITALIC_MARKDOWN]: [
|
|
35
|
+
// e.g: ~~*lol*~~
|
|
36
|
+
ValidAutoformatChars.STRIKE,
|
|
37
|
+
// e.g: __*lol*__
|
|
38
|
+
ValidAutoformatChars.STRONG],
|
|
39
|
+
[ValidAutoformatChars.ITALIC]: [
|
|
40
|
+
// e.g: ~~_lol_~~
|
|
41
|
+
ValidAutoformatChars.STRIKE,
|
|
42
|
+
// e.g: **_lol_**
|
|
43
|
+
ValidAutoformatChars.STRONG_MARKDOWN],
|
|
44
|
+
[ValidAutoformatChars.CODE]: [
|
|
45
|
+
// e.g: loko (`some code`
|
|
46
|
+
'( ']
|
|
47
|
+
};
|
|
48
|
+
function addMark(markType, schema, char) {
|
|
49
|
+
return (state, match, start, end) => {
|
|
50
|
+
var _schema$marks, _schema$marks$code;
|
|
51
|
+
const {
|
|
52
|
+
doc,
|
|
53
|
+
schema,
|
|
54
|
+
tr
|
|
55
|
+
} = state;
|
|
56
|
+
const textPrefix = state.doc.textBetween(start, start + char.length);
|
|
57
|
+
|
|
58
|
+
// fixes the following case: my `*name` is *
|
|
59
|
+
// expected result: should ignore special characters inside "code"
|
|
60
|
+
if (textPrefix !== char || schema !== null && schema !== void 0 && (_schema$marks = schema.marks) !== null && _schema$marks !== void 0 && (_schema$marks$code = _schema$marks.code) !== null && _schema$marks$code !== void 0 && _schema$marks$code.isInSet(doc.resolve(start + 1).marks())) {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Prevent autoformatting across hardbreaks
|
|
65
|
+
let containsHardBreak;
|
|
66
|
+
doc.nodesBetween(start, end, node => {
|
|
67
|
+
if (node.type === schema.nodes.hardBreak) {
|
|
68
|
+
containsHardBreak = true;
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
return !containsHardBreak;
|
|
72
|
+
});
|
|
73
|
+
if (containsHardBreak) {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// fixes autoformatting in heading nodes: # Heading *bold*
|
|
78
|
+
// expected result: should not autoformat *bold*; <h1>Heading *bold*</h1>
|
|
79
|
+
const startPosResolved = doc.resolve(start);
|
|
80
|
+
const endPosResolved = doc.resolve(end);
|
|
81
|
+
if (startPosResolved.sameParent(endPosResolved) && !startPosResolved.parent.type.allowsMarkType(markType)) {
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
if (markType.name === 'code') {
|
|
85
|
+
transformSmartCharsMentionsAndEmojis(tr.mapping.map(start), tr.mapping.map(end), tr);
|
|
86
|
+
}
|
|
87
|
+
const mappedStart = tr.mapping.map(start);
|
|
88
|
+
const mappedEnd = tr.mapping.map(end);
|
|
89
|
+
tr.addMark(mappedStart, mappedEnd, markType.create());
|
|
90
|
+
const textSuffix = tr.doc.textBetween(mappedEnd - char.length, mappedEnd);
|
|
91
|
+
if (textSuffix === char) {
|
|
92
|
+
tr.delete(mappedEnd - char.length, mappedEnd);
|
|
93
|
+
}
|
|
94
|
+
if (textPrefix === char) {
|
|
95
|
+
tr.delete(mappedStart, mappedStart + char.length);
|
|
96
|
+
}
|
|
97
|
+
return tr.removeStoredMark(markType);
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
class ReverseRegexExp extends RegExp {
|
|
101
|
+
exec(str) {
|
|
102
|
+
if (!str) {
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
const reverseStr = [...str].reverse().join('');
|
|
106
|
+
const result = super.exec(reverseStr);
|
|
107
|
+
if (!result) {
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
for (let i = 0; i < result.length; i++) {
|
|
111
|
+
if (result[i] && typeof result[i] === 'string') {
|
|
112
|
+
result[i] = [...result[i]].reverse().join('');
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
if (result.input && typeof result.input === 'string') {
|
|
116
|
+
result.input = [...result.input].reverse().join('');
|
|
117
|
+
}
|
|
118
|
+
if (result.input && result[0]) {
|
|
119
|
+
result.index = result.input.length - result[0].length;
|
|
120
|
+
}
|
|
121
|
+
return result;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
const buildRegex = char => {
|
|
125
|
+
const escapedChar = char.replace(/(\W)/g, '\\$1');
|
|
126
|
+
const combinations = ValidCombinations[char].map(c => c.replace(/(\W)/g, '\\$1')).join('|');
|
|
127
|
+
|
|
128
|
+
// Single X - https://regex101.com/r/McT3yq/14/
|
|
129
|
+
// Double X - https://regex101.com/r/pQUgjx/1/
|
|
130
|
+
const baseRegex = '^X(?=[^X\\s]).*?[^\\sX]X(?=[\\sOBJECT_REPLACEMENT_CHARACTER]COMBINATIONS|$)'.replace('OBJECT_REPLACEMENT_CHARACTER', leafNodeReplacementCharacter).replace('COMBINATIONS', combinations ? `|${combinations}` : '');
|
|
131
|
+
const replacedRegex = String.prototype.hasOwnProperty('replaceAll') ? baseRegex.replaceAll('X', escapedChar) : baseRegex.replace(/X/g, escapedChar);
|
|
132
|
+
return new ReverseRegexExp(replacedRegex);
|
|
133
|
+
};
|
|
134
|
+
export const strongRegex1 = buildRegex(ValidAutoformatChars.STRONG);
|
|
135
|
+
export const strongRegex2 = buildRegex(ValidAutoformatChars.STRONG_MARKDOWN);
|
|
136
|
+
export const italicRegex1 = buildRegex(ValidAutoformatChars.ITALIC);
|
|
137
|
+
export const italicRegex2 = buildRegex(ValidAutoformatChars.ITALIC_MARKDOWN);
|
|
138
|
+
export const strikeRegex = buildRegex(ValidAutoformatChars.STRIKE);
|
|
139
|
+
export const codeRegex = buildRegex(ValidAutoformatChars.CODE);
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Create input rules for strong mark
|
|
143
|
+
*
|
|
144
|
+
* @param {Schema} schema
|
|
145
|
+
* @returns {InputRuleWrapper[]}
|
|
146
|
+
*/
|
|
147
|
+
function getStrongInputRules(schema, editorAnalyticsAPI) {
|
|
148
|
+
const ruleWithStrongAnalytics = inputRuleWithAnalytics({
|
|
149
|
+
action: ACTION.FORMATTED,
|
|
150
|
+
actionSubject: ACTION_SUBJECT.TEXT,
|
|
151
|
+
actionSubjectId: ACTION_SUBJECT_ID.FORMAT_STRONG,
|
|
152
|
+
eventType: EVENT_TYPE.TRACK,
|
|
153
|
+
attributes: {
|
|
154
|
+
inputMethod: INPUT_METHOD.FORMATTING
|
|
155
|
+
}
|
|
156
|
+
}, editorAnalyticsAPI);
|
|
157
|
+
// **string** or __strong__ should bold the text
|
|
158
|
+
const doubleUnderscoreRule = createRule(strongRegex1, addMark(schema.marks.strong, schema, ValidAutoformatChars.STRONG));
|
|
159
|
+
const doubleAsterixRule = createRule(strongRegex2, addMark(schema.marks.strong, schema, ValidAutoformatChars.STRONG_MARKDOWN));
|
|
160
|
+
return [ruleWithStrongAnalytics(doubleUnderscoreRule), ruleWithStrongAnalytics(doubleAsterixRule)];
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Create input rules for em mark
|
|
165
|
+
*
|
|
166
|
+
* @param {Schema} schema
|
|
167
|
+
* @returns {InputRuleWrapper[]}
|
|
168
|
+
*/
|
|
169
|
+
function getItalicInputRules(schema, editorAnalyticsAPI) {
|
|
170
|
+
const ruleWithItalicAnalytics = inputRuleWithAnalytics({
|
|
171
|
+
action: ACTION.FORMATTED,
|
|
172
|
+
actionSubject: ACTION_SUBJECT.TEXT,
|
|
173
|
+
actionSubjectId: ACTION_SUBJECT_ID.FORMAT_ITALIC,
|
|
174
|
+
eventType: EVENT_TYPE.TRACK,
|
|
175
|
+
attributes: {
|
|
176
|
+
inputMethod: INPUT_METHOD.FORMATTING
|
|
177
|
+
}
|
|
178
|
+
}, editorAnalyticsAPI);
|
|
179
|
+
const underscoreRule = createRule(italicRegex1, addMark(schema.marks.em, schema, ValidAutoformatChars.ITALIC));
|
|
180
|
+
const asterixRule = createRule(italicRegex2, addMark(schema.marks.em, schema, ValidAutoformatChars.ITALIC_MARKDOWN));
|
|
181
|
+
return [ruleWithItalicAnalytics(underscoreRule), ruleWithItalicAnalytics(asterixRule)];
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Create input rules for strike mark
|
|
186
|
+
*
|
|
187
|
+
* @param {Schema} schema
|
|
188
|
+
* @returns {InputRuleWrapper[]}
|
|
189
|
+
*/
|
|
190
|
+
function getStrikeInputRules(schema, editorAnalyticsAPI) {
|
|
191
|
+
const ruleWithStrikeAnalytics = inputRuleWithAnalytics({
|
|
192
|
+
action: ACTION.FORMATTED,
|
|
193
|
+
actionSubject: ACTION_SUBJECT.TEXT,
|
|
194
|
+
actionSubjectId: ACTION_SUBJECT_ID.FORMAT_STRIKE,
|
|
195
|
+
eventType: EVENT_TYPE.TRACK,
|
|
196
|
+
attributes: {
|
|
197
|
+
inputMethod: INPUT_METHOD.FORMATTING
|
|
198
|
+
}
|
|
199
|
+
}, editorAnalyticsAPI);
|
|
200
|
+
const doubleTildeRule = createRule(strikeRegex, addMark(schema.marks.strike, schema, ValidAutoformatChars.STRIKE));
|
|
201
|
+
return [ruleWithStrikeAnalytics(doubleTildeRule)];
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Create input rules for code mark
|
|
206
|
+
*
|
|
207
|
+
* @param {Schema} schema
|
|
208
|
+
* @returns {InputRuleWrapper[]}
|
|
209
|
+
*/
|
|
210
|
+
function getCodeInputRules(schema, editorAnalyticsAPI) {
|
|
211
|
+
const ruleWithCodeAnalytics = inputRuleWithAnalytics({
|
|
212
|
+
action: ACTION.FORMATTED,
|
|
213
|
+
actionSubject: ACTION_SUBJECT.TEXT,
|
|
214
|
+
actionSubjectId: ACTION_SUBJECT_ID.FORMAT_CODE,
|
|
215
|
+
eventType: EVENT_TYPE.TRACK,
|
|
216
|
+
attributes: {
|
|
217
|
+
inputMethod: INPUT_METHOD.FORMATTING
|
|
218
|
+
}
|
|
219
|
+
}, editorAnalyticsAPI);
|
|
220
|
+
const backTickRule = createRule(codeRegex, addMark(schema.marks.code, schema, ValidAutoformatChars.CODE));
|
|
221
|
+
return [ruleWithCodeAnalytics(backTickRule)];
|
|
222
|
+
}
|
|
223
|
+
export function inputRulePlugin(schema, editorAnalyticsAPI) {
|
|
224
|
+
const rules = [];
|
|
225
|
+
if (schema.marks.strong) {
|
|
226
|
+
rules.push(...getStrongInputRules(schema, editorAnalyticsAPI));
|
|
227
|
+
}
|
|
228
|
+
if (schema.marks.em) {
|
|
229
|
+
rules.push(...getItalicInputRules(schema, editorAnalyticsAPI));
|
|
230
|
+
}
|
|
231
|
+
if (schema.marks.strike) {
|
|
232
|
+
rules.push(...getStrikeInputRules(schema, editorAnalyticsAPI));
|
|
233
|
+
}
|
|
234
|
+
if (schema.marks.code) {
|
|
235
|
+
rules.push(...getCodeInputRules(schema, editorAnalyticsAPI));
|
|
236
|
+
}
|
|
237
|
+
if (rules.length !== 0) {
|
|
238
|
+
return createPlugin('text-formatting', rules);
|
|
239
|
+
}
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
export default inputRulePlugin;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { INPUT_METHOD } from '@atlaskit/editor-common/analytics';
|
|
2
|
+
import * as keymaps from '@atlaskit/editor-common/keymaps';
|
|
3
|
+
import { keymap } from '@atlaskit/editor-prosemirror/keymap';
|
|
4
|
+
import { toggleCodeWithAnalytics, toggleEmWithAnalytics, toggleStrikeWithAnalytics, toggleStrongWithAnalytics, toggleSubscriptWithAnalytics, toggleSuperscriptWithAnalytics, toggleUnderlineWithAnalytics } from '../actions';
|
|
5
|
+
export default function keymapPlugin(schema, editorAnalyticsAPI) {
|
|
6
|
+
const list = {};
|
|
7
|
+
if (schema.marks.strong) {
|
|
8
|
+
keymaps.bindKeymapWithCommand(keymaps.toggleBold.common, toggleStrongWithAnalytics(editorAnalyticsAPI)({
|
|
9
|
+
inputMethod: INPUT_METHOD.SHORTCUT
|
|
10
|
+
}), list);
|
|
11
|
+
}
|
|
12
|
+
if (schema.marks.em) {
|
|
13
|
+
keymaps.bindKeymapWithCommand(keymaps.toggleItalic.common, toggleEmWithAnalytics(editorAnalyticsAPI)({
|
|
14
|
+
inputMethod: INPUT_METHOD.SHORTCUT
|
|
15
|
+
}), list);
|
|
16
|
+
}
|
|
17
|
+
if (schema.marks.code) {
|
|
18
|
+
keymaps.bindKeymapWithCommand(keymaps.toggleCode.common, toggleCodeWithAnalytics(editorAnalyticsAPI)({
|
|
19
|
+
inputMethod: INPUT_METHOD.SHORTCUT
|
|
20
|
+
}), list);
|
|
21
|
+
}
|
|
22
|
+
if (schema.marks.strike) {
|
|
23
|
+
keymaps.bindKeymapWithCommand(keymaps.toggleStrikethrough.common, toggleStrikeWithAnalytics(editorAnalyticsAPI)({
|
|
24
|
+
inputMethod: INPUT_METHOD.SHORTCUT
|
|
25
|
+
}), list);
|
|
26
|
+
}
|
|
27
|
+
if (schema.marks.subsup) {
|
|
28
|
+
keymaps.bindKeymapWithCommand(keymaps.toggleSubscript.common, toggleSubscriptWithAnalytics(editorAnalyticsAPI)({
|
|
29
|
+
inputMethod: INPUT_METHOD.SHORTCUT
|
|
30
|
+
}), list);
|
|
31
|
+
}
|
|
32
|
+
if (schema.marks.subsup) {
|
|
33
|
+
keymaps.bindKeymapWithCommand(keymaps.toggleSuperscript.common, toggleSuperscriptWithAnalytics(editorAnalyticsAPI)({
|
|
34
|
+
inputMethod: INPUT_METHOD.SHORTCUT
|
|
35
|
+
}), list);
|
|
36
|
+
}
|
|
37
|
+
if (schema.marks.underline) {
|
|
38
|
+
keymaps.bindKeymapWithCommand(keymaps.toggleUnderline.common, toggleUnderlineWithAnalytics(editorAnalyticsAPI)({
|
|
39
|
+
inputMethod: INPUT_METHOD.SHORTCUT
|
|
40
|
+
}), list);
|
|
41
|
+
}
|
|
42
|
+
return keymap(list);
|
|
43
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
// TODO: Ideally this should use the custom toggleMark function from @atlaskit/editor-common so we also disable the options when selecting inline nodes but it disables the marks when the selection is empty at this point in time which is undesirable
|
|
2
|
+
// import { toggleMark } from '@atlaskit/editor-common/mark';
|
|
3
|
+
|
|
4
|
+
import { moveLeft as keymapMoveLeft, moveRight as keymapMoveRight } from '@atlaskit/editor-common/keymaps';
|
|
5
|
+
import { anyMarkActive } from '@atlaskit/editor-common/mark';
|
|
6
|
+
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
7
|
+
import { shallowEqual } from '@atlaskit/editor-common/utils';
|
|
8
|
+
import { toggleMark } from '@atlaskit/editor-prosemirror/commands';
|
|
9
|
+
import { createInlineCodeFromTextInputWithAnalytics } from '../commands/text-formatting';
|
|
10
|
+
import * as commands from '../commands/text-formatting';
|
|
11
|
+
import { pluginKey } from './plugin-key';
|
|
12
|
+
export { pluginKey };
|
|
13
|
+
const getTextFormattingState = (editorState, editorAnalyticsAPI) => {
|
|
14
|
+
const {
|
|
15
|
+
em,
|
|
16
|
+
code,
|
|
17
|
+
strike,
|
|
18
|
+
strong,
|
|
19
|
+
subsup,
|
|
20
|
+
underline
|
|
21
|
+
} = editorState.schema.marks;
|
|
22
|
+
const state = {};
|
|
23
|
+
if (code) {
|
|
24
|
+
state.codeActive = anyMarkActive(editorState, code.create());
|
|
25
|
+
state.codeDisabled = !toggleMark(code)(editorState);
|
|
26
|
+
}
|
|
27
|
+
if (em) {
|
|
28
|
+
state.emActive = anyMarkActive(editorState, em);
|
|
29
|
+
state.emDisabled = state.codeActive ? true : !toggleMark(em)(editorState);
|
|
30
|
+
}
|
|
31
|
+
if (strike) {
|
|
32
|
+
state.strikeActive = anyMarkActive(editorState, strike);
|
|
33
|
+
state.strikeDisabled = state.codeActive ? true : !toggleMark(strike)(editorState);
|
|
34
|
+
}
|
|
35
|
+
if (strong) {
|
|
36
|
+
state.strongActive = anyMarkActive(editorState, strong);
|
|
37
|
+
state.strongDisabled = state.codeActive ? true : !toggleMark(strong)(editorState);
|
|
38
|
+
}
|
|
39
|
+
if (subsup) {
|
|
40
|
+
const subMark = subsup.create({
|
|
41
|
+
type: 'sub'
|
|
42
|
+
});
|
|
43
|
+
const supMark = subsup.create({
|
|
44
|
+
type: 'sup'
|
|
45
|
+
});
|
|
46
|
+
state.subscriptActive = anyMarkActive(editorState, subMark);
|
|
47
|
+
state.subscriptDisabled = state.codeActive ? true : !toggleMark(subsup, {
|
|
48
|
+
type: 'sub'
|
|
49
|
+
})(editorState);
|
|
50
|
+
state.superscriptActive = anyMarkActive(editorState, supMark);
|
|
51
|
+
state.superscriptDisabled = state.codeActive ? true : !toggleMark(subsup, {
|
|
52
|
+
type: 'sup'
|
|
53
|
+
})(editorState);
|
|
54
|
+
}
|
|
55
|
+
if (underline) {
|
|
56
|
+
state.underlineActive = anyMarkActive(editorState, underline);
|
|
57
|
+
state.underlineDisabled = state.codeActive ? true : !toggleMark(underline)(editorState);
|
|
58
|
+
}
|
|
59
|
+
return state;
|
|
60
|
+
};
|
|
61
|
+
export const plugin = (dispatch, editorAnalyticsAPI) => new SafePlugin({
|
|
62
|
+
state: {
|
|
63
|
+
init(_config, state) {
|
|
64
|
+
return getTextFormattingState(state, editorAnalyticsAPI);
|
|
65
|
+
},
|
|
66
|
+
apply(_tr, pluginState, _oldState, newState) {
|
|
67
|
+
const state = getTextFormattingState(newState, editorAnalyticsAPI);
|
|
68
|
+
if (!shallowEqual(pluginState, state)) {
|
|
69
|
+
dispatch(pluginKey, state);
|
|
70
|
+
return state;
|
|
71
|
+
}
|
|
72
|
+
return pluginState;
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
key: pluginKey,
|
|
76
|
+
props: {
|
|
77
|
+
handleKeyDown(view, event) {
|
|
78
|
+
const {
|
|
79
|
+
state,
|
|
80
|
+
dispatch
|
|
81
|
+
} = view;
|
|
82
|
+
if (event.key === keymapMoveRight.common && !event.metaKey) {
|
|
83
|
+
return commands.moveRight()(state, dispatch);
|
|
84
|
+
} else if (event.key === keymapMoveLeft.common && !event.metaKey) {
|
|
85
|
+
return commands.moveLeft()(state, dispatch);
|
|
86
|
+
}
|
|
87
|
+
return false;
|
|
88
|
+
},
|
|
89
|
+
handleTextInput(view, from, to, text) {
|
|
90
|
+
const {
|
|
91
|
+
state,
|
|
92
|
+
dispatch
|
|
93
|
+
} = view;
|
|
94
|
+
const {
|
|
95
|
+
schema,
|
|
96
|
+
selection: {
|
|
97
|
+
$from: {
|
|
98
|
+
parent: {
|
|
99
|
+
type: parentNodeType
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
} = state;
|
|
104
|
+
if (parentNodeType.allowsMarkType(schema.marks.code)) {
|
|
105
|
+
return createInlineCodeFromTextInputWithAnalytics(editorAnalyticsAPI)(from, to, text)(state, dispatch);
|
|
106
|
+
}
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
});
|