From 809a27e61e070a125e2fe5183574f1bf35668a52 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Wed, 22 Nov 2017 13:39:16 +0000 Subject: started move to web worker for diff calculation --- .../javascripts/repo/components/repo_editor.vue | 6 ++-- app/assets/javascripts/repo/lib/common/model.js | 41 ++++++++++------------ .../javascripts/repo/lib/common/model_manager.js | 5 +-- .../javascripts/repo/lib/decorations/controller.js | 11 +++--- app/assets/javascripts/repo/lib/diff/controller.js | 24 +++++++------ app/assets/javascripts/repo/lib/diff/diff.js | 38 ++++++++++++++++++++ app/assets/javascripts/repo/lib/diff/worker.js | 34 ------------------ app/assets/javascripts/repo/lib/editor.js | 18 ++++++---- 8 files changed, 90 insertions(+), 87 deletions(-) create mode 100644 app/assets/javascripts/repo/lib/diff/diff.js delete mode 100644 app/assets/javascripts/repo/lib/diff/worker.js diff --git a/app/assets/javascripts/repo/components/repo_editor.vue b/app/assets/javascripts/repo/components/repo_editor.vue index 8772b45669f..fa6070dbf92 100644 --- a/app/assets/javascripts/repo/components/repo_editor.vue +++ b/app/assets/javascripts/repo/components/repo_editor.vue @@ -10,12 +10,12 @@ export default { this.editor.dispose(); }, mounted() { - this.editor = Editor.create(); - if (this.monaco) { this.initMonaco(); } else { monacoLoader(['vs/editor/editor.main'], () => { + this.editor = Editor.create(monaco); + this.initMonaco(); }); } @@ -35,7 +35,7 @@ export default { this.editor.createInstance(this.$el); }) .then(() => this.setupEditor()) - .catch(() => flash('Error setting up monaco. Please try again.')); + .catch((e) => { throw e;flash('Error setting up monaco. Please try again.'); }); }, setupEditor() { if (!this.activeFile) return; diff --git a/app/assets/javascripts/repo/lib/common/model.js b/app/assets/javascripts/repo/lib/common/model.js index 75828bfb09d..fd6f41f87b1 100644 --- a/app/assets/javascripts/repo/lib/common/model.js +++ b/app/assets/javascripts/repo/lib/common/model.js @@ -2,25 +2,25 @@ import Disposable from './disposable'; export default class Model { - constructor(file) { + constructor(monaco, file) { + this.monaco = monaco; this.disposable = new Disposable(); this.file = file; this.content = file.content !== '' ? file.content : file.raw; this.disposable.add( - this.originalModel = monaco.editor.createModel( - this.content, + this.originalModel = this.monaco.editor.createModel( + this.file.raw, undefined, - new monaco.Uri(null, null, `original/${this.file.path}`), + new this.monaco.Uri(null, null, `original/${this.file.path}`), ), - this.model = monaco.editor.createModel( + this.model = this.monaco.editor.createModel( this.content, undefined, - new monaco.Uri(null, null, this.file.path), + new this.monaco.Uri(null, null, this.file.path), ), ); - this.attachedToWorker = false; this.events = new Map(); } @@ -37,19 +37,18 @@ export default class Model { } get diffModel() { - return { - url: this.model.uri.toString(), - versionId: this.model.getVersionId(), - lines: this.model.getLinesContent(), - EOL: '\n', - }; + return Model.getDiffModel(this.model); } get originalDiffModel() { + return Model.getDiffModel(this.originalModel); + } + + static getDiffModel(model) { return { - url: this.originalModel.uri.toString(), - versionId: this.originalModel.getVersionId(), - lines: this.originalModel.getLinesContent(), + url: model.uri.toString(), + versionId: model.getVersionId(), + lines: model.getLinesContent(), EOL: '\n', }; } @@ -62,21 +61,17 @@ export default class Model { return this.originalModel; } - setAttachedToWorker(val) { - this.attachedToWorker = val; - } - onChange(cb) { this.events.set( this.file.path, - this.model.onDidChangeContent(e => cb(this.model, e)), + this.disposable.add( + this.model.onDidChangeContent(e => cb(this.model, e)), + ), ); } dispose() { this.disposable.dispose(); - - 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 index fdb1e148681..fd462252795 100644 --- a/app/assets/javascripts/repo/lib/common/model_manager.js +++ b/app/assets/javascripts/repo/lib/common/model_manager.js @@ -2,7 +2,8 @@ import Disposable from './disposable'; import Model from './model'; export default class ModelManager { - constructor() { + constructor(monaco) { + this.monaco = monaco; this.disposable = new Disposable(); this.models = new Map(); } @@ -16,7 +17,7 @@ export default class ModelManager { return this.models.get(file.path); } - const model = new Model(file); + const model = new Model(this.monaco, file); this.models.set(model.path, model); this.disposable.add(model); diff --git a/app/assets/javascripts/repo/lib/decorations/controller.js b/app/assets/javascripts/repo/lib/decorations/controller.js index eb369dbbfe1..0954b7973c4 100644 --- a/app/assets/javascripts/repo/lib/decorations/controller.js +++ b/app/assets/javascripts/repo/lib/decorations/controller.js @@ -1,7 +1,6 @@ -import editor from '../editor'; - -class DecorationsController { - constructor() { +export default class DecorationsController { + constructor(editor) { + this.editor = editor; this.decorations = new Map(); this.editorDecorations = new Map(); } @@ -33,7 +32,7 @@ class DecorationsController { this.editorDecorations.set( model.url, - editor.editorInstance.instance.deltaDecorations(oldDecorations, decorations), + this.editor.instance.deltaDecorations(oldDecorations, decorations), ); } @@ -42,5 +41,3 @@ class DecorationsController { this.editorDecorations.clear(); } } - -export default new DecorationsController(); diff --git a/app/assets/javascripts/repo/lib/diff/controller.js b/app/assets/javascripts/repo/lib/diff/controller.js index 6c97f1cc24d..9b6c164a81c 100644 --- a/app/assets/javascripts/repo/lib/diff/controller.js +++ b/app/assets/javascripts/repo/lib/diff/controller.js @@ -1,7 +1,7 @@ /* global monaco */ -import DirtyDiffWorker from './worker'; +import DirtyDiffWorker from './diff'; +console.log(DirtyDiffWorker); import Disposable from '../common/disposable'; -import decorationsController from '../decorations/controller'; export const getDiffChangeType = (change) => { if (change.modified) { @@ -28,17 +28,14 @@ export const getDecorator = change => ({ }, }); -export const decorate = (model, changes) => { - const decorations = changes.map(change => getDecorator(change)); - decorationsController.addDecorations(model, 'dirtyDiff', decorations); -}; - export default class DirtyDiffController { - constructor(modelManager) { + constructor(modelManager, decorationsController) { this.disposable = new Disposable(); this.editorSimpleWorker = null; this.modelManager = modelManager; - this.dirtyDiffWorker = new DirtyDiffWorker(); + this.decorationsController = decorationsController; + console.log(DirtyDiffWorker); + // this.dirtyDiffWorker = new DirtyDiffWorker(); } attachModel(model) { @@ -46,12 +43,17 @@ export default class DirtyDiffController { } computeDiff(model) { - decorate(model, this.dirtyDiffWorker.compute(model)); + this.decorate(model, this.dirtyDiffWorker.compute(model)); } // eslint-disable-next-line class-methods-use-this reDecorate(model) { - decorationsController.decorate(model); + this.decorationsController.decorate(model); + } + + decorate(model, changes) { + const decorations = changes.map(change => getDecorator(change)); + this.decorationsController.addDecorations(model, 'dirtyDiff', decorations); } dispose() { diff --git a/app/assets/javascripts/repo/lib/diff/diff.js b/app/assets/javascripts/repo/lib/diff/diff.js new file mode 100644 index 00000000000..bc183fec70a --- /dev/null +++ b/app/assets/javascripts/repo/lib/diff/diff.js @@ -0,0 +1,38 @@ +import { diffLines } from 'diff'; + +// export default class DirtyDiffWorker { +// // eslint-disable-next-line class-methods-use-this +// compute(model) { +// console.time('a'); +// const originalContent = model.getOriginalModel().getValue(); +// const newContent = model.getModel().getValue(); +// const changes = diffLines(originalContent, newContent); +// +// let lineNumber = 1; +// const a = changes.reduce((acc, change) => { +// const findOnLine = acc.find(c => c.lineNumber === lineNumber); +// +// if (findOnLine) { +// Object.assign(findOnLine, change, { +// modified: true, +// endLineNumber: (lineNumber + change.count) - 1, +// }); +// } else if ('added' in change || 'removed' in change) { +// acc.push(Object.assign({}, change, { +// lineNumber, +// modified: undefined, +// endLineNumber: (lineNumber + change.count) - 1, +// })); +// } +// +// if (!change.removed) { +// lineNumber += change.count; +// } +// +// return acc; +// }, []); +// console.timeEnd('a'); +// +// return a; +// } +// } diff --git a/app/assets/javascripts/repo/lib/diff/worker.js b/app/assets/javascripts/repo/lib/diff/worker.js deleted file mode 100644 index aa684e6e2a5..00000000000 --- a/app/assets/javascripts/repo/lib/diff/worker.js +++ /dev/null @@ -1,34 +0,0 @@ -import { diffLines } from 'diff'; - -export default class DirtyDiffWorker { - // eslint-disable-next-line class-methods-use-this - compute(model) { - const originalContent = model.getOriginalModel().getValue(); - const newContent = model.getModel().getValue(); - const changes = diffLines(originalContent, newContent); - - let lineNumber = 1; - return changes.reduce((acc, change) => { - const findOnLine = acc.find(c => c.lineNumber === lineNumber); - - if (findOnLine) { - Object.assign(findOnLine, change, { - modified: true, - endLineNumber: (lineNumber + change.count) - 1, - }); - } else if ('added' in change || 'removed' in change) { - acc.push(Object.assign({}, change, { - lineNumber, - modified: undefined, - endLineNumber: (lineNumber + change.count) - 1, - })); - } - - if (!change.removed) { - lineNumber += change.count; - } - - return acc; - }, []); - } -} diff --git a/app/assets/javascripts/repo/lib/editor.js b/app/assets/javascripts/repo/lib/editor.js index ea3bfe16462..e82fbfc0e9c 100644 --- a/app/assets/javascripts/repo/lib/editor.js +++ b/app/assets/javascripts/repo/lib/editor.js @@ -1,36 +1,40 @@ -/* global monaco */ +import DecorationsController from './decorations/controller'; import DirtyDiffController from './diff/controller'; import Disposable from './common/disposable'; import ModelManager from './common/model_manager'; export default class Editor { - static create() { - this.editorInstance = new Editor(); + static create(monaco) { + this.editorInstance = new Editor(monaco); return this.editorInstance; } - constructor() { + constructor(monaco) { + this.monaco = monaco; this.currentModel = null; this.instance = null; this.dirtyDiffController = null; this.disposable = new Disposable(); this.disposable.add( - this.modelManager = new ModelManager(), + this.modelManager = new ModelManager(this.monaco), + this.decorationsController = new DecorationsController(this), ); } createInstance(domElement) { if (!this.instance) { this.disposable.add( - this.instance = monaco.editor.create(domElement, { + this.instance = this.monaco.editor.create(domElement, { model: null, readOnly: false, contextmenu: true, scrollBeyondLastLine: false, }), - this.dirtyDiffController = new DirtyDiffController(this.modelManager), + this.dirtyDiffController = new DirtyDiffController( + this.modelManager, this.decorationsController, + ), ); } } -- cgit v1.2.1