summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/editor
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/editor')
-rw-r--r--app/assets/javascripts/editor/constants.js9
-rw-r--r--app/assets/javascripts/editor/editor_lite.js28
-rw-r--r--app/assets/javascripts/editor/extensions/editor_ci_schema_ext.js38
-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.js2
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) {