diff --git a/packages/kbn-monaco/src/esql/index.ts b/packages/kbn-monaco/src/esql/index.ts index a3f9df00118b7..4b50a222ad2d6 100644 --- a/packages/kbn-monaco/src/esql/index.ts +++ b/packages/kbn-monaco/src/esql/index.ts @@ -6,7 +6,8 @@ * Side Public License, v 1. */ +import { LangModule as LangModuleType } from '../types'; import { ID } from './constants'; import { lexerRules } from './lexer_rules'; -export const EsqlLang = { ID, lexerRules }; +export const EsqlLang: LangModuleType = { ID, lexerRules }; diff --git a/packages/kbn-monaco/src/helpers.ts b/packages/kbn-monaco/src/helpers.ts new file mode 100644 index 0000000000000..e525b8c132132 --- /dev/null +++ b/packages/kbn-monaco/src/helpers.ts @@ -0,0 +1,21 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ +import { monaco } from './monaco_imports'; +import { LangModule as LangModuleType } from './types'; + +function registerLanguage(language: LangModuleType) { + const { ID, lexerRules, languageConfiguration } = language; + + monaco.languages.register({ id: ID }); + monaco.languages.setMonarchTokensProvider(ID, lexerRules); + if (languageConfiguration) { + monaco.languages.setLanguageConfiguration(ID, languageConfiguration); + } +} + +export { registerLanguage }; diff --git a/packages/kbn-monaco/src/index.ts b/packages/kbn-monaco/src/index.ts index ce35d7c3572e6..85d3518461a49 100644 --- a/packages/kbn-monaco/src/index.ts +++ b/packages/kbn-monaco/src/index.ts @@ -12,7 +12,13 @@ import './register_globals'; export { monaco } from './monaco_imports'; export { XJsonLang } from './xjson'; export { PainlessLang, PainlessContext, PainlessAutocompleteField } from './painless'; - /* eslint-disable-next-line @kbn/eslint/module_migration */ import * as BarePluginApi from 'monaco-editor/esm/vs/editor/editor.api'; -export { BarePluginApi }; + +import { registerLanguage } from './helpers'; +import { + LangModule as LangModuleType, + CompleteLangModule as CompleteLangModuleType, +} from './types'; + +export { BarePluginApi, registerLanguage, LangModuleType, CompleteLangModuleType }; diff --git a/packages/kbn-monaco/src/painless/index.ts b/packages/kbn-monaco/src/painless/index.ts index 6858209756430..9863204117b12 100644 --- a/packages/kbn-monaco/src/painless/index.ts +++ b/packages/kbn-monaco/src/painless/index.ts @@ -9,8 +9,9 @@ import { ID } from './constants'; import { lexerRules, languageConfiguration } from './lexer_rules'; import { getSuggestionProvider, getSyntaxErrors } from './language'; +import { CompleteLangModule as CompleteLangModuleType } from '../types'; -export const PainlessLang = { +export const PainlessLang: CompleteLangModuleType = { ID, getSuggestionProvider, lexerRules, diff --git a/packages/kbn-monaco/src/register_globals.ts b/packages/kbn-monaco/src/register_globals.ts index 4047ddedeca42..c6eb68b89e718 100644 --- a/packages/kbn-monaco/src/register_globals.ts +++ b/packages/kbn-monaco/src/register_globals.ts @@ -10,6 +10,8 @@ import { XJsonLang } from './xjson'; import { PainlessLang } from './painless'; import { EsqlLang } from './esql'; import { monaco } from './monaco_imports'; +import { registerLanguage } from './helpers'; + // @ts-ignore import xJsonWorkerSrc from '!!raw-loader!../../target_web/xjson.editor.worker.js'; // @ts-ignore @@ -20,14 +22,9 @@ import painlessWorkerSrc from '!!raw-loader!../../target_web/painless.editor.wor /** * Register languages and lexer rules */ -monaco.languages.register({ id: XJsonLang.ID }); -monaco.languages.setMonarchTokensProvider(XJsonLang.ID, XJsonLang.lexerRules); -monaco.languages.setLanguageConfiguration(XJsonLang.ID, XJsonLang.languageConfiguration); -monaco.languages.register({ id: PainlessLang.ID }); -monaco.languages.setMonarchTokensProvider(PainlessLang.ID, PainlessLang.lexerRules); -monaco.languages.setLanguageConfiguration(PainlessLang.ID, PainlessLang.languageConfiguration); -monaco.languages.register({ id: EsqlLang.ID }); -monaco.languages.setMonarchTokensProvider(EsqlLang.ID, EsqlLang.lexerRules); +registerLanguage(XJsonLang); +registerLanguage(PainlessLang); +registerLanguage(EsqlLang); /** * Create web workers by language ID diff --git a/packages/kbn-monaco/src/types.ts b/packages/kbn-monaco/src/types.ts new file mode 100644 index 0000000000000..f977ada5b624b --- /dev/null +++ b/packages/kbn-monaco/src/types.ts @@ -0,0 +1,22 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ +import { monaco } from './monaco_imports'; + +export interface LangModule { + ID: string; + lexerRules: monaco.languages.IMonarchLanguage; + languageConfiguration?: monaco.languages.LanguageConfiguration; + getSuggestionProvider?: Function; + getSyntaxErrors?: Function; +} + +export interface CompleteLangModule extends LangModule { + languageConfiguration: monaco.languages.LanguageConfiguration; + getSuggestionProvider: Function; + getSyntaxErrors: Function; +} diff --git a/packages/kbn-monaco/src/xjson/index.ts b/packages/kbn-monaco/src/xjson/index.ts index 5e278795fef12..e9ece97ac0023 100644 --- a/packages/kbn-monaco/src/xjson/index.ts +++ b/packages/kbn-monaco/src/xjson/index.ts @@ -12,5 +12,6 @@ import './language'; import { ID } from './constants'; import { lexerRules, languageConfiguration } from './lexer_rules'; +import { LangModule as LangModuleType } from '../types'; -export const XJsonLang = { ID, lexerRules, languageConfiguration }; +export const XJsonLang: LangModuleType = { ID, lexerRules, languageConfiguration }; diff --git a/src/plugins/kibana_react/public/code_editor/index.tsx b/src/plugins/kibana_react/public/code_editor/index.tsx index 2440974c3b1d1..9e3824b784219 100644 --- a/src/plugins/kibana_react/public/code_editor/index.tsx +++ b/src/plugins/kibana_react/public/code_editor/index.tsx @@ -17,6 +17,9 @@ import darkTheme from '@elastic/eui/dist/eui_theme_dark.json'; import lightTheme from '@elastic/eui/dist/eui_theme_light.json'; import { useUiSetting } from '../ui_settings'; import { Props } from './code_editor'; +import './register_languages'; + +export * from './languages'; const LazyBaseEditor = React.lazy(() => import('./code_editor')); diff --git a/src/plugins/kibana_react/public/url_template_editor/constants.ts b/src/plugins/kibana_react/public/code_editor/languages/css/constants.ts similarity index 90% rename from src/plugins/kibana_react/public/url_template_editor/constants.ts rename to src/plugins/kibana_react/public/code_editor/languages/css/constants.ts index 6c1a1dbce5d67..2f465775e2a1b 100644 --- a/src/plugins/kibana_react/public/url_template_editor/constants.ts +++ b/src/plugins/kibana_react/public/code_editor/languages/css/constants.ts @@ -6,4 +6,4 @@ * Side Public License, v 1. */ -export const LANG = 'handlebars_url'; +export const LANG = 'css'; diff --git a/src/plugins/kibana_react/public/code_editor/languages/css/index.ts b/src/plugins/kibana_react/public/code_editor/languages/css/index.ts new file mode 100644 index 0000000000000..fa1cbf4808a4e --- /dev/null +++ b/src/plugins/kibana_react/public/code_editor/languages/css/index.ts @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ +import { LangModuleType } from '@kbn/monaco'; +import { lexerRules, languageConfiguration } from './language'; +import { LANG } from './constants'; + +export const Lang: LangModuleType = { ID: LANG, lexerRules, languageConfiguration }; diff --git a/src/plugins/kibana_react/public/code_editor/languages/css/language.ts b/src/plugins/kibana_react/public/code_editor/languages/css/language.ts new file mode 100644 index 0000000000000..5bdd6c8eb8b1f --- /dev/null +++ b/src/plugins/kibana_react/public/code_editor/languages/css/language.ts @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +/* eslint-disable @kbn/eslint/module_migration */ +import { conf, language } from 'monaco-editor/esm/vs/basic-languages/css/css'; + +export { conf as languageConfiguration, language as lexerRules }; diff --git a/src/plugins/kibana_react/public/code_editor/languages/handlebars/constants.ts b/src/plugins/kibana_react/public/code_editor/languages/handlebars/constants.ts new file mode 100644 index 0000000000000..1634c02429f59 --- /dev/null +++ b/src/plugins/kibana_react/public/code_editor/languages/handlebars/constants.ts @@ -0,0 +1,9 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export const LANG = 'handlebars'; diff --git a/src/plugins/kibana_react/public/code_editor/languages/handlebars/index.ts b/src/plugins/kibana_react/public/code_editor/languages/handlebars/index.ts new file mode 100644 index 0000000000000..ff3c08267da9b --- /dev/null +++ b/src/plugins/kibana_react/public/code_editor/languages/handlebars/index.ts @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { LangModuleType } from '@kbn/monaco'; +import { languageConfiguration, lexerRules } from './language'; +import { LANG } from './constants'; + +export const Lang: LangModuleType = { ID: LANG, languageConfiguration, lexerRules }; diff --git a/src/plugins/kibana_react/public/url_template_editor/language.ts b/src/plugins/kibana_react/public/code_editor/languages/handlebars/language.ts similarity index 96% rename from src/plugins/kibana_react/public/url_template_editor/language.ts rename to src/plugins/kibana_react/public/code_editor/languages/handlebars/language.ts index 278a7130ad1fa..7f760836088d6 100644 --- a/src/plugins/kibana_react/public/url_template_editor/language.ts +++ b/src/plugins/kibana_react/public/code_editor/languages/handlebars/language.ts @@ -13,7 +13,7 @@ import { monaco } from '@kbn/monaco'; -export const conf: monaco.languages.LanguageConfiguration = { +export const languageConfiguration: monaco.languages.LanguageConfiguration = { wordPattern: /(-?\d*\.\d\w*)|([^\`\~\!\@\$\^\&\*\(\)\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\s]+)/g, comments: { @@ -42,7 +42,7 @@ export const conf: monaco.languages.LanguageConfiguration = { ], }; -export const language: monaco.languages.IMonarchLanguage = { +export const lexerRules: monaco.languages.IMonarchLanguage = { // Set defaultToken to invalid to see what you do not tokenize yet. defaultToken: 'invalid', tokenPostfix: '', diff --git a/src/plugins/kibana_react/public/code_editor/languages/index.ts b/src/plugins/kibana_react/public/code_editor/languages/index.ts new file mode 100644 index 0000000000000..ff7da1725fa7f --- /dev/null +++ b/src/plugins/kibana_react/public/code_editor/languages/index.ts @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { Lang as CssLang } from './css'; +import { Lang as HandlebarsLang } from './handlebars'; +import { Lang as MarkdownLang } from './markdown'; + +export { CssLang, HandlebarsLang, MarkdownLang }; diff --git a/src/plugins/kibana_react/public/code_editor/languages/markdown/constants.ts b/src/plugins/kibana_react/public/code_editor/languages/markdown/constants.ts new file mode 100644 index 0000000000000..bd8aa23256637 --- /dev/null +++ b/src/plugins/kibana_react/public/code_editor/languages/markdown/constants.ts @@ -0,0 +1,9 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export const LANG = 'markdown'; diff --git a/src/plugins/kibana_react/public/code_editor/languages/markdown/index.ts b/src/plugins/kibana_react/public/code_editor/languages/markdown/index.ts new file mode 100644 index 0000000000000..f501de74debec --- /dev/null +++ b/src/plugins/kibana_react/public/code_editor/languages/markdown/index.ts @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ +import { LangModuleType } from '@kbn/monaco'; +import { languageConfiguration, lexerRules } from './language'; +import { LANG } from './constants'; + +export const Lang: LangModuleType = { ID: LANG, languageConfiguration, lexerRules }; diff --git a/src/plugins/kibana_react/public/code_editor/languages/markdown/language.ts b/src/plugins/kibana_react/public/code_editor/languages/markdown/language.ts new file mode 100644 index 0000000000000..d8a1234fcf191 --- /dev/null +++ b/src/plugins/kibana_react/public/code_editor/languages/markdown/language.ts @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +/* eslint-disable @kbn/eslint/module_migration */ +import { conf, language } from 'monaco-editor/esm/vs/basic-languages/markdown/markdown'; + +export { conf as languageConfiguration, language as lexerRules }; diff --git a/src/plugins/kibana_react/public/code_editor/register_languages.ts b/src/plugins/kibana_react/public/code_editor/register_languages.ts new file mode 100644 index 0000000000000..b4a0f4d53cdf4 --- /dev/null +++ b/src/plugins/kibana_react/public/code_editor/register_languages.ts @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ +import { registerLanguage } from '@kbn/monaco'; +import { CssLang, HandlebarsLang, MarkdownLang } from './languages'; + +registerLanguage(CssLang); +registerLanguage(HandlebarsLang); +registerLanguage(MarkdownLang); diff --git a/src/plugins/kibana_react/public/url_template_editor/url_template_editor.tsx b/src/plugins/kibana_react/public/url_template_editor/url_template_editor.tsx index f830b4012976a..0fed4d37e4f7f 100644 --- a/src/plugins/kibana_react/public/url_template_editor/url_template_editor.tsx +++ b/src/plugins/kibana_react/public/url_template_editor/url_template_editor.tsx @@ -9,18 +9,10 @@ import * as React from 'react'; import { monaco } from '@kbn/monaco'; import { Props as CodeEditorProps } from '../code_editor/code_editor'; -import { CodeEditor } from '../code_editor'; -import { LANG } from './constants'; -import { language, conf } from './language'; +import { CodeEditor, HandlebarsLang } from '../code_editor'; import './styles.scss'; -monaco.languages.register({ - id: LANG, -}); -monaco.languages.setMonarchTokensProvider(LANG, language); -monaco.languages.setLanguageConfiguration(LANG, conf); - export interface UrlTemplateEditorVariable { label: string; title?: string; @@ -74,7 +66,7 @@ export const UrlTemplateEditor: React.FC = ({ return; } - const { dispose } = monaco.languages.registerCompletionItemProvider(LANG, { + const { dispose } = monaco.languages.registerCompletionItemProvider(HandlebarsLang.ID, { triggerCharacters: ['{', '/', '?', '&', '='], provideCompletionItems(model, position, context, token) { const { lineNumber } = position; @@ -132,7 +124,7 @@ export const UrlTemplateEditor: React.FC = ({ return (
- diff --git a/src/plugins/vis_type_timeseries/public/application/components/panel_config/markdown.tsx b/src/plugins/vis_type_timeseries/public/application/components/panel_config/markdown.tsx index c33b4df914a81..7f82f95d250ea 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/panel_config/markdown.tsx +++ b/src/plugins/vis_type_timeseries/public/application/components/panel_config/markdown.tsx @@ -20,7 +20,6 @@ import { EuiSpacer, EuiTitle, EuiHorizontalRule, - EuiCodeEditor, } from '@elastic/eui'; // @ts-expect-error import less from 'less/lib/less-browser'; @@ -43,6 +42,7 @@ import { getDefaultQueryLanguage } from '../lib/get_default_query_language'; import { VisDataContext } from '../../contexts/vis_data_context'; import { PanelConfigProps, PANEL_CONFIG_TABS } from './types'; import { TimeseriesVisParams } from '../../../types'; +import { CodeEditor, CssLang } from '../../../../../kibana_react/public'; const lessC = less(window, { env: 'production' }); @@ -281,12 +281,10 @@ export class MarkdownPanelConfig extends Component< - diff --git a/test/functional/page_objects/visual_builder_page.ts b/test/functional/page_objects/visual_builder_page.ts index d796067372fa8..6e263dd1cdbbf 100644 --- a/test/functional/page_objects/visual_builder_page.ts +++ b/test/functional/page_objects/visual_builder_page.ts @@ -132,19 +132,18 @@ export class VisualBuilderPageObject extends FtrService { } public async clearMarkdown() { - // Since we use ACE editor and that isn't really storing its value inside - // a textarea we must really select all text and remove it, and cannot use - // clearValue(). await this.retry.waitForWithTimeout('text area is cleared', 20000, async () => { - const editor = await this.testSubjects.find('codeEditorContainer'); - const $ = await editor.parseDomContent(); - const value = $('.ace_line').text(); - if (value.length > 0) { - this.log.debug('Clearing text area input'); - this.waitForMarkdownTextAreaCleaned(); - } - - return value.length === 0; + const input = await this.find.byCssSelector('.tvbMarkdownEditor__editor textarea'); + await input.clickMouseButton(); + await input.clearValueWithKeyboard(); + + const linesContainer = await this.find.byCssSelector( + '.tvbMarkdownEditor__editor .view-lines' + ); + // lines of code in monaco-editor + // text is not present in textarea + const lines = await linesContainer.findAllByClassName('mtk1'); + return lines.length === 0; }); } diff --git a/typings/index.d.ts b/typings/index.d.ts index c7186a0e5795b..2a5c5e3fa430f 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -33,3 +33,7 @@ declare module 'axios/lib/adapters/xhr'; // See https://github.com/storybookjs/storybook/issues/11684 declare module 'react-syntax-highlighter/dist/cjs/create-element'; declare module 'react-syntax-highlighter/dist/cjs/prism-light'; + +// Monaco languages support +declare module 'monaco-editor/esm/vs/basic-languages/markdown/markdown'; +declare module 'monaco-editor/esm/vs/basic-languages/css/css';