-
Notifications
You must be signed in to change notification settings - Fork 464
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
For now it just stores the elemId referenced by the cursor in the backend, updates the frontend-backend protocol to handle cursors, and instantiates Cursor objects in the frontend. Does not actually perform the conversion from elemId to index yet; that's next.
- Loading branch information
Showing
11 changed files
with
179 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
const { OBJECT_ID, ELEM_IDS } = require('./constants') | ||
const { isObject } = require('../src/common') | ||
|
||
/** | ||
* A cursor references a particular element in a list, or a character in an | ||
* Automerge.Text object. As list elements get inserted/deleted ahead of the | ||
* cursor position, the index of the cursor is automatically recomputed. | ||
*/ | ||
class Cursor { | ||
constructor(object, index, elemId = undefined) { | ||
if (Array.isArray(object) && object[ELEM_IDS] && typeof index === 'number') { | ||
this.objectId = object[OBJECT_ID] | ||
this.elemId = object[ELEM_IDS][index] | ||
this.index = index | ||
} else if (isObject(object) && object.getElemId && typeof index === 'number') { | ||
this.objectId = object[OBJECT_ID] | ||
this.elemId = object.getElemId(index) | ||
this.index = index | ||
} else if (typeof object == 'string' && /*typeof index === 'number' &&*/ typeof elemId === 'string') { | ||
this.objectId = object | ||
this.elemId = elemId | ||
this.index = index | ||
} else { | ||
throw new TypeError('Construct a cursor using a list/text object and index') | ||
} | ||
} | ||
|
||
/** | ||
* Called when a cursor is accessed within a change callback. `context` is the | ||
* proxy context that keeps track of any mutations. | ||
*/ | ||
getWriteable(context, path) { | ||
const instance = new Cursor(this.objectId, this.index, this.elemId) | ||
instance.context = context | ||
instance.path = path | ||
return instance | ||
} | ||
} | ||
|
||
module.exports = { Cursor } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
const assert = require('assert') | ||
const Automerge = process.env.TEST_DIST === '1' ? require('../dist/automerge') : require('../src/automerge') | ||
|
||
describe('Automerge.Cursor', () => { | ||
it('should allow a cursor on a list element', () => { | ||
let s1 = Automerge.change(Automerge.init(), doc => { | ||
doc.list = [1,2,3] | ||
doc.cursor = new Automerge.Cursor(doc.list, 2) | ||
assert.ok(doc.cursor instanceof Automerge.Cursor) | ||
assert.strictEqual(doc.cursor.elemId, `4@${Automerge.getActorId(doc)}`) | ||
}) | ||
assert.ok(s1.cursor instanceof Automerge.Cursor) | ||
assert.strictEqual(s1.cursor.elemId, `4@${Automerge.getActorId(s1)}`) | ||
|
||
let s2 = Automerge.applyChanges(Automerge.init(), Automerge.getAllChanges(s1)) | ||
assert.ok(s2.cursor instanceof Automerge.Cursor) | ||
assert.strictEqual(s2.cursor.elemId, `4@${Automerge.getActorId(s1)}`) | ||
|
||
let s3 = Automerge.load(Automerge.save(s1)) | ||
assert.ok(s3.cursor instanceof Automerge.Cursor) | ||
assert.strictEqual(s3.cursor.elemId, `4@${Automerge.getActorId(s1)}`) | ||
}) | ||
|
||
it('should allow a cursor on a text character', () => { | ||
let s1 = Automerge.change(Automerge.init(), doc => { | ||
doc.text = new Automerge.Text(['a', 'b', 'c']) | ||
doc.cursor = doc.text.getCursorAt(2) | ||
assert.ok(doc.cursor instanceof Automerge.Cursor) | ||
assert.strictEqual(doc.cursor.elemId, `4@${Automerge.getActorId(doc)}`) | ||
}) | ||
assert.ok(s1.cursor instanceof Automerge.Cursor) | ||
assert.strictEqual(s1.cursor.elemId, `4@${Automerge.getActorId(s1)}`) | ||
|
||
let s2 = Automerge.applyChanges(Automerge.init(), Automerge.getAllChanges(s1)) | ||
assert.ok(s2.cursor instanceof Automerge.Cursor) | ||
assert.strictEqual(s2.cursor.elemId, `4@${Automerge.getActorId(s1)}`) | ||
|
||
let s3 = Automerge.load(Automerge.save(s1)) | ||
assert.ok(s3.cursor instanceof Automerge.Cursor) | ||
assert.strictEqual(s3.cursor.elemId, `4@${Automerge.getActorId(s1)}`) | ||
}) | ||
}) |