@neo4j-cypher/react-codemirror 2.0.0-next.4 → 2.0.0-next.41
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 +370 -0
- package/README.md +3 -2
- package/dist/src/CypherEditor.d.ts +245 -0
- package/dist/src/CypherEditor.js +513 -0
- package/dist/src/CypherEditor.js.map +1 -0
- package/dist/src/CypherEditor.test.js +162 -0
- package/dist/src/CypherEditor.test.js.map +1 -0
- package/dist/src/constants.d.ts +1 -0
- package/dist/src/constants.js +2 -0
- package/dist/src/constants.js.map +1 -0
- package/dist/src/diffView.d.ts +13 -0
- package/dist/src/diffView.js +11 -0
- package/dist/src/diffView.js.map +1 -0
- package/dist/src/e2e_tests/autoCompletion.spec.js +334 -0
- package/dist/src/e2e_tests/autoCompletion.spec.js.map +1 -0
- package/dist/src/e2e_tests/configuration.spec.js +83 -0
- package/dist/src/e2e_tests/configuration.spec.js.map +1 -0
- package/dist/src/e2e_tests/debounce.spec.js +66 -0
- package/dist/src/e2e_tests/debounce.spec.js.map +1 -0
- package/dist/{types/e2e_tests/e2e-utils.d.ts → src/e2e_tests/e2eUtils.d.ts} +2 -0
- package/dist/src/e2e_tests/e2eUtils.js +79 -0
- package/dist/src/e2e_tests/e2eUtils.js.map +1 -0
- package/dist/src/e2e_tests/extraKeybindings.spec.js +43 -0
- package/dist/src/e2e_tests/extraKeybindings.spec.js.map +1 -0
- package/dist/src/e2e_tests/historyNavigation.spec.js +227 -0
- package/dist/src/e2e_tests/historyNavigation.spec.js.map +1 -0
- package/dist/src/e2e_tests/performanceTest.spec.d.ts +6 -0
- package/dist/src/e2e_tests/performanceTest.spec.js +97 -0
- package/dist/src/e2e_tests/performanceTest.spec.js.map +1 -0
- package/dist/src/e2e_tests/sanityChecks.spec.js +64 -0
- package/dist/src/e2e_tests/sanityChecks.spec.js.map +1 -0
- package/dist/src/e2e_tests/signatureHelp.spec.js +226 -0
- package/dist/src/e2e_tests/signatureHelp.spec.js.map +1 -0
- package/dist/src/e2e_tests/snippets.spec.js +14 -0
- package/dist/src/e2e_tests/snippets.spec.js.map +1 -0
- package/dist/src/e2e_tests/syntaxHighlighting.spec.d.ts +1 -0
- package/dist/src/e2e_tests/syntaxHighlighting.spec.js +90 -0
- package/dist/src/e2e_tests/syntaxHighlighting.spec.js.map +1 -0
- package/dist/src/e2e_tests/syntaxValidation.spec.d.ts +1 -0
- package/dist/src/e2e_tests/syntaxValidation.spec.js +129 -0
- package/dist/src/e2e_tests/syntaxValidation.spec.js.map +1 -0
- package/dist/src/editorActions.d.ts +17 -0
- package/dist/src/editorActions.js +259 -0
- package/dist/src/editorActions.js.map +1 -0
- package/dist/{types/history-navigation.d.ts → src/historyNavigation.d.ts} +1 -1
- package/dist/src/historyNavigation.js +163 -0
- package/dist/src/historyNavigation.js.map +1 -0
- package/dist/src/hostCallbacks.d.ts +9 -0
- package/dist/src/hostCallbacks.js +2 -0
- package/dist/src/hostCallbacks.js.map +1 -0
- package/dist/{types → src}/icons.d.ts +1 -1
- package/dist/src/icons.js +62 -0
- package/dist/src/icons.js.map +1 -0
- package/dist/src/index.d.ts +6 -0
- package/dist/src/index.js +5 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/inlinePanel.d.ts +27 -0
- package/dist/src/inlinePanel.js +86 -0
- package/dist/src/inlinePanel.js.map +1 -0
- package/dist/src/lang-cypher/autocomplete.d.ts +6 -0
- package/dist/src/lang-cypher/autocomplete.js +116 -0
- package/dist/src/lang-cypher/autocomplete.js.map +1 -0
- package/dist/{types → src}/lang-cypher/constants.d.ts +15 -2
- package/dist/src/lang-cypher/constants.js +74 -0
- package/dist/src/lang-cypher/constants.js.map +1 -0
- package/dist/src/lang-cypher/contants.test.d.ts +1 -0
- package/dist/src/lang-cypher/contants.test.js +103 -0
- package/dist/src/lang-cypher/contants.test.js.map +1 -0
- package/dist/{types/lang-cypher/create-cypher-theme.d.ts → src/lang-cypher/createCypherTheme.d.ts} +14 -3
- package/dist/src/lang-cypher/createCypherTheme.js +202 -0
- package/dist/src/lang-cypher/createCypherTheme.js.map +1 -0
- package/dist/src/lang-cypher/langCypher.d.ts +15 -0
- package/dist/src/lang-cypher/langCypher.js +23 -0
- package/dist/src/lang-cypher/langCypher.js.map +1 -0
- package/dist/src/lang-cypher/lintWorker.mjs +2039 -0
- package/dist/src/lang-cypher/parser-adapter.d.ts +21 -0
- package/dist/src/lang-cypher/parser-adapter.js +115 -0
- package/dist/src/lang-cypher/parser-adapter.js.map +1 -0
- package/dist/src/lang-cypher/prism-global.d.ts +1 -0
- package/dist/src/lang-cypher/prism-global.js +7 -0
- package/dist/src/lang-cypher/prism-global.js.map +1 -0
- package/dist/src/lang-cypher/signatureHelp.d.ts +4 -0
- package/dist/src/lang-cypher/signatureHelp.js +108 -0
- package/dist/src/lang-cypher/signatureHelp.js.map +1 -0
- package/dist/src/lang-cypher/syntaxValidation.d.ts +4 -0
- package/dist/src/lang-cypher/syntaxValidation.js +65 -0
- package/dist/src/lang-cypher/syntaxValidation.js.map +1 -0
- package/dist/src/lang-cypher/themeIcons.js +22 -0
- package/dist/src/lang-cypher/themeIcons.js.map +1 -0
- package/dist/src/lang-cypher/utils.d.ts +2 -0
- package/dist/src/lang-cypher/utils.js +10 -0
- package/dist/src/lang-cypher/utils.js.map +1 -0
- package/dist/src/ndlTokensCopy.d.ts +570 -0
- package/dist/src/ndlTokensCopy.js +571 -0
- package/dist/src/ndlTokensCopy.js.map +1 -0
- package/dist/src/ndlTokensCopy.test.d.ts +1 -0
- package/dist/src/ndlTokensCopy.test.js +12 -0
- package/dist/src/ndlTokensCopy.test.js.map +1 -0
- package/dist/src/neo4jSetup.d.ts +6 -0
- package/dist/src/neo4jSetup.js +120 -0
- package/dist/src/neo4jSetup.js.map +1 -0
- package/dist/src/richClipboardCopier.d.ts +4 -0
- package/dist/src/richClipboardCopier.js +78 -0
- package/dist/src/richClipboardCopier.js.map +1 -0
- package/dist/src/richClipboardCopier.test.d.ts +1 -0
- package/dist/src/richClipboardCopier.test.js +53 -0
- package/dist/src/richClipboardCopier.test.js.map +1 -0
- package/dist/src/themes.d.ts +5 -0
- package/dist/src/themes.js +107 -0
- package/dist/src/themes.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +64 -62
- package/src/CypherEditor.test.tsx +211 -0
- package/src/CypherEditor.tsx +586 -59
- package/src/constants.ts +1 -0
- package/src/diffView.ts +24 -0
- package/src/e2e_tests/autoCompletion.spec.tsx +576 -0
- package/src/e2e_tests/configuration.spec.tsx +111 -0
- package/src/e2e_tests/debounce.spec.tsx +102 -0
- package/src/e2e_tests/{e2e-utils.ts → e2eUtils.ts} +41 -3
- package/src/e2e_tests/{extra-keybindings.spec.tsx → extraKeybindings.spec.tsx} +1 -3
- package/src/e2e_tests/{history-navigation.spec.tsx → historyNavigation.spec.tsx} +138 -19
- package/src/e2e_tests/performanceTest.spec.tsx +163 -0
- package/src/e2e_tests/{sanity-checks.spec.tsx → sanityChecks.spec.tsx} +28 -20
- package/src/e2e_tests/signatureHelp.spec.tsx +442 -0
- package/src/e2e_tests/snippets.spec.tsx +19 -0
- package/src/e2e_tests/{syntax-highlighting.spec.tsx → syntaxHighlighting.spec.tsx} +26 -24
- package/src/e2e_tests/syntaxValidation.spec.tsx +252 -0
- package/src/editorActions.ts +334 -0
- package/src/{history-navigation.ts → historyNavigation.ts} +6 -4
- package/src/hostCallbacks.ts +9 -0
- package/src/icons.ts +3 -0
- package/src/index.ts +4 -2
- package/src/inlinePanel.ts +140 -0
- package/src/lang-cypher/autocomplete.ts +96 -19
- package/src/lang-cypher/constants.ts +35 -2
- package/src/lang-cypher/contants.test.ts +7 -3
- package/src/lang-cypher/{create-cypher-theme.ts → createCypherTheme.ts} +97 -33
- package/src/lang-cypher/langCypher.ts +44 -0
- package/src/lang-cypher/lintWorker.mjs +2039 -0
- package/src/lang-cypher/parser-adapter.ts +146 -0
- package/src/lang-cypher/prism-global.ts +7 -0
- package/src/lang-cypher/signatureHelp.ts +154 -0
- package/src/lang-cypher/syntaxValidation.ts +81 -0
- package/src/lang-cypher/utils.ts +9 -0
- package/src/{ndl-tokens-copy.test.ts → ndlTokensCopy.test.ts} +2 -1
- package/src/ndlTokensCopy.ts +570 -0
- package/src/{neo4j-setup.tsx → neo4jSetup.tsx} +79 -18
- package/src/richClipboardCopier.test.ts +67 -0
- package/src/richClipboardCopier.ts +99 -0
- package/src/themes.ts +63 -71
- package/src/viteEnv.d.ts +1 -0
- package/dist/cjs/index.cjs +0 -1441
- package/dist/cjs/index.cjs.map +0 -7
- package/dist/esm/index.mjs +0 -1464
- package/dist/esm/index.mjs.map +0 -7
- package/dist/types/CypherEditor.d.ts +0 -113
- package/dist/types/e2e_tests/mock-data.d.ts +0 -3779
- package/dist/types/index.d.ts +0 -4
- package/dist/types/lang-cypher/ParserAdapter.d.ts +0 -14
- package/dist/types/lang-cypher/autocomplete.d.ts +0 -3
- package/dist/types/lang-cypher/lang-cypher.d.ts +0 -7
- package/dist/types/lang-cypher/syntax-validation.d.ts +0 -3
- package/dist/types/ndl-tokens-copy.d.ts +0 -379
- package/dist/types/neo4j-setup.d.ts +0 -2
- package/dist/types/themes.d.ts +0 -11
- package/dist/types/tsconfig.tsbuildinfo +0 -1
- package/src/e2e_tests/auto-completion.spec.tsx +0 -232
- package/src/e2e_tests/mock-data.ts +0 -4310
- package/src/e2e_tests/performance-test.spec.tsx +0 -71
- package/src/e2e_tests/syntax-validation.spec.tsx +0 -156
- package/src/lang-cypher/ParserAdapter.ts +0 -92
- package/src/lang-cypher/lang-cypher.ts +0 -32
- package/src/lang-cypher/syntax-validation.ts +0 -24
- package/src/ndl-tokens-copy.ts +0 -379
- /package/dist/{types/e2e_tests/auto-completion.spec.d.ts → src/CypherEditor.test.d.ts} +0 -0
- /package/dist/{types/e2e_tests/extra-keybindings.spec.d.ts → src/e2e_tests/autoCompletion.spec.d.ts} +0 -0
- /package/dist/{types/e2e_tests/history-navigation.spec.d.ts → src/e2e_tests/configuration.spec.d.ts} +0 -0
- /package/dist/{types/e2e_tests/performance-test.spec.d.ts → src/e2e_tests/debounce.spec.d.ts} +0 -0
- /package/dist/{types/e2e_tests/sanity-checks.spec.d.ts → src/e2e_tests/extraKeybindings.spec.d.ts} +0 -0
- /package/dist/{types/e2e_tests/syntax-highlighting.spec.d.ts → src/e2e_tests/historyNavigation.spec.d.ts} +0 -0
- /package/dist/{types/e2e_tests/syntax-validation.spec.d.ts → src/e2e_tests/sanityChecks.spec.d.ts} +0 -0
- /package/dist/{types/lang-cypher/contants.test.d.ts → src/e2e_tests/signatureHelp.spec.d.ts} +0 -0
- /package/dist/{types/ndl-tokens-copy.test.d.ts → src/e2e_tests/snippets.spec.d.ts} +0 -0
- /package/dist/{types/lang-cypher/theme-icons.d.ts → src/lang-cypher/themeIcons.d.ts} +0 -0
- /package/src/lang-cypher/{theme-icons.ts → themeIcons.ts} +0 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { testData } from '@neo4j-cypher/language-support';
|
|
3
|
+
import { expect, test } from '@playwright/experimental-ct-react';
|
|
4
|
+
import { CypherEditor } from '../CypherEditor';
|
|
5
|
+
import { CypherEditorPage } from './e2eUtils';
|
|
6
|
+
test.use({ viewport: { width: 1000, height: 500 } });
|
|
7
|
+
test('Prop lint set to false disables syntax validation', async ({ page, mount, }) => {
|
|
8
|
+
const query = 'METCH (n) RETURN n';
|
|
9
|
+
await mount(_jsx(CypherEditor, { value: query, lint: false }));
|
|
10
|
+
await expect(page.locator('.cm-lintRange-error').last()).not.toBeVisible({
|
|
11
|
+
timeout: 10000,
|
|
12
|
+
});
|
|
13
|
+
});
|
|
14
|
+
test('Can turn linting back on', async ({ page, mount }) => {
|
|
15
|
+
const editorPage = new CypherEditorPage(page);
|
|
16
|
+
const query = 'METCH (n) RETURN n';
|
|
17
|
+
const component = await mount(_jsx(CypherEditor, { value: query, lint: false }));
|
|
18
|
+
await expect(page.locator('.cm-lintRange-error').last()).not.toBeVisible({
|
|
19
|
+
timeout: 10000,
|
|
20
|
+
});
|
|
21
|
+
await component.update(_jsx(CypherEditor, { value: query, lint: true }));
|
|
22
|
+
await editorPage.getEditor().fill('METCH (n) RETURN n');
|
|
23
|
+
await editorPage.checkErrorMessage('METCH', `Invalid input 'METCH': expected 'ALTER', 'ORDER BY', 'CALL', 'USING PERIODIC COMMIT', 'CREATE', 'LOAD CSV', 'START DATABASE', 'STOP DATABASE', 'DEALLOCATE', 'DELETE', 'DENY', 'DETACH', 'DROP', 'DRYRUN', 'FINISH', 'FOREACH', 'GRANT', 'INSERT', 'LIMIT', 'MATCH', 'MERGE', 'NODETACH', 'OFFSET', 'OPTIONAL', 'REALLOCATE', 'REMOVE', 'RENAME', 'RETURN', 'REVOKE', 'ENABLE SERVER', 'SET', 'SHOW', 'SKIP', 'TERMINATE', 'UNWIND', 'USE' or 'WITH'`);
|
|
24
|
+
});
|
|
25
|
+
test('Syntactic errors are surfaced', async ({ page, mount }) => {
|
|
26
|
+
const editorPage = new CypherEditorPage(page);
|
|
27
|
+
const query = 'METCH (n) RETURN n';
|
|
28
|
+
await mount(_jsx(CypherEditor, { value: query }));
|
|
29
|
+
await editorPage.checkErrorMessage('METCH', `Invalid input 'METCH': expected 'ALTER', 'ORDER BY', 'CALL', 'USING PERIODIC COMMIT', 'CREATE', 'LOAD CSV', 'START DATABASE', 'STOP DATABASE', 'DEALLOCATE', 'DELETE', 'DENY', 'DETACH', 'DROP', 'DRYRUN', 'FINISH', 'FOREACH', 'GRANT', 'INSERT', 'LIMIT', 'MATCH', 'MERGE', 'NODETACH', 'OFFSET', 'OPTIONAL', 'REALLOCATE', 'REMOVE', 'RENAME', 'RETURN', 'REVOKE', 'ENABLE SERVER', 'SET', 'SHOW', 'SKIP', 'TERMINATE', 'UNWIND', 'USE' or 'WITH'`);
|
|
30
|
+
});
|
|
31
|
+
test('Does not trigger syntax errors for backticked parameters in parameter creation', async ({ page, mount, }) => {
|
|
32
|
+
const editorPage = new CypherEditorPage(page);
|
|
33
|
+
const query = ':param x => "abc"';
|
|
34
|
+
await mount(_jsx(CypherEditor, { value: query }));
|
|
35
|
+
await editorPage.checkNoNotificationMessage('error');
|
|
36
|
+
});
|
|
37
|
+
test('Errors for undefined labels are surfaced', async ({ page, mount }) => {
|
|
38
|
+
const editorPage = new CypherEditorPage(page);
|
|
39
|
+
const query = 'MATCH (n: Person) RETURN n';
|
|
40
|
+
await mount(_jsx(CypherEditor, { value: query, schema: { labels: ['Movie'], relationshipTypes: [] } }));
|
|
41
|
+
await editorPage.checkWarningMessage('Person', "Label Person is not present in the database. Make sure you didn't misspell it or that it is available when you run this statement in your application");
|
|
42
|
+
});
|
|
43
|
+
test('Errors for multiline undefined labels are highlighted correctly', async ({ page, mount, }) => {
|
|
44
|
+
const editorPage = new CypherEditorPage(page);
|
|
45
|
+
const query = `MATCH (n:\`Foo
|
|
46
|
+
Bar\`) RETURN n`;
|
|
47
|
+
const expectedMsg = `Label \`Foo
|
|
48
|
+
Bar\` is not present in the database. Make sure you didn't misspell it or that it is available when you run this statement in your application`;
|
|
49
|
+
await mount(_jsx(CypherEditor, { value: query, schema: { labels: ['Movie'], relationshipTypes: [] } }));
|
|
50
|
+
await editorPage.checkWarningMessage('`Foo', expectedMsg);
|
|
51
|
+
await editorPage.checkWarningMessage('Bar`', expectedMsg);
|
|
52
|
+
});
|
|
53
|
+
test('Semantic errors work in firefox', async ({ browserName, page, mount, }) => {
|
|
54
|
+
test.skip(browserName !== 'firefox');
|
|
55
|
+
const editorPage = new CypherEditorPage(page);
|
|
56
|
+
const query = 'MATCH (n:OperationalPoint)--(m:OperationalPoint) RETURN s,m,n';
|
|
57
|
+
await mount(_jsx(CypherEditor, { value: query, schema: testData.mockSchema }));
|
|
58
|
+
await editorPage.checkErrorMessage('s,m,n', 'Variable `s` not defined');
|
|
59
|
+
});
|
|
60
|
+
test('Semantic errors are surfaced when there are no syntactic errors', async ({ page, mount, }) => {
|
|
61
|
+
const editorPage = new CypherEditorPage(page);
|
|
62
|
+
const query = 'MATCH (n) RETURN m';
|
|
63
|
+
await mount(_jsx(CypherEditor, { value: query }));
|
|
64
|
+
await editorPage.checkErrorMessage('m', 'Variable `m` not defined');
|
|
65
|
+
});
|
|
66
|
+
test('Semantic errors are correctly accumulated', async ({ page, mount }) => {
|
|
67
|
+
const editorPage = new CypherEditorPage(page);
|
|
68
|
+
const query = 'CALL { MATCH (n) } IN TRANSACTIONS OF -1 ROWS';
|
|
69
|
+
await mount(_jsx(CypherEditor, { value: query }));
|
|
70
|
+
await editorPage.checkErrorMessage('-1', "Invalid input. '-1' is not a valid value. Must be a positive integer.");
|
|
71
|
+
});
|
|
72
|
+
test('Multiline errors are correctly placed', async ({ page, mount }) => {
|
|
73
|
+
const editorPage = new CypherEditorPage(page);
|
|
74
|
+
const query = `CALL {
|
|
75
|
+
MATCH (n)
|
|
76
|
+
} IN TRANSACTIONS
|
|
77
|
+
OF -1 ROWS`;
|
|
78
|
+
await mount(_jsx(CypherEditor, { value: query }));
|
|
79
|
+
await editorPage.checkErrorMessage('-1', "Invalid input. '-1' is not a valid value. Must be a positive integer.");
|
|
80
|
+
});
|
|
81
|
+
test('Validation errors are correctly overlapped', async ({ page, mount }) => {
|
|
82
|
+
const editorPage = new CypherEditorPage(page);
|
|
83
|
+
const query = `CALL { MATCH (n)
|
|
84
|
+
RETURN n
|
|
85
|
+
} IN TRANSACTIONS
|
|
86
|
+
OF -1 ROWS`;
|
|
87
|
+
await mount(_jsx(CypherEditor, { value: query }));
|
|
88
|
+
await editorPage.checkErrorMessage('-1', "Invalid input. '-1' is not a valid value. Must be a positive integer.");
|
|
89
|
+
});
|
|
90
|
+
test('Syntax highlighting works as expected with multiple separate linting messages', async ({ page, mount, }) => {
|
|
91
|
+
const editorPage = new CypherEditorPage(page);
|
|
92
|
+
const query = `MATCH (n)--(m) CALL (n) {RETURN id(n) AS b} RETURN apoc.create.uuid(), a`;
|
|
93
|
+
await mount(_jsx(CypherEditor, { value: query, schema: testData.mockSchema }));
|
|
94
|
+
await expect(editorPage.page.locator('.cm-deprecated-element').last()).toBeVisible({
|
|
95
|
+
timeout: 10000,
|
|
96
|
+
});
|
|
97
|
+
await editorPage.checkWarningMessage('id', 'Function id is deprecated.');
|
|
98
|
+
await editorPage.checkWarningMessage('id', `The query used a deprecated function. ('id' has been replaced by 'elementId or consider using an application-generated id')`);
|
|
99
|
+
await editorPage.checkWarningMessage('apoc.create.uuid', 'Function apoc.create.uuid is deprecated. Alternative: Neo4j randomUUID() function');
|
|
100
|
+
await editorPage.checkErrorMessage('a', 'Variable `a` not defined');
|
|
101
|
+
});
|
|
102
|
+
test('Strikethroughs are shown for deprecated functions', async ({ page, mount, }) => {
|
|
103
|
+
const editorPage = new CypherEditorPage(page);
|
|
104
|
+
const query = `RETURN id(1)`;
|
|
105
|
+
await mount(_jsx(CypherEditor, { value: query, schema: testData.mockSchema }));
|
|
106
|
+
await expect(editorPage.page.locator('.cm-deprecated-element').last()).toBeVisible({
|
|
107
|
+
timeout: 10000,
|
|
108
|
+
});
|
|
109
|
+
await editorPage.checkWarningMessage('id', 'Function id is deprecated.');
|
|
110
|
+
});
|
|
111
|
+
test('Strikethroughs are shown for deprecated procedures', async ({ page, mount, }) => {
|
|
112
|
+
const editorPage = new CypherEditorPage(page);
|
|
113
|
+
const query = `CALL apoc.create.uuids(5)`;
|
|
114
|
+
await mount(_jsx(CypherEditor, { value: query, schema: testData.mockSchema }));
|
|
115
|
+
await expect(editorPage.page.locator('.cm-deprecated-element').last()).toBeVisible({
|
|
116
|
+
timeout: 10000,
|
|
117
|
+
});
|
|
118
|
+
await editorPage.checkWarningMessage('apoc.create.uuids', "Procedure apoc.create.uuids is deprecated. Alternative: Neo4j's randomUUID() function can be used as a replacement, for example: `UNWIND range(0,$count) AS row RETURN row, randomUUID() AS uuid`");
|
|
119
|
+
});
|
|
120
|
+
test('Syntax validation depends on the Cypher version', async ({ page, mount, }) => {
|
|
121
|
+
await mount(_jsx(CypherEditor, { schema: testData.mockSchema }));
|
|
122
|
+
const editorPage = new CypherEditorPage(page);
|
|
123
|
+
const textField = page.getByRole('textbox');
|
|
124
|
+
await textField.fill('CYPHER 5 CALL apoc.create.uuids(5)');
|
|
125
|
+
await editorPage.checkWarningMessage('apoc.create.uuids', "Procedure apoc.create.uuids is deprecated. Alternative: Neo4j's randomUUID() function can be used as a replacement, for example: `UNWIND range(0,$count) AS row RETURN row, randomUUID() AS uuid`");
|
|
126
|
+
await textField.fill('CYPHER 25 CALL apoc.create.uuids(5)');
|
|
127
|
+
await editorPage.checkErrorMessage('apoc.create.uuids', `Procedure apoc.create.uuids is not present in the database. Make sure you didn't misspell it or that it is available when you run this statement in your application`);
|
|
128
|
+
});
|
|
129
|
+
//# sourceMappingURL=syntaxValidation.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"syntaxValidation.spec.js","sourceRoot":"","sources":["../../../src/e2e_tests/syntaxValidation.spec.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAC1D,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,mCAAmC,CAAC;AACjE,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE9C,IAAI,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;AACrD,IAAI,CAAC,mDAAmD,EAAE,KAAK,EAAE,EAC/D,IAAI,EACJ,KAAK,GACN,EAAE,EAAE;IACH,MAAM,KAAK,GAAG,oBAAoB,CAAC;IAEnC,MAAM,KAAK,CAAC,KAAC,YAAY,IAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,GAAI,CAAC,CAAC;IAEzD,MAAM,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,qBAAqB,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC;QACvE,OAAO,EAAE,KAAK;KACf,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,0BAA0B,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE;IACzD,MAAM,UAAU,GAAG,IAAI,gBAAgB,CAAC,IAAI,CAAC,CAAC;IAC9C,MAAM,KAAK,GAAG,oBAAoB,CAAC;IAEnC,MAAM,SAAS,GAAG,MAAM,KAAK,CAAC,KAAC,YAAY,IAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,GAAI,CAAC,CAAC;IAE3E,MAAM,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,qBAAqB,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC;QACvE,OAAO,EAAE,KAAK;KACf,CAAC,CAAC;IAEH,MAAM,SAAS,CAAC,MAAM,CAAC,KAAC,YAAY,IAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,GAAI,CAAC,CAAC;IAEnE,MAAM,UAAU,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;IAExD,MAAM,UAAU,CAAC,iBAAiB,CAChC,OAAO,EACP,sbAAsb,CACvb,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,+BAA+B,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE;IAC9D,MAAM,UAAU,GAAG,IAAI,gBAAgB,CAAC,IAAI,CAAC,CAAC;IAC9C,MAAM,KAAK,GAAG,oBAAoB,CAAC;IAEnC,MAAM,KAAK,CAAC,KAAC,YAAY,IAAC,KAAK,EAAE,KAAK,GAAI,CAAC,CAAC;IAE5C,MAAM,UAAU,CAAC,iBAAiB,CAChC,OAAO,EACP,sbAAsb,CACvb,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,gFAAgF,EAAE,KAAK,EAAE,EAC5F,IAAI,EACJ,KAAK,GACN,EAAE,EAAE;IACH,MAAM,UAAU,GAAG,IAAI,gBAAgB,CAAC,IAAI,CAAC,CAAC;IAE9C,MAAM,KAAK,GAAG,mBAAmB,CAAC;IAClC,MAAM,KAAK,CAAC,KAAC,YAAY,IAAC,KAAK,EAAE,KAAK,GAAI,CAAC,CAAC;IAE5C,MAAM,UAAU,CAAC,0BAA0B,CAAC,OAAO,CAAC,CAAC;AACvD,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,0CAA0C,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE;IACzE,MAAM,UAAU,GAAG,IAAI,gBAAgB,CAAC,IAAI,CAAC,CAAC;IAC9C,MAAM,KAAK,GAAG,4BAA4B,CAAC;IAE3C,MAAM,KAAK,CACT,KAAC,YAAY,IACX,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,EAAE,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,iBAAiB,EAAE,EAAE,EAAE,GACpD,CACH,CAAC;IAEF,MAAM,UAAU,CAAC,mBAAmB,CAClC,QAAQ,EACR,uJAAuJ,CACxJ,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,iEAAiE,EAAE,KAAK,EAAE,EAC7E,IAAI,EACJ,KAAK,GACN,EAAE,EAAE;IACH,MAAM,UAAU,GAAG,IAAI,gBAAgB,CAAC,IAAI,CAAC,CAAC;IAC9C,MAAM,KAAK,GAAG;oBACI,CAAC;IACnB,MAAM,WAAW,GAAG;mJAC6H,CAAC;IAElJ,MAAM,KAAK,CACT,KAAC,YAAY,IACX,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,EAAE,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,iBAAiB,EAAE,EAAE,EAAE,GACpD,CACH,CAAC;IAEF,MAAM,UAAU,CAAC,mBAAmB,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAC1D,MAAM,UAAU,CAAC,mBAAmB,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;AAC5D,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,iCAAiC,EAAE,KAAK,EAAE,EAC7C,WAAW,EACX,IAAI,EACJ,KAAK,GACN,EAAE,EAAE;IACH,IAAI,CAAC,IAAI,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC;IACrC,MAAM,UAAU,GAAG,IAAI,gBAAgB,CAAC,IAAI,CAAC,CAAC;IAC9C,MAAM,KAAK,GAAG,+DAA+D,CAAC;IAE9E,MAAM,KAAK,CAAC,KAAC,YAAY,IAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,UAAU,GAAI,CAAC,CAAC;IAEzE,MAAM,UAAU,CAAC,iBAAiB,CAAC,OAAO,EAAE,0BAA0B,CAAC,CAAC;AAC1E,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,iEAAiE,EAAE,KAAK,EAAE,EAC7E,IAAI,EACJ,KAAK,GACN,EAAE,EAAE;IACH,MAAM,UAAU,GAAG,IAAI,gBAAgB,CAAC,IAAI,CAAC,CAAC;IAC9C,MAAM,KAAK,GAAG,oBAAoB,CAAC;IAEnC,MAAM,KAAK,CAAC,KAAC,YAAY,IAAC,KAAK,EAAE,KAAK,GAAI,CAAC,CAAC;IAE5C,MAAM,UAAU,CAAC,iBAAiB,CAAC,GAAG,EAAE,0BAA0B,CAAC,CAAC;AACtE,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,2CAA2C,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE;IAC1E,MAAM,UAAU,GAAG,IAAI,gBAAgB,CAAC,IAAI,CAAC,CAAC;IAC9C,MAAM,KAAK,GAAG,+CAA+C,CAAC;IAE9D,MAAM,KAAK,CAAC,KAAC,YAAY,IAAC,KAAK,EAAE,KAAK,GAAI,CAAC,CAAC;IAE5C,MAAM,UAAU,CAAC,iBAAiB,CAChC,IAAI,EACJ,uEAAuE,CACxE,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,uCAAuC,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE;IACtE,MAAM,UAAU,GAAG,IAAI,gBAAgB,CAAC,IAAI,CAAC,CAAC;IAC9C,MAAM,KAAK,GAAG;;;aAGH,CAAC;IAEZ,MAAM,KAAK,CAAC,KAAC,YAAY,IAAC,KAAK,EAAE,KAAK,GAAI,CAAC,CAAC;IAE5C,MAAM,UAAU,CAAC,iBAAiB,CAChC,IAAI,EACJ,uEAAuE,CACxE,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,4CAA4C,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE;IAC3E,MAAM,UAAU,GAAG,IAAI,gBAAgB,CAAC,IAAI,CAAC,CAAC;IAC9C,MAAM,KAAK,GAAG;;;aAGH,CAAC;IAEZ,MAAM,KAAK,CAAC,KAAC,YAAY,IAAC,KAAK,EAAE,KAAK,GAAI,CAAC,CAAC;IAE5C,MAAM,UAAU,CAAC,iBAAiB,CAChC,IAAI,EACJ,uEAAuE,CACxE,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,+EAA+E,EAAE,KAAK,EAAE,EAC3F,IAAI,EACJ,KAAK,GACN,EAAE,EAAE;IACH,MAAM,UAAU,GAAG,IAAI,gBAAgB,CAAC,IAAI,CAAC,CAAC;IAC9C,MAAM,KAAK,GAAG,0EAA0E,CAAC;IAEzF,MAAM,KAAK,CAAC,KAAC,YAAY,IAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,UAAU,GAAI,CAAC,CAAC;IACzE,MAAM,MAAM,CACV,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,wBAAwB,CAAC,CAAC,IAAI,EAAE,CACzD,CAAC,WAAW,CAAC;QACZ,OAAO,EAAE,KAAK;KACf,CAAC,CAAC;IACH,MAAM,UAAU,CAAC,mBAAmB,CAAC,IAAI,EAAE,4BAA4B,CAAC,CAAC;IACzE,MAAM,UAAU,CAAC,mBAAmB,CAClC,IAAI,EACJ,6HAA6H,CAC9H,CAAC;IACF,MAAM,UAAU,CAAC,mBAAmB,CAClC,kBAAkB,EAClB,mFAAmF,CACpF,CAAC;IACF,MAAM,UAAU,CAAC,iBAAiB,CAAC,GAAG,EAAE,0BAA0B,CAAC,CAAC;AACtE,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,mDAAmD,EAAE,KAAK,EAAE,EAC/D,IAAI,EACJ,KAAK,GACN,EAAE,EAAE;IACH,MAAM,UAAU,GAAG,IAAI,gBAAgB,CAAC,IAAI,CAAC,CAAC;IAC9C,MAAM,KAAK,GAAG,cAAc,CAAC;IAE7B,MAAM,KAAK,CAAC,KAAC,YAAY,IAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,UAAU,GAAI,CAAC,CAAC;IACzE,MAAM,MAAM,CACV,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,wBAAwB,CAAC,CAAC,IAAI,EAAE,CACzD,CAAC,WAAW,CAAC;QACZ,OAAO,EAAE,KAAK;KACf,CAAC,CAAC;IACH,MAAM,UAAU,CAAC,mBAAmB,CAAC,IAAI,EAAE,4BAA4B,CAAC,CAAC;AAC3E,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,oDAAoD,EAAE,KAAK,EAAE,EAChE,IAAI,EACJ,KAAK,GACN,EAAE,EAAE;IACH,MAAM,UAAU,GAAG,IAAI,gBAAgB,CAAC,IAAI,CAAC,CAAC;IAC9C,MAAM,KAAK,GAAG,2BAA2B,CAAC;IAE1C,MAAM,KAAK,CAAC,KAAC,YAAY,IAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,UAAU,GAAI,CAAC,CAAC;IACzE,MAAM,MAAM,CACV,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,wBAAwB,CAAC,CAAC,IAAI,EAAE,CACzD,CAAC,WAAW,CAAC;QACZ,OAAO,EAAE,KAAK;KACf,CAAC,CAAC;IAEH,MAAM,UAAU,CAAC,mBAAmB,CAClC,mBAAmB,EACnB,mMAAmM,CACpM,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,iDAAiD,EAAE,KAAK,EAAE,EAC7D,IAAI,EACJ,KAAK,GACN,EAAE,EAAE;IACH,MAAM,KAAK,CAAC,KAAC,YAAY,IAAC,MAAM,EAAE,QAAQ,CAAC,UAAU,GAAI,CAAC,CAAC;IAE3D,MAAM,UAAU,GAAG,IAAI,gBAAgB,CAAC,IAAI,CAAC,CAAC;IAC9C,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IAC5C,MAAM,SAAS,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAC;IAE3D,MAAM,UAAU,CAAC,mBAAmB,CAClC,mBAAmB,EACnB,mMAAmM,CACpM,CAAC;IAEF,MAAM,SAAS,CAAC,IAAI,CAAC,qCAAqC,CAAC,CAAC;IAE5D,MAAM,UAAU,CAAC,iBAAiB,CAChC,mBAAmB,EACnB,sKAAsK,CACvK,CAAC;AACJ,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { StateEffect, type Extension } from '@codemirror/state';
|
|
2
|
+
import type { HostPortalCallbacks } from './hostCallbacks';
|
|
3
|
+
/** Lifecycle callbacks for the editor action buttons. See {@link HostPortalCallbacks}. */
|
|
4
|
+
export type EditorActionsCallbacks = HostPortalCallbacks;
|
|
5
|
+
export type EditorActionsController = {
|
|
6
|
+
/** CodeMirror extension to register on the editor. */
|
|
7
|
+
extension: Extension;
|
|
8
|
+
/**
|
|
9
|
+
* Drive the action buttons from the host's state: pass callbacks to mount
|
|
10
|
+
* them, or `null` to unmount. Returns the effect for the host to dispatch.
|
|
11
|
+
*
|
|
12
|
+
* Visibility is purely a function of whether callbacks exist — there's no
|
|
13
|
+
* separate show/hide toggle.
|
|
14
|
+
*/
|
|
15
|
+
set: (callbacks: EditorActionsCallbacks | null) => StateEffect<boolean>;
|
|
16
|
+
};
|
|
17
|
+
export declare function createEditorActionsController(): EditorActionsController;
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
import { StateEffect, StateField } from '@codemirror/state';
|
|
2
|
+
import { Decoration, EditorView, ViewPlugin, WidgetType, } from '@codemirror/view';
|
|
3
|
+
/**
|
|
4
|
+
* Renders a host-provided cluster of action buttons at the top-right corner
|
|
5
|
+
* of the editor.
|
|
6
|
+
*
|
|
7
|
+
* The cluster is split into two cooperating pieces so it can both reserve
|
|
8
|
+
* space *and* stay pinned — which a single element can't do (reserving needs
|
|
9
|
+
* to be in flow, pinning needs to be out of it):
|
|
10
|
+
*
|
|
11
|
+
* - A **spacer**: an empty, floated inline widget at the very start of the
|
|
12
|
+
* document. Being in flow, it makes the first line's text wrap around it —
|
|
13
|
+
* and because it's a float, the browser handles arbitrary cluster heights.
|
|
14
|
+
* It carries no content; it only reserves the footprint.
|
|
15
|
+
* - An **overlay**: the real, host-rendered buttons in a container pinned
|
|
16
|
+
* `absolute` on the editor element (which does not scroll). It never moves
|
|
17
|
+
* when the document grows, when an inline panel opens above the first line,
|
|
18
|
+
* or when the content scrolls — content simply scrolls behind it.
|
|
19
|
+
*
|
|
20
|
+
* The overlay is measured against the scroller's visible box rather than
|
|
21
|
+
* against the spacer or the content: the spacer moves down the document
|
|
22
|
+
* whenever something renders above the first line (an inline panel, the
|
|
23
|
+
* deleted lines of a diff), and the content reaches past the right edge as
|
|
24
|
+
* soon as it overflows.
|
|
25
|
+
* Vertically the cluster is centred on the first line.
|
|
26
|
+
*/
|
|
27
|
+
const SPACER_BOTTOM_GAP = 2;
|
|
28
|
+
const SPACER_LEFT_GAP = 4;
|
|
29
|
+
/**
|
|
30
|
+
* Floor for the overlay's inset from the visible right edge, so it stays off
|
|
31
|
+
* the content's last pixel even if a theme zeroes `.cm-line`'s right padding
|
|
32
|
+
* (the base theme's 2px, which is what normally provides the inset).
|
|
33
|
+
*/
|
|
34
|
+
const MIN_OVERLAY_RIGHT_INSET = 2;
|
|
35
|
+
export function createEditorActionsController() {
|
|
36
|
+
const setActiveEffect = StateEffect.define();
|
|
37
|
+
let callbacksRef = null;
|
|
38
|
+
const activeField = StateField.define({
|
|
39
|
+
create: () => false,
|
|
40
|
+
update(active, transaction) {
|
|
41
|
+
for (const effect of transaction.effects) {
|
|
42
|
+
if (effect.is(setActiveEffect)) {
|
|
43
|
+
active = effect.value;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return active;
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
class SpacerWidget extends WidgetType {
|
|
50
|
+
toDOM() {
|
|
51
|
+
const spacer = document.createElement('div');
|
|
52
|
+
spacer.className = 'cm-editor-actions-spacer';
|
|
53
|
+
spacer.setAttribute('aria-hidden', 'true');
|
|
54
|
+
return spacer;
|
|
55
|
+
}
|
|
56
|
+
eq() {
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* The spacer floats right, so CodeMirror's default — the widget's own box —
|
|
61
|
+
* puts the caret at the right edge of the cluster whenever the spacer is
|
|
62
|
+
* the only thing it can measure on the first line (an empty document).
|
|
63
|
+
* Report the start of the line's inline content instead: the node after
|
|
64
|
+
* the spacer (text, a placeholder, or CodeMirror's trailing `<br>`).
|
|
65
|
+
*/
|
|
66
|
+
coordsAt(dom) {
|
|
67
|
+
const next = dom.nextSibling;
|
|
68
|
+
if (!next) {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
let rects;
|
|
72
|
+
if (next instanceof Element) {
|
|
73
|
+
rects = next.getClientRects();
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
const range = document.createRange();
|
|
77
|
+
range.selectNodeContents(next);
|
|
78
|
+
rects = range.getClientRects();
|
|
79
|
+
}
|
|
80
|
+
const rect = rects[0];
|
|
81
|
+
if (!rect) {
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
return {
|
|
85
|
+
left: rect.left,
|
|
86
|
+
right: rect.left,
|
|
87
|
+
top: rect.top,
|
|
88
|
+
bottom: rect.bottom,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
ignoreEvent() {
|
|
92
|
+
return true;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
const spacer = EditorView.decorations.compute(['doc', activeField], (state) => {
|
|
96
|
+
if (!state.field(activeField)) {
|
|
97
|
+
return Decoration.none;
|
|
98
|
+
}
|
|
99
|
+
return Decoration.set([
|
|
100
|
+
Decoration.widget({
|
|
101
|
+
widget: new SpacerWidget(),
|
|
102
|
+
side: -1,
|
|
103
|
+
}).range(0),
|
|
104
|
+
]);
|
|
105
|
+
});
|
|
106
|
+
const overlay = ViewPlugin.fromClass(class {
|
|
107
|
+
dom = null;
|
|
108
|
+
resizeObserver = null;
|
|
109
|
+
mounted = null;
|
|
110
|
+
constructor(view) {
|
|
111
|
+
if (view.state.field(activeField)) {
|
|
112
|
+
this.mount(view);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
update(update) {
|
|
116
|
+
const isActive = update.state.field(activeField);
|
|
117
|
+
if (isActive && !this.dom) {
|
|
118
|
+
this.mount(update.view);
|
|
119
|
+
}
|
|
120
|
+
else if (!isActive && this.dom) {
|
|
121
|
+
this.unmount();
|
|
122
|
+
}
|
|
123
|
+
else if (this.dom &&
|
|
124
|
+
(update.geometryChanged ||
|
|
125
|
+
update.docChanged ||
|
|
126
|
+
update.viewportChanged)) {
|
|
127
|
+
this.align(update.view);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
destroy() {
|
|
131
|
+
this.unmount();
|
|
132
|
+
}
|
|
133
|
+
mount(view) {
|
|
134
|
+
const container = document.createElement('div');
|
|
135
|
+
container.className = 'cm-editor-actions';
|
|
136
|
+
view.dom.appendChild(container);
|
|
137
|
+
this.resizeObserver = new ResizeObserver(() => {
|
|
138
|
+
view.dom.style.setProperty('--cm-editor-actions-width', `${container.offsetWidth}px`);
|
|
139
|
+
view.dom.style.setProperty('--cm-editor-actions-reserved-width', `${container.offsetWidth + SPACER_LEFT_GAP}px`);
|
|
140
|
+
// The spacer's height follows the overlay's position, so `align`
|
|
141
|
+
// owns it.
|
|
142
|
+
this.align(view);
|
|
143
|
+
});
|
|
144
|
+
this.resizeObserver.observe(container);
|
|
145
|
+
this.dom = container;
|
|
146
|
+
this.mounted = callbacksRef;
|
|
147
|
+
callbacksRef?.onMount(container);
|
|
148
|
+
this.align(view);
|
|
149
|
+
}
|
|
150
|
+
align(view) {
|
|
151
|
+
view.requestMeasure({
|
|
152
|
+
read: () => {
|
|
153
|
+
if (!this.dom) {
|
|
154
|
+
return null;
|
|
155
|
+
}
|
|
156
|
+
const editorRect = view.dom.getBoundingClientRect();
|
|
157
|
+
const scrollerRect = view.scrollDOM.getBoundingClientRect();
|
|
158
|
+
const style = window.getComputedStyle(view.contentDOM);
|
|
159
|
+
const visibleRight = scrollerRect.left + view.scrollDOM.clientWidth;
|
|
160
|
+
// Match the inset `.cm-line`'s right padding gives the spacer, so
|
|
161
|
+
// the overlay lands on the space the spacer reserves and stays off
|
|
162
|
+
// `contentRect.right - 1`, the pixel CodeMirror hit-tests to
|
|
163
|
+
// measure a wrapped line's selection. Cover it and the first
|
|
164
|
+
// line's highlight collapses to zero width — hence the floor.
|
|
165
|
+
const line = view.contentDOM.querySelector('.cm-line');
|
|
166
|
+
const lineRightPadding = line
|
|
167
|
+
? parseFloat(window.getComputedStyle(line).paddingRight) || 0
|
|
168
|
+
: 0;
|
|
169
|
+
const contentPaddingTop = parseFloat(style.paddingTop) || 0;
|
|
170
|
+
const height = this.dom.offsetHeight;
|
|
171
|
+
// How far the cluster has to rise above the first line's top to
|
|
172
|
+
// sit centred on it, limited to the padding it can rise into.
|
|
173
|
+
const lift = Math.min(Math.max((height - view.defaultLineHeight) / 2, 0), contentPaddingTop);
|
|
174
|
+
return {
|
|
175
|
+
top: scrollerRect.top - editorRect.top + contentPaddingTop - lift,
|
|
176
|
+
right: editorRect.right -
|
|
177
|
+
visibleRight +
|
|
178
|
+
(parseFloat(style.paddingRight) || 0) +
|
|
179
|
+
Math.max(lineRightPadding, MIN_OVERLAY_RIGHT_INSET),
|
|
180
|
+
// The spacer starts at the first line's top, so it only needs to
|
|
181
|
+
// clear the part of the cluster that hangs below it.
|
|
182
|
+
spacerHeight: height - lift,
|
|
183
|
+
// A floor under the content, so an empty document is still tall
|
|
184
|
+
// enough to hold the overlay.
|
|
185
|
+
contentMinHeight: contentPaddingTop - lift + height,
|
|
186
|
+
};
|
|
187
|
+
},
|
|
188
|
+
write: (pos) => {
|
|
189
|
+
if (!pos || !this.dom) {
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
view.dom.style.setProperty('--cm-editor-actions-top', `${pos.top}px`);
|
|
193
|
+
view.dom.style.setProperty('--cm-editor-actions-right', `${pos.right}px`);
|
|
194
|
+
view.dom.style.setProperty('--cm-editor-actions-height', `${pos.spacerHeight}px`);
|
|
195
|
+
view.dom.style.setProperty('--cm-editor-actions-content-min-height', `${pos.contentMinHeight}px`);
|
|
196
|
+
},
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
unmount() {
|
|
200
|
+
if (!this.dom) {
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
this.resizeObserver?.disconnect();
|
|
204
|
+
this.resizeObserver = null;
|
|
205
|
+
this.mounted?.onUnmount();
|
|
206
|
+
this.mounted = null;
|
|
207
|
+
const root = this.dom?.parentElement;
|
|
208
|
+
if (root) {
|
|
209
|
+
root.style.removeProperty('--cm-editor-actions-width');
|
|
210
|
+
root.style.removeProperty('--cm-editor-actions-height');
|
|
211
|
+
root.style.removeProperty('--cm-editor-actions-content-min-height');
|
|
212
|
+
root.style.removeProperty('--cm-editor-actions-reserved-width');
|
|
213
|
+
root.style.removeProperty('--cm-editor-actions-top');
|
|
214
|
+
root.style.removeProperty('--cm-editor-actions-right');
|
|
215
|
+
}
|
|
216
|
+
this.dom?.remove();
|
|
217
|
+
this.dom = null;
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
const theme = EditorView.theme({
|
|
221
|
+
'.cm-content': {
|
|
222
|
+
minHeight: 'var(--cm-editor-actions-content-min-height, 0px)',
|
|
223
|
+
},
|
|
224
|
+
'.cm-editor-actions-spacer': {
|
|
225
|
+
float: 'right',
|
|
226
|
+
boxSizing: 'content-box',
|
|
227
|
+
width: 'var(--cm-editor-actions-width, 0px)',
|
|
228
|
+
height: 'var(--cm-editor-actions-height, 0px)',
|
|
229
|
+
paddingLeft: `${SPACER_LEFT_GAP}px`,
|
|
230
|
+
paddingBottom: `${SPACER_BOTTOM_GAP}px`,
|
|
231
|
+
userSelect: 'none',
|
|
232
|
+
WebkitUserSelect: 'none',
|
|
233
|
+
pointerEvents: 'none',
|
|
234
|
+
},
|
|
235
|
+
// The spacer only clears the first line, so a panel above it makes its own room.
|
|
236
|
+
'.cm-inline-panel': {
|
|
237
|
+
paddingRight: 'var(--cm-editor-actions-reserved-width, 0px)',
|
|
238
|
+
},
|
|
239
|
+
'.cm-placeholder': {
|
|
240
|
+
display: 'inline',
|
|
241
|
+
},
|
|
242
|
+
'.cm-editor-actions': {
|
|
243
|
+
position: 'absolute',
|
|
244
|
+
top: 'var(--cm-editor-actions-top, 0px)',
|
|
245
|
+
right: 'var(--cm-editor-actions-right, 0px)',
|
|
246
|
+
zIndex: '2',
|
|
247
|
+
userSelect: 'none',
|
|
248
|
+
WebkitUserSelect: 'none',
|
|
249
|
+
},
|
|
250
|
+
});
|
|
251
|
+
return {
|
|
252
|
+
extension: [activeField, spacer, overlay, theme],
|
|
253
|
+
set: (callbacks) => {
|
|
254
|
+
callbacksRef = callbacks;
|
|
255
|
+
return setActiveEffect.of(callbacks !== null);
|
|
256
|
+
},
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
//# sourceMappingURL=editorActions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"editorActions.js","sourceRoot":"","sources":["../../src/editorActions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { StateEffect } from '@codemirror/state';
|
|
2
|
+
import { keymap } from '@codemirror/view';
|
|
3
|
+
import { StateField } from '@codemirror/state';
|
|
4
|
+
const DRAFT_ENTRY_INDEX = -1;
|
|
5
|
+
const historyInitialState = {
|
|
6
|
+
history: [],
|
|
7
|
+
index: DRAFT_ENTRY_INDEX,
|
|
8
|
+
documentUpdate: null,
|
|
9
|
+
draft: '',
|
|
10
|
+
};
|
|
11
|
+
const historyState = StateField.define({
|
|
12
|
+
create() {
|
|
13
|
+
return historyInitialState;
|
|
14
|
+
},
|
|
15
|
+
toJSON(value) {
|
|
16
|
+
return JSON.stringify(value);
|
|
17
|
+
},
|
|
18
|
+
update(value, transaction) {
|
|
19
|
+
for (const effect of transaction.effects) {
|
|
20
|
+
if (effect.is(moveInHistory)) {
|
|
21
|
+
if (value.history.length === 0) {
|
|
22
|
+
return {
|
|
23
|
+
...value,
|
|
24
|
+
documentUpdate: null,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
const currentHistoryIndex = value.index;
|
|
28
|
+
if (effect.value === 'BACK') {
|
|
29
|
+
const newHistoryIndex = currentHistoryIndex + 1;
|
|
30
|
+
if (newHistoryIndex === value.history.length) {
|
|
31
|
+
return {
|
|
32
|
+
...value,
|
|
33
|
+
documentUpdate: null,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
let draft = value.draft;
|
|
37
|
+
if (currentHistoryIndex === DRAFT_ENTRY_INDEX) {
|
|
38
|
+
draft = transaction.state.doc.toString();
|
|
39
|
+
}
|
|
40
|
+
return {
|
|
41
|
+
...value,
|
|
42
|
+
draft,
|
|
43
|
+
index: newHistoryIndex,
|
|
44
|
+
documentUpdate: value.history[newHistoryIndex],
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
else if (effect.value === 'FORWARDS') {
|
|
48
|
+
const newHistoryIndex = currentHistoryIndex - 1;
|
|
49
|
+
if (currentHistoryIndex === DRAFT_ENTRY_INDEX) {
|
|
50
|
+
return { ...value, documentUpdate: null };
|
|
51
|
+
}
|
|
52
|
+
if (newHistoryIndex === DRAFT_ENTRY_INDEX) {
|
|
53
|
+
return {
|
|
54
|
+
...value,
|
|
55
|
+
index: newHistoryIndex,
|
|
56
|
+
documentUpdate: value.draft,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
return {
|
|
61
|
+
...value,
|
|
62
|
+
index: newHistoryIndex,
|
|
63
|
+
documentUpdate: value.history[newHistoryIndex],
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
else if (effect.is(replaceHistory)) {
|
|
69
|
+
return {
|
|
70
|
+
...value,
|
|
71
|
+
index: DRAFT_ENTRY_INDEX,
|
|
72
|
+
history: effect.value,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return value;
|
|
77
|
+
},
|
|
78
|
+
});
|
|
79
|
+
const moveInHistory = StateEffect.define();
|
|
80
|
+
export const replaceHistory = StateEffect.define();
|
|
81
|
+
function navigateHistory(view, direction) {
|
|
82
|
+
view.dispatch(view.state.update({
|
|
83
|
+
effects: moveInHistory.of(direction),
|
|
84
|
+
selection: { anchor: direction === 'BACK' ? 0 : view.state.doc.length },
|
|
85
|
+
}));
|
|
86
|
+
const updatedHistory = view.state.field(historyState, false);
|
|
87
|
+
if (updatedHistory.documentUpdate !== null) {
|
|
88
|
+
view.dispatch(view.state.update({
|
|
89
|
+
changes: {
|
|
90
|
+
from: 0,
|
|
91
|
+
to: view.state.doc.length,
|
|
92
|
+
insert: updatedHistory.documentUpdate,
|
|
93
|
+
},
|
|
94
|
+
}));
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
export const replMode = ({ history }) => {
|
|
98
|
+
return [
|
|
99
|
+
historyState.init(() => ({
|
|
100
|
+
...historyInitialState,
|
|
101
|
+
history,
|
|
102
|
+
})),
|
|
103
|
+
keymap.of([
|
|
104
|
+
{
|
|
105
|
+
key: 'ArrowUp',
|
|
106
|
+
preventDefault: true,
|
|
107
|
+
run: (view) => {
|
|
108
|
+
// If text is selected or cursor is not at top of document, do nothing
|
|
109
|
+
const { empty, head } = view.state.selection.main;
|
|
110
|
+
if (!empty || head !== 0) {
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
113
|
+
navigateHistory(view, 'BACK');
|
|
114
|
+
return true;
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
mac: 'Cmd-ArrowUp',
|
|
119
|
+
win: 'Ctrl-ArrowUp',
|
|
120
|
+
linux: 'Ctrl-ArrowUp',
|
|
121
|
+
preventDefault: true,
|
|
122
|
+
run: (view) => {
|
|
123
|
+
// If text is selected or cursor is not at top of document, do nothing
|
|
124
|
+
const { empty, head } = view.state.selection.main;
|
|
125
|
+
if (!empty || head !== 0) {
|
|
126
|
+
return false;
|
|
127
|
+
}
|
|
128
|
+
navigateHistory(view, 'BACK');
|
|
129
|
+
return true;
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
key: 'ArrowDown',
|
|
134
|
+
preventDefault: true,
|
|
135
|
+
run: (view) => {
|
|
136
|
+
const { empty, head } = view.state.selection.main;
|
|
137
|
+
// If text is selected or cursor is not at end of document, do nothing
|
|
138
|
+
if (!empty || head !== view.state.doc.length) {
|
|
139
|
+
return false;
|
|
140
|
+
}
|
|
141
|
+
navigateHistory(view, 'FORWARDS');
|
|
142
|
+
return true;
|
|
143
|
+
},
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
mac: 'Cmd-ArrowDown',
|
|
147
|
+
win: 'Ctrl-ArrowDown',
|
|
148
|
+
linux: 'Ctrl-ArrowDown',
|
|
149
|
+
preventDefault: true,
|
|
150
|
+
run: (view) => {
|
|
151
|
+
const { empty, head } = view.state.selection.main;
|
|
152
|
+
// If text is selected or cursor is not at end of document, do nothing
|
|
153
|
+
if (!empty || head !== view.state.doc.length) {
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
navigateHistory(view, 'FORWARDS');
|
|
157
|
+
return true;
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
]),
|
|
161
|
+
];
|
|
162
|
+
};
|
|
163
|
+
//# sourceMappingURL=historyNavigation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"historyNavigation.js","sourceRoot":"","sources":["../../src/historyNavigation.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAQ/C,MAAM,iBAAiB,GAAG,CAAC,CAAC,CAAC;AAC7B,MAAM,mBAAmB,GAAiB;IACxC,OAAO,EAAE,EAAE;IACX,KAAK,EAAE,iBAAiB;IACxB,cAAc,EAAE,IAAI;IACpB,KAAK,EAAE,EAAE;CACV,CAAC;AAEF,MAAM,YAAY,GAAG,UAAU,CAAC,MAAM,CAAe;IACnD,MAAM;QACJ,OAAO,mBAAmB,CAAC;IAC7B,CAAC;IACD,MAAM,CAAC,KAAK;QACV,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC/B,CAAC;IACD,MAAM,CAAC,KAAK,EAAE,WAAW;QACvB,KAAK,MAAM,MAAM,IAAI,WAAW,CAAC,OAAO,EAAE,CAAC;YACzC,IAAI,MAAM,CAAC,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC;gBAC7B,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBAC/B,OAAO;wBACL,GAAG,KAAK;wBACR,cAAc,EAAE,IAAI;qBACrB,CAAC;gBACJ,CAAC;gBAED,MAAM,mBAAmB,GAAG,KAAK,CAAC,KAAK,CAAC;gBACxC,IAAI,MAAM,CAAC,KAAK,KAAK,MAAM,EAAE,CAAC;oBAC5B,MAAM,eAAe,GAAG,mBAAmB,GAAG,CAAC,CAAC;oBAEhD,IAAI,eAAe,KAAK,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;wBAC7C,OAAO;4BACL,GAAG,KAAK;4BACR,cAAc,EAAE,IAAI;yBACrB,CAAC;oBACJ,CAAC;oBAED,IAAI,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;oBACxB,IAAI,mBAAmB,KAAK,iBAAiB,EAAE,CAAC;wBAC9C,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;oBAC3C,CAAC;oBAED,OAAO;wBACL,GAAG,KAAK;wBACR,KAAK;wBACL,KAAK,EAAE,eAAe;wBACtB,cAAc,EAAE,KAAK,CAAC,OAAO,CAAC,eAAe,CAAC;qBAC/C,CAAC;gBACJ,CAAC;qBAAM,IAAI,MAAM,CAAC,KAAK,KAAK,UAAU,EAAE,CAAC;oBACvC,MAAM,eAAe,GAAG,mBAAmB,GAAG,CAAC,CAAC;oBAEhD,IAAI,mBAAmB,KAAK,iBAAiB,EAAE,CAAC;wBAC9C,OAAO,EAAE,GAAG,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC;oBAC5C,CAAC;oBAED,IAAI,eAAe,KAAK,iBAAiB,EAAE,CAAC;wBAC1C,OAAO;4BACL,GAAG,KAAK;4BACR,KAAK,EAAE,eAAe;4BACtB,cAAc,EAAE,KAAK,CAAC,KAAK;yBAC5B,CAAC;oBACJ,CAAC;yBAAM,CAAC;wBACN,OAAO;4BACL,GAAG,KAAK;4BACR,KAAK,EAAE,eAAe;4BACtB,cAAc,EAAE,KAAK,CAAC,OAAO,CAAC,eAAe,CAAC;yBAC/C,CAAC;oBACJ,CAAC;gBACH,CAAC;YACH,CAAC;iBAAM,IAAI,MAAM,CAAC,EAAE,CAAC,cAAc,CAAC,EAAE,CAAC;gBACrC,OAAO;oBACL,GAAG,KAAK;oBACR,KAAK,EAAE,iBAAiB;oBACxB,OAAO,EAAE,MAAM,CAAC,KAAK;iBACtB,CAAC;YACJ,CAAC;QACH,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;CACF,CAAC,CAAC;AAGH,MAAM,aAAa,GAAG,WAAW,CAAC,MAAM,EAAqB,CAAC;AAC9D,MAAM,CAAC,MAAM,cAAc,GAAG,WAAW,CAAC,MAAM,EAAY,CAAC;AAE7D,SAAS,eAAe,CAAC,IAAgB,EAAE,SAA4B;IACrE,IAAI,CAAC,QAAQ,CACX,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;QAChB,OAAO,EAAE,aAAa,CAAC,EAAE,CAAC,SAAS,CAAC;QACpC,SAAS,EAAE,EAAE,MAAM,EAAE,SAAS,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE;KACxE,CAAC,CACH,CAAC;IAEF,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAe,YAAY,EAAE,KAAK,CAAC,CAAC;IAC3E,IAAI,cAAc,CAAC,cAAc,KAAK,IAAI,EAAE,CAAC;QAC3C,IAAI,CAAC,QAAQ,CACX,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;YAChB,OAAO,EAAE;gBACP,IAAI,EAAE,CAAC;gBACP,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM;gBACzB,MAAM,EAAE,cAAc,CAAC,cAAc;aACtC;SACF,CAAC,CACH,CAAC;IACJ,CAAC;AACH,CAAC;AAMD,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,EAAE,OAAO,EAAa,EAAe,EAAE;IAC9D,OAAO;QACL,YAAY,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;YACvB,GAAG,mBAAmB;YACtB,OAAO;SACR,CAAC,CAAC;QACH,MAAM,CAAC,EAAE,CAAC;YACR;gBACE,GAAG,EAAE,SAAS;gBACd,cAAc,EAAE,IAAI;gBACpB,GAAG,EAAE,CAAC,IAAI,EAAE,EAAE;oBACZ,sEAAsE;oBACtE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC;oBAClD,IAAI,CAAC,KAAK,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;wBACzB,OAAO,KAAK,CAAC;oBACf,CAAC;oBAED,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;oBAC9B,OAAO,IAAI,CAAC;gBACd,CAAC;aACF;YACD;gBACE,GAAG,EAAE,aAAa;gBAClB,GAAG,EAAE,cAAc;gBACnB,KAAK,EAAE,cAAc;gBACrB,cAAc,EAAE,IAAI;gBACpB,GAAG,EAAE,CAAC,IAAI,EAAE,EAAE;oBACZ,sEAAsE;oBACtE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC;oBAClD,IAAI,CAAC,KAAK,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;wBACzB,OAAO,KAAK,CAAC;oBACf,CAAC;oBAED,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;oBAC9B,OAAO,IAAI,CAAC;gBACd,CAAC;aACF;YACD;gBACE,GAAG,EAAE,WAAW;gBAChB,cAAc,EAAE,IAAI;gBACpB,GAAG,EAAE,CAAC,IAAI,EAAE,EAAE;oBACZ,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC;oBAClD,sEAAsE;oBACtE,IAAI,CAAC,KAAK,IAAI,IAAI,KAAK,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;wBAC7C,OAAO,KAAK,CAAC;oBACf,CAAC;oBACD,eAAe,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;oBAElC,OAAO,IAAI,CAAC;gBACd,CAAC;aACF;YACD;gBACE,GAAG,EAAE,eAAe;gBACpB,GAAG,EAAE,gBAAgB;gBACrB,KAAK,EAAE,gBAAgB;gBACvB,cAAc,EAAE,IAAI;gBACpB,GAAG,EAAE,CAAC,IAAI,EAAE,EAAE;oBACZ,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC;oBAClD,sEAAsE;oBACtE,IAAI,CAAC,KAAK,IAAI,IAAI,KAAK,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;wBAC7C,OAAO,KAAK,CAAC;oBACf,CAAC;oBACD,eAAe,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;oBAElC,OAAO,IAAI,CAAC;gBACd,CAAC;aACF;SACF,CAAC;KACH,CAAC;AACJ,CAAC,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lifecycle callbacks for host-rendered overlay content (inline panels, editor
|
|
3
|
+
* action buttons, …). The host renders into the provided DOM container (e.g.
|
|
4
|
+
* via React `createPortal`) and is expected to clean up on unmount.
|
|
5
|
+
*/
|
|
6
|
+
export type HostPortalCallbacks = {
|
|
7
|
+
onMount: (container: HTMLElement) => void;
|
|
8
|
+
onUnmount: () => void;
|
|
9
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hostCallbacks.js","sourceRoot":"","sources":["../../src/hostCallbacks.ts"],"names":[],"mappings":""}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export type CompletionItemIcons = 'Text' | 'Method' | 'Function' | 'Constructor' | 'Field' | 'Variable' | 'Class' | 'Interface' | 'Module' | 'Property' | 'Unit' | 'Value' | 'Enum' | 'Keyword' | 'Snippet' | 'Color' | 'File' | 'Reference' | 'Folder' | 'EnumMember' | 'Constant' | 'Struct' | 'Event' | 'Operator' | 'TypeParameter';
|
|
1
|
+
export type CompletionItemIcons = 'Text' | 'Method' | 'Function' | 'Constructor' | 'Field' | 'Variable' | 'Class' | 'Interface' | 'Module' | 'Property' | 'Unit' | 'Value' | 'Enum' | 'Keyword' | 'Snippet' | 'Color' | 'File' | 'Reference' | 'Folder' | 'EnumMember' | 'Constant' | 'Struct' | 'Event' | 'Operator' | 'Console' | 'TypeParameter';
|
|
2
2
|
export declare function getIconForType(iconTypeString?: string, isDarkTheme?: boolean): string;
|