diff options
Diffstat (limited to 'app/assets/javascripts/editor')
-rw-r--r-- | app/assets/javascripts/editor/constants.js | 9 | ||||
-rw-r--r-- | app/assets/javascripts/editor/editor_lite.js | 28 | ||||
-rw-r--r-- | app/assets/javascripts/editor/extensions/editor_ci_schema_ext.js | 38 | ||||
-rw-r--r-- | app/assets/javascripts/editor/extensions/editor_file_template_ext.js (renamed from app/assets/javascripts/editor/editor_file_template_ext.js) | 0 | ||||
-rw-r--r-- | app/assets/javascripts/editor/extensions/editor_lite_extension_base.js (renamed from app/assets/javascripts/editor/editor_lite_extension_base.js) | 2 | ||||
-rw-r--r-- | app/assets/javascripts/editor/extensions/editor_markdown_ext.js (renamed from app/assets/javascripts/editor/editor_markdown_ext.js) | 2 | ||||
-rw-r--r-- | app/assets/javascripts/editor/utils.js | 2 |
7 files changed, 64 insertions, 17 deletions
diff --git a/app/assets/javascripts/editor/constants.js b/app/assets/javascripts/editor/constants.js index d6f87872bde..8d1a3d17c6e 100644 --- a/app/assets/javascripts/editor/constants.js +++ b/app/assets/javascripts/editor/constants.js @@ -10,3 +10,12 @@ export const CONTENT_UPDATE_DEBOUNCE = 250; export const ERROR_INSTANCE_REQUIRED_FOR_EXTENSION = __( 'Editor Lite instance is required to set up an extension.', ); + +// +// EXTENSIONS' CONSTANTS +// + +// For CI config schemas the filename must match +// '*.gitlab-ci.yml' regardless of project configuration. +// https://gitlab.com/gitlab-org/gitlab/-/issues/293641 +export const EXTENSION_CI_SCHEMA_FILE_NAME_MATCH = '.gitlab-ci.yml'; diff --git a/app/assets/javascripts/editor/editor_lite.js b/app/assets/javascripts/editor/editor_lite.js index 2bd1cdc84d0..1808f968b8c 100644 --- a/app/assets/javascripts/editor/editor_lite.js +++ b/app/assets/javascripts/editor/editor_lite.js @@ -24,7 +24,7 @@ export default class EditorLite { static setupMonacoTheme() { const themeName = window.gon?.user_color_scheme || DEFAULT_THEME; - const theme = themes.find(t => t.name === themeName); + const theme = themes.find((t) => t.name === themeName); if (theme) monacoEditor.defineTheme(themeName, theme.data); monacoEditor.setTheme(theme ? themeName : DEFAULT_THEME); } @@ -35,7 +35,7 @@ export default class EditorLite { const ext = `.${path.split('.').pop()}`; const language = monacoLanguages .getLanguages() - .find(lang => lang.extensions.indexOf(ext) !== -1); + .find((lang) => lang.extensions.indexOf(ext) !== -1); const id = language ? language.id : 'plaintext'; monacoEditor.setModelLanguage(model, id); } @@ -51,7 +51,7 @@ export default class EditorLite { const promises = []; const extensionsArray = typeof extensions === 'string' ? extensions.split(',') : extensions; - extensionsArray.forEach(ext => { + extensionsArray.forEach((ext) => { const prefix = ext.includes('/') ? '' : 'editor/'; const trimmedExt = ext.replace(/^\//, '').trim(); EditorLite.pushToImportsArray(promises, `~/${prefix}${trimmedExt}`); @@ -66,7 +66,7 @@ export default class EditorLite { } const isClassInstance = source.constructor.prototype !== Object.prototype; const sanitizedSource = isClassInstance ? source.constructor.prototype : source; - Object.getOwnPropertyNames(sanitizedSource).forEach(prop => { + Object.getOwnPropertyNames(sanitizedSource).forEach((prop) => { if (prop !== 'constructor') { Object.assign(inst, { [prop]: source[prop] }); } @@ -110,17 +110,17 @@ export default class EditorLite { }); instance.setModel(model); instance.onDidDispose(() => { - const index = this.instances.findIndex(inst => inst === instance); + const index = this.instances.findIndex((inst) => inst === instance); this.instances.splice(index, 1); model.dispose(); }); - instance.updateModelLanguage = path => EditorLite.updateModelLanguage(path, instance); - instance.use = args => this.use(args, instance); + instance.updateModelLanguage = (path) => EditorLite.updateModelLanguage(path, instance); + instance.use = (args) => this.use(args, instance); EditorLite.loadExtensions(extensions, instance) - .then(modules => { + .then((modules) => { if (modules) { - modules.forEach(module => { + modules.forEach((module) => { instance.use(module.default); }); } @@ -128,7 +128,7 @@ export default class EditorLite { .then(() => { el.dispatchEvent(new Event('editor-ready')); }) - .catch(e => { + .catch((e) => { throw e; }); @@ -137,20 +137,20 @@ export default class EditorLite { } dispose() { - this.instances.forEach(instance => instance.dispose()); + this.instances.forEach((instance) => instance.dispose()); } use(exts = [], instance = null) { const extensions = Array.isArray(exts) ? exts : [exts]; - const initExtensions = inst => { - extensions.forEach(extension => { + const initExtensions = (inst) => { + extensions.forEach((extension) => { EditorLite.mixIntoInstance(extension, inst); }); }; if (instance) { initExtensions(instance); } else { - this.instances.forEach(inst => { + this.instances.forEach((inst) => { initExtensions(inst); }); } diff --git a/app/assets/javascripts/editor/extensions/editor_ci_schema_ext.js b/app/assets/javascripts/editor/extensions/editor_ci_schema_ext.js new file mode 100644 index 00000000000..eb47c20912e --- /dev/null +++ b/app/assets/javascripts/editor/extensions/editor_ci_schema_ext.js @@ -0,0 +1,38 @@ +import Api from '~/api'; +import { registerSchema } from '~/ide/utils'; +import { EditorLiteExtension } from './editor_lite_extension_base'; +import { EXTENSION_CI_SCHEMA_FILE_NAME_MATCH } from '../constants'; + +export class CiSchemaExtension extends EditorLiteExtension { + /** + * Registers a syntax schema to the editor based on project + * identifier and commit. + * + * The schema is added to the file that is currently edited + * in the editor. + * + * @param {Object} opts + * @param {String} opts.projectNamespace + * @param {String} opts.projectPath + * @param {String?} opts.ref - Current ref. Defaults to master + */ + registerCiSchema({ projectNamespace, projectPath, ref = 'master' } = {}) { + const ciSchemaPath = Api.buildUrl(Api.projectFileSchemaPath) + .replace(':namespace_path', projectNamespace) + .replace(':project_path', projectPath) + .replace(':ref', ref) + .replace(':filename', EXTENSION_CI_SCHEMA_FILE_NAME_MATCH); + // In order for workers loaded from `data://` as the + // ones loaded by monaco editor, we use absolute URLs + // to fetch schema files, hence the `gon.gitlab_url` + // reference. This prevents error: + // "Failed to execute 'fetch' on 'WorkerGlobalScope'" + const absoluteSchemaUrl = gon.gitlab_url + ciSchemaPath; + const modelFileName = this.getModel().uri.path.split('/').pop(); + + registerSchema({ + uri: absoluteSchemaUrl, + fileMatch: [modelFileName], + }); + } +} diff --git a/app/assets/javascripts/editor/editor_file_template_ext.js b/app/assets/javascripts/editor/extensions/editor_file_template_ext.js index f5474318447..f5474318447 100644 --- a/app/assets/javascripts/editor/editor_file_template_ext.js +++ b/app/assets/javascripts/editor/extensions/editor_file_template_ext.js diff --git a/app/assets/javascripts/editor/editor_lite_extension_base.js b/app/assets/javascripts/editor/extensions/editor_lite_extension_base.js index b8d87fa4969..8d350068973 100644 --- a/app/assets/javascripts/editor/editor_lite_extension_base.js +++ b/app/assets/javascripts/editor/extensions/editor_lite_extension_base.js @@ -1,4 +1,4 @@ -import { ERROR_INSTANCE_REQUIRED_FOR_EXTENSION } from './constants'; +import { ERROR_INSTANCE_REQUIRED_FOR_EXTENSION } from '../constants'; export class EditorLiteExtension { constructor({ instance, ...options } = {}) { diff --git a/app/assets/javascripts/editor/editor_markdown_ext.js b/app/assets/javascripts/editor/extensions/editor_markdown_ext.js index 19e0037c175..2ce003753f7 100644 --- a/app/assets/javascripts/editor/editor_markdown_ext.js +++ b/app/assets/javascripts/editor/extensions/editor_markdown_ext.js @@ -76,7 +76,7 @@ export class EditorMarkdownExtension extends EditorLiteExtension { if (textLines.length > 1) { // Multi-line selection - lineShift = textLines.findIndex(line => line.indexOf(toSelect) !== -1); + lineShift = textLines.findIndex((line) => line.indexOf(toSelect) !== -1); newStartLineNumber = currentSelection.startLineNumber + lineShift; newStartColumn = textLines[lineShift].indexOf(toSelect) + 1; } else { diff --git a/app/assets/javascripts/editor/utils.js b/app/assets/javascripts/editor/utils.js index d8b6396b671..af4473413f4 100644 --- a/app/assets/javascripts/editor/utils.js +++ b/app/assets/javascripts/editor/utils.js @@ -1,4 +1,4 @@ -export const clearDomElement = el => { +export const clearDomElement = (el) => { if (!el || !el.firstChild) return; while (el.firstChild) { |