started move to web worker for diff calculation
This commit is contained in:
parent
7c04e4086c
commit
809a27e61e
8 changed files with 90 additions and 87 deletions
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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() {
|
||||
|
|
38
app/assets/javascripts/repo/lib/diff/diff.js
Normal file
38
app/assets/javascripts/repo/lib/diff/diff.js
Normal file
|
@ -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;
|
||||
// }
|
||||
// }
|
|
@ -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;
|
||||
}, []);
|
||||
}
|
||||
}
|
|
@ -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,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue