summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/content_editor/services/code_block_language_loader.js
blob: 1afaf4bfef6e9c63e2c6216e3a1a7d8101da5908 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import { lowlight } from 'lowlight/lib/core';
import { __, sprintf } from '~/locale';
import CODE_BLOCK_LANGUAGES from '../constants/code_block_languages';
import languageLoader from './highlight_js_language_loader';

const codeBlockLanguageLoader = {
  lowlight,

  allLanguages: CODE_BLOCK_LANGUAGES,

  findLanguageBySyntax(value) {
    const lowercaseValue = value?.toLowerCase() || 'plaintext';
    return (
      this.allLanguages.find(
        ({ syntax, variants }) =>
          syntax === lowercaseValue || variants?.toLowerCase().split(', ').includes(lowercaseValue),
      ) || {
        syntax: lowercaseValue,
        label: sprintf(__(`Custom (%{language})`), { language: lowercaseValue }),
      }
    );
  },

  filterLanguages(value) {
    if (!value) return this.allLanguages;

    const lowercaseValue = value?.toLowerCase() || '';
    return this.allLanguages.filter(
      ({ syntax, label, variants }) =>
        syntax.toLowerCase().includes(lowercaseValue) ||
        label.toLowerCase().includes(lowercaseValue) ||
        variants?.toLowerCase().includes(lowercaseValue),
    );
  },

  isLanguageLoaded(language) {
    return this.lowlight.registered(language);
  },

  loadLanguageFromInputRule(match) {
    const { syntax } = this.findLanguageBySyntax(match[1]);

    this.loadLanguage(syntax);

    return { language: syntax };
  },

  async loadLanguage(languageName) {
    if (this.isLanguageLoaded(languageName)) return false;

    try {
      const { default: language } = await languageLoader[languageName]();
      this.lowlight.registerLanguage(languageName, language);
      return true;
    } catch {
      return false;
    }
  },
};

export default codeBlockLanguageLoader;