Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhil Hughes <me@iamphill.com>2017-11-21 17:22:33 +0300
committerPhil Hughes <me@iamphill.com>2017-11-28 12:23:41 +0300
commiteb8a609519fe45b13aa945e36637381741313aed (patch)
tree8f67be9e4c11f69a593b1d54563651b579db7628 /app/assets/javascripts/repo
parentc90b520d793be1a1f69811aafdeff00e4f463346 (diff)
added disposable manager
added model manager [ci skip]
Diffstat (limited to 'app/assets/javascripts/repo')
-rw-r--r--app/assets/javascripts/repo/components/repo_editor.vue14
-rw-r--r--app/assets/javascripts/repo/lib/common/disposable.js14
-rw-r--r--app/assets/javascripts/repo/lib/common/model.js66
-rw-r--r--app/assets/javascripts/repo/lib/common/model_manager.js31
-rw-r--r--app/assets/javascripts/repo/lib/decorations/controller.js2
-rw-r--r--app/assets/javascripts/repo/lib/diff/controller.js25
-rw-r--r--app/assets/javascripts/repo/lib/diff/worker.js39
-rw-r--r--app/assets/javascripts/repo/lib/editor.js41
8 files changed, 152 insertions, 80 deletions
diff --git a/app/assets/javascripts/repo/components/repo_editor.vue b/app/assets/javascripts/repo/components/repo_editor.vue
index e0ce8a97665..8772b45669f 100644
--- a/app/assets/javascripts/repo/components/repo_editor.vue
+++ b/app/assets/javascripts/repo/components/repo_editor.vue
@@ -3,13 +3,15 @@
import { mapGetters, mapActions } from 'vuex';
import flash from '../../flash';
import monacoLoader from '../monaco_loader';
-import editor from '../lib/editor';
+import Editor from '../lib/editor';
export default {
destroyed() {
- editor.dispose();
+ this.editor.dispose();
},
mounted() {
+ this.editor = Editor.create();
+
if (this.monaco) {
this.initMonaco();
} else {
@@ -26,11 +28,11 @@ export default {
initMonaco() {
if (this.shouldHideEditor) return;
- editor.clearEditor();
+ this.editor.clearEditor();
this.getRawFileData(this.activeFile)
.then(() => {
- editor.createInstance(this.$el);
+ this.editor.createInstance(this.$el);
})
.then(() => this.setupEditor())
.catch(() => flash('Error setting up monaco. Please try again.'));
@@ -38,9 +40,9 @@ export default {
setupEditor() {
if (!this.activeFile) return;
- const model = editor.createModel(this.activeFile);
+ const model = this.editor.createModel(this.activeFile);
- editor.attachModel(model);
+ this.editor.attachModel(model);
model.onChange((m) => {
this.changeFileContent({
file: this.activeFile,
diff --git a/app/assets/javascripts/repo/lib/common/disposable.js b/app/assets/javascripts/repo/lib/common/disposable.js
new file mode 100644
index 00000000000..84b29bdb600
--- /dev/null
+++ b/app/assets/javascripts/repo/lib/common/disposable.js
@@ -0,0 +1,14 @@
+export default class Disposable {
+ constructor() {
+ this.disposers = new Set();
+ }
+
+ add(...disposers) {
+ disposers.forEach(disposer => this.disposers.add(disposer));
+ }
+
+ dispose() {
+ this.disposers.forEach(disposer => disposer.dispose());
+ this.disposers.clear();
+ }
+}
diff --git a/app/assets/javascripts/repo/lib/common/model.js b/app/assets/javascripts/repo/lib/common/model.js
index 77d36b4f52c..75828bfb09d 100644
--- a/app/assets/javascripts/repo/lib/common/model.js
+++ b/app/assets/javascripts/repo/lib/common/model.js
@@ -1,26 +1,59 @@
/* global monaco */
+import Disposable from './disposable';
export default class Model {
constructor(file) {
+ this.disposable = new Disposable();
this.file = file;
this.content = file.content !== '' ? file.content : file.raw;
- this.originalModel = monaco.editor.createModel(
- this.content,
- undefined,
- new monaco.Uri(null, null, `original/${this.file.path}`),
- );
- this.model = monaco.editor.createModel(
- this.content,
- undefined,
- new monaco.Uri(null, null, this.file.path),
+
+ this.disposable.add(
+ this.originalModel = monaco.editor.createModel(
+ this.content,
+ undefined,
+ new monaco.Uri(null, null, `original/${this.file.path}`),
+ ),
+ this.model = monaco.editor.createModel(
+ this.content,
+ undefined,
+ new monaco.Uri(null, null, this.file.path),
+ ),
);
- this.disposers = new Map();
+
+ this.attachedToWorker = false;
+ this.events = new Map();
}
get url() {
return this.model.uri.toString();
}
+ get originalUrl() {
+ return this.originalModel.uri.toString();
+ }
+
+ get path() {
+ return this.file.path;
+ }
+
+ get diffModel() {
+ return {
+ url: this.model.uri.toString(),
+ versionId: this.model.getVersionId(),
+ lines: this.model.getLinesContent(),
+ EOL: '\n',
+ };
+ }
+
+ get originalDiffModel() {
+ return {
+ url: this.originalModel.uri.toString(),
+ versionId: this.originalModel.getVersionId(),
+ lines: this.originalModel.getLinesContent(),
+ EOL: '\n',
+ };
+ }
+
getModel() {
return this.model;
}
@@ -29,18 +62,21 @@ export default class Model {
return this.originalModel;
}
+ setAttachedToWorker(val) {
+ this.attachedToWorker = val;
+ }
+
onChange(cb) {
- this.disposers.set(
+ this.events.set(
this.file.path,
this.model.onDidChangeContent(e => cb(this.model, e)),
);
}
dispose() {
- this.model.dispose();
- this.originalModel.dispose();
+ this.disposable.dispose();
- this.disposers.forEach(disposer => disposer.dispose());
- this.disposers.clear();
+ this.events.forEach(disposer => disposer.dispose());
+ this.events.clear();
}
}
diff --git a/app/assets/javascripts/repo/lib/common/model_manager.js b/app/assets/javascripts/repo/lib/common/model_manager.js
new file mode 100644
index 00000000000..fdb1e148681
--- /dev/null
+++ b/app/assets/javascripts/repo/lib/common/model_manager.js
@@ -0,0 +1,31 @@
+import Disposable from './disposable';
+import Model from './model';
+
+export default class ModelManager {
+ constructor() {
+ this.disposable = new Disposable();
+ this.models = new Map();
+ }
+
+ hasCachedModel(path) {
+ return this.models.has(path);
+ }
+
+ addModel(file) {
+ if (this.hasCachedModel(file.path)) {
+ return this.models.get(file.path);
+ }
+
+ const model = new Model(file);
+ this.models.set(model.path, model);
+ this.disposable.add(model);
+
+ return model;
+ }
+
+ dispose() {
+ // dispose of all the models
+ this.disposable.dispose();
+ this.models.clear();
+ }
+}
diff --git a/app/assets/javascripts/repo/lib/decorations/controller.js b/app/assets/javascripts/repo/lib/decorations/controller.js
index 0ab74f1ebdf..eb369dbbfe1 100644
--- a/app/assets/javascripts/repo/lib/decorations/controller.js
+++ b/app/assets/javascripts/repo/lib/decorations/controller.js
@@ -33,7 +33,7 @@ class DecorationsController {
this.editorDecorations.set(
model.url,
- editor.instance.deltaDecorations(oldDecorations, decorations),
+ editor.editorInstance.instance.deltaDecorations(oldDecorations, decorations),
);
}
diff --git a/app/assets/javascripts/repo/lib/diff/controller.js b/app/assets/javascripts/repo/lib/diff/controller.js
index 77d07b730cf..39c6cb92e0f 100644
--- a/app/assets/javascripts/repo/lib/diff/controller.js
+++ b/app/assets/javascripts/repo/lib/diff/controller.js
@@ -1,4 +1,5 @@
/* global monaco */
+import Disposable from '../common/disposable';
import DirtyDiffWorker from './worker';
import decorationsController from '../decorations/controller';
@@ -32,27 +33,21 @@ export const decorate = (model, changes) => {
};
export default class DirtyDiffController {
- constructor() {
+ constructor(modelManager) {
+ this.disposable = new Disposable();
this.editorSimpleWorker = null;
- this.models = new Map();
- this.worker = new DirtyDiffWorker();
+ this.modelManager = modelManager;
+ this.disposable.add(this.worker = new DirtyDiffWorker());
}
attachModel(model) {
- if (this.models.has(model.getModel().uri.toString())) return;
+ if (model.attachedToWorker) return;
- [model.getModel(), model.getOriginalModel()].forEach((iModel) => {
- this.worker.attachModel({
- url: iModel.uri.toString(),
- versionId: iModel.getVersionId(),
- lines: iModel.getLinesContent(),
- EOL: '\n',
- });
+ [model.getModel(), model.getOriginalModel()].forEach(() => {
+ this.worker.attachModel(model);
});
model.onChange((_, e) => this.computeDiff(model, e));
-
- this.models.set(model.getModel().uri.toString(), model);
}
computeDiff(model, e) {
@@ -66,8 +61,6 @@ export default class DirtyDiffController {
}
dispose() {
- this.models.clear();
- this.worker.dispose();
- decorationsController.dispose();
+ this.disposable.dispose();
}
}
diff --git a/app/assets/javascripts/repo/lib/diff/worker.js b/app/assets/javascripts/repo/lib/diff/worker.js
index 93d94f8d138..39047d85507 100644
--- a/app/assets/javascripts/repo/lib/diff/worker.js
+++ b/app/assets/javascripts/repo/lib/diff/worker.js
@@ -1,15 +1,17 @@
/* global monaco */
+import Disposable from '../common/disposable';
+
export default class DirtyDiffWorker {
constructor() {
this.editorSimpleWorker = null;
- this.models = new Map();
+ this.disposable = new Disposable();
this.actions = new Set();
// eslint-disable-next-line promise/catch-or-return
monaco.editor.createWebWorker({
moduleId: 'vs/editor/common/services/editorSimpleWorker',
}).getProxy().then((editorSimpleWorker) => {
- this.editorSimpleWorker = editorSimpleWorker;
+ this.disposable.add(this.editorSimpleWorker = editorSimpleWorker);
this.ready();
});
}
@@ -26,10 +28,11 @@ export default class DirtyDiffWorker {
}
attachModel(model) {
- if (this.editorSimpleWorker && !this.models.has(model.url)) {
- this.editorSimpleWorker.acceptNewModel(model);
+ if (this.editorSimpleWorker && !model.attachedToWorker) {
+ this.editorSimpleWorker.acceptNewModel(model.diffModel);
+ this.editorSimpleWorker.acceptNewModel(model.originalDiffModel);
- this.models.set(model.url, model);
+ model.setAttachedToWorker(true);
} else if (!this.editorSimpleWorker) {
this.actions.add({
attachModel: [model],
@@ -40,7 +43,7 @@ export default class DirtyDiffWorker {
modelChanged(model, e) {
if (this.editorSimpleWorker) {
this.editorSimpleWorker.acceptModelChanged(
- model.getModel().uri.toString(),
+ model.url,
e,
);
} else {
@@ -52,27 +55,23 @@ export default class DirtyDiffWorker {
compute(model, cb) {
if (this.editorSimpleWorker) {
- // eslint-disable-next-line promise/catch-or-return
- this.editorSimpleWorker.computeDiff(
- model.getOriginalModel().uri.toString(),
- model.getModel().uri.toString(),
+ return this.editorSimpleWorker.computeDiff(
+ model.originalUrl,
+ model.url,
).then(cb);
- } else {
- this.actions.add({
- compute: [model, cb],
- });
}
+
+ this.actions.add({
+ compute: [model, cb],
+ });
+
+ return null;
}
dispose() {
- this.models.forEach(model =>
- this.editorSimpleWorker.acceptRemovedModel(model.url),
- );
- this.models.clear();
-
this.actions.clear();
- this.editorSimpleWorker.dispose();
+ this.disposable.dispose();
this.editorSimpleWorker = null;
}
}
diff --git a/app/assets/javascripts/repo/lib/editor.js b/app/assets/javascripts/repo/lib/editor.js
index de1c6d61b10..173eacbd65c 100644
--- a/app/assets/javascripts/repo/lib/editor.js
+++ b/app/assets/javascripts/repo/lib/editor.js
@@ -1,14 +1,24 @@
/* global monaco */
import DirtyDiffController from './diff/controller';
-import Model from './common/model';
+import Disposable from './common/disposable';
+import ModelManager from './common/model_manager';
+
+export default class Editor {
+ static create() {
+ this.editorInstance = new Editor();
+
+ return this.editorInstance;
+ }
-class Editor {
constructor() {
- this.models = new Map();
this.diffComputers = new Map();
this.currentModel = null;
this.instance = null;
this.dirtyDiffController = null;
+ this.modelManager = new ModelManager();
+ this.disposable = new Disposable();
+
+ this.disposable.add(this.modelManager);
}
createInstance(domElement) {
@@ -20,19 +30,14 @@ class Editor {
scrollBeyondLastLine: false,
});
- this.dirtyDiffController = new DirtyDiffController();
+ this.dirtyDiffController = new DirtyDiffController(this.modelManager);
+
+ this.disposable.add(this.dirtyDiffController, this.instance);
}
}
createModel(file) {
- if (this.models.has(file.path)) {
- return this.models.get(file.path);
- }
-
- const model = new Model(file);
- this.models.set(file.path, model);
-
- return model;
+ return this.modelManager.addModel(file);
}
attachModel(model) {
@@ -51,19 +56,11 @@ class Editor {
}
dispose() {
+ this.disposable.dispose();
+
// dispose main monaco instance
if (this.instance) {
- this.instance.dispose();
this.instance = null;
}
-
- // dispose of all the models
- this.models.forEach(model => model.dispose());
- this.models.clear();
-
- this.dirtyDiffController.dispose();
- this.dirtyDiffController = null;
}
}
-
-export default new Editor();