diff options
Diffstat (limited to 'app/assets/javascripts/editor')
5 files changed, 54 insertions, 16 deletions
diff --git a/app/assets/javascripts/editor/constants.js b/app/assets/javascripts/editor/constants.js index b02eb37206a..d6f87872bde 100644 --- a/app/assets/javascripts/editor/constants.js +++ b/app/assets/javascripts/editor/constants.js @@ -6,3 +6,7 @@ export const EDITOR_LITE_INSTANCE_ERROR_NO_EL = __( export const URI_PREFIX = 'gitlab'; export const CONTENT_UPDATE_DEBOUNCE = 250; + +export const ERROR_INSTANCE_REQUIRED_FOR_EXTENSION = __( + 'Editor Lite instance is required to set up an extension.', +); diff --git a/app/assets/javascripts/editor/editor_file_template_ext.js b/app/assets/javascripts/editor/editor_file_template_ext.js index 343908b831d..f5474318447 100644 --- a/app/assets/javascripts/editor/editor_file_template_ext.js +++ b/app/assets/javascripts/editor/editor_file_template_ext.js @@ -1,7 +1,8 @@ import { Position } from 'monaco-editor'; +import { EditorLiteExtension } from './editor_lite_extension_base'; -export default { +export class FileTemplateExtension extends EditorLiteExtension { navigateFileStart() { this.setPosition(new Position(1, 1)); - }, -}; + } +} diff --git a/app/assets/javascripts/editor/editor_lite.js b/app/assets/javascripts/editor/editor_lite.js index e7535c211db..2bd1cdc84d0 100644 --- a/app/assets/javascripts/editor/editor_lite.js +++ b/app/assets/javascripts/editor/editor_lite.js @@ -8,7 +8,7 @@ import { clearDomElement } from './utils'; import { EDITOR_LITE_INSTANCE_ERROR_NO_EL, URI_PREFIX } from './constants'; import { uuids } from '~/diffs/utils/uuids'; -export default class Editor { +export default class EditorLite { constructor(options = {}) { this.instances = []; this.options = { @@ -17,7 +17,7 @@ export default class Editor { ...options, }; - Editor.setupMonacoTheme(); + EditorLite.setupMonacoTheme(); registerLanguages(...languages); } @@ -54,12 +54,25 @@ export default class Editor { extensionsArray.forEach(ext => { const prefix = ext.includes('/') ? '' : 'editor/'; const trimmedExt = ext.replace(/^\//, '').trim(); - Editor.pushToImportsArray(promises, `~/${prefix}${trimmedExt}`); + EditorLite.pushToImportsArray(promises, `~/${prefix}${trimmedExt}`); }); return Promise.all(promises); } + static mixIntoInstance(source, inst) { + if (!inst) { + return; + } + const isClassInstance = source.constructor.prototype !== Object.prototype; + const sanitizedSource = isClassInstance ? source.constructor.prototype : source; + Object.getOwnPropertyNames(sanitizedSource).forEach(prop => { + if (prop !== 'constructor') { + Object.assign(inst, { [prop]: source[prop] }); + } + }); + } + /** * Creates a monaco instance with the given options. * @@ -101,10 +114,10 @@ export default class Editor { this.instances.splice(index, 1); model.dispose(); }); - instance.updateModelLanguage = path => Editor.updateModelLanguage(path, instance); + instance.updateModelLanguage = path => EditorLite.updateModelLanguage(path, instance); instance.use = args => this.use(args, instance); - Editor.loadExtensions(extensions, instance) + EditorLite.loadExtensions(extensions, instance) .then(modules => { if (modules) { modules.forEach(module => { @@ -129,10 +142,17 @@ export default class Editor { use(exts = [], instance = null) { const extensions = Array.isArray(exts) ? exts : [exts]; + const initExtensions = inst => { + extensions.forEach(extension => { + EditorLite.mixIntoInstance(extension, inst); + }); + }; if (instance) { - Object.assign(instance, ...extensions); + initExtensions(instance); } else { - this.instances.forEach(inst => Object.assign(inst, ...extensions)); + this.instances.forEach(inst => { + initExtensions(inst); + }); } } } diff --git a/app/assets/javascripts/editor/editor_lite_extension_base.js b/app/assets/javascripts/editor/editor_lite_extension_base.js new file mode 100644 index 00000000000..b8d87fa4969 --- /dev/null +++ b/app/assets/javascripts/editor/editor_lite_extension_base.js @@ -0,0 +1,11 @@ +import { ERROR_INSTANCE_REQUIRED_FOR_EXTENSION } from './constants'; + +export class EditorLiteExtension { + constructor({ instance, ...options } = {}) { + if (instance) { + Object.assign(instance, options); + } else if (Object.entries(options).length) { + throw new Error(ERROR_INSTANCE_REQUIRED_FOR_EXTENSION); + } + } +} diff --git a/app/assets/javascripts/editor/editor_markdown_ext.js b/app/assets/javascripts/editor/editor_markdown_ext.js index c46f5736912..19e0037c175 100644 --- a/app/assets/javascripts/editor/editor_markdown_ext.js +++ b/app/assets/javascripts/editor/editor_markdown_ext.js @@ -1,4 +1,6 @@ -export default { +import { EditorLiteExtension } from './editor_lite_extension_base'; + +export class EditorMarkdownExtension extends EditorLiteExtension { getSelectedText(selection = this.getSelection()) { const { startLineNumber, endLineNumber, startColumn, endColumn } = selection; const valArray = this.getValue().split('\n'); @@ -18,19 +20,19 @@ export default { : [startLineText, endLineText].join('\n'); } return text; - }, + } replaceSelectedText(text, select = undefined) { const forceMoveMarkers = !select; this.executeEdits('', [{ range: this.getSelection(), text, forceMoveMarkers }]); - }, + } moveCursor(dx = 0, dy = 0) { const pos = this.getPosition(); pos.column += dx; pos.lineNumber += dy; this.setPosition(pos); - }, + } /** * Adjust existing selection to select text within the original selection. @@ -91,5 +93,5 @@ export default { .setEndPosition(newEndLineNumber, newEndColumn); this.setSelection(newSelection); - }, -}; + } +} |