2022-08-08 17:00:14 +02:00
|
|
|
import { markdown } from '@codemirror/lang-markdown';
|
|
|
|
import { GFM as GithubFlavoredMarkdownExt } from '@lezer/markdown';
|
2022-12-30 19:25:31 +02:00
|
|
|
import { indentUnit, syntaxTree } from '@codemirror/language';
|
2023-12-13 21:45:17 +02:00
|
|
|
import { SelectionRange, EditorSelection, EditorState, Extension } from '@codemirror/state';
|
2022-08-08 17:00:14 +02:00
|
|
|
import { EditorView } from '@codemirror/view';
|
2023-09-21 10:12:40 +02:00
|
|
|
import { MarkdownMathExtension } from '../markdown/markdownMathParser';
|
2022-12-07 23:28:17 +02:00
|
|
|
import forceFullParse from './forceFullParse';
|
2024-02-26 12:16:23 +02:00
|
|
|
import loadLanguages from './loadLanguages';
|
2022-12-30 19:25:31 +02:00
|
|
|
|
|
|
|
// Creates and returns a minimal editor with markdown extensions. Waits to return the editor
|
|
|
|
// until all syntax tree tags in `expectedSyntaxTreeTags` exist.
|
2023-09-21 10:12:40 +02:00
|
|
|
const createTestEditor = async (
|
2023-12-13 21:45:17 +02:00
|
|
|
initialText: string,
|
|
|
|
initialSelection: SelectionRange,
|
|
|
|
expectedSyntaxTreeTags: string[],
|
|
|
|
extraExtensions: Extension[] = [],
|
2022-12-30 19:25:31 +02:00
|
|
|
): Promise<EditorView> => {
|
2024-02-26 12:16:23 +02:00
|
|
|
await loadLanguages();
|
2022-08-08 17:00:14 +02:00
|
|
|
|
2022-08-29 13:40:19 +02:00
|
|
|
const editor = new EditorView({
|
2022-08-08 17:00:14 +02:00
|
|
|
doc: initialText,
|
|
|
|
selection: EditorSelection.create([initialSelection]),
|
|
|
|
extensions: [
|
|
|
|
markdown({
|
|
|
|
extensions: [MarkdownMathExtension, GithubFlavoredMarkdownExt],
|
|
|
|
}),
|
|
|
|
indentUnit.of('\t'),
|
|
|
|
EditorState.tabSize.of(4),
|
2024-09-21 14:00:43 +02:00
|
|
|
EditorState.allowMultipleSelections.of(true),
|
2023-12-13 21:45:17 +02:00
|
|
|
extraExtensions,
|
2022-08-08 17:00:14 +02:00
|
|
|
],
|
|
|
|
});
|
2022-08-29 13:40:19 +02:00
|
|
|
|
2022-12-30 19:25:31 +02:00
|
|
|
let sawExpectedTagCount = 0;
|
|
|
|
while (sawExpectedTagCount < expectedSyntaxTreeTags.length) {
|
|
|
|
forceFullParse(editor.state);
|
|
|
|
|
|
|
|
sawExpectedTagCount = 0;
|
|
|
|
const seenTags = new Set<string>();
|
|
|
|
|
|
|
|
syntaxTree(editor.state).iterate({
|
|
|
|
from: 0,
|
|
|
|
to: editor.state.doc.length,
|
|
|
|
enter: (node) => {
|
|
|
|
for (const expectedTag of expectedSyntaxTreeTags) {
|
|
|
|
if (node.name === expectedTag) {
|
|
|
|
seenTags.add(node.name);
|
|
|
|
sawExpectedTagCount ++;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
if (sawExpectedTagCount < expectedSyntaxTreeTags.length) {
|
2023-07-02 18:45:01 +02:00
|
|
|
// const missingTags = expectedSyntaxTreeTags.filter(tagName => {
|
|
|
|
// return !seenTags.has(tagName);
|
|
|
|
// });
|
|
|
|
// console.warn(`Didn't find all expected tags. Missing ${missingTags}. Retrying...`);
|
2022-12-30 19:25:31 +02:00
|
|
|
|
|
|
|
await new Promise(resolve => {
|
|
|
|
setTimeout(resolve, 500);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-29 13:40:19 +02:00
|
|
|
return editor;
|
2022-08-08 17:00:14 +02:00
|
|
|
};
|
|
|
|
|
2023-09-21 10:12:40 +02:00
|
|
|
export default createTestEditor;
|