Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 9dec729

Browse files
committed
multiple changes calculate a diff - fixes #11
1 parent a613f70 commit 9dec729

4 files changed

Lines changed: 102 additions & 72 deletions

File tree

demo/codemirror.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import CodeMirror from 'codemirror'
77
import 'codemirror/mode/javascript/javascript.js'
88

99
const ydoc = new Y.Doc()
10-
const provider = new WebrtcProvider('codemirror-demo-room', ydoc)
10+
const provider = new WebrtcProvider('codemirror-demo-room-x', ydoc)
1111
const yText = ydoc.getText('codemirror')
1212

1313
const editorContainer = document.createElement('div')

package-lock.json

Lines changed: 65 additions & 51 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,18 +43,18 @@
4343
"codemirror": "^5.52.2"
4444
},
4545
"dependencies": {
46-
"lib0": "^0.2.32"
46+
"lib0": "^0.2.33"
4747
},
4848
"devDependencies": {
4949
"@types/codemirror": "0.0.91",
50-
"codemirror": "^5.56.0",
51-
"concurrently": "^5.2.0",
50+
"codemirror": "^5.57.0",
51+
"concurrently": "^5.3.0",
5252
"http-server": "^0.12.3",
53-
"jsdom": "^16.3.0",
54-
"rollup": "^2.22.1",
53+
"jsdom": "^16.4.0",
54+
"rollup": "^2.26.10",
5555
"standard": "^14.3.4",
5656
"typescript": "^3.9.7",
5757
"y-webrtc": "^10.1.6",
58-
"yjs": "^13.3.0"
58+
"yjs": "^13.3.2"
5959
}
6060
}

src/y-codemirror.js

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import * as math from 'lib0/math.js'
77
import * as Y from 'yjs'
88
import * as func from 'lib0/function.js'
99
import * as eventloop from 'lib0/eventloop.js'
10+
import * as diff from 'lib0/diff.js'
1011
import CodeMirror from 'codemirror'
1112

1213
export const cmOrigin = 'prosemirror-binding'
@@ -77,16 +78,25 @@ const typeObserver = (binding, event) => {
7778
})
7879
}
7980

80-
const targetObserver = (binding, change) => {
81+
const targetObserver = (binding, changes) => {
8182
binding._mux(() => {
8283
binding.doc.transact(() => {
83-
const start = binding.cmDoc.indexFromPos(change.from)
84-
const delLen = change.removed.map(s => s.length).reduce(math.add) + change.removed.length - 1
85-
if (delLen > 0) {
86-
binding.type.delete(start, delLen)
87-
}
88-
if (change.text.length > 0) {
89-
binding.type.insert(start, change.text.join('\n'))
84+
if (changes.length > 1) {
85+
// If there are several consecutive changes, we can't reliably compute the positions anymore. See y-codemirror#11
86+
// Instead, we will compute the diff and apply the changes
87+
const d = diff.simpleDiffString(binding.type.toString(), binding.cmDoc.getValue())
88+
binding.type.delete(d.index, d.remove)
89+
binding.type.insert(d.index, d.insert)
90+
} else {
91+
const change = changes[0]
92+
const start = binding.cmDoc.indexFromPos(change.from)
93+
const delLen = change.removed.map(s => s.length).reduce(math.add) + change.removed.length - 1
94+
if (delLen > 0) {
95+
binding.type.delete(start, delLen)
96+
}
97+
if (change.text.length > 0) {
98+
binding.type.insert(start, change.text.join('\n'))
99+
}
90100
}
91101
}, binding)
92102
})
@@ -231,7 +241,11 @@ export class CodemirrorBinding {
231241
cmDoc.setValue(textType.toString())
232242
// observe type and target
233243
this._typeObserver = event => typeObserver(this, event)
234-
this._targetObserver = (_, change) => targetObserver(this, change)
244+
this._targetObserver = (instance, changes) => {
245+
if (instance.getDoc() === cmDoc) {
246+
targetObserver(this, changes)
247+
}
248+
}
235249
this._cursors = new Map()
236250
this._changedCursors = new Set()
237251
this._debounceCursorEvent = eventloop.createDebouncer(10)
@@ -258,19 +272,21 @@ export class CodemirrorBinding {
258272
}
259273
this._cursorListener = () => {
260274
if (codeMirror.getDoc() === cmDoc) {
261-
codemirrorCursorActivity(doc, codeMirror, textType, awareness)
275+
setTimeout(() => {
276+
codemirrorCursorActivity(doc, codeMirror, textType, awareness)
277+
}, 0)
262278
}
263279
}
264280
this._blurListeer = () => awareness.setLocalStateField('cursor', null)
265281

266282
textType.observe(this._typeObserver)
267283
// @ts-ignore
268-
cmDoc.on('change', this._targetObserver)
284+
codeMirror.on('changes', this._targetObserver)
269285
if (awareness) {
270286
codeMirror.on('swapDoc', this._blurListeer)
271287
awareness.on('change', this._awarenessListener)
272288
// @ts-ignore
273-
cmDoc.on('cursorActivity', this._cursorListener)
289+
codeMirror.on('cursorActivity', this._cursorListener)
274290
codeMirror.on('blur', this._blurListeer)
275291
codeMirror.on('focus', this._cursorListener)
276292
}
@@ -280,9 +296,9 @@ export class CodemirrorBinding {
280296
this.type.unobserve(this._typeObserver)
281297
this.cm.off('swapDoc', this._blurListeer)
282298
// @ts-ignore
283-
this.cmDoc.off('change', this._targetObserver)
299+
this.cm.off('changes', this._targetObserver)
284300
// @ts-ignore
285-
this.cmDoc.off('cursorActivity', this._cursorListener)
301+
this.cm.off('cursorActivity', this._cursorListener)
286302
this.cm.off('focus', this._cursorListener)
287303
this.cm.off('blur', this._blurListeer)
288304
if (this.awareness) {

0 commit comments

Comments
 (0)