mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
[Monaco] Refactor the way XJSON grammar checker gets registered (#75160)
* Refactor the way XJSON grammar checker gets registered - avoid registering multiple model add listeners - remove regsiterGrammarChecker from public API! - fix getWorker handler to register XJSON only for XJSON models * remove unused import * updateAnnos -> updateAnnotations
This commit is contained in:
parent
2a212cbad8
commit
36f0c75088
6 changed files with 56 additions and 45 deletions
|
@ -22,6 +22,19 @@ export enum AnnoTypes {
|
|||
warning = 'warning',
|
||||
}
|
||||
|
||||
export type Parser = ReturnType<typeof createParser>;
|
||||
|
||||
export interface Annotation {
|
||||
name?: string;
|
||||
type: AnnoTypes;
|
||||
text: string;
|
||||
at: number;
|
||||
}
|
||||
|
||||
export interface ParseResult {
|
||||
annotations: Annotation[];
|
||||
}
|
||||
|
||||
/* eslint-disable */
|
||||
|
||||
export const createParser = () => {
|
||||
|
|
|
@ -17,8 +17,10 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { registerGrammarChecker } from './language';
|
||||
|
||||
/**
|
||||
* This import registers the XJSON monaco language contribution
|
||||
*/
|
||||
import './language';
|
||||
import { ID } from './constants';
|
||||
|
||||
export const XJsonLang = { registerGrammarChecker, ID };
|
||||
export const XJsonLang = { ID };
|
||||
|
|
|
@ -32,13 +32,16 @@ const wps = new WorkerProxyService();
|
|||
registerLexerRules(monaco);
|
||||
|
||||
// In future we will need to make this map languages to workers using "id" and/or "label" values
|
||||
// that get passed in.
|
||||
// that get passed in. Also this should not live inside the "xjson" dir directly. We can update this
|
||||
// once we have another worker.
|
||||
// @ts-ignore
|
||||
window.MonacoEnvironment = {
|
||||
getWorker: (id: any, label: any) => {
|
||||
// In kibana we will probably build this once and then load with raw-loader
|
||||
const blob = new Blob([workerSrc], { type: 'application/javascript' });
|
||||
return new Worker(URL.createObjectURL(blob));
|
||||
getWorker: (module: string, languageId: string) => {
|
||||
if (languageId === ID) {
|
||||
// In kibana we will probably build this once and then load with raw-loader
|
||||
const blob = new Blob([workerSrc], { type: 'application/javascript' });
|
||||
return new Worker(URL.createObjectURL(blob));
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -47,15 +50,19 @@ monaco.languages.onLanguage(ID, async () => {
|
|||
});
|
||||
|
||||
const OWNER = 'XJSON_GRAMMAR_CHECKER';
|
||||
export const registerGrammarChecker = (editor: monaco.editor.IEditor) => {
|
||||
|
||||
export const registerGrammarChecker = () => {
|
||||
const allDisposables: monaco.IDisposable[] = [];
|
||||
|
||||
const updateAnnos = async () => {
|
||||
const { annotations } = await wps.getAnnos();
|
||||
const model = editor.getModel() as monaco.editor.ITextModel | null;
|
||||
if (!model) {
|
||||
const updateAnnotations = async (model: monaco.editor.IModel): Promise<void> => {
|
||||
if (model.isDisposed()) {
|
||||
return;
|
||||
}
|
||||
const parseResult = await wps.getAnnos(model.uri);
|
||||
if (!parseResult) {
|
||||
return;
|
||||
}
|
||||
const { annotations } = parseResult;
|
||||
monaco.editor.setModelMarkers(
|
||||
model,
|
||||
OWNER,
|
||||
|
@ -74,19 +81,21 @@ export const registerGrammarChecker = (editor: monaco.editor.IEditor) => {
|
|||
};
|
||||
|
||||
const onModelAdd = (model: monaco.editor.IModel) => {
|
||||
allDisposables.push(
|
||||
model.onDidChangeContent(async () => {
|
||||
updateAnnos();
|
||||
})
|
||||
);
|
||||
if (model.getModeId() === ID) {
|
||||
allDisposables.push(
|
||||
model.onDidChangeContent(async () => {
|
||||
updateAnnotations(model);
|
||||
})
|
||||
);
|
||||
|
||||
updateAnnos();
|
||||
updateAnnotations(model);
|
||||
}
|
||||
};
|
||||
|
||||
allDisposables.push(monaco.editor.onDidCreateModel(onModelAdd));
|
||||
monaco.editor.getModels().forEach(onModelAdd);
|
||||
return () => {
|
||||
wps.stop();
|
||||
allDisposables.forEach((d) => d.dispose());
|
||||
};
|
||||
};
|
||||
|
||||
registerGrammarChecker();
|
||||
|
|
|
@ -19,17 +19,19 @@
|
|||
|
||||
/* eslint-disable-next-line @kbn/eslint/module_migration */
|
||||
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api';
|
||||
import { createParser } from '../grammar';
|
||||
import { createParser, Parser, ParseResult } from '../grammar';
|
||||
|
||||
export class XJsonWorker {
|
||||
constructor(private ctx: monaco.worker.IWorkerContext) {}
|
||||
private parser: any;
|
||||
private parser: Parser | undefined;
|
||||
|
||||
async parse() {
|
||||
async parse(modelUri: string): Promise<ParseResult | undefined> {
|
||||
if (!this.parser) {
|
||||
this.parser = createParser();
|
||||
}
|
||||
const [model] = this.ctx.getMirrorModels();
|
||||
return this.parser(model.getValue());
|
||||
const model = this.ctx.getMirrorModels().find((m) => m.uri.toString() === modelUri);
|
||||
if (model) {
|
||||
return this.parser(model.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,32 +17,21 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { AnnoTypes } from './grammar';
|
||||
import { ParseResult } from './grammar';
|
||||
import { monaco } from '../monaco';
|
||||
import { XJsonWorker } from './worker';
|
||||
import { ID } from './constants';
|
||||
|
||||
export interface Annotation {
|
||||
name?: string;
|
||||
type: AnnoTypes;
|
||||
text: string;
|
||||
at: number;
|
||||
}
|
||||
|
||||
export interface AnnotationsResponse {
|
||||
annotations: Annotation[];
|
||||
}
|
||||
|
||||
export class WorkerProxyService {
|
||||
private worker: monaco.editor.MonacoWebWorker<XJsonWorker> | undefined;
|
||||
|
||||
public async getAnnos(): Promise<AnnotationsResponse> {
|
||||
public async getAnnos(modelUri: monaco.Uri): Promise<ParseResult | undefined> {
|
||||
if (!this.worker) {
|
||||
throw new Error('Worker Proxy Service has not been setup!');
|
||||
}
|
||||
await this.worker.withSyncedResources(monaco.editor.getModels().map(({ uri }) => uri));
|
||||
await this.worker.withSyncedResources([modelUri]);
|
||||
const proxy = await this.worker.getProxy();
|
||||
return proxy.parse();
|
||||
return proxy.parse(modelUri.toString());
|
||||
}
|
||||
|
||||
public setup() {
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { XJsonLang } from '@kbn/monaco';
|
||||
import React, { FunctionComponent, useCallback } from 'react';
|
||||
import { FieldHook, Monaco } from '../../../../../../shared_imports';
|
||||
|
@ -33,9 +32,6 @@ export const XJsonEditor: FunctionComponent<Props> = ({ field, editorProps }) =>
|
|||
value: xJson,
|
||||
languageId: XJsonLang.ID,
|
||||
options: { minimap: { enabled: false } },
|
||||
editorDidMount: (m: any) => {
|
||||
XJsonLang.registerGrammarChecker(m);
|
||||
},
|
||||
onChange,
|
||||
...editorProps,
|
||||
}}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue