Skip to content

Commit eb55fd7

Browse files
authored
feat: extract apidom language into separate plugin (#3977)
The name of the new plugin is editor-monaco-language-apidom. BREAKING CHANGE: createData is now passed to individual language plugins and not to editor-monaco one
1 parent f5b6721 commit eb55fd7

22 files changed

+152
-136
lines changed
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
# Plug points
22

3-
- [editor-monaco](./editor-monaco.md)
3+
- [editor-monaco-language-apidom](./editor-monaco-language-apidom.md)

docs/customization/plug-points/editor-monaco.md renamed to docs/customization/plug-points/editor-monaco-language-apidom.md

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@
22

33
## Extending web worker capabilities
44

5-
`editor-monaco` plugin is using monaco editor, which is using web workers to provide
6-
editor capabilities. `editor-monaco` comes with a web worker called `apidom.worker`.
7-
This worker contains all the language service utilizing ApiDOM capabilities.
5+
`editor-monaco-language-apidom` comes with implementation of `apidom` language.
6+
The plugin comes with `apidom.worker` utilizing ApiDOM capabilities.
87
`apidom.worker` can be extended in two ways: dynamic and static.
98

109
### Dynamic extension
@@ -14,7 +13,7 @@ Dynamic extension happens during runtime, and we recommend to use it only for si
1413
First thing we need to do is to pass a `customApiDOMWorkerPath` option to the `EditorMonaco` plugin.
1514

1615
```js
17-
EditorMonaco({
16+
EditorMonacoLanguageApiDOM({
1817
createData: {
1918
customApiDOMWorkerPath: 'https://example.com/index.js',
2019
},
@@ -107,7 +106,7 @@ it will be fetching data on demand from authorized REST endpoint.
107106
`EditorMonaco` plugin configuration.
108107

109108
```js
110-
EditorMonaco({
109+
EditorMonacoLanguageApiDOM({
111110
createData: {
112111
authToken: 'c32d8b45-92fe-44f6-8b61-42c2107dfe87',
113112
customApiDOMWorkerPath: 'https://example.com/index.js',

src/App.jsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import DropzonePlugin from './plugins/dropzone/index.js';
1414
import VersionsPlugin from './plugins/versions/index.js';
1515
import EditorTextareaPlugin from './plugins/editor-textarea/index.js';
1616
import EditorMonacoPlugin from './plugins/editor-monaco/index.js';
17+
import EditorMonacoLanguageApiDOMPlugin from './plugins/editor-monaco-language-apidom/index.js';
1718
import EditorPreviewPlugin from './plugins/editor-preview/index.js';
1819
import EditorPreviewSwaggerUIPlugin from './plugins/editor-preview-swagger-ui/index.js';
1920
import EditorPreviewAsyncAPIPlugin from './plugins/editor-preview-asyncapi/index.js';
@@ -63,6 +64,7 @@ SwaggerEditor.plugins = {
6364
Versions: VersionsPlugin,
6465
EditorTextarea: EditorTextareaPlugin,
6566
EditorMonaco: EditorMonacoPlugin,
67+
EditorMonacoLanguageApiDOM: EditorMonacoLanguageApiDOMPlugin,
6668
EditorContentReadOnly: EditorContentReadOnlyPlugin,
6769
EditorContentOrigin: EditorContentOriginPlugin,
6870
EditorContentType: EditorContentTypePlugin,
@@ -109,6 +111,7 @@ SwaggerEditor.presets = {
109111
VersionsPlugin,
110112
EditorTextareaPlugin,
111113
EditorMonacoPlugin,
114+
EditorMonacoLanguageApiDOMPlugin,
112115
EditorContentReadOnlyPlugin,
113116
EditorContentOriginPlugin,
114117
EditorContentTypePlugin,
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import { ModesRegistry } from 'monaco-editor/esm/vs/editor/common/languages/modesRegistry.js';
2+
import * as monaco from 'monaco-editor';
3+
4+
import { languageExtensionPoint, monarchLanguage, languageId } from './language/config.js';
5+
import { setupApiDOM } from './language/apidom-mode.js';
6+
7+
const makeAfterLoad =
8+
({ createData = {} } = {}) =>
9+
() => {
10+
/**
11+
* Parts of this code use ModesRegistry API instead of monaco.languages API.
12+
* The reason is that monaco.languages API is using ModesRegistory under the hood
13+
* but doesn't return disposables produced by ModesRegistry. By using ModesRegistry
14+
* directly we're able to obtain disposables.
15+
*/
16+
17+
// guard for multiple language registration
18+
const languages = ModesRegistry.getLanguages().map(({ id }) => id);
19+
if (languages.includes(languageId)) {
20+
return;
21+
}
22+
23+
// setup monaco environment
24+
globalThis.MonacoEnvironment = {
25+
// expect monaco plugin to have already executed
26+
...globalThis.MonacoEnvironment,
27+
getWorkerUrl(moduleId, label) {
28+
if (label === languageId) {
29+
return new URL('./apidom.worker.js', this.baseUrl).toString();
30+
}
31+
return new URL('./editor.worker.js', this.baseUrl).toString();
32+
},
33+
};
34+
35+
// setting up ApiDOM language
36+
const disposables = [];
37+
disposables.push(ModesRegistry.registerLanguage(languageExtensionPoint));
38+
disposables.push(
39+
monaco.languages.onLanguage(languageId, () => {
40+
disposables.push(monaco.languages.setMonarchTokensProvider(languageId, monarchLanguage)); // enable syntax highlighting
41+
disposables.push(setupApiDOM({ languageId, options: createData }));
42+
43+
// disposing of all allocated disposables
44+
disposables.push(
45+
monaco.editor.onWillDisposeModel((model) => {
46+
if (model.getLanguageId() === languageId) {
47+
disposables.forEach((disposable) => disposable.dispose());
48+
}
49+
})
50+
);
51+
})
52+
);
53+
};
54+
55+
export default makeAfterLoad;
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import makeAfterLoad from './after-load.js';
2+
3+
const EditorMonacoLanguageApiDOMPlugin = (opts = {}) => {
4+
const isCalledWithGetSystem = typeof opts.getSystem === 'function';
5+
const options = isCalledWithGetSystem ? {} : opts;
6+
const plugin = () => ({
7+
afterLoad: makeAfterLoad(options),
8+
});
9+
10+
return isCalledWithGetSystem ? plugin(opts) : plugin;
11+
};
12+
13+
export default EditorMonacoLanguageApiDOMPlugin;

src/plugins/editor-monaco/workers/apidom/ApiDOMWorker.js renamed to src/plugins/editor-monaco-language-apidom/language/ApiDOMWorker.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* eslint-disable no-underscore-dangle */
2-
import * as vscodeLanguageServerTextDocument from 'vscode-languageserver-textdocument'; // this is true source
2+
import * as vscodeLanguageServerTextDocument from 'vscode-languageserver-textdocument';
33
import * as apidomLS from '@swagger-api/apidom-ls';
44

55
export class ApiDOMWorker {
@@ -91,7 +91,7 @@ export class ApiDOMWorker {
9191
}
9292

9393
_getTextDocument(uri) {
94-
const models = this._ctx.getMirrorModels()[0];
94+
const [model] = this._ctx.getMirrorModels();
9595
/**
9696
* When there are multiple files open, this will be an array
9797
* expect models: _lines[], _uri, _versionId
@@ -106,8 +106,8 @@ export class ApiDOMWorker {
106106
return vscodeLanguageServerTextDocument.TextDocument.create(
107107
uri,
108108
this._createData.languageId,
109-
models._versionId,
110-
models.getValue()
109+
model.version,
110+
model.getValue()
111111
);
112112
}
113113
}

src/plugins/editor-monaco/workers/apidom/WorkerManager.js renamed to src/plugins/editor-monaco-language-apidom/language/WorkerManager.js

File renamed without changes.

src/plugins/editor-monaco/workers/apidom/adapters/Adapter.js renamed to src/plugins/editor-monaco-language-apidom/language/adapters/Adapter.js

File renamed without changes.

src/plugins/editor-monaco/workers/apidom/adapters/CodeActionsAdapter.js renamed to src/plugins/editor-monaco-language-apidom/language/adapters/CodeActionsAdapter.js

File renamed without changes.

0 commit comments

Comments
 (0)