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 { defaultEditorOptions } from '~/ide/lib/editor_options';
import languages from '~/ide/lib/languages'; import languages from '~/ide/lib/languages';
import { DEFAULT_THEME, themes } from '~/ide/lib/themes';
import { registerLanguages } from '~/ide/utils'; import { registerLanguages } from '~/ide/utils';
import { joinPaths } from '~/lib/utils/url_utility'; import { joinPaths } from '~/lib/utils/url_utility';
import { uuids } from '~/lib/utils/uuids'; import { uuids } from '~/lib/utils/uuids';
...@@ -11,7 +10,7 @@ import { ...@@ -11,7 +10,7 @@ import {
EDITOR_READY_EVENT, EDITOR_READY_EVENT,
EDITOR_TYPE_DIFF, EDITOR_TYPE_DIFF,
} from './constants'; } from './constants';
import { clearDomElement } from './utils'; import { clearDomElement, setupEditorTheme, getBlobLanguage } from './utils';
export default class SourceEditor { export default class SourceEditor {
constructor(options = {}) { constructor(options = {}) {
...@@ -22,26 +21,11 @@ export default class SourceEditor { ...@@ -22,26 +21,11 @@ export default class SourceEditor {
...options, ...options,
}; };
SourceEditor.setupMonacoTheme(); setupEditorTheme();
registerLanguages(...languages); 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) { static pushToImportsArray(arr, toImport) {
arr.push(import(toImport)); arr.push(import(toImport));
} }
...@@ -124,10 +108,7 @@ export default class SourceEditor { ...@@ -124,10 +108,7 @@ export default class SourceEditor {
return model; return model;
} }
const diffModel = { const diffModel = {
original: monacoEditor.createModel( original: monacoEditor.createModel(blobOriginalContent, getBlobLanguage(model.uri.path)),
blobOriginalContent,
SourceEditor.getModelLanguage(model.uri.path),
),
modified: model, modified: model,
}; };
instance.setModel(diffModel); instance.setModel(diffModel);
...@@ -155,7 +136,7 @@ export default class SourceEditor { ...@@ -155,7 +136,7 @@ export default class SourceEditor {
}; };
static instanceUpdateLanguage(inst, path) { static instanceUpdateLanguage(inst, path) {
const lang = SourceEditor.getModelLanguage(path); const lang = getBlobLanguage(path);
const model = inst.getModel(); const model = inst.getModel();
return monacoEditor.setModelLanguage(model, lang); 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) => { export const clearDomElement = (el) => {
if (!el || !el.firstChild) return; if (!el || !el.firstChild) return;
...@@ -6,6 +9,22 @@ export const clearDomElement = (el) => { ...@@ -6,6 +9,22 @@ export const clearDomElement = (el) => {
} }
}; };
export default () => ({ export const setupEditorTheme = () => {
clearDomElement, 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