From 2ff0009fb6334974dddc8f430d3aa5c2dda658f9 Mon Sep 17 00:00:00 2001 From: Martin Kleppmann Date: Tue, 10 Sep 2019 18:35:24 -0500 Subject: [PATCH] Allow objects to appear as elements in Automerge.Text Fixes #194 --- frontend/apply_patch.js | 5 +++-- frontend/text.js | 13 +++++++++++-- test/text_test.js | 8 +++++--- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/frontend/apply_patch.js b/frontend/apply_patch.js index d40bcd24d..a8b5437e6 100644 --- a/frontend/apply_patch.js +++ b/frontend/apply_patch.js @@ -341,7 +341,8 @@ function updateTextObject(diffs, startIndex, endIndex, cache, updated) { insertions = [] } maxElem = Math.max(maxElem, parseElemId(diff.elemId).counter) - insertions.push({elemId: diff.elemId, value: diff.value, conflicts: diff.conflicts}) + const value = getValue(diff, cache, updated) + insertions.push({elemId: diff.elemId, value, conflicts: diff.conflicts}) if (startIndex === endIndex || diffs[startIndex + 1].action !== 'insert' || diffs[startIndex + 1].index !== diff.index + 1) { @@ -352,7 +353,7 @@ function updateTextObject(diffs, startIndex, endIndex, cache, updated) { } else if (diff.action === 'set') { elems[diff.index] = { elemId: elems[diff.index].elemId, - value: diff.value, + value: getValue(diff, cache, updated), conflicts: diff.conflicts } diff --git a/frontend/text.js b/frontend/text.js index 0d3908cdf..42a190c4e 100644 --- a/frontend/text.js +++ b/frontend/text.js @@ -27,6 +27,10 @@ class Text { return this.elems[index].elemId } + /** + * Iterates over the text elements character by character, including any + * inline objects. + */ [Symbol.iterator] () { let elems = this.elems, index = -1 return { @@ -45,14 +49,19 @@ class Text { * Returns the content of the Text object as a simple string. */ toString() { - return this.join('') + let chars = [] + for (let elem of this.elems) { + if (typeof elem.value === 'string') chars.push(elem.value) + } + return chars.join('') } + /** * Returns the content of the Text object as a simple string, so that the * JSON serialization of an Automerge document represents text nicely. */ toJSON() { - return this.join('') + return this.toString() } /** diff --git a/test/text_test.js b/test/text_test.js index afef125ad..33ad63713 100644 --- a/test/text_test.js +++ b/test/text_test.js @@ -160,15 +160,17 @@ describe('Automerge.Text', () => { assert.strictEqual(s1.text.toString(), 'Init') }) }) + describe('non-textual control characters', () => { let s1 beforeEach(() => { s1 = Automerge.change(Automerge.init(), doc => { - doc.text = new Automerge.Text() - doc.text.insertAt(0, 'a') - doc.text.insertAt(1, { attribute: 'bold' }) + doc.text = new Automerge.Text() + doc.text.insertAt(0, 'a') + doc.text.insertAt(1, { attribute: 'bold' }) }) }) + it('should allow fetching non-textual characters', () => { assert.deepEqual(s1.text.get(1), { attribute: 'bold' }) })