Commit 92fa252f authored by Brandon Labuschagne's avatar Brandon Labuschagne

Merge branch 'dmishunov/source-editor-utils' into 'master'

Moved Source Editor's theming into utilities

See merge request gitlab-org/gitlab!67916
parents a96ba32b 74622098
import { editor as monacoEditor, languages as monacoLanguages, Uri } from 'monaco-editor';
import { editor as monacoEditor, Uri } from 'monaco-editor';
import { defaultEditorOptions } from '~/ide/lib/editor_options';
import languages from '~/ide/lib/languages';
import { DEFAULT_THEME, themes } from '~/ide/lib/themes';
import { registerLanguages } from '~/ide/utils';
import { joinPaths } from '~/lib/utils/url_utility';
import { uuids } from '~/lib/utils/uuids';
......@@ -11,7 +10,7 @@ import {
EDITOR_READY_EVENT,
EDITOR_TYPE_DIFF,
} from './constants';
import { clearDomElement } from './utils';
import { clearDomElement, setupEditorTheme, getBlobLanguage } from './utils';
export default class SourceEditor {
constructor(options = {}) {
......@@ -22,26 +21,11 @@ export default class SourceEditor {
...options,
};
SourceEditor.setupMonacoTheme();
setupEditorTheme();
registerLanguages(...languages);
}
static setupMonacoTheme() {
const themeName = window.gon?.user_color_scheme || DEFAULT_THEME;
const theme = themes.find((t) => t.name === themeName);
if (theme) monacoEditor.defineTheme(themeName, theme.data);
monacoEditor.setTheme(theme ? themeName : DEFAULT_THEME);
}
static getModelLanguage(path) {
const ext = `.${path.split('.').pop()}`;
const language = monacoLanguages
.getLanguages()
.find((lang) => lang.extensions.indexOf(ext) !== -1);
return language ? language.id : 'plaintext';
}
static pushToImportsArray(arr, toImport) {
arr.push(import(toImport));
}
......@@ -124,10 +108,7 @@ export default class SourceEditor {
return model;
}
const diffModel = {
original: monacoEditor.createModel(
blobOriginalContent,
SourceEditor.getModelLanguage(model.uri.path),
),
original: monacoEditor.createModel(blobOriginalContent, getBlobLanguage(model.uri.path)),
modified: model,
};
instance.setModel(diffModel);
......@@ -155,7 +136,7 @@ export default class SourceEditor {
};
static instanceUpdateLanguage(inst, path) {
const lang = SourceEditor.getModelLanguage(path);
const lang = getBlobLanguage(path);
const model = inst.getModel();
return monacoEditor.setModelLanguage(model, lang);
}
......
import { editor as monacoEditor, languages as monacoLanguages } from 'monaco-editor';
import { DEFAULT_THEME, themes } from '~/ide/lib/themes';
export const clearDomElement = (el) => {
if (!el || !el.firstChild) return;
......@@ -6,6 +9,22 @@ export const clearDomElement = (el) => {
}
};
export default () => ({
clearDomElement,
});
export const setupEditorTheme = () => {
const themeName = window.gon?.user_color_scheme || DEFAULT_THEME;
const theme = themes.find((t) => t.name === themeName);
if (theme) monacoEditor.defineTheme(themeName, theme.data);
monacoEditor.setTheme(theme ? themeName : DEFAULT_THEME);
};
export const getBlobLanguage = (path) => {
const ext = `.${path.split('.').pop()}`;
const language = monacoLanguages
.getLanguages()
.find((lang) => lang.extensions.indexOf(ext) !== -1);
return language ? language.id : 'plaintext';
};
export const setupCodeSnippet = (el) => {
monacoEditor.colorizeElement(el);
setupEditorTheme();
};
import { editor as monacoEditor } from 'monaco-editor';
import * as utils from '~/editor/utils';
import { DEFAULT_THEME } from '~/ide/lib/themes';
describe('Source Editor utils', () => {
let el;
const stubUserColorScheme = (value) => {
if (window.gon == null) {
window.gon = {};
}
window.gon.user_color_scheme = value;
};
describe('clearDomElement', () => {
beforeEach(() => {
setFixtures('<div id="foo"><div id="bar">Foo</div></div>');
el = document.getElementById('foo');
});
it('removes all child nodes from an element', () => {
expect(el.children.length).toBe(1);
utils.clearDomElement(el);
expect(el.children.length).toBe(0);
});
});
describe('setupEditorTheme', () => {
beforeEach(() => {
jest.spyOn(monacoEditor, 'defineTheme').mockImplementation();
jest.spyOn(monacoEditor, 'setTheme').mockImplementation();
});
it.each`
themeName | expectedThemeName
${'solarized-light'} | ${'solarized-light'}
${DEFAULT_THEME} | ${DEFAULT_THEME}
${'non-existent'} | ${DEFAULT_THEME}
`(
'sets the $expectedThemeName theme when $themeName is set in the user preference',
({ themeName, expectedThemeName }) => {
stubUserColorScheme(themeName);
utils.setupEditorTheme();
expect(monacoEditor.setTheme).toHaveBeenCalledWith(expectedThemeName);
},
);
});
describe('getBlobLanguage', () => {
it.each`
path | expectedLanguage
${'foo.js'} | ${'javascript'}
${'foo.js.rb'} | ${'ruby'}
${'foo.bar'} | ${'plaintext'}
`(
'sets the $expectedThemeName theme when $themeName is set in the user preference',
({ path, expectedLanguage }) => {
const language = utils.getBlobLanguage(path);
expect(language).toEqual(expectedLanguage);
},
);
});
describe('setupCodeSnipet', () => {
beforeEach(() => {
jest.spyOn(monacoEditor, 'colorizeElement').mockImplementation();
jest.spyOn(monacoEditor, 'setTheme').mockImplementation();
setFixtures('<pre id="foo"></pre>');
el = document.getElementById('foo');
});
it('colorizes the element and applies the preference theme', () => {
expect(monacoEditor.colorizeElement).not.toHaveBeenCalled();
expect(monacoEditor.setTheme).not.toHaveBeenCalled();
utils.setupCodeSnippet(el);
expect(monacoEditor.colorizeElement).toHaveBeenCalledWith(el);
expect(monacoEditor.setTheme).toHaveBeenCalled();
});
});
});
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment