@onereach/ui-components 4.1.1 → 4.2.0-beta.2544.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/dist/bundled/v2/components/OrCode/OrCode.js +6 -3727
- package/dist/bundled/v2/components/OrCode/index.js +6 -2
- package/dist/bundled/v2/components/OrCode/lang.js +3897 -3
- package/dist/bundled/v2/components/OrCode/theme.js +2 -1
- package/dist/bundled/v2/components/OrConfirm/OrConfirm.js +1 -0
- package/dist/bundled/v2/components/OrConfirm/index.js +1 -0
- package/dist/bundled/v2/components/OrModal/OrModal.js +3 -1266
- package/dist/bundled/v2/components/OrModal/index.js +1 -0
- package/dist/bundled/v2/components/OrRichTextEditorV3/OrRichTextEditor.js +1988 -0
- package/dist/bundled/v2/components/OrRichTextEditorV3/OrRichTextEditor.vue.d.ts +170 -0
- package/dist/bundled/v2/components/OrRichTextEditorV3/index.d.ts +1 -0
- package/dist/bundled/v2/components/OrRichTextEditorV3/index.js +68 -0
- package/dist/bundled/v2/components/OrRichTextEditorV3/styles.d.ts +6 -0
- package/dist/bundled/v2/components/OrRichTextEditorV3/styles.js +38 -0
- package/dist/bundled/v2/components/OrRichTextEditorV3/utils/codemirror/codemirrorNode.d.ts +3 -0
- package/dist/bundled/v2/components/OrRichTextEditorV3/utils/codemirror/codemirrorNode.js +45 -0
- package/dist/bundled/v2/components/OrRichTextEditorV3/utils/codemirror/codemirrorView.d.ts +27 -0
- package/dist/bundled/v2/components/OrRichTextEditorV3/utils/codemirror/codemirrorView.js +184 -0
- package/dist/bundled/v2/components/OrRichTextEditorV3/utils/codemirror/index.d.ts +1 -0
- package/dist/bundled/v2/components/OrRichTextEditorV3/utils/codemirror/index.js +5 -0
- package/dist/bundled/v2/components/OrRichTextEditorV3/utils/codemirror/theme.d.ts +24 -0
- package/dist/bundled/v2/components/OrRichTextEditorV3/utils/codemirror/theme.js +190 -0
- package/dist/bundled/v2/components/OrRichTextEditorV3/utils/codemirror/types.d.ts +19 -0
- package/dist/bundled/v2/components/OrRichTextEditorV3/utils/codemirror/types.js +1 -0
- package/dist/bundled/v2/components/OrRichTextEditorV3/utils/markdown.d.ts +3 -0
- package/dist/bundled/v2/components/OrRichTextEditorV3/utils/markdown.js +5 -0
- package/dist/bundled/v2/components/index.d.ts +1 -0
- package/dist/bundled/v2/components/index.js +15 -2
- package/dist/bundled/{v3/OrCode.vue_vue_type_script_lang-c5a9adb7.js → v2/index-16aee5bc.js} +14 -234
- package/dist/bundled/v2/index-62c3221b.js +6956 -0
- package/dist/bundled/{v3/lang-02d2bb2d.js → v2/index-70ca38c5.js} +73 -3965
- package/dist/bundled/v2/{index-6976c52a.js → index-f5487f12.js} +3 -115
- package/dist/bundled/v2/index.es-3f39f316.js +115 -0
- package/dist/bundled/v2/index.js +18 -5
- package/dist/bundled/v2/markdown-516daba9.js +18737 -0
- package/dist/bundled/v2/tiptap-core.esm-f85402b1.js +9360 -0
- package/dist/bundled/{v3/OrModal.vue_vue_type_script_lang-d5fb0b11.js → v2/useFocusTrap-9567b3c8.js} +3 -105
- package/dist/bundled/v3/OrCode.vue_vue_type_script_lang-f6f74339.js +236 -0
- package/dist/bundled/v3/{OrConfirm.vue_vue_type_script_lang-806d209b.js → OrConfirm.vue_vue_type_script_lang-36318ca2.js} +1 -1
- package/dist/bundled/v3/OrModal.vue_vue_type_script_lang-af0c4288.js +107 -0
- package/dist/bundled/v3/OrRichTextEditor.vue_vue_type_script_lang-2bb9d87f.js +1765 -0
- package/dist/bundled/v3/components/OrCode/OrCode.js +10 -6
- package/dist/bundled/v3/components/OrCode/index.js +8 -4
- package/dist/bundled/v3/components/OrCode/lang.js +3897 -3
- package/dist/bundled/v3/components/OrCode/theme.js +2 -1
- package/dist/bundled/v3/components/OrConfirm/OrConfirm.js +4 -3
- package/dist/bundled/v3/components/OrConfirm/index.js +3 -2
- package/dist/bundled/v3/components/OrModal/OrModal.js +3 -2
- package/dist/bundled/v3/components/OrModal/index.js +2 -1
- package/dist/bundled/v3/components/OrRichTextEditorV3/OrRichTextEditor.js +227 -0
- package/dist/bundled/v3/components/OrRichTextEditorV3/OrRichTextEditor.vue.d.ts +170 -0
- package/dist/bundled/v3/components/OrRichTextEditorV3/index.d.ts +1 -0
- package/dist/bundled/v3/components/OrRichTextEditorV3/index.js +84 -0
- package/dist/bundled/v3/components/OrRichTextEditorV3/styles.d.ts +6 -0
- package/dist/bundled/v3/components/OrRichTextEditorV3/styles.js +38 -0
- package/dist/bundled/v3/components/OrRichTextEditorV3/utils/codemirror/codemirrorNode.d.ts +3 -0
- package/dist/bundled/v3/components/OrRichTextEditorV3/utils/codemirror/codemirrorNode.js +45 -0
- package/dist/bundled/v3/components/OrRichTextEditorV3/utils/codemirror/codemirrorView.d.ts +27 -0
- package/dist/bundled/v3/components/OrRichTextEditorV3/utils/codemirror/codemirrorView.js +184 -0
- package/dist/bundled/v3/components/OrRichTextEditorV3/utils/codemirror/index.d.ts +1 -0
- package/dist/bundled/v3/components/OrRichTextEditorV3/utils/codemirror/index.js +5 -0
- package/dist/bundled/v3/components/OrRichTextEditorV3/utils/codemirror/theme.d.ts +24 -0
- package/dist/bundled/v3/components/OrRichTextEditorV3/utils/codemirror/theme.js +190 -0
- package/dist/bundled/v3/components/OrRichTextEditorV3/utils/codemirror/types.d.ts +19 -0
- package/dist/bundled/v3/components/OrRichTextEditorV3/utils/codemirror/types.js +1 -0
- package/dist/bundled/v3/components/OrRichTextEditorV3/utils/markdown.d.ts +3 -0
- package/dist/bundled/v3/components/OrRichTextEditorV3/utils/markdown.js +5 -0
- package/dist/bundled/v3/components/index.d.ts +1 -0
- package/dist/bundled/v3/components/index.js +19 -5
- package/dist/bundled/v3/index-16aee5bc.js +3740 -0
- package/dist/bundled/v3/index-62c3221b.js +6956 -0
- package/dist/bundled/{v2/lang-02d2bb2d.js → v3/index-70ca38c5.js} +73 -3965
- package/dist/bundled/v3/{index-6976c52a.js → index-f5487f12.js} +3 -115
- package/dist/bundled/v3/index.es-3f39f316.js +115 -0
- package/dist/bundled/v3/index.js +23 -9
- package/dist/bundled/v3/markdown-516daba9.js +18737 -0
- package/dist/bundled/v3/tiptap-core.esm-f85402b1.js +9360 -0
- package/dist/bundled/v3/useFocusTrap-9567b3c8.js +1268 -0
- package/dist/esm/v2/OrRichTextEditor-dfddef2b.js +722 -0
- package/dist/esm/v2/codemirrorView-be2c7423.js +353 -0
- package/dist/esm/v2/components/index.d.ts +1 -0
- package/dist/esm/v2/components/index.js +24 -0
- package/dist/esm/v2/components/or-rich-text-editor-v3/OrRichTextEditor.vue.d.ts +170 -0
- package/dist/esm/v2/components/or-rich-text-editor-v3/index.d.ts +1 -0
- package/dist/esm/v2/components/or-rich-text-editor-v3/index.js +59 -0
- package/dist/esm/v2/components/or-rich-text-editor-v3/styles.d.ts +6 -0
- package/dist/esm/v2/components/or-rich-text-editor-v3/utils/codemirror/codemirrorNode.d.ts +3 -0
- package/dist/esm/v2/components/or-rich-text-editor-v3/utils/codemirror/codemirrorView.d.ts +27 -0
- package/dist/esm/v2/components/or-rich-text-editor-v3/utils/codemirror/index.d.ts +1 -0
- package/dist/esm/v2/components/or-rich-text-editor-v3/utils/codemirror/index.js +7 -0
- package/dist/esm/v2/components/or-rich-text-editor-v3/utils/codemirror/theme.d.ts +24 -0
- package/dist/esm/v2/components/or-rich-text-editor-v3/utils/codemirror/types.d.ts +19 -0
- package/dist/esm/v2/components/or-rich-text-editor-v3/utils/markdown.d.ts +3 -0
- package/dist/esm/v2/index.js +24 -0
- package/dist/esm/v3/OrRichTextEditor-f4ce18ef.js +686 -0
- package/dist/esm/v3/codemirrorView-be2c7423.js +353 -0
- package/dist/esm/v3/components/index.d.ts +1 -0
- package/dist/esm/v3/components/index.js +24 -0
- package/dist/esm/v3/components/or-rich-text-editor-v3/OrRichTextEditor.vue.d.ts +170 -0
- package/dist/esm/v3/components/or-rich-text-editor-v3/index.d.ts +1 -0
- package/dist/esm/v3/components/or-rich-text-editor-v3/index.js +57 -0
- package/dist/esm/v3/components/or-rich-text-editor-v3/styles.d.ts +6 -0
- package/dist/esm/v3/components/or-rich-text-editor-v3/utils/codemirror/codemirrorNode.d.ts +3 -0
- package/dist/esm/v3/components/or-rich-text-editor-v3/utils/codemirror/codemirrorView.d.ts +27 -0
- package/dist/esm/v3/components/or-rich-text-editor-v3/utils/codemirror/index.d.ts +1 -0
- package/dist/esm/v3/components/or-rich-text-editor-v3/utils/codemirror/index.js +7 -0
- package/dist/esm/v3/components/or-rich-text-editor-v3/utils/codemirror/theme.d.ts +24 -0
- package/dist/esm/v3/components/or-rich-text-editor-v3/utils/codemirror/types.d.ts +19 -0
- package/dist/esm/v3/components/or-rich-text-editor-v3/utils/markdown.d.ts +3 -0
- package/dist/esm/v3/index.js +24 -0
- package/package.json +25 -5
- package/src/components/index.ts +1 -0
- package/src/components/or-rich-text-editor-v3/OrRichTextEditor.docs.mdx +7 -0
- package/src/components/or-rich-text-editor-v3/OrRichTextEditor.stories3.ts +103 -0
- package/src/components/or-rich-text-editor-v3/OrRichTextEditor.vue +624 -0
- package/src/components/or-rich-text-editor-v3/index.ts +1 -0
- package/src/components/or-rich-text-editor-v3/styles.ts +64 -0
- package/src/components/or-rich-text-editor-v3/utils/codemirror/codemirrorNode.ts +40 -0
- package/src/components/or-rich-text-editor-v3/utils/codemirror/codemirrorView.ts +254 -0
- package/src/components/or-rich-text-editor-v3/utils/codemirror/index.ts +1 -0
- package/src/components/or-rich-text-editor-v3/utils/codemirror/theme.ts +213 -0
- package/src/components/or-rich-text-editor-v3/utils/codemirror/types.ts +22 -0
- package/src/components/or-rich-text-editor-v3/utils/markdown.ts +117 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Node } from '@tiptap/core';
|
|
2
|
+
import CodeBlockView from './codemirrorView';
|
|
3
|
+
import { minimalSetup } from 'codemirror';
|
|
4
|
+
import { javascript } from '@codemirror/lang-javascript';
|
|
5
|
+
|
|
6
|
+
export default Node.create({
|
|
7
|
+
name: 'codeBlock',
|
|
8
|
+
content: 'text*',
|
|
9
|
+
marks: '',
|
|
10
|
+
group: 'block',
|
|
11
|
+
code: true,
|
|
12
|
+
defining: true,
|
|
13
|
+
isolating: true,
|
|
14
|
+
|
|
15
|
+
parseHTML() {
|
|
16
|
+
return [
|
|
17
|
+
{
|
|
18
|
+
tag: 'pre',
|
|
19
|
+
preserveWhitespace: 'full',
|
|
20
|
+
},
|
|
21
|
+
];
|
|
22
|
+
},
|
|
23
|
+
|
|
24
|
+
renderHTML() {
|
|
25
|
+
return ['pre', ['code', 0]];
|
|
26
|
+
},
|
|
27
|
+
|
|
28
|
+
addNodeView() {
|
|
29
|
+
return ({ node, editor, getPos }) => {
|
|
30
|
+
return new CodeBlockView({
|
|
31
|
+
node,
|
|
32
|
+
view: editor.view,
|
|
33
|
+
getPos: getPos as () => number,
|
|
34
|
+
cmOptions: {
|
|
35
|
+
extensions: [minimalSetup, javascript()],
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
};
|
|
39
|
+
},
|
|
40
|
+
});
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
import { Selection, TextSelection } from 'prosemirror-state';
|
|
2
|
+
import { EditorView, NodeView } from 'prosemirror-view';
|
|
3
|
+
import { Node as ProsemirrorNode } from 'prosemirror-model';
|
|
4
|
+
import { exitCode } from 'prosemirror-commands';
|
|
5
|
+
import { EditorState as CMState, Transaction as CMTransaction } from '@codemirror/state';
|
|
6
|
+
import {
|
|
7
|
+
Command,
|
|
8
|
+
EditorView as CMView,
|
|
9
|
+
keymap,
|
|
10
|
+
highlightActiveLine,
|
|
11
|
+
highlightActiveLineGutter,
|
|
12
|
+
lineNumbers,
|
|
13
|
+
} from '@codemirror/view';
|
|
14
|
+
import orCodeTheme from './theme';
|
|
15
|
+
|
|
16
|
+
import { ComputeChange, CodeMirrorViewOptions } from './types';
|
|
17
|
+
|
|
18
|
+
const computeChange = (oldVal: string, newVal: string): ComputeChange | null => {
|
|
19
|
+
if (oldVal === newVal) {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
let start = 0;
|
|
24
|
+
let oldEnd = oldVal.length;
|
|
25
|
+
let newEnd = newVal.length;
|
|
26
|
+
|
|
27
|
+
while (start < oldEnd && oldVal.charCodeAt(start) === newVal.charCodeAt(start)) {
|
|
28
|
+
start += 1;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
while (oldEnd > start && newEnd > start && oldVal.charCodeAt(oldEnd - 1) === newVal.charCodeAt(newEnd - 1)) {
|
|
32
|
+
oldEnd -= 1;
|
|
33
|
+
newEnd -= 1;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return {
|
|
37
|
+
from: start,
|
|
38
|
+
to: oldEnd,
|
|
39
|
+
text: newVal.slice(start, newEnd),
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
class CodeMirrorView implements NodeView {
|
|
44
|
+
name: string;
|
|
45
|
+
|
|
46
|
+
node: ProsemirrorNode;
|
|
47
|
+
|
|
48
|
+
view: EditorView;
|
|
49
|
+
|
|
50
|
+
dom: HTMLElement;
|
|
51
|
+
|
|
52
|
+
cm: CMView;
|
|
53
|
+
|
|
54
|
+
getPos: () => number;
|
|
55
|
+
|
|
56
|
+
updating = false;
|
|
57
|
+
|
|
58
|
+
constructor(options: CodeMirrorViewOptions) {
|
|
59
|
+
// Store for later
|
|
60
|
+
this.node = options.node;
|
|
61
|
+
this.view = options.view;
|
|
62
|
+
const cmExtensions = options.cmOptions?.extensions || [];
|
|
63
|
+
this.name = 'codeBlock',
|
|
64
|
+
|
|
65
|
+
this.getPos = options.getPos as () => number;
|
|
66
|
+
|
|
67
|
+
const changeFilter = CMState.changeFilter.of((tr) => {
|
|
68
|
+
if (!tr.docChanged && !this.updating) {
|
|
69
|
+
this.forwardSelection();
|
|
70
|
+
}
|
|
71
|
+
return true;
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
// Create a CodeMirror instancew
|
|
75
|
+
this.cm = new CMView({
|
|
76
|
+
dispatch: this.dispatch.bind(this),
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
// The editor's outer node is our DOM representation
|
|
80
|
+
this.dom = this.cm.dom;
|
|
81
|
+
|
|
82
|
+
const cmState = CMState.create({
|
|
83
|
+
doc: this.node.textContent,
|
|
84
|
+
extensions: [
|
|
85
|
+
orCodeTheme,
|
|
86
|
+
changeFilter,
|
|
87
|
+
highlightActiveLine(),
|
|
88
|
+
highlightActiveLineGutter(),
|
|
89
|
+
lineNumbers(),
|
|
90
|
+
keymap.of([
|
|
91
|
+
{
|
|
92
|
+
key: 'ArrowUp',
|
|
93
|
+
run: this.mayBeEscape('line', -1),
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
key: 'ArrowLeft',
|
|
97
|
+
run: this.mayBeEscape('char', -1),
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
key: 'ArrowDown',
|
|
101
|
+
run: this.mayBeEscape('line', 1),
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
key: 'ArrowRight',
|
|
105
|
+
run: this.mayBeEscape('char', 1),
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
key: 'Ctrl-Enter',
|
|
109
|
+
run: () => {
|
|
110
|
+
if (exitCode(this.view.state, this.view.dispatch)) {
|
|
111
|
+
this.view.focus();
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
114
|
+
return false;
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
]),
|
|
118
|
+
cmExtensions,
|
|
119
|
+
],
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
this.cm.setState(cmState);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
forwardSelection() {
|
|
126
|
+
if (!this.cm.hasFocus) {
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const { state } = this.view;
|
|
131
|
+
const selection = this.asProseMirrorSelection(state.doc);
|
|
132
|
+
|
|
133
|
+
if (!selection.eq(state.selection)) {
|
|
134
|
+
this.view.dispatch(state.tr.setSelection(selection));
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
asProseMirrorSelection(doc: ProsemirrorNode) {
|
|
139
|
+
const offset = this.getPos() + 1;
|
|
140
|
+
const { anchor, head } = this.cm.state.selection.main;
|
|
141
|
+
return TextSelection.create(doc, anchor + offset, head + offset);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
dispatch(cmTr: CMTransaction) {
|
|
145
|
+
this.cm.setState(cmTr.state);
|
|
146
|
+
|
|
147
|
+
if (cmTr.docChanged && !this.updating) {
|
|
148
|
+
const start = this.getPos() + 1;
|
|
149
|
+
|
|
150
|
+
const cmValue = cmTr.state.doc.toString();
|
|
151
|
+
const change = computeChange(this.node.textContent, cmValue);
|
|
152
|
+
|
|
153
|
+
if (!change) {
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const content = change.text ? this.view.state.schema.text(change.text) : null;
|
|
158
|
+
|
|
159
|
+
const tr = this.view.state.tr.replaceWith(change.from + start, change.to + start, content as ProsemirrorNode);
|
|
160
|
+
this.view.dispatch(tr);
|
|
161
|
+
this.forwardSelection();
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
mayBeEscape(unit: 'char' | 'line', dir: -1 | 1): Command {
|
|
166
|
+
return (view) => {
|
|
167
|
+
const { state } = view;
|
|
168
|
+
const { selection } = state;
|
|
169
|
+
|
|
170
|
+
const offsetToPos = () => {
|
|
171
|
+
const offset = selection.main.from;
|
|
172
|
+
const line = state.doc.lineAt(offset);
|
|
173
|
+
return {
|
|
174
|
+
line: line.number,
|
|
175
|
+
ch: offset - line.from,
|
|
176
|
+
};
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
const pos = offsetToPos();
|
|
180
|
+
const hasSelection = state.selection.ranges.some((r) => !r.empty);
|
|
181
|
+
|
|
182
|
+
const firstLine = 1;
|
|
183
|
+
const lastLine = state.doc.lineAt(state.doc.length).number;
|
|
184
|
+
|
|
185
|
+
if (
|
|
186
|
+
hasSelection
|
|
187
|
+
|| pos.line !== (dir < 0 ? firstLine : lastLine)
|
|
188
|
+
|| (unit === 'char' && pos.ch !== (dir < 0 ? 0 : state.doc.line(pos.line).length))
|
|
189
|
+
) {
|
|
190
|
+
return false;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
const targetPos = this.getPos() + (dir < 0 ? 0 : this.node.nodeSize);
|
|
194
|
+
const pmSelection = Selection.near(this.view.state.doc.resolve(targetPos), dir);
|
|
195
|
+
this.view.dispatch(this.view.state.tr.setSelection(pmSelection).scrollIntoView());
|
|
196
|
+
this.view.focus();
|
|
197
|
+
return true;
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
update(node: ProsemirrorNode) {
|
|
202
|
+
if (node.type !== this.node.type) {
|
|
203
|
+
return false;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
this.node = node;
|
|
207
|
+
const change = computeChange(this.cm.state.doc.toString(), node.textContent);
|
|
208
|
+
|
|
209
|
+
if (change) {
|
|
210
|
+
this.updating = true;
|
|
211
|
+
this.cm.dispatch({
|
|
212
|
+
changes: {
|
|
213
|
+
from: change.from,
|
|
214
|
+
to: change.to,
|
|
215
|
+
insert: change.text,
|
|
216
|
+
},
|
|
217
|
+
});
|
|
218
|
+
this.updating = false;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
return true;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
setSelection(anchor: number, head: number): void {
|
|
225
|
+
this.focus();
|
|
226
|
+
this.updating = true;
|
|
227
|
+
this.cm.dispatch({
|
|
228
|
+
selection: {
|
|
229
|
+
anchor,
|
|
230
|
+
head,
|
|
231
|
+
},
|
|
232
|
+
});
|
|
233
|
+
this.updating = false;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
focus() {
|
|
237
|
+
this.cm.focus();
|
|
238
|
+
this.forwardSelection();
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
selectNode() {
|
|
242
|
+
this.focus();
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
stopEvent() {
|
|
246
|
+
return true;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
destroy() {
|
|
250
|
+
this.cm.destroy();
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
export default CodeMirrorView;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as CodeMirrorView } from './codemirrorView';
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import { EditorView } from '@codemirror/view';
|
|
2
|
+
import { Extension } from '@codemirror/state';
|
|
3
|
+
import { HighlightStyle, syntaxHighlighting } from '@codemirror/language';
|
|
4
|
+
import { tags as t } from '@lezer/highlight';
|
|
5
|
+
|
|
6
|
+
// Using https://github.com/one-dark/vscode-one-dark-theme/ as reference for the colors
|
|
7
|
+
|
|
8
|
+
const chalky = 'var(--c-warning-darken-20)',
|
|
9
|
+
coral = 'var(--c-error)',
|
|
10
|
+
cyan = '#56b6c2',
|
|
11
|
+
invalid = 'var(--c-white)',
|
|
12
|
+
ivory = 'var(--c-neutral-6)',
|
|
13
|
+
stone = 'var(--c-neutral-5)', // Brightened compared to original to increase contrast
|
|
14
|
+
malibu = '#61afef',
|
|
15
|
+
sage = 'var(--c-success)',
|
|
16
|
+
whiskey = 'var(--c-warning-darken-5)',
|
|
17
|
+
violet = '#c678dd',
|
|
18
|
+
darkBackground = 'var(--c-neutral-1)',
|
|
19
|
+
highlightBackground = 'var(--c-neutral-2)',
|
|
20
|
+
background = 'var(--c-neutral-1)',
|
|
21
|
+
tooltipBackground = 'var(--c-neutral-2)',
|
|
22
|
+
selection = 'var(--c-neutral-3)',
|
|
23
|
+
cursor = 'var(--c-primary)';
|
|
24
|
+
|
|
25
|
+
/// The colors used in the theme, as CSS color strings.
|
|
26
|
+
export const color = {
|
|
27
|
+
chalky,
|
|
28
|
+
coral,
|
|
29
|
+
cyan,
|
|
30
|
+
invalid,
|
|
31
|
+
ivory,
|
|
32
|
+
stone,
|
|
33
|
+
malibu,
|
|
34
|
+
sage,
|
|
35
|
+
whiskey,
|
|
36
|
+
violet,
|
|
37
|
+
darkBackground,
|
|
38
|
+
highlightBackground,
|
|
39
|
+
background,
|
|
40
|
+
tooltipBackground,
|
|
41
|
+
selection,
|
|
42
|
+
cursor,
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
/// The editor theme styles for One Dark.
|
|
46
|
+
export const orCodeTheme = EditorView.theme({
|
|
47
|
+
'&': {
|
|
48
|
+
color: ivory,
|
|
49
|
+
backgroundColor: background,
|
|
50
|
+
},
|
|
51
|
+
|
|
52
|
+
'.cm-content': {
|
|
53
|
+
caretColor: cursor,
|
|
54
|
+
},
|
|
55
|
+
|
|
56
|
+
'.cm-button': {
|
|
57
|
+
background: highlightBackground,
|
|
58
|
+
color: 'var(--c-neutral-6)',
|
|
59
|
+
border: 0,
|
|
60
|
+
borderRadius: 'var(--s-2)',
|
|
61
|
+
},
|
|
62
|
+
|
|
63
|
+
'.cm-panel.cm-search input[type=checkbox]': {
|
|
64
|
+
display: 'inline-block',
|
|
65
|
+
verticalAlign: 'middle',
|
|
66
|
+
},
|
|
67
|
+
|
|
68
|
+
'.cm-cursor, .cm-dropCursor': { borderLeftColor: cursor },
|
|
69
|
+
'&.cm-focused .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection': {
|
|
70
|
+
backgroundColor: selection,
|
|
71
|
+
},
|
|
72
|
+
|
|
73
|
+
'.cm-panels': {
|
|
74
|
+
backgroundColor: darkBackground,
|
|
75
|
+
color: ivory,
|
|
76
|
+
},
|
|
77
|
+
'.cm-panels.cm-panels-top': { borderBottom: '2px solid var(--c-neutral-2)' },
|
|
78
|
+
'.cm-panels.cm-panels-bottom': { borderTop: '2px solid var(--c-neutral-2)' },
|
|
79
|
+
|
|
80
|
+
'.cm-searchMatch': {
|
|
81
|
+
backgroundColor: 'var(--c-neutral-1)',
|
|
82
|
+
outline: '1px solid var(--c-neutral-2)',
|
|
83
|
+
},
|
|
84
|
+
'.cm-searchMatch.cm-searchMatch-selected': {
|
|
85
|
+
backgroundColor: '#6199ff2f',
|
|
86
|
+
},
|
|
87
|
+
|
|
88
|
+
'.cm-activeLine': { backgroundColor: '#6699ff0b' },
|
|
89
|
+
'.cm-selectionMatch': { backgroundColor: '#aafe661a' },
|
|
90
|
+
|
|
91
|
+
'&.cm-focused .cm-matchingBracket, &.cm-focused .cm-nonmatchingBracket': {
|
|
92
|
+
backgroundColor: '#bad0f847',
|
|
93
|
+
},
|
|
94
|
+
|
|
95
|
+
'.cm-gutters': {
|
|
96
|
+
backgroundColor: background,
|
|
97
|
+
color: stone,
|
|
98
|
+
border: 'none',
|
|
99
|
+
},
|
|
100
|
+
|
|
101
|
+
'.cm-activeLineGutter': {
|
|
102
|
+
backgroundColor: highlightBackground,
|
|
103
|
+
},
|
|
104
|
+
|
|
105
|
+
'.cm-foldPlaceholder': {
|
|
106
|
+
backgroundColor: 'transparent',
|
|
107
|
+
border: 'none',
|
|
108
|
+
color: '#ddd',
|
|
109
|
+
},
|
|
110
|
+
|
|
111
|
+
'.cm-tooltip': {
|
|
112
|
+
border: 'none',
|
|
113
|
+
backgroundColor: tooltipBackground,
|
|
114
|
+
},
|
|
115
|
+
'.cm-tooltip .cm-tooltip-arrow:before': {
|
|
116
|
+
borderTopColor: 'transparent',
|
|
117
|
+
borderBottomColor: 'transparent',
|
|
118
|
+
},
|
|
119
|
+
'.cm-tooltip .cm-tooltip-arrow:after': {
|
|
120
|
+
borderTopColor: tooltipBackground,
|
|
121
|
+
borderBottomColor: tooltipBackground,
|
|
122
|
+
},
|
|
123
|
+
'.cm-tooltip-autocomplete': {
|
|
124
|
+
'& > ul > li[aria-selected]': {
|
|
125
|
+
backgroundColor: highlightBackground,
|
|
126
|
+
color: ivory,
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
'.cm-textfield': {
|
|
130
|
+
outline: 'none',
|
|
131
|
+
background: background,
|
|
132
|
+
color: 'var(--c-neutral-6)',
|
|
133
|
+
backgroundColor: 'var(--c-neutral-1)',
|
|
134
|
+
border: '1px solid var(--c-neutral-2)',
|
|
135
|
+
borderRadius: 'var(--s-2)',
|
|
136
|
+
},
|
|
137
|
+
}, { dark: true });
|
|
138
|
+
|
|
139
|
+
/// The highlighting style for code in the One Dark theme.
|
|
140
|
+
export const orCodeHighlightStyle = HighlightStyle.define([
|
|
141
|
+
{
|
|
142
|
+
tag: t.keyword,
|
|
143
|
+
color: violet,
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
tag: [t.name, t.deleted, t.character, t.propertyName, t.macroName],
|
|
147
|
+
color: coral,
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
tag: [t.function(t.variableName), t.labelName],
|
|
151
|
+
color: malibu,
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
tag: [t.color, t.constant(t.name), t.standard(t.name)],
|
|
155
|
+
color: whiskey,
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
tag: [t.definition(t.name), t.separator],
|
|
159
|
+
color: ivory,
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
tag: [t.typeName, t.className, t.number, t.changed, t.annotation, t.modifier, t.self, t.namespace],
|
|
163
|
+
color: chalky,
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
tag: [t.operator, t.operatorKeyword, t.url, t.escape, t.regexp, t.link, t.special(t.string)],
|
|
167
|
+
color: cyan,
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
tag: [t.meta, t.comment],
|
|
171
|
+
color: stone,
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
tag: t.strong,
|
|
175
|
+
fontWeight: 'bold',
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
tag: t.emphasis,
|
|
179
|
+
fontStyle: 'italic',
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
tag: t.strikethrough,
|
|
183
|
+
textDecoration: 'line-through',
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
tag: t.link,
|
|
187
|
+
color: stone,
|
|
188
|
+
textDecoration: 'underline',
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
tag: t.heading,
|
|
192
|
+
fontWeight: 'bold',
|
|
193
|
+
color: coral,
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
tag: [t.atom, t.bool, t.special(t.variableName)],
|
|
197
|
+
color: whiskey,
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
tag: [t.processingInstruction, t.string, t.inserted],
|
|
201
|
+
color: sage,
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
tag: t.invalid,
|
|
205
|
+
color: invalid,
|
|
206
|
+
},
|
|
207
|
+
]);
|
|
208
|
+
|
|
209
|
+
/// Extension to enable the One Dark theme (both the editor theme and
|
|
210
|
+
/// the highlight style).
|
|
211
|
+
const theme: Extension = [orCodeTheme, syntaxHighlighting(orCodeHighlightStyle)];
|
|
212
|
+
|
|
213
|
+
export default theme;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { EditorView } from 'prosemirror-view';
|
|
2
|
+
import type { Node as ProsemirrorNode } from 'prosemirror-model';
|
|
3
|
+
import type { Extension } from '@codemirror/state';
|
|
4
|
+
|
|
5
|
+
export interface ComputeChange {
|
|
6
|
+
from: number;
|
|
7
|
+
to: number;
|
|
8
|
+
text: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
interface CMOptions {
|
|
12
|
+
extensions: Extension;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export type GetPos = () => number | undefined;
|
|
16
|
+
|
|
17
|
+
export interface CodeMirrorViewOptions {
|
|
18
|
+
node: ProsemirrorNode;
|
|
19
|
+
view: EditorView;
|
|
20
|
+
getPos: GetPos;
|
|
21
|
+
cmOptions?: CMOptions;
|
|
22
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import {
|
|
2
|
+
MarkdownSerializer as ProseMirrorMarkdownSerializer,
|
|
3
|
+
defaultMarkdownSerializer,
|
|
4
|
+
} from 'prosemirror-markdown';
|
|
5
|
+
import { DOMParser as ProseMirrorDOMParser, Node, Mark } from 'prosemirror-model';
|
|
6
|
+
import { marked } from 'marked';
|
|
7
|
+
|
|
8
|
+
import Paragraph from '@tiptap/extension-paragraph';
|
|
9
|
+
import BulletList from '@tiptap/extension-bullet-list';
|
|
10
|
+
import ListItem from '@tiptap/extension-list-item';
|
|
11
|
+
import OrderedList from '@tiptap/extension-ordered-list';
|
|
12
|
+
import Strike from '@tiptap/extension-strike';
|
|
13
|
+
import Italic from '@tiptap/extension-italic';
|
|
14
|
+
import HardBreak from '@tiptap/extension-hard-break';
|
|
15
|
+
import Bold from '@tiptap/extension-bold';
|
|
16
|
+
import CodeBlock from '@tiptap/extension-code-block';
|
|
17
|
+
import Blockquote from '@tiptap/extension-blockquote';
|
|
18
|
+
import Link from '@tiptap/extension-link';
|
|
19
|
+
import Highlight from '@tiptap/extension-highlight';
|
|
20
|
+
import Underline from '@tiptap/extension-underline';
|
|
21
|
+
|
|
22
|
+
const serializerNodes = {
|
|
23
|
+
...defaultMarkdownSerializer.nodes,
|
|
24
|
+
[Paragraph.name]: defaultMarkdownSerializer.nodes.paragraph,
|
|
25
|
+
[BulletList.name]: defaultMarkdownSerializer.nodes.bullet_list,
|
|
26
|
+
[ListItem.name]: defaultMarkdownSerializer.nodes.list_item,
|
|
27
|
+
[OrderedList.name]: defaultMarkdownSerializer.nodes.ordered_list,
|
|
28
|
+
[HardBreak.name]: defaultMarkdownSerializer.nodes.hard_break,
|
|
29
|
+
[CodeBlock.name]: defaultMarkdownSerializer.nodes.code_block,
|
|
30
|
+
[Blockquote.name]: defaultMarkdownSerializer.nodes.blockquote,
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const serializerMarks = {
|
|
34
|
+
...defaultMarkdownSerializer.marks,
|
|
35
|
+
[Bold.name]: defaultMarkdownSerializer.marks.strong,
|
|
36
|
+
[Strike.name]: {
|
|
37
|
+
open: '~~',
|
|
38
|
+
close: '~~',
|
|
39
|
+
mixable: true,
|
|
40
|
+
expelEnclosingWhitespace: true,
|
|
41
|
+
},
|
|
42
|
+
[Italic.name]: {
|
|
43
|
+
open: '_',
|
|
44
|
+
close: '_',
|
|
45
|
+
mixable: true,
|
|
46
|
+
expelEnclosingWhitespace: true,
|
|
47
|
+
},
|
|
48
|
+
[Highlight.name]: {
|
|
49
|
+
open: '==',
|
|
50
|
+
close: '==',
|
|
51
|
+
mixable: true,
|
|
52
|
+
expelEnclosingWhitespace: true,
|
|
53
|
+
},
|
|
54
|
+
[Underline.name]: {
|
|
55
|
+
open: '',
|
|
56
|
+
close: '',
|
|
57
|
+
mixable: true,
|
|
58
|
+
expelEnclosingWhitespace: true,
|
|
59
|
+
},
|
|
60
|
+
[Link.name]: {
|
|
61
|
+
open(state: any, mark: Mark, parent: Node, index: number) {
|
|
62
|
+
return isPlainURL(mark, parent, index, 1) ? '<' : '[';
|
|
63
|
+
},
|
|
64
|
+
close(state: any, mark: Mark, parent: Node, index: number) {
|
|
65
|
+
const href = mark.attrs.canonicalSrc || mark.attrs.href;
|
|
66
|
+
|
|
67
|
+
return isPlainURL(mark, parent, index, -1)
|
|
68
|
+
? '>'
|
|
69
|
+
: `](${state.esc(href)}${
|
|
70
|
+
mark.attrs.title ? ` ${state.quote(mark.attrs.title)}` : ''
|
|
71
|
+
})`;
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
const isPlainURL = (link: Mark, parent: Node, index: number, side: number) => {
|
|
77
|
+
if (link.attrs.title || !/^\w+:/.test(link.attrs.href)) return false;
|
|
78
|
+
const content = parent.child(index + (side < 0 ? -1 : 0));
|
|
79
|
+
if (
|
|
80
|
+
!content.isText ||
|
|
81
|
+
content.text !== link.attrs.href ||
|
|
82
|
+
content.marks[content.marks.length - 1] !== link
|
|
83
|
+
)
|
|
84
|
+
return false;
|
|
85
|
+
if (index === (side < 0 ? 1 : parent.childCount - 1)) return true;
|
|
86
|
+
const next = parent.child(index + (side < 0 ? -2 : 1));
|
|
87
|
+
return !link.isInSet(next.marks);
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
const serialize = (schema: any, content: any) => {
|
|
91
|
+
const proseMirrorDocument = schema.nodeFromJSON(content);
|
|
92
|
+
const serializer = new ProseMirrorMarkdownSerializer(
|
|
93
|
+
serializerNodes,
|
|
94
|
+
serializerMarks,
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
return serializer.serialize(proseMirrorDocument);
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
const deserialize = (schema: any, content: any) => {
|
|
101
|
+
if (!content) return null;
|
|
102
|
+
|
|
103
|
+
const html = marked.parse(content);
|
|
104
|
+
|
|
105
|
+
if (!html) return null;
|
|
106
|
+
|
|
107
|
+
const parser = new DOMParser();
|
|
108
|
+
const { body } = parser.parseFromString(html, 'text/html');
|
|
109
|
+
|
|
110
|
+
// append original source as a comment that nodes can access
|
|
111
|
+
body.append(document.createComment(content));
|
|
112
|
+
|
|
113
|
+
const state = ProseMirrorDOMParser.fromSchema(schema).parse(body);
|
|
114
|
+
return state.toJSON();
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
export { serialize, deserialize };
|