@atlaskit/editor-plugin-code-block-advanced 1.0.1 → 1.0.3
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 +23 -0
- package/afm-cc/tsconfig.json +6 -0
- package/afm-jira/tsconfig.json +6 -0
- package/afm-post-office/tsconfig.json +6 -0
- package/dist/cjs/nodeviews/codeBlockAdvanced.js +31 -8
- package/dist/cjs/nodeviews/codeBlockNodeWithToDOMFixed.js +2 -1
- package/dist/cjs/nodeviews/codemirrorSync/syncCMWithPM.js +0 -1
- package/dist/cjs/nodeviews/extensions/keymap/index.js +23 -3
- package/dist/cjs/nodeviews/extensions/manageSelectionMarker.js +28 -0
- package/dist/cjs/nodeviews/extensions/prosemirrorDecorations.js +142 -0
- package/dist/es2019/nodeviews/codeBlockAdvanced.js +28 -10
- package/dist/es2019/nodeviews/codeBlockNodeWithToDOMFixed.js +2 -1
- package/dist/es2019/nodeviews/codemirrorSync/syncCMWithPM.js +0 -1
- package/dist/es2019/nodeviews/extensions/keymap/index.js +23 -3
- package/dist/es2019/nodeviews/extensions/manageSelectionMarker.js +22 -0
- package/dist/es2019/nodeviews/extensions/prosemirrorDecorations.js +107 -0
- package/dist/esm/nodeviews/codeBlockAdvanced.js +33 -10
- package/dist/esm/nodeviews/codeBlockNodeWithToDOMFixed.js +2 -1
- package/dist/esm/nodeviews/codemirrorSync/syncCMWithPM.js +0 -1
- package/dist/esm/nodeviews/extensions/keymap/index.js +23 -3
- package/dist/esm/nodeviews/extensions/manageSelectionMarker.js +22 -0
- package/dist/esm/nodeviews/extensions/prosemirrorDecorations.js +135 -0
- package/dist/types/codeBlockAdvancedPluginType.d.ts +9 -1
- package/dist/types/nodeviews/codeBlockAdvanced.d.ts +10 -2
- package/dist/types/nodeviews/extensions/keymap/index.d.ts +2 -1
- package/dist/types/nodeviews/extensions/manageSelectionMarker.d.ts +10 -0
- package/dist/types/nodeviews/extensions/prosemirrorDecorations.d.ts +20 -0
- package/dist/types-ts4.5/codeBlockAdvancedPluginType.d.ts +5 -1
- package/dist/types-ts4.5/nodeviews/codeBlockAdvanced.d.ts +10 -2
- package/dist/types-ts4.5/nodeviews/extensions/keymap/index.d.ts +2 -1
- package/dist/types-ts4.5/nodeviews/extensions/manageSelectionMarker.d.ts +10 -0
- package/dist/types-ts4.5/nodeviews/extensions/prosemirrorDecorations.d.ts +20 -0
- package/package.json +6 -4
- package/src/codeBlockAdvancedPluginType.ts +9 -1
- package/src/nodeviews/codeBlockAdvanced.ts +33 -7
- package/src/nodeviews/codeBlockNodeWithToDOMFixed.ts +1 -0
- package/src/nodeviews/codemirrorSync/syncCMWithPM.ts +0 -1
- package/src/nodeviews/extensions/keymap/index.ts +31 -1
- package/src/nodeviews/extensions/manageSelectionMarker.ts +28 -0
- package/src/nodeviews/extensions/prosemirrorDecorations.ts +156 -0
- package/tsconfig.app.json +6 -0
- package/dist/cjs/nodeviews/extensions/bidiCharWarning.js +0 -83
- package/dist/es2019/nodeviews/extensions/bidiCharWarning.js +0 -53
- package/dist/esm/nodeviews/extensions/bidiCharWarning.js +0 -77
- package/dist/types/nodeviews/extensions/bidiCharWarning.d.ts +0 -8
- package/dist/types-ts4.5/nodeviews/extensions/bidiCharWarning.d.ts +0 -8
- package/src/nodeviews/extensions/bidiCharWarning.ts +0 -72
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-code-block-advanced",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "CodeBlockAdvanced plugin for @atlaskit/editor-core",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -33,12 +33,14 @@
|
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
35
|
"@atlaskit/adf-schema": "^46.1.0",
|
|
36
|
-
"@atlaskit/editor-common": "^99.
|
|
37
|
-
"@atlaskit/editor-plugin-code-block": "^3.
|
|
36
|
+
"@atlaskit/editor-common": "^99.5.0",
|
|
37
|
+
"@atlaskit/editor-plugin-code-block": "^3.6.0",
|
|
38
38
|
"@atlaskit/editor-plugin-editor-disabled": "^1.3.0",
|
|
39
|
+
"@atlaskit/editor-plugin-find-replace": "^1.7.0",
|
|
39
40
|
"@atlaskit/editor-plugin-selection": "^1.6.0",
|
|
41
|
+
"@atlaskit/editor-plugin-selection-marker": "^1.6.0",
|
|
40
42
|
"@atlaskit/editor-prosemirror": "6.2.1",
|
|
41
|
-
"@atlaskit/tokens": "^3.
|
|
43
|
+
"@atlaskit/tokens": "^3.2.0",
|
|
42
44
|
"@babel/runtime": "^7.0.0",
|
|
43
45
|
"@codemirror/autocomplete": "6.18.4",
|
|
44
46
|
"@codemirror/commands": "6.7.1",
|
|
@@ -3,12 +3,20 @@ import type { Extension } from '@codemirror/state';
|
|
|
3
3
|
import type { NextEditorPlugin, OptionalPlugin } from '@atlaskit/editor-common/types';
|
|
4
4
|
import type { CodeBlockPlugin } from '@atlaskit/editor-plugin-code-block';
|
|
5
5
|
import type { EditorDisabledPlugin } from '@atlaskit/editor-plugin-editor-disabled';
|
|
6
|
+
import type { FindReplacePlugin } from '@atlaskit/editor-plugin-find-replace';
|
|
6
7
|
import type { SelectionPlugin } from '@atlaskit/editor-plugin-selection';
|
|
8
|
+
import type { SelectionMarkerPlugin } from '@atlaskit/editor-plugin-selection-marker';
|
|
7
9
|
|
|
8
10
|
export type CodeBlockAdvancedPlugin = NextEditorPlugin<
|
|
9
11
|
'codeBlockAdvanced',
|
|
10
12
|
{
|
|
11
|
-
dependencies: [
|
|
13
|
+
dependencies: [
|
|
14
|
+
CodeBlockPlugin,
|
|
15
|
+
SelectionPlugin,
|
|
16
|
+
OptionalPlugin<EditorDisabledPlugin>,
|
|
17
|
+
OptionalPlugin<SelectionMarkerPlugin>,
|
|
18
|
+
OptionalPlugin<FindReplacePlugin>,
|
|
19
|
+
];
|
|
12
20
|
pluginConfiguration:
|
|
13
21
|
| {
|
|
14
22
|
extensions?: Extension[];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { closeBrackets } from '@codemirror/autocomplete';
|
|
2
|
-
import { syntaxHighlighting } from '@codemirror/language';
|
|
3
|
-
import { Compartment, Extension, EditorSelection } from '@codemirror/state';
|
|
2
|
+
import { syntaxHighlighting, bracketMatching } from '@codemirror/language';
|
|
3
|
+
import { Compartment, Extension, EditorSelection, Facet } from '@codemirror/state';
|
|
4
4
|
import { EditorView as CodeMirror, lineNumbers, ViewUpdate, gutters } from '@codemirror/view';
|
|
5
5
|
|
|
6
6
|
import { isCodeBlockWordWrapEnabled } from '@atlaskit/editor-common/code-block';
|
|
@@ -13,7 +13,12 @@ import type {
|
|
|
13
13
|
import { EditorSelectionAPI } from '@atlaskit/editor-plugin-selection';
|
|
14
14
|
import { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
|
|
15
15
|
import { NodeSelection } from '@atlaskit/editor-prosemirror/state';
|
|
16
|
-
import type {
|
|
16
|
+
import type {
|
|
17
|
+
Decoration,
|
|
18
|
+
DecorationSource,
|
|
19
|
+
EditorView,
|
|
20
|
+
NodeView,
|
|
21
|
+
} from '@atlaskit/editor-prosemirror/view';
|
|
17
22
|
|
|
18
23
|
import type { CodeBlockAdvancedPlugin } from '../codeBlockAdvancedPluginType';
|
|
19
24
|
import { highlightStyle } from '../ui/syntaxHighlightingTheme';
|
|
@@ -21,8 +26,9 @@ import { cmTheme } from '../ui/theme';
|
|
|
21
26
|
|
|
22
27
|
import { syncCMWithPM } from './codemirrorSync/syncCMWithPM';
|
|
23
28
|
import { updateCMSelection } from './codemirrorSync/updateCMSelection';
|
|
24
|
-
import { bidiCharWarningExtension } from './extensions/bidiCharWarning';
|
|
25
29
|
import { keymapExtension } from './extensions/keymap';
|
|
30
|
+
import { manageSelectionMarker } from './extensions/manageSelectionMarker';
|
|
31
|
+
import { prosemirrorDecorationPlugin } from './extensions/prosemirrorDecorations';
|
|
26
32
|
import { LanguageLoader } from './languages/loader';
|
|
27
33
|
|
|
28
34
|
interface ConfigProps {
|
|
@@ -38,6 +44,7 @@ class CodeBlockAdvancedNodeView implements NodeView {
|
|
|
38
44
|
private lineWrappingCompartment = new Compartment();
|
|
39
45
|
private languageCompartment = new Compartment();
|
|
40
46
|
private readOnlyCompartment = new Compartment();
|
|
47
|
+
private pmDecorationsCompartment = new Compartment();
|
|
41
48
|
private node: PMNode;
|
|
42
49
|
private getPos: getPosHandlerNode;
|
|
43
50
|
private cm: CodeMirror;
|
|
@@ -45,8 +52,8 @@ class CodeBlockAdvancedNodeView implements NodeView {
|
|
|
45
52
|
private maybeTryingToReachNodeSelection = false;
|
|
46
53
|
private cleanupDisabledState: (() => void) | undefined;
|
|
47
54
|
private languageLoader: LanguageLoader;
|
|
55
|
+
private pmFacet = Facet.define<DecorationSource>();
|
|
48
56
|
|
|
49
|
-
// eslint-disable-next-line @typescript-eslint/max-params
|
|
50
57
|
constructor(node: PMNode, view: EditorView, getPos: getPosHandlerNode, config: ConfigProps) {
|
|
51
58
|
this.node = node;
|
|
52
59
|
this.view = view;
|
|
@@ -71,15 +78,18 @@ class CodeBlockAdvancedNodeView implements NodeView {
|
|
|
71
78
|
...config.extensions,
|
|
72
79
|
this.lineWrappingCompartment.of([]),
|
|
73
80
|
this.languageCompartment.of([]),
|
|
81
|
+
this.pmDecorationsCompartment.of([]),
|
|
74
82
|
keymapExtension({
|
|
75
83
|
view,
|
|
76
84
|
getPos,
|
|
77
85
|
getNode,
|
|
78
86
|
selectCodeBlockNode: this.selectCodeBlockNode.bind(this),
|
|
79
87
|
onMaybeNodeSelection,
|
|
88
|
+
customFindReplace: Boolean(config.api?.findReplace),
|
|
80
89
|
}),
|
|
81
90
|
cmTheme,
|
|
82
91
|
syntaxHighlighting(highlightStyle),
|
|
92
|
+
bracketMatching(),
|
|
83
93
|
lineNumbers(),
|
|
84
94
|
// Explicitly disable "sticky" positioning on line numbers to match
|
|
85
95
|
// Renderer behaviour
|
|
@@ -88,7 +98,8 @@ class CodeBlockAdvancedNodeView implements NodeView {
|
|
|
88
98
|
this.readOnlyCompartment.of(CodeMirror.editable.of(this.view.editable)),
|
|
89
99
|
closeBrackets(),
|
|
90
100
|
CodeMirror.editorAttributes.of({ class: 'code-block' }),
|
|
91
|
-
|
|
101
|
+
manageSelectionMarker(config.api),
|
|
102
|
+
prosemirrorDecorationPlugin(this.pmFacet, view, getPos),
|
|
92
103
|
],
|
|
93
104
|
});
|
|
94
105
|
|
|
@@ -166,7 +177,7 @@ class CodeBlockAdvancedNodeView implements NodeView {
|
|
|
166
177
|
}
|
|
167
178
|
}
|
|
168
179
|
|
|
169
|
-
update(node: PMNode) {
|
|
180
|
+
update(node: PMNode, _: readonly Decoration[], innerDecorations: DecorationSource) {
|
|
170
181
|
this.maybeTryingToReachNodeSelection = false;
|
|
171
182
|
|
|
172
183
|
if (node.type !== this.node.type) {
|
|
@@ -185,9 +196,24 @@ class CodeBlockAdvancedNodeView implements NodeView {
|
|
|
185
196
|
this.cm.dispatch(tr);
|
|
186
197
|
this.updating = false;
|
|
187
198
|
});
|
|
199
|
+
this.updateProseMirrorDecorations(innerDecorations);
|
|
188
200
|
return true;
|
|
189
201
|
}
|
|
190
202
|
|
|
203
|
+
/**
|
|
204
|
+
* Updates a facet which stores information on the prosemirror decorations
|
|
205
|
+
*
|
|
206
|
+
* This then gets translated to codemirror decorations in `prosemirrorDecorationPlugin`
|
|
207
|
+
*/
|
|
208
|
+
private updateProseMirrorDecorations(decorationSource: DecorationSource) {
|
|
209
|
+
this.updating = true;
|
|
210
|
+
const computedFacet = this.pmFacet.compute([], () => decorationSource);
|
|
211
|
+
this.cm.dispatch({
|
|
212
|
+
effects: this.pmDecorationsCompartment.reconfigure(computedFacet),
|
|
213
|
+
});
|
|
214
|
+
this.updating = false;
|
|
215
|
+
}
|
|
216
|
+
|
|
191
217
|
stopEvent(e: Event) {
|
|
192
218
|
if (e instanceof MouseEvent && e.type === 'mousedown') {
|
|
193
219
|
// !Warning: Side effect!
|
|
@@ -25,7 +25,6 @@ export const syncCMWithPM = ({ view, update, offset }: Props): void => {
|
|
|
25
25
|
const pmSel = view.state.selection;
|
|
26
26
|
if (update.docChanged || pmSel.from !== selFrom || pmSel.to !== selTo) {
|
|
27
27
|
const tr = view.state.tr;
|
|
28
|
-
// eslint-disable-next-line @typescript-eslint/max-params
|
|
29
28
|
update.changes.iterChanges((fromA, toA, fromB, toB, text) => {
|
|
30
29
|
if (text.length) {
|
|
31
30
|
tr.replaceWith(offset + fromA, offset + toA, view.state.schema.text(text.toString()));
|
|
@@ -2,6 +2,7 @@ import { defaultKeymap, indentWithTab } from '@codemirror/commands';
|
|
|
2
2
|
import { Extension } from '@codemirror/state';
|
|
3
3
|
import { KeyBinding, keymap as cmKeymap } from '@codemirror/view';
|
|
4
4
|
|
|
5
|
+
import { browser } from '@atlaskit/editor-common/browser';
|
|
5
6
|
import { RelativeSelectionPos } from '@atlaskit/editor-common/selection';
|
|
6
7
|
import type { getPosHandlerNode } from '@atlaskit/editor-common/types';
|
|
7
8
|
import { exitCode } from '@atlaskit/editor-prosemirror/commands';
|
|
@@ -18,6 +19,7 @@ interface KeymapProps {
|
|
|
18
19
|
getPos: getPosHandlerNode;
|
|
19
20
|
selectCodeBlockNode: (relativeSelectionPos: RelativeSelectionPos | undefined) => void;
|
|
20
21
|
onMaybeNodeSelection: () => void;
|
|
22
|
+
customFindReplace: boolean;
|
|
21
23
|
}
|
|
22
24
|
|
|
23
25
|
export const keymapExtension = ({
|
|
@@ -26,9 +28,17 @@ export const keymapExtension = ({
|
|
|
26
28
|
getPos,
|
|
27
29
|
selectCodeBlockNode,
|
|
28
30
|
onMaybeNodeSelection,
|
|
31
|
+
customFindReplace,
|
|
29
32
|
}: KeymapProps): Extension => {
|
|
30
33
|
return cmKeymap.of(
|
|
31
|
-
codeBlockKeymap({
|
|
34
|
+
codeBlockKeymap({
|
|
35
|
+
view,
|
|
36
|
+
getNode,
|
|
37
|
+
getPos,
|
|
38
|
+
selectCodeBlockNode,
|
|
39
|
+
onMaybeNodeSelection,
|
|
40
|
+
customFindReplace,
|
|
41
|
+
}),
|
|
32
42
|
);
|
|
33
43
|
};
|
|
34
44
|
|
|
@@ -38,6 +48,7 @@ const codeBlockKeymap = ({
|
|
|
38
48
|
getPos,
|
|
39
49
|
selectCodeBlockNode,
|
|
40
50
|
onMaybeNodeSelection,
|
|
51
|
+
customFindReplace,
|
|
41
52
|
}: KeymapProps): readonly KeyBinding[] => {
|
|
42
53
|
return [
|
|
43
54
|
{
|
|
@@ -96,6 +107,25 @@ const codeBlockKeymap = ({
|
|
|
96
107
|
onMaybeNodeSelection,
|
|
97
108
|
}),
|
|
98
109
|
},
|
|
110
|
+
{
|
|
111
|
+
key: 'Ctrl-f',
|
|
112
|
+
mac: 'Cmd-f',
|
|
113
|
+
run: () => {
|
|
114
|
+
// Pass synthetic event to prosemirror
|
|
115
|
+
if (customFindReplace) {
|
|
116
|
+
view.dispatchEvent(
|
|
117
|
+
new KeyboardEvent('keydown', {
|
|
118
|
+
key: 'f',
|
|
119
|
+
code: 'KeyF',
|
|
120
|
+
metaKey: browser.mac ? true : false,
|
|
121
|
+
ctrlKey: browser.mac ? false : true,
|
|
122
|
+
}),
|
|
123
|
+
);
|
|
124
|
+
return true;
|
|
125
|
+
}
|
|
126
|
+
return false;
|
|
127
|
+
},
|
|
128
|
+
},
|
|
99
129
|
{
|
|
100
130
|
key: 'Ctrl-Enter',
|
|
101
131
|
run: () => {
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Extension } from '@codemirror/state';
|
|
2
|
+
import { EditorView as CodeMirror } from '@codemirror/view';
|
|
3
|
+
|
|
4
|
+
import { type ExtractInjectionAPI } from '@atlaskit/editor-common/types';
|
|
5
|
+
|
|
6
|
+
import { CodeBlockAdvancedPlugin } from '../../codeBlockAdvancedPluginType';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Hides selection marker decoration when focused on codemirror editor and re-enables on blur
|
|
10
|
+
*
|
|
11
|
+
* @param api
|
|
12
|
+
* @returns CodeMirror Extension
|
|
13
|
+
*/
|
|
14
|
+
export const manageSelectionMarker = (
|
|
15
|
+
api: ExtractInjectionAPI<CodeBlockAdvancedPlugin> | undefined,
|
|
16
|
+
): Extension => {
|
|
17
|
+
let decoHide: (() => void) | undefined;
|
|
18
|
+
return CodeMirror.focusChangeEffect.of((_state, focusing) => {
|
|
19
|
+
if (focusing) {
|
|
20
|
+
api?.selectionMarker?.actions.queueHideDecoration((hideDecoration) => {
|
|
21
|
+
decoHide = hideDecoration;
|
|
22
|
+
});
|
|
23
|
+
} else {
|
|
24
|
+
decoHide?.();
|
|
25
|
+
}
|
|
26
|
+
return null;
|
|
27
|
+
});
|
|
28
|
+
};
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { Facet } from '@codemirror/state';
|
|
2
|
+
import {
|
|
3
|
+
ViewPlugin,
|
|
4
|
+
WidgetType,
|
|
5
|
+
Decoration as CodeMirrorDecoration,
|
|
6
|
+
EditorView as CodeMirror,
|
|
7
|
+
DecorationSet,
|
|
8
|
+
ViewUpdate,
|
|
9
|
+
} from '@codemirror/view';
|
|
10
|
+
|
|
11
|
+
import type { EditorView, Decoration, DecorationSource } from '@atlaskit/editor-prosemirror/view';
|
|
12
|
+
|
|
13
|
+
class PMWidget extends WidgetType {
|
|
14
|
+
constructor(readonly toDOMElement: HTMLElement) {
|
|
15
|
+
super();
|
|
16
|
+
}
|
|
17
|
+
toDOM() {
|
|
18
|
+
return this.toDOMElement;
|
|
19
|
+
}
|
|
20
|
+
ignoreEvent() {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// This type is not exposed publically by ProseMirror but we need it to map to CodeMirror
|
|
26
|
+
// See: https://github.com/ProseMirror/prosemirror-view/blob/master/src/decoration.ts
|
|
27
|
+
type WidgetConstructor = ((view: EditorView, getPos: () => number | undefined) => Node) | Node;
|
|
28
|
+
|
|
29
|
+
// This type is not exposed publically by ProseMirror but we need it to map to CodeMirror
|
|
30
|
+
// See: https://github.com/ProseMirror/prosemirror-view/blob/master/src/decoration.ts
|
|
31
|
+
interface ExtendedProseMirrorDecoration extends Decoration {
|
|
32
|
+
inline: boolean;
|
|
33
|
+
widget: boolean;
|
|
34
|
+
type: {
|
|
35
|
+
attrs?: Record<string, string>;
|
|
36
|
+
toDOM?: WidgetConstructor;
|
|
37
|
+
side?: number;
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// This type is not exposed publically by ProseMirror but we need it to map to CodeMirror
|
|
42
|
+
// See: https://github.com/ProseMirror/prosemirror-view/blob/master/src/decoration.ts
|
|
43
|
+
function isExtendedDecoration(decoration: Decoration): decoration is ExtendedProseMirrorDecoration {
|
|
44
|
+
return (
|
|
45
|
+
(decoration as ExtendedProseMirrorDecoration).inline !== undefined &&
|
|
46
|
+
(decoration as ExtendedProseMirrorDecoration).widget !== undefined &&
|
|
47
|
+
(decoration as ExtendedProseMirrorDecoration).type !== undefined
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const getHTMLElement = (
|
|
52
|
+
toDOM: WidgetConstructor | undefined,
|
|
53
|
+
view: EditorView,
|
|
54
|
+
getPos: () => number | undefined,
|
|
55
|
+
): HTMLElement | undefined => {
|
|
56
|
+
if (toDOM instanceof Function) {
|
|
57
|
+
const element = toDOM(view, getPos);
|
|
58
|
+
return element instanceof HTMLElement ? element : undefined;
|
|
59
|
+
} else if (toDOM instanceof HTMLElement) {
|
|
60
|
+
return toDOM;
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
const mapPMDecorationToCMDecoration = (
|
|
65
|
+
decoration: Decoration,
|
|
66
|
+
view: EditorView,
|
|
67
|
+
getPos: () => number | undefined,
|
|
68
|
+
) => {
|
|
69
|
+
if (!isExtendedDecoration(decoration)) {
|
|
70
|
+
return undefined;
|
|
71
|
+
}
|
|
72
|
+
if (decoration.inline) {
|
|
73
|
+
const markDecoration = CodeMirrorDecoration.mark({
|
|
74
|
+
attributes: decoration.type.attrs,
|
|
75
|
+
});
|
|
76
|
+
return markDecoration.range(decoration.from, decoration.to);
|
|
77
|
+
} else if (decoration.widget) {
|
|
78
|
+
const toDOM = getHTMLElement(decoration?.type?.toDOM, view, getPos);
|
|
79
|
+
if (!toDOM) {
|
|
80
|
+
return undefined;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const widgetDecoration = CodeMirrorDecoration.widget({
|
|
84
|
+
widget: new PMWidget(toDOM),
|
|
85
|
+
side: decoration.type.side,
|
|
86
|
+
});
|
|
87
|
+
return widgetDecoration.range(decoration.from, decoration.to);
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
function isDefined<TValue>(value: TValue | undefined): value is TValue {
|
|
92
|
+
return value !== undefined;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Creates CodeMirror versions of the decorations provided by ProseMirror.
|
|
97
|
+
*
|
|
98
|
+
* Inline ProseMirror decorations -> Mark CodeMirror decorations
|
|
99
|
+
* Widget ProseMirror decorations -> Widget CodeMirror decorations
|
|
100
|
+
*
|
|
101
|
+
* This way any decorations applied in ProseMirror land should automatically be supported
|
|
102
|
+
* by the CodeMirror editor
|
|
103
|
+
*
|
|
104
|
+
* @param updateDecorationsEffect Facet for the prosemirror decorations
|
|
105
|
+
* @returns CodeMirror extension
|
|
106
|
+
*/
|
|
107
|
+
export const prosemirrorDecorationPlugin = (
|
|
108
|
+
updateDecorationsEffect: Facet<DecorationSource>,
|
|
109
|
+
editorView: EditorView,
|
|
110
|
+
getPos: () => number | undefined,
|
|
111
|
+
) =>
|
|
112
|
+
ViewPlugin.fromClass(
|
|
113
|
+
class {
|
|
114
|
+
decorations: DecorationSet;
|
|
115
|
+
|
|
116
|
+
constructor(view: CodeMirror) {
|
|
117
|
+
this.decorations = this.updateDecorations(view);
|
|
118
|
+
}
|
|
119
|
+
updateDecorations(view: CodeMirror) {
|
|
120
|
+
const { from, to } = view.viewport;
|
|
121
|
+
|
|
122
|
+
const innnerDecorations = view.state.facet(updateDecorationsEffect);
|
|
123
|
+
const allDecorations: Decoration[] = [];
|
|
124
|
+
innnerDecorations?.map((source) => {
|
|
125
|
+
// Temporary: this only exists on prosemirror-view@1.34.0. Since post-office is lower it causes an error.
|
|
126
|
+
// Once we do our prosemirror bump (very soon) we should remove this.
|
|
127
|
+
// https://product-fabric.atlassian.net/browse/ED-26398
|
|
128
|
+
// @ts-ignore
|
|
129
|
+
source?.forEachSet((set) => {
|
|
130
|
+
const decorations = set
|
|
131
|
+
.find(from, to)
|
|
132
|
+
// Do not render the code block line decorations
|
|
133
|
+
// Temporary: this only exists on prosemirror-view@1.34.0. Since post-office is lower it causes an error.
|
|
134
|
+
// Once we do our prosemirror bump (very soon) we should remove this.
|
|
135
|
+
// https://product-fabric.atlassian.net/browse/ED-26398
|
|
136
|
+
// @ts-ignore
|
|
137
|
+
.filter((dec) => dec.spec.type !== 'decorationWidgetType');
|
|
138
|
+
allDecorations.push(...decorations);
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
const cmDecorations = allDecorations
|
|
143
|
+
.sort((a, b) => (a.from < b.from ? -1 : 1))
|
|
144
|
+
.map((decoration) => mapPMDecorationToCMDecoration(decoration, editorView, getPos))
|
|
145
|
+
.filter(isDefined);
|
|
146
|
+
|
|
147
|
+
return CodeMirrorDecoration.set(cmDecorations);
|
|
148
|
+
}
|
|
149
|
+
update(update: ViewUpdate) {
|
|
150
|
+
this.decorations = this.updateDecorations(update.view);
|
|
151
|
+
}
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
decorations: (v) => v.decorations,
|
|
155
|
+
},
|
|
156
|
+
);
|
package/tsconfig.app.json
CHANGED
|
@@ -43,9 +43,15 @@
|
|
|
43
43
|
{
|
|
44
44
|
"path": "../editor-plugin-editor-disabled/tsconfig.app.json"
|
|
45
45
|
},
|
|
46
|
+
{
|
|
47
|
+
"path": "../editor-plugin-find-replace/tsconfig.app.json"
|
|
48
|
+
},
|
|
46
49
|
{
|
|
47
50
|
"path": "../editor-plugin-selection/tsconfig.app.json"
|
|
48
51
|
},
|
|
52
|
+
{
|
|
53
|
+
"path": "../editor-plugin-selection-marker/tsconfig.app.json"
|
|
54
|
+
},
|
|
49
55
|
{
|
|
50
56
|
"path": "../../design-system/tokens/tsconfig.app.json"
|
|
51
57
|
}
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
-
Object.defineProperty(exports, "__esModule", {
|
|
5
|
-
value: true
|
|
6
|
-
});
|
|
7
|
-
exports.bidiCharWarningExtension = void 0;
|
|
8
|
-
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
|
|
9
|
-
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
|
|
10
|
-
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
|
|
11
|
-
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
|
|
12
|
-
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
|
|
13
|
-
var _view = require("@codemirror/view");
|
|
14
|
-
function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2.default)(o), (0, _possibleConstructorReturn2.default)(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], (0, _getPrototypeOf2.default)(t).constructor) : o.apply(t, e)); }
|
|
15
|
-
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); } /**
|
|
16
|
-
* Code based on warning from @atlaskit/code
|
|
17
|
-
*/
|
|
18
|
-
var bidiCharacterRegex = /[\u202A-\u202E\u2066-\u2069]/g;
|
|
19
|
-
var placeholderMatcher = new _view.MatchDecorator({
|
|
20
|
-
regexp: bidiCharacterRegex,
|
|
21
|
-
decoration: function decoration(match) {
|
|
22
|
-
return _view.Decoration.replace({
|
|
23
|
-
widget: new PlaceholderWidget(match[0])
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
});
|
|
27
|
-
var bidiCharWarningExtension = exports.bidiCharWarningExtension = _view.ViewPlugin.fromClass( /*#__PURE__*/function () {
|
|
28
|
-
function _class(view) {
|
|
29
|
-
(0, _classCallCheck2.default)(this, _class);
|
|
30
|
-
this.placeholders = placeholderMatcher.createDeco(view);
|
|
31
|
-
}
|
|
32
|
-
return (0, _createClass2.default)(_class, [{
|
|
33
|
-
key: "update",
|
|
34
|
-
value: function update(_update) {
|
|
35
|
-
this.placeholders = placeholderMatcher.updateDeco(_update, this.placeholders);
|
|
36
|
-
}
|
|
37
|
-
}]);
|
|
38
|
-
}(), {
|
|
39
|
-
decorations: function decorations(instance) {
|
|
40
|
-
return instance.placeholders;
|
|
41
|
-
},
|
|
42
|
-
provide: function provide(plugin) {
|
|
43
|
-
return _view.EditorView.atomicRanges.of(function (view) {
|
|
44
|
-
var _view$plugin;
|
|
45
|
-
return ((_view$plugin = view.plugin(plugin)) === null || _view$plugin === void 0 ? void 0 : _view$plugin.placeholders) || _view.Decoration.none;
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
});
|
|
49
|
-
function getBidiCharacterCode(bidiCharacter) {
|
|
50
|
-
var _bidiCharacter$codePo;
|
|
51
|
-
var bidiCharacterCode = (_bidiCharacter$codePo = bidiCharacter.codePointAt(0)) === null || _bidiCharacter$codePo === void 0 ? void 0 : _bidiCharacter$codePo.toString(16);
|
|
52
|
-
return "U+".concat(bidiCharacterCode);
|
|
53
|
-
}
|
|
54
|
-
var PlaceholderWidget = /*#__PURE__*/function (_WidgetType) {
|
|
55
|
-
function PlaceholderWidget(name) {
|
|
56
|
-
var _this;
|
|
57
|
-
(0, _classCallCheck2.default)(this, PlaceholderWidget);
|
|
58
|
-
_this = _callSuper(this, PlaceholderWidget);
|
|
59
|
-
_this.name = name;
|
|
60
|
-
return _this;
|
|
61
|
-
}
|
|
62
|
-
(0, _inherits2.default)(PlaceholderWidget, _WidgetType);
|
|
63
|
-
return (0, _createClass2.default)(PlaceholderWidget, [{
|
|
64
|
-
key: "eq",
|
|
65
|
-
value: function eq(other) {
|
|
66
|
-
return this.name === other.name;
|
|
67
|
-
}
|
|
68
|
-
}, {
|
|
69
|
-
key: "toDOM",
|
|
70
|
-
value: function toDOM() {
|
|
71
|
-
var elt = document.createElement('span');
|
|
72
|
-
elt.setAttribute('data-bidi-character-code', this.name);
|
|
73
|
-
elt.style.cssText = "\n padding: 0 3px;\n color: ".concat("var(--ds-text-warning, #A54800)", ";\n\t\t\tbackground: ", "var(--ds-background-warning, #FFF7D6)", ";\n\t\t\taria-hidden=\"true\"");
|
|
74
|
-
elt.textContent = "<".concat(getBidiCharacterCode(this.name), ">");
|
|
75
|
-
return elt;
|
|
76
|
-
}
|
|
77
|
-
}, {
|
|
78
|
-
key: "ignoreEvent",
|
|
79
|
-
value: function ignoreEvent() {
|
|
80
|
-
return false;
|
|
81
|
-
}
|
|
82
|
-
}]);
|
|
83
|
-
}(_view.WidgetType);
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Code based on warning from @atlaskit/code
|
|
3
|
-
*/
|
|
4
|
-
import { EditorView as CodeMirror, ViewPlugin, Decoration, MatchDecorator, WidgetType } from '@codemirror/view';
|
|
5
|
-
const bidiCharacterRegex = /[\u202A-\u202E\u2066-\u2069]/gu;
|
|
6
|
-
const placeholderMatcher = new MatchDecorator({
|
|
7
|
-
regexp: bidiCharacterRegex,
|
|
8
|
-
decoration: match => Decoration.replace({
|
|
9
|
-
widget: new PlaceholderWidget(match[0])
|
|
10
|
-
})
|
|
11
|
-
});
|
|
12
|
-
export const bidiCharWarningExtension = ViewPlugin.fromClass(class {
|
|
13
|
-
constructor(view) {
|
|
14
|
-
this.placeholders = placeholderMatcher.createDeco(view);
|
|
15
|
-
}
|
|
16
|
-
update(update) {
|
|
17
|
-
this.placeholders = placeholderMatcher.updateDeco(update, this.placeholders);
|
|
18
|
-
}
|
|
19
|
-
}, {
|
|
20
|
-
decorations: instance => instance.placeholders,
|
|
21
|
-
provide: plugin => CodeMirror.atomicRanges.of(view => {
|
|
22
|
-
var _view$plugin;
|
|
23
|
-
return ((_view$plugin = view.plugin(plugin)) === null || _view$plugin === void 0 ? void 0 : _view$plugin.placeholders) || Decoration.none;
|
|
24
|
-
})
|
|
25
|
-
});
|
|
26
|
-
function getBidiCharacterCode(bidiCharacter) {
|
|
27
|
-
var _bidiCharacter$codePo;
|
|
28
|
-
const bidiCharacterCode = (_bidiCharacter$codePo = bidiCharacter.codePointAt(0)) === null || _bidiCharacter$codePo === void 0 ? void 0 : _bidiCharacter$codePo.toString(16);
|
|
29
|
-
return `U+${bidiCharacterCode}`;
|
|
30
|
-
}
|
|
31
|
-
class PlaceholderWidget extends WidgetType {
|
|
32
|
-
constructor(name) {
|
|
33
|
-
super();
|
|
34
|
-
this.name = name;
|
|
35
|
-
}
|
|
36
|
-
eq(other) {
|
|
37
|
-
return this.name === other.name;
|
|
38
|
-
}
|
|
39
|
-
toDOM() {
|
|
40
|
-
const elt = document.createElement('span');
|
|
41
|
-
elt.setAttribute('data-bidi-character-code', this.name);
|
|
42
|
-
elt.style.cssText = `
|
|
43
|
-
padding: 0 3px;
|
|
44
|
-
color: ${"var(--ds-text-warning, #A54800)"};
|
|
45
|
-
background: ${"var(--ds-background-warning, #FFF7D6)"};
|
|
46
|
-
aria-hidden="true"`;
|
|
47
|
-
elt.textContent = `<${getBidiCharacterCode(this.name)}>`;
|
|
48
|
-
return elt;
|
|
49
|
-
}
|
|
50
|
-
ignoreEvent() {
|
|
51
|
-
return false;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn";
|
|
2
|
-
import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
|
|
3
|
-
import _inherits from "@babel/runtime/helpers/inherits";
|
|
4
|
-
import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
|
|
5
|
-
import _createClass from "@babel/runtime/helpers/createClass";
|
|
6
|
-
function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
|
|
7
|
-
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
|
|
8
|
-
/**
|
|
9
|
-
* Code based on warning from @atlaskit/code
|
|
10
|
-
*/
|
|
11
|
-
import { EditorView as CodeMirror, ViewPlugin, Decoration, MatchDecorator, WidgetType } from '@codemirror/view';
|
|
12
|
-
var bidiCharacterRegex = /[\u202A-\u202E\u2066-\u2069]/g;
|
|
13
|
-
var placeholderMatcher = new MatchDecorator({
|
|
14
|
-
regexp: bidiCharacterRegex,
|
|
15
|
-
decoration: function decoration(match) {
|
|
16
|
-
return Decoration.replace({
|
|
17
|
-
widget: new PlaceholderWidget(match[0])
|
|
18
|
-
});
|
|
19
|
-
}
|
|
20
|
-
});
|
|
21
|
-
export var bidiCharWarningExtension = ViewPlugin.fromClass( /*#__PURE__*/function () {
|
|
22
|
-
function _class(view) {
|
|
23
|
-
_classCallCheck(this, _class);
|
|
24
|
-
this.placeholders = placeholderMatcher.createDeco(view);
|
|
25
|
-
}
|
|
26
|
-
return _createClass(_class, [{
|
|
27
|
-
key: "update",
|
|
28
|
-
value: function update(_update) {
|
|
29
|
-
this.placeholders = placeholderMatcher.updateDeco(_update, this.placeholders);
|
|
30
|
-
}
|
|
31
|
-
}]);
|
|
32
|
-
}(), {
|
|
33
|
-
decorations: function decorations(instance) {
|
|
34
|
-
return instance.placeholders;
|
|
35
|
-
},
|
|
36
|
-
provide: function provide(plugin) {
|
|
37
|
-
return CodeMirror.atomicRanges.of(function (view) {
|
|
38
|
-
var _view$plugin;
|
|
39
|
-
return ((_view$plugin = view.plugin(plugin)) === null || _view$plugin === void 0 ? void 0 : _view$plugin.placeholders) || Decoration.none;
|
|
40
|
-
});
|
|
41
|
-
}
|
|
42
|
-
});
|
|
43
|
-
function getBidiCharacterCode(bidiCharacter) {
|
|
44
|
-
var _bidiCharacter$codePo;
|
|
45
|
-
var bidiCharacterCode = (_bidiCharacter$codePo = bidiCharacter.codePointAt(0)) === null || _bidiCharacter$codePo === void 0 ? void 0 : _bidiCharacter$codePo.toString(16);
|
|
46
|
-
return "U+".concat(bidiCharacterCode);
|
|
47
|
-
}
|
|
48
|
-
var PlaceholderWidget = /*#__PURE__*/function (_WidgetType) {
|
|
49
|
-
function PlaceholderWidget(name) {
|
|
50
|
-
var _this;
|
|
51
|
-
_classCallCheck(this, PlaceholderWidget);
|
|
52
|
-
_this = _callSuper(this, PlaceholderWidget);
|
|
53
|
-
_this.name = name;
|
|
54
|
-
return _this;
|
|
55
|
-
}
|
|
56
|
-
_inherits(PlaceholderWidget, _WidgetType);
|
|
57
|
-
return _createClass(PlaceholderWidget, [{
|
|
58
|
-
key: "eq",
|
|
59
|
-
value: function eq(other) {
|
|
60
|
-
return this.name === other.name;
|
|
61
|
-
}
|
|
62
|
-
}, {
|
|
63
|
-
key: "toDOM",
|
|
64
|
-
value: function toDOM() {
|
|
65
|
-
var elt = document.createElement('span');
|
|
66
|
-
elt.setAttribute('data-bidi-character-code', this.name);
|
|
67
|
-
elt.style.cssText = "\n padding: 0 3px;\n color: ".concat("var(--ds-text-warning, #A54800)", ";\n\t\t\tbackground: ", "var(--ds-background-warning, #FFF7D6)", ";\n\t\t\taria-hidden=\"true\"");
|
|
68
|
-
elt.textContent = "<".concat(getBidiCharacterCode(this.name), ">");
|
|
69
|
-
return elt;
|
|
70
|
-
}
|
|
71
|
-
}, {
|
|
72
|
-
key: "ignoreEvent",
|
|
73
|
-
value: function ignoreEvent() {
|
|
74
|
-
return false;
|
|
75
|
-
}
|
|
76
|
-
}]);
|
|
77
|
-
}(WidgetType);
|