gitlab-org--gitlab-foss/app/assets/javascripts/ide/components/repo_editor.vue

168 lines
3.9 KiB
Vue
Raw Normal View History

<script>
/* global monaco */
2018-03-25 08:02:09 -04:00
import { mapState, mapGetters, mapActions } from 'vuex';
import flash from '~/flash';
import monacoLoader from '../monaco_loader';
import Editor from '../lib/editor';
export default {
props: {
file: {
type: Object,
required: true,
},
},
computed: {
2018-03-25 14:16:20 -04:00
...mapState(['leftPanelCollapsed', 'rightPanelCollapsed', 'viewer', 'delayViewerUpdated']),
2018-03-25 08:02:09 -04:00
...mapGetters(['currentMergeRequest']),
shouldHideEditor() {
return this.file && this.file.binary && !this.file.raw;
},
},
watch: {
file(oldVal, newVal) {
// Compare key to allow for files opened in review mode to be cached differently
2018-03-23 04:41:43 -04:00
if (newVal.key !== this.file.key) {
this.initMonaco();
}
},
leftPanelCollapsed() {
this.editor.updateDimensions();
},
rightPanelCollapsed() {
this.editor.updateDimensions();
},
viewer() {
this.createEditorInstance();
},
},
beforeDestroy() {
this.editor.dispose();
},
mounted() {
if (this.editor && monaco) {
this.initMonaco();
} else {
monacoLoader(['vs/editor/editor.main'], () => {
this.editor = Editor.create(monaco);
this.initMonaco();
});
}
},
methods: {
...mapActions([
'getRawFileData',
'changeFileContent',
'setFileLanguage',
'setEditorPosition',
'setFileEOL',
'updateViewer',
'updateDelayViewerUpdated',
]),
initMonaco() {
if (this.shouldHideEditor) return;
this.editor.clearEditor();
2018-03-25 08:02:09 -04:00
this.getRawFileData({
path: this.file.path,
2018-03-25 14:16:20 -04:00
baseSha: this.currentMergeRequest ? this.currentMergeRequest.baseCommitSha : '',
2018-03-25 08:02:09 -04:00
})
.then(() => {
2018-03-23 04:41:43 -04:00
const viewerPromise = this.delayViewerUpdated
2018-03-23 07:37:34 -04:00
? this.updateViewer(this.file.pending ? 'diff' : 'editor')
2018-03-23 04:41:43 -04:00
: Promise.resolve();
return viewerPromise;
})
.then(() => {
this.updateDelayViewerUpdated(false);
this.createEditorInstance();
})
2018-03-23 04:41:43 -04:00
.catch(err => {
2018-03-25 14:16:20 -04:00
flash('Error setting up monaco. Please try again.', 'alert', document, null, false, true);
throw err;
});
},
createEditorInstance() {
this.editor.dispose();
this.$nextTick(() => {
if (this.viewer === 'editor') {
this.editor.createInstance(this.$refs.editor);
} else {
this.editor.createDiffInstance(this.$refs.editor);
}
this.setupEditor();
});
},
setupEditor() {
if (!this.file || !this.editor.instance) return;
this.model = this.editor.createModel(this.file);
2018-03-23 06:45:43 -04:00
if (this.viewer === 'mrdiff') {
this.editor.attachMergeRequestModel(this.model);
} else {
this.editor.attachModel(this.model);
}
2018-03-23 04:41:43 -04:00
this.model.onChange(model => {
const { file } = model;
if (file.active) {
this.changeFileContent({
path: file.path,
content: model.getModel().getValue(),
});
}
});
// Handle Cursor Position
this.editor.onPositionChange((instance, e) => {
this.setEditorPosition({
editorRow: e.position.lineNumber,
editorColumn: e.position.column,
});
});
this.editor.setPosition({
lineNumber: this.file.editorRow,
column: this.file.editorColumn,
});
// Handle File Language
this.setFileLanguage({
fileLanguage: this.model.language,
});
// Get File eol
this.setFileEOL({
eol: this.model.eol,
});
},
},
};
</script>
<template>
<div
id="ide"
class="blob-viewer-container blob-editor-container"
>
<div
v-if="shouldHideEditor"
v-html="file.html"
>
</div>
<div
v-show="!shouldHideEditor"
ref="editor"
class="multi-file-editor-holder"
>
</div>
</div>
</template>