diff --git a/packages/grafana-ui/src/components/DataLinks/DataLinkInput.tsx b/packages/grafana-ui/src/components/DataLinks/DataLinkInput.tsx index 821cde4c7ce..fa696622a1e 100644 --- a/packages/grafana-ui/src/components/DataLinks/DataLinkInput.tsx +++ b/packages/grafana-ui/src/components/DataLinks/DataLinkInput.tsx @@ -6,7 +6,7 @@ import { SelectionReference } from './SelectionReference'; import { Portal, getFormStyles } from '../index'; // @ts-ignore -import Prism from 'prismjs'; +import Prism, { Grammar, LanguageMap } from 'prismjs'; import { Editor } from '@grafana/slate-react'; import { Value } from 'slate'; import Plain from 'slate-plain-serializer'; @@ -27,11 +27,20 @@ interface DataLinkInputProps { placeholder?: string; } +const datalinksSyntax: Grammar = { + builtInVariable: { + pattern: /(\${\S+?})/, + }, +}; + const plugins = [ - SlatePrism({ - onlyIn: (node: any) => node.type === 'code_block', - getSyntax: () => 'links', - }), + SlatePrism( + { + onlyIn: (node: any) => node.type === 'code_block', + getSyntax: () => 'links', + }, + { ...(Prism.languages as LanguageMap), links: datalinksSyntax } + ), ]; const getStyles = stylesFactory((theme: GrafanaTheme) => ({ @@ -56,19 +65,10 @@ const getStyles = stylesFactory((theme: GrafanaTheme) => ({ `, })); -export const enableDatalinksPrismSyntax = () => { - Prism.languages['links'] = { - builtInVariable: { - pattern: /(\${\S+?})/, - }, - }; -}; - // This memoised also because rerendering the slate editor grabs focus which created problem in some cases this // was used and changes to different state were propagated here. export const DataLinkInput: React.FC = memo( ({ value, onChange, suggestions, placeholder = 'http://your-grafana.com/d/000000010/annotations' }) => { - enableDatalinksPrismSyntax(); const editorRef = useRef() as RefObject; const theme = useContext(ThemeContext); const styles = getStyles(theme); diff --git a/packages/grafana-ui/src/slate-plugins/slate-prism/index.ts b/packages/grafana-ui/src/slate-plugins/slate-prism/index.ts index c54b1cefd70..41cf75bdba9 100644 --- a/packages/grafana-ui/src/slate-plugins/slate-prism/index.ts +++ b/packages/grafana-ui/src/slate-plugins/slate-prism/index.ts @@ -1,4 +1,4 @@ -import Prism from 'prismjs'; +import Prism, { LanguageMap } from 'prismjs'; import { Block, Text, Decoration } from 'slate'; import { Plugin } from '@grafana/slate-react'; import Options, { OptionsFormat } from './options'; @@ -19,7 +19,7 @@ export interface Token { /** * A Slate plugin to highlight code syntax. */ -export function SlatePrism(optsParam: OptionsFormat = {}): Plugin { +export function SlatePrism(optsParam: OptionsFormat = {}, prismLanguages = Prism.languages as LanguageMap): Plugin { const opts: Options = new Options(optsParam); return { @@ -30,7 +30,7 @@ export function SlatePrism(optsParam: OptionsFormat = {}): Plugin { const block = Block.create(node as Block); const grammarName = opts.getSyntax(block); - const grammar = Prism.languages[grammarName]; + const grammar = prismLanguages[grammarName]; if (!grammar) { // Grammar not loaded diff --git a/public/app/plugins/datasource/cloudwatch/components/LogsCheatSheet.tsx b/public/app/plugins/datasource/cloudwatch/components/LogsCheatSheet.tsx index af083254e67..cd636cbdbf0 100644 --- a/public/app/plugins/datasource/cloudwatch/components/LogsCheatSheet.tsx +++ b/public/app/plugins/datasource/cloudwatch/components/LogsCheatSheet.tsx @@ -192,7 +192,7 @@ const CLIQ_EXAMPLES: QueryExample[] = [ ]; function renderHighlightedMarkup(code: string, keyPrefix: string) { - const grammar = Prism.languages['cloudwatch'] ?? tokenizer; + const grammar = tokenizer; const tokens = flattenTokens(Prism.tokenize(code, grammar)); const spans = tokens .filter(token => typeof token !== 'string') diff --git a/public/app/plugins/datasource/cloudwatch/components/LogsQueryField.tsx b/public/app/plugins/datasource/cloudwatch/components/LogsQueryField.tsx index f152a93e723..b40fdb4c6fa 100644 --- a/public/app/plugins/datasource/cloudwatch/components/LogsQueryField.tsx +++ b/public/app/plugins/datasource/cloudwatch/components/LogsQueryField.tsx @@ -24,7 +24,7 @@ import syntax from '../syntax'; import { ExploreQueryFieldProps, AbsoluteTimeRange, SelectableValue, AppEvents } from '@grafana/data'; import { CloudWatchQuery, CloudWatchLogsQuery } from '../types'; import { CloudWatchDatasource } from '../datasource'; -import Prism, { Grammar } from 'prismjs'; +import { Grammar, LanguageMap, languages as prismLanguages } from 'prismjs'; import { CloudWatchLanguageProvider } from '../language_provider'; import { css } from 'emotion'; import { ExploreId } from 'app/types'; @@ -95,13 +95,15 @@ export class CloudWatchLogsQueryField extends React.PureComponent) { super(props, context); - Prism.languages['cloudwatch'] = syntax; this.plugins = [ BracesPlugin(), - SlatePrism({ - onlyIn: (node: Node) => node.object === 'block' && node.type === 'code_block', - getSyntax: (node: Node) => 'cloudwatch', - }), + SlatePrism( + { + onlyIn: (node: Node) => node.object === 'block' && node.type === 'code_block', + getSyntax: (node: Node) => 'cloudwatch', + }, + { ...(prismLanguages as LanguageMap), cloudwatch: syntax } + ), ]; } diff --git a/public/app/plugins/datasource/cloudwatch/useCloudwatchSyntax.ts b/public/app/plugins/datasource/cloudwatch/useCloudwatchSyntax.ts index 6fdb3a73a2c..5a982350f64 100644 --- a/public/app/plugins/datasource/cloudwatch/useCloudwatchSyntax.ts +++ b/public/app/plugins/datasource/cloudwatch/useCloudwatchSyntax.ts @@ -1,11 +1,9 @@ import { useState, useEffect } from 'react'; -import Prism, { Grammar } from 'prismjs'; +import { Grammar } from 'prismjs'; import { AbsoluteTimeRange } from '@grafana/data'; import { useRefMounted } from 'app/core/hooks/useRefMounted'; import { CloudWatchLanguageProvider } from './language_provider'; -const PRISM_SYNTAX = 'cloudwatch'; - /** * Initialise the language provider. Returns a languageProviderInitialized boolean cause there does not seem other way * to know if the provider is already initialised or not. By the initialisation it modifies the provided @@ -44,7 +42,6 @@ const useCloudwatchSyntax = (languageProvider: CloudWatchLanguageProvider, langu useEffect(() => { if (languageProviderInitialized) { const syntax = languageProvider.getSyntax(); - Prism.languages[PRISM_SYNTAX] = syntax; setSyntax(syntax); } }, [languageProviderInitialized, languageProvider]); diff --git a/public/app/plugins/datasource/loki/components/LokiQueryFieldForm.tsx b/public/app/plugins/datasource/loki/components/LokiQueryFieldForm.tsx index 763603e4659..a9d1dd7b56a 100644 --- a/public/app/plugins/datasource/loki/components/LokiQueryFieldForm.tsx +++ b/public/app/plugins/datasource/loki/components/LokiQueryFieldForm.tsx @@ -20,7 +20,7 @@ import { Plugin, Node } from 'slate'; import { DOMUtil } from '@grafana/ui'; import { ExploreQueryFieldProps, AbsoluteTimeRange } from '@grafana/data'; import { LokiQuery, LokiOptions } from '../types'; -import { Grammar } from 'prismjs'; +import { Grammar, LanguageMap, languages as prismLanguages } from 'prismjs'; import LokiLanguageProvider, { LokiHistoryItem } from '../language_provider'; import LokiDatasource from '../datasource'; import LokiOptionFields from './LokiOptionFields'; @@ -82,10 +82,13 @@ export class LokiQueryFieldForm extends React.PureComponent node.object === 'block' && node.type === 'code_block', - getSyntax: (node: Node) => 'promql', - }), + SlatePrism( + { + onlyIn: (node: Node) => node.object === 'block' && node.type === 'code_block', + getSyntax: (node: Node) => 'logql', + }, + { ...(prismLanguages as LanguageMap), logql: this.props.datasource.languageProvider.getSyntax() } + ), ]; } diff --git a/public/app/plugins/datasource/loki/components/useLokiSyntaxAndLabels.ts b/public/app/plugins/datasource/loki/components/useLokiSyntaxAndLabels.ts index 19b66e22705..ac4f8384c9f 100644 --- a/public/app/plugins/datasource/loki/components/useLokiSyntaxAndLabels.ts +++ b/public/app/plugins/datasource/loki/components/useLokiSyntaxAndLabels.ts @@ -1,12 +1,10 @@ import { useState, useEffect } from 'react'; -import Prism, { Grammar } from 'prismjs'; +import { Grammar } from 'prismjs'; import { AbsoluteTimeRange } from '@grafana/data'; import LokiLanguageProvider from 'app/plugins/datasource/loki/language_provider'; import { useLokiLabels } from 'app/plugins/datasource/loki/components/useLokiLabels'; import { useRefMounted } from 'app/core/hooks/useRefMounted'; -const PRISM_SYNTAX = 'promql'; - /** * Initialise the language provider. Returns a languageProviderInitialized boolean cause there does not seem other way * to know if the provider is already initialised or not. By the initialisation it modifies the provided @@ -45,7 +43,6 @@ const useLokiSyntax = (languageProvider: LokiLanguageProvider, languageProviderI useEffect(() => { if (languageProviderInitialized) { const syntax = languageProvider.getSyntax(); - Prism.languages[PRISM_SYNTAX] = syntax; setSyntax(syntax); } }, [languageProviderInitialized, languageProvider]); diff --git a/public/app/plugins/datasource/prometheus/components/PromExploreQueryEditor.test.tsx b/public/app/plugins/datasource/prometheus/components/PromExploreQueryEditor.test.tsx index 50777e801af..6501fe7f9a1 100644 --- a/public/app/plugins/datasource/prometheus/components/PromExploreQueryEditor.test.tsx +++ b/public/app/plugins/datasource/prometheus/components/PromExploreQueryEditor.test.tsx @@ -7,7 +7,11 @@ import { PromQuery } from '../types'; import { LoadingState, PanelData, toUtc, TimeRange } from '@grafana/data'; const setup = (renderMethod: any, propOverrides?: object) => { - const datasourceMock: unknown = {}; + const datasourceMock: unknown = { + languageProvider: { + syntax: () => {}, + }, + }; const datasource: PrometheusDatasource = datasourceMock as PrometheusDatasource; const onRunQuery = jest.fn(); const onChange = jest.fn(); diff --git a/public/app/plugins/datasource/prometheus/components/PromQueryField.test.tsx b/public/app/plugins/datasource/prometheus/components/PromQueryField.test.tsx index 3bc79ea44d0..07175ecd17b 100644 --- a/public/app/plugins/datasource/prometheus/components/PromQueryField.test.tsx +++ b/public/app/plugins/datasource/prometheus/components/PromQueryField.test.tsx @@ -17,6 +17,7 @@ describe('PromQueryField', () => { const datasource = ({ languageProvider: { start: () => Promise.resolve([]), + syntax: () => {}, }, } as unknown) as DataSourceInstanceSettings; @@ -35,10 +36,16 @@ describe('PromQueryField', () => { }); it('renders a disabled metrics chooser if lookups are disabled in datasource settings', () => { + const datasource = ({ + languageProvider: { + start: () => Promise.resolve([]), + syntax: () => {}, + }, + } as unknown) as DataSourceInstanceSettings; const queryField = render( {}} onChange={() => {}} diff --git a/public/app/plugins/datasource/prometheus/components/PromQueryField.tsx b/public/app/plugins/datasource/prometheus/components/PromQueryField.tsx index b94322277a6..16ca7b0f20c 100644 --- a/public/app/plugins/datasource/prometheus/components/PromQueryField.tsx +++ b/public/app/plugins/datasource/prometheus/components/PromQueryField.tsx @@ -12,7 +12,7 @@ import { BracesPlugin, } from '@grafana/ui'; -import Prism from 'prismjs'; +import { LanguageMap, languages as prismLanguages } from 'prismjs'; // dom also includes Element polyfills import { PromQuery, PromOptions, PromMetricsMetadata } from '../types'; @@ -22,7 +22,6 @@ import { DOMUtil, SuggestionsState } from '@grafana/ui'; import { PrometheusDatasource } from '../datasource'; const HISTOGRAM_GROUP = '__histograms__'; -const PRISM_SYNTAX = 'promql'; export const RECORDING_RULES_GROUP = '__recording_rules__'; function getChooserText(metricsLookupDisabled: boolean, hasSyntax: boolean, metrics: string[]) { @@ -133,10 +132,13 @@ class PromQueryField extends React.PureComponent node.type === 'code_block', - getSyntax: (node: any) => 'promql', - }), + SlatePrism( + { + onlyIn: (node: any) => node.type === 'code_block', + getSyntax: (node: any) => 'promql', + }, + { ...(prismLanguages as LanguageMap), promql: this.props.datasource.languageProvider.syntax } + ), ]; this.state = { @@ -222,7 +224,6 @@ class PromQueryField extends React.PureComponent