From c59016ed9a088953aff5d47c17b94d5add5323e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yulia=20=C4=8Cech?= <6585477+yuliacech@users.noreply.github.com> Date: Wed, 27 Mar 2024 11:06:40 +0100 Subject: [PATCH] [Console] Add theme and more lexer rules (#178757) ## Summary This PR adds a theme for the Console language in Monaco editor and adds more lexer rules to bring the highlighting of the input closed to the original in Ace editor. ### Screenshots Monaco editor Screenshot 2024-03-19 at 12 38 07 Ace editor Screenshot 2024-03-19 at 12 37 52 ### How to test 1. Add `console.dev.enableMonaco: true` to `kibana.dev.yml`` 2. Type different requests into Console and check that the highlighting works the same as in Ace. For example, use the following requests ``` GET ${pathVariable}/_search { "query": { "match": { "${bodyNameVariable}": "${bodyValueVariable}", "number_property": 1234, "array_property": ["test1", 1234, false], "boolean_property": true, "text_property": "text_value", "triple_quote": """ inside triple quote """ // line comment /* block comment */ } } } // line comment /* block comment */ GET _sql { "query": """ SELECT "field" FROM "index-*" WHERE "column" = "value" """ } ``` 3. To check that `xjson` highlighting still works a. Navigate to Ingest pipelines and click the "create from csv" button b. Load a valid csv file, for example this [one](https://github.com/kgeller/ecs-mapper/blob/master/example/mapping.csv) #### Known issues that will be addressed in follow up PRs - SQL highlighting needs to be re-implemented (added to the follow up list in https://github.com/elastic/kibana/issues/176926) - Strings inside triple quotes are not using italics (added to the follow up list in https://github.com/elastic/kibana/issues/176926) - Font size needs to be set via settings and the default value provided (fixed via https://github.com/elastic/kibana/pull/178982) - Font family: do we want to use the same font as for other Monaco languages are use the one for Ace? (added to the follow up list in https://github.com/elastic/kibana/issues/176926) - In the future, we might want to use the same theme for `xjson` and Console (added to the follow up list in https://github.com/elastic/kibana/issues/176926) --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- packages/kbn-monaco/index.ts | 2 +- .../shared.ts => common/lexer_rules.ts} | 0 packages/kbn-monaco/src/common/theme.ts | 16 ++ packages/kbn-monaco/src/console/constants.ts | 2 + packages/kbn-monaco/src/console/index.ts | 4 +- .../src/console/lexer_rules/index.ts | 205 +++++++++++++++--- packages/kbn-monaco/src/console/theme.ts | 54 +++++ .../src/esql/lib/monaco/esql_theme.ts | 8 +- packages/kbn-monaco/src/register_globals.ts | 3 +- .../kbn-monaco/src/xjson/lexer_rules/xjson.ts | 23 +- .../editor/monaco/monaco_editor.tsx | 3 +- .../mode/input_highlight_rules.ts | 33 ++- .../field_editor/field_editor.test.tsx | 1 + .../components/splits/terms.test.js | 1 + .../card_step/content/video.test.tsx | 1 + 15 files changed, 305 insertions(+), 51 deletions(-) rename packages/kbn-monaco/src/{xjson/lexer_rules/shared.ts => common/lexer_rules.ts} (100%) create mode 100644 packages/kbn-monaco/src/common/theme.ts create mode 100644 packages/kbn-monaco/src/console/theme.ts diff --git a/packages/kbn-monaco/index.ts b/packages/kbn-monaco/index.ts index 49f93e85e77d1..d018dd53c673c 100644 --- a/packages/kbn-monaco/index.ts +++ b/packages/kbn-monaco/index.ts @@ -32,4 +32,4 @@ import { registerLanguage } from './src/helpers'; export { BarePluginApi, registerLanguage }; export * from './src/types'; -export { CONSOLE_LANG_ID } from './src/console'; +export { CONSOLE_LANG_ID, CONSOLE_THEME_ID } from './src/console'; diff --git a/packages/kbn-monaco/src/xjson/lexer_rules/shared.ts b/packages/kbn-monaco/src/common/lexer_rules.ts similarity index 100% rename from packages/kbn-monaco/src/xjson/lexer_rules/shared.ts rename to packages/kbn-monaco/src/common/lexer_rules.ts diff --git a/packages/kbn-monaco/src/common/theme.ts b/packages/kbn-monaco/src/common/theme.ts new file mode 100644 index 0000000000000..57f42eb70fc87 --- /dev/null +++ b/packages/kbn-monaco/src/common/theme.ts @@ -0,0 +1,16 @@ +/* + * 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 themeRuleGroupBuilderFactory = + (postfix: string = '') => + (tokens: string[], color: string, isBold: boolean = false) => + tokens.map((i) => ({ + token: i + postfix, + foreground: color, + fontStyle: isBold ? 'bold' : '', + })); diff --git a/packages/kbn-monaco/src/console/constants.ts b/packages/kbn-monaco/src/console/constants.ts index b777e6eb22532..1eba867b617c0 100644 --- a/packages/kbn-monaco/src/console/constants.ts +++ b/packages/kbn-monaco/src/console/constants.ts @@ -7,3 +7,5 @@ */ export const CONSOLE_LANG_ID = 'console'; +export const CONSOLE_THEME_ID = 'consoleTheme'; +export const CONSOLE_POSTFIX = '.console'; diff --git a/packages/kbn-monaco/src/console/index.ts b/packages/kbn-monaco/src/console/index.ts index b7f22299d62ee..e94ebdd0ccae5 100644 --- a/packages/kbn-monaco/src/console/index.ts +++ b/packages/kbn-monaco/src/console/index.ts @@ -15,7 +15,9 @@ import type { LangModuleType } from '../types'; import { CONSOLE_LANG_ID } from './constants'; import { lexerRules, languageConfiguration } from './lexer_rules'; -export { CONSOLE_LANG_ID } from './constants'; +export { CONSOLE_LANG_ID, CONSOLE_THEME_ID } from './constants'; + +export { buildConsoleTheme } from './theme'; export const ConsoleLang: LangModuleType = { ID: CONSOLE_LANG_ID, diff --git a/packages/kbn-monaco/src/console/lexer_rules/index.ts b/packages/kbn-monaco/src/console/lexer_rules/index.ts index fcde238930d57..bf40e2c2824f6 100644 --- a/packages/kbn-monaco/src/console/lexer_rules/index.ts +++ b/packages/kbn-monaco/src/console/lexer_rules/index.ts @@ -7,46 +7,191 @@ */ import { monaco } from '../../monaco_imports'; +import { globals } from '../../common/lexer_rules'; +import { buildXjsonRules } from '../../xjson/lexer_rules/xjson'; -export const languageConfiguration: monaco.languages.LanguageConfiguration = {}; +export const languageConfiguration: monaco.languages.LanguageConfiguration = { + brackets: [ + ['{', '}'], + ['[', ']'], + ], + autoClosingPairs: [ + { open: '{', close: '}' }, + { open: '[', close: ']' }, + { open: '"', close: '"' }, + ], +}; + +/* + util function to build the action object + */ +const addNextStateToAction = (tokens: string[], nextState?: string) => { + return tokens.map((token, index) => { + // only last action needs to specify the next state + if (index === tokens.length - 1 && nextState) { + return { token, next: nextState }; + } + return token; + }); +}; + +/* + if regex is matched, tokenize as "token" and move to the state "nextState" if defined + */ +const matchToken = (token: string, regex: string | RegExp, nextState?: string) => { + if (nextState) { + return { regex, action: { token, next: nextState } }; + } + return { regex, action: { token } }; +}; + +/* + if regex is matched, tokenize as "tokens" consecutively and move to the state "nextState" + regex needs to have the same number of capturing group as the number of tokens + */ +const matchTokens = (tokens: string[], regex: string | RegExp, nextState?: string) => { + const action = addNextStateToAction(tokens, nextState); + return { + regex, + action, + }; +}; + +const matchTokensWithEOL = ( + tokens: string | string[], + regex: string | RegExp, + nextIfEOL: string, + normalNext?: string +) => { + if (Array.isArray(tokens)) { + const endOfLineAction = addNextStateToAction(tokens, nextIfEOL); + const action = addNextStateToAction(tokens, normalNext); + return { + regex, + action: { + cases: { + '@eos': endOfLineAction, + '@default': action, + }, + }, + }; + } + return { + regex, + action: { + cases: { + '@eos': { token: tokens, next: nextIfEOL }, + '@default': { token: tokens, next: normalNext }, + }, + }, + }; +}; + +const xjsonRules = { ...buildXjsonRules('json_root') }; +// @ts-expect-error include comments into json +xjsonRules.json_root = [{ include: '@comments' }, ...xjsonRules.json_root]; +xjsonRules.json_root = [ + // @ts-expect-error include variables into json + matchToken('variable.template', /("\${\w+}")/), + ...xjsonRules.json_root, +]; export const lexerRules: monaco.languages.IMonarchLanguage = { + ...(globals as any), + defaultToken: 'invalid', - regex_method: /get|post|put|patch|delete/, - regex_url: /.*$/, - // C# style strings - escapes: /\\(?:[abfnrtv\\"']|x[0-9A-Fa-f]{1,4}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/, - ignoreCase: true, tokenizer: { root: [ - // whitespace - { include: '@rule_whitespace' }, - // start a multi-line comment - { include: '@rule_start_multi_comment' }, - // a one-line comment - [/\/\/.*$/, 'comment'], + // warning comment + matchToken('warning', '#!.*$'), + // comments + { include: '@comments' }, + // start of json + matchToken('paren.lparen', '{', 'json_root'), // method - [/@regex_method/, 'keyword'], - // url - [/@regex_url/, 'identifier'], + matchTokensWithEOL('method', /([a-zA-Z]+)/, 'root', 'method_sep'), + // whitespace + matchToken('whitespace', '\\s+'), + // text + matchToken('text', '.+?'), ], - rule_whitespace: [[/[ \t\r\n]+/, 'WHITESPACE']], - rule_start_multi_comment: [[/\/\*/, 'comment', '@rule_multi_comment']], - rule_multi_comment: [ + method_sep: [ + // protocol host with slash + matchTokensWithEOL( + ['whitespace', 'url.protocol_host', 'url.slash'], + /(\s+)(https?:\/\/[^?\/,]+)(\/)/, + 'root', + 'url' + ), + // variable template + matchTokensWithEOL(['whitespace', 'variable.template'], /(\s+)(\${\w+})/, 'root', 'url'), + // protocol host + matchTokensWithEOL( + ['whitespace', 'url.protocol_host'], + /(\s+)(https?:\/\/[^?\/,]+)/, + 'root', + 'url' + ), + // slash + matchTokensWithEOL(['whitespace', 'url.slash'], /(\s+)(\/)/, 'root', 'url'), + // whitespace + matchTokensWithEOL('whitespace', /(\s+)/, 'root', 'url'), + ], + url: [ + // variable template + matchTokensWithEOL('variable.template', /(\${\w+})/, 'root'), + // pathname + matchTokensWithEOL('url.part', /([^?\/,\s]+)\s*/, 'root'), + // comma + matchTokensWithEOL('url.comma', /(,)/, 'root'), + // slash + matchTokensWithEOL('url.slash', /(\/)/, 'root'), + // question mark + matchTokensWithEOL('url.questionmark', /(\?)/, 'root', 'urlParams'), + // comment + matchTokensWithEOL( + ['whitespace', 'comment.punctuation', 'comment.line'], + /(\s+)(\/\/)(.*$)/, + 'root' + ), + ], + urlParams: [ + // param with variable template + matchTokensWithEOL( + ['url.param', 'url.equal', 'variable.template'], + /([^&=]+)(=)(\${\w+})/, + 'root' + ), + // param with value + matchTokensWithEOL(['url.param', 'url.equal', 'url.value'], /([^&=]+)(=)([^&]*)/, 'root'), + // param + matchTokensWithEOL('url.param', /([^&=]+)/, 'root'), + // ampersand + matchTokensWithEOL('url.amp', /(&)/, 'root'), + // comment + matchTokensWithEOL( + ['whitespace', 'comment.punctuation', 'comment.line'], + /(\s+)(\/\/)(.*$)/, + 'root' + ), + ], + comments: [ + // line comment indicated by # + matchTokens(['comment.punctuation', 'comment.line'], /(#)(.*$)/), + // start a block comment indicated by /* + matchToken('comment.punctuation', /\/\*/, 'block_comment'), + // line comment indicated by // + matchTokens(['comment.punctuation', 'comment.line'], /(\/\/)(.*$)/), + ], + block_comment: [ // match everything on a single line inside the comment except for chars / and * - [/[^\/*]+/, 'comment'], - // start a nested comment by going 1 level down - [/\/\*/, 'comment', '@push'], - // match the closing of the comment and return 1 level up - ['\\*/', 'comment', '@pop'], + matchToken('comment', /[^\/*]+/), + // end block comment + matchToken('comment.punctuation', /\*\//, '@pop'), // match individual chars inside a multi-line comment - [/[\/*]/, 'comment'], - ], - string: [ - [/[^\\"]+/, 'string'], - [/@escapes/, 'string.escape'], - [/\\./, 'string.escape.invalid'], - [/"/, { token: 'string.quote', bracket: '@close', next: '@pop' }], + matchToken('comment', /[\/*]/), ], + // include json rules + ...xjsonRules, }, }; diff --git a/packages/kbn-monaco/src/console/theme.ts b/packages/kbn-monaco/src/console/theme.ts new file mode 100644 index 0000000000000..b9330ec97afee --- /dev/null +++ b/packages/kbn-monaco/src/console/theme.ts @@ -0,0 +1,54 @@ +/* + * 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 { makeHighContrastColor } from '@elastic/eui'; +import { darkMode, euiThemeVars } from '@kbn/ui-theme'; + +import { themeRuleGroupBuilderFactory } from '../common/theme'; +import { monaco } from '../monaco_imports'; + +const buildRuleGroup = themeRuleGroupBuilderFactory(); + +const background = euiThemeVars.euiColorLightestShade; +const methodTextColor = '#DD0A73'; +const urlTextColor = '#00A69B'; +const stringTextColor = '#009926'; +const commentTextColor = '#4C886B'; +const variableTextColor = '#0079A5'; +const booleanTextColor = '#585CF6'; +const numericTextColor = variableTextColor; +export const buildConsoleTheme = (): monaco.editor.IStandaloneThemeData => { + return { + base: darkMode ? 'vs-dark' : 'vs', + inherit: true, + rules: [ + ...buildRuleGroup(['method'], makeHighContrastColor(methodTextColor)(background)), + ...buildRuleGroup(['url'], makeHighContrastColor(urlTextColor)(background)), + ...buildRuleGroup( + ['string', 'string-literal', 'multi-string', 'punctuation.end-triple-quote'], + makeHighContrastColor(stringTextColor)(background) + ), + ...buildRuleGroup(['comment'], makeHighContrastColor(commentTextColor)(background)), + ...buildRuleGroup(['variable'], makeHighContrastColor(variableTextColor)(background)), + ...buildRuleGroup( + ['constant.language.boolean'], + makeHighContrastColor(booleanTextColor)(background) + ), + ...buildRuleGroup(['constant.numeric'], makeHighContrastColor(numericTextColor)(background)), + ], + colors: { + 'editor.background': background, + // color of the line numbers + 'editorLineNumber.foreground': euiThemeVars.euiColorDarkShade, + // color of the active line number + 'editorLineNumber.activeForeground': euiThemeVars.euiColorDarkShade, + // background of the line numbers side panel + 'editorGutter.background': euiThemeVars.euiColorEmptyShade, + }, + }; +}; diff --git a/packages/kbn-monaco/src/esql/lib/monaco/esql_theme.ts b/packages/kbn-monaco/src/esql/lib/monaco/esql_theme.ts index c6a06d048e699..c38a0900d8e43 100644 --- a/packages/kbn-monaco/src/esql/lib/monaco/esql_theme.ts +++ b/packages/kbn-monaco/src/esql/lib/monaco/esql_theme.ts @@ -7,15 +7,11 @@ */ import { euiThemeVars, darkMode } from '@kbn/ui-theme'; +import { themeRuleGroupBuilderFactory } from '../../../common/theme'; import { ESQL_TOKEN_POSTFIX } from '../constants'; import { monaco } from '../../../monaco_imports'; -const buildRuleGroup = (tokens: string[], color: string, isBold: boolean = false) => - tokens.map((i) => ({ - token: i + ESQL_TOKEN_POSTFIX, - foreground: color, - fontStyle: isBold ? 'bold' : '', - })); +const buildRuleGroup = themeRuleGroupBuilderFactory(ESQL_TOKEN_POSTFIX); export const buildESQlTheme = (): monaco.editor.IStandaloneThemeData => ({ base: darkMode ? 'vs-dark' : 'vs', diff --git a/packages/kbn-monaco/src/register_globals.ts b/packages/kbn-monaco/src/register_globals.ts index 8b12b34866a98..dc69e2ceaa8b0 100644 --- a/packages/kbn-monaco/src/register_globals.ts +++ b/packages/kbn-monaco/src/register_globals.ts @@ -13,7 +13,7 @@ import { monaco } from './monaco_imports'; import { ESQL_THEME_ID, ESQLLang, buildESQlTheme } from './esql'; import { YAML_LANG_ID } from './yaml'; import { registerLanguage, registerTheme } from './helpers'; -import { ConsoleLang } from './console'; +import { ConsoleLang, CONSOLE_THEME_ID, buildConsoleTheme } from './console'; export const DEFAULT_WORKER_ID = 'default'; const langSpecificWorkerIds = [ @@ -38,6 +38,7 @@ registerLanguage(ConsoleLang); * Register custom themes */ registerTheme(ESQL_THEME_ID, buildESQlTheme()); +registerTheme(CONSOLE_THEME_ID, buildConsoleTheme()); const monacoBundleDir = (window as any).__kbnPublicPath__?.['kbn-monaco']; diff --git a/packages/kbn-monaco/src/xjson/lexer_rules/xjson.ts b/packages/kbn-monaco/src/xjson/lexer_rules/xjson.ts index f2ab22f8c97df..e028ff38bb2af 100644 --- a/packages/kbn-monaco/src/xjson/lexer_rules/xjson.ts +++ b/packages/kbn-monaco/src/xjson/lexer_rules/xjson.ts @@ -8,16 +8,11 @@ import { monaco } from '../../monaco_imports'; -import { globals } from './shared'; +import { globals } from '../../common/lexer_rules'; -export const lexerRules: monaco.languages.IMonarchLanguage = { - ...(globals as any), - - defaultToken: 'invalid', - tokenPostfix: '', - - tokenizer: { - root: [ +export const buildXjsonRules = (root: string = 'root') => { + return { + [root]: [ [ /("(?:[^"]*_)?script"|"inline"|"source")(\s*?)(:)(\s*?)(""")/, [ @@ -106,7 +101,15 @@ export const lexerRules: monaco.languages.IMonarchLanguage = { [/\\""""/, { token: 'punctuation.end_triple_quote', next: '@pop' }], [/./, { token: 'multi_string' }], ], - }, + }; +}; +export const lexerRules: monaco.languages.IMonarchLanguage = { + ...(globals as any), + + defaultToken: 'invalid', + tokenPostfix: '', + + tokenizer: { ...buildXjsonRules() }, }; export const languageConfiguration: monaco.languages.LanguageConfiguration = { diff --git a/src/plugins/console/public/application/containers/editor/monaco/monaco_editor.tsx b/src/plugins/console/public/application/containers/editor/monaco/monaco_editor.tsx index 4f637120e32c5..31f4aa328c282 100644 --- a/src/plugins/console/public/application/containers/editor/monaco/monaco_editor.tsx +++ b/src/plugins/console/public/application/containers/editor/monaco/monaco_editor.tsx @@ -9,7 +9,7 @@ import React, { FunctionComponent, useState } from 'react'; import { CodeEditor } from '@kbn/code-editor'; import { css } from '@emotion/react'; -import { CONSOLE_LANG_ID } from '@kbn/monaco'; +import { CONSOLE_LANG_ID, CONSOLE_THEME_ID } from '@kbn/monaco'; import { useEditorReadContext } from '../../../contexts'; export const MonacoEditor: FunctionComponent = () => { @@ -31,6 +31,7 @@ export const MonacoEditor: FunctionComponent = () => { options={{ fontSize: settings.fontSize, wordWrap: settings.wrapMode === true ? 'on' : 'off', + theme: CONSOLE_THEME_ID, }} /> diff --git a/src/plugins/console/public/application/models/legacy_core_editor/mode/input_highlight_rules.ts b/src/plugins/console/public/application/models/legacy_core_editor/mode/input_highlight_rules.ts index acf4b091c6b0f..e4ec266f002ee 100644 --- a/src/plugins/console/public/application/models/legacy_core_editor/mode/input_highlight_rules.ts +++ b/src/plugins/console/public/application/models/legacy_core_editor/mode/input_highlight_rules.ts @@ -31,11 +31,12 @@ export function addEOL( export const mergeTokens = (...args: any[]) => [].concat.apply([], args); const TextHighlightRules = ace.acequire('ace/mode/text_highlight_rules').TextHighlightRules; - +// translating this to monaco export class InputHighlightRules extends TextHighlightRules { constructor() { super(); this.$rules = { + // TODO 'start-sql': [ { token: 'whitespace', regex: '\\s+' }, { token: 'paren.lparen', regex: '{', next: 'json-sql', push: true }, @@ -43,16 +44,22 @@ export class InputHighlightRules extends TextHighlightRules { ], start: mergeTokens( [ + // done { token: 'warning', regex: '#!.*$' }, + // done { include: 'comments' }, + // done { token: 'paren.lparen', regex: '{', next: 'json', push: true }, ], + // done addEOL(['method'], /([a-zA-Z]+)/, 'start', 'method_sep'), [ + // done { token: 'whitespace', regex: '\\s+', }, + // done { token: 'text', regex: '.+?', @@ -60,39 +67,58 @@ export class InputHighlightRules extends TextHighlightRules { ] ), method_sep: mergeTokens( + // done addEOL( ['whitespace', 'url.protocol_host', 'url.slash'], /(\s+)(https?:\/\/[^?\/,]+)(\/)/, 'start', 'url' ), + // done addEOL(['whitespace', 'variable.template'], /(\s+)(\${\w+})/, 'start', 'url'), + // done addEOL(['whitespace', 'url.protocol_host'], /(\s+)(https?:\/\/[^?\/,]+)/, 'start', 'url'), + // done addEOL(['whitespace', 'url.slash'], /(\s+)(\/)/, 'start', 'url'), + // done addEOL(['whitespace'], /(\s+)/, 'start', 'url') ), url: mergeTokens( + // done addEOL(['variable.template'], /(\${\w+})/, 'start'), + // TODO addEOL(['url.part'], /(_sql)/, 'start-sql', 'url-sql'), + // done addEOL(['url.part'], /([^?\/,\s]+)/, 'start'), + // done addEOL(['url.comma'], /(,)/, 'start'), + // done addEOL(['url.slash'], /(\/)/, 'start'), + // done addEOL(['url.questionmark'], /(\?)/, 'start', 'urlParams'), + // done addEOL(['whitespace', 'comment.punctuation', 'comment.line'], /(\s+)(\/\/)(.*$)/, 'start') ), urlParams: mergeTokens( + // done addEOL(['url.param', 'url.equal', 'variable.template'], /([^&=]+)(=)(\${\w+})/, 'start'), + // done addEOL(['url.param', 'url.equal', 'url.value'], /([^&=]+)(=)([^&]*)/, 'start'), + // done addEOL(['url.param'], /([^&=]+)/, 'start'), + // done addEOL(['url.amp'], /(&)/, 'start'), + // done addEOL(['whitespace', 'comment.punctuation', 'comment.line'], /(\s+)(\/\/)(.*$)/, 'start') ), + // TODO 'url-sql': mergeTokens( addEOL(['url.part'], /([^?\/,\s]+)/, 'start-sql'), addEOL(['url.comma'], /(,)/, 'start-sql'), addEOL(['url.slash'], /(\/)/, 'start-sql'), addEOL(['url.questionmark'], /(\?)/, 'start-sql', 'urlParams-sql') ), + // TODO 'urlParams-sql': mergeTokens( addEOL(['url.param', 'url.equal', 'url.value'], /([^&=]+)(=)([^&]*)/, 'start-sql'), addEOL(['url.param'], /([^&=]+)/, 'start-sql'), @@ -108,27 +134,32 @@ export class InputHighlightRules extends TextHighlightRules { comments: [ { // Capture a line comment, indicated by # + // done token: ['comment.punctuation', 'comment.line'], regex: /(#)(.*$)/, }, { // Begin capturing a block comment, indicated by /* + // done token: 'comment.punctuation', regex: /\/\*/, push: [ { // Finish capturing a block comment, indicated by */ + // done token: 'comment.punctuation', regex: /\*\//, next: 'pop', }, { + // done defaultToken: 'comment.block', }, ], }, { // Capture a line comment, indicated by // + // done token: ['comment.punctuation', 'comment.line'], regex: /(\/\/)(.*$)/, }, diff --git a/src/plugins/data_view_management/public/components/field_editor/field_editor.test.tsx b/src/plugins/data_view_management/public/components/field_editor/field_editor.test.tsx index 3f1f8ca06f798..6af3b555c74b5 100644 --- a/src/plugins/data_view_management/public/components/field_editor/field_editor.test.tsx +++ b/src/plugins/data_view_management/public/components/field_editor/field_editor.test.tsx @@ -16,6 +16,7 @@ import { mockManagementPlugin } from '../../mocks'; import { createComponentWithContext } from '../test_utils'; jest.mock('@elastic/eui', () => ({ + ...jest.requireActual('@elastic/eui'), EuiBasicTable: 'eui-basic-table', EuiButton: 'eui-button', EuiButtonEmpty: 'eui-button-empty', diff --git a/src/plugins/vis_types/timeseries/public/application/components/splits/terms.test.js b/src/plugins/vis_types/timeseries/public/application/components/splits/terms.test.js index 8139dcc34a326..3348d32f519eb 100644 --- a/src/plugins/vis_types/timeseries/public/application/components/splits/terms.test.js +++ b/src/plugins/vis_types/timeseries/public/application/components/splits/terms.test.js @@ -11,6 +11,7 @@ import { shallow } from 'enzyme'; import { SplitByTermsUI } from './terms'; jest.mock('@elastic/eui', () => ({ + ...jest.requireActual('@elastic/eui'), htmlIdGenerator: jest.fn(() => () => '42'), EuiFlexGroup: jest.requireActual('@elastic/eui').EuiFlexGroup, EuiFlexItem: jest.requireActual('@elastic/eui').EuiFlexItem, diff --git a/x-pack/plugins/security_solution/public/common/components/landing_page/onboarding/card_step/content/video.test.tsx b/x-pack/plugins/security_solution/public/common/components/landing_page/onboarding/card_step/content/video.test.tsx index ff891e1f1dd70..d8092c41781a6 100644 --- a/x-pack/plugins/security_solution/public/common/components/landing_page/onboarding/card_step/content/video.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/landing_page/onboarding/card_step/content/video.test.tsx @@ -17,6 +17,7 @@ jest.mock('../../context/step_context'); jest.mock('./content_wrapper'); jest.mock('@elastic/eui', () => ({ + ...jest.requireActual('@elastic/eui'), EuiFlexGroup: ({ children, onClick }: EuiFlexGroupProps) => { return ( // eslint-disable-next-line jsx-a11y/click-events-have-key-events