mirror of
https://github.com/yjs/yjs.git
synced 2026-08-29 10:09:05 +02:00
rename concept AttributionManager => Renderer
definitely a breaking change to all users of the current attribution api
This commit is contained in:
@@ -20,9 +20,9 @@ export const testRelativePositions = _tc => {
|
||||
const v1 = Y.cloneDoc(ydoc)
|
||||
ytext.delete(1, 6)
|
||||
ytext.insert(1, 'x')
|
||||
const am = Y.createAttributionManagerFromDiff(v1, ydoc)
|
||||
const rel = Y.createRelativePositionFromTypeIndex(ytext, 9, 1, am) // pos after "hello wo"
|
||||
const abs1 = Y.createAbsolutePositionFromRelativePosition(rel, ydoc, true, am)
|
||||
const renderer = Y.createDiffRenderer(v1, ydoc)
|
||||
const rel = Y.createRelativePositionFromTypeIndex(ytext, 9, 1, renderer) // pos after "hello wo"
|
||||
const abs1 = Y.createAbsolutePositionFromRelativePosition(rel, ydoc, true, renderer)
|
||||
const abs2 = Y.createAbsolutePositionFromRelativePosition(rel, ydoc, true)
|
||||
t.assert(abs1?.index === 9)
|
||||
t.assert(abs2?.index === 3)
|
||||
@@ -39,16 +39,16 @@ export const testAttributedEvents = _tc => {
|
||||
ydoc.transact(() => {
|
||||
ytext.delete(6, 5)
|
||||
})
|
||||
const am = Y.createAttributionManagerFromDiff(v1, ydoc)
|
||||
const c1 = ytext.toDelta(am)
|
||||
const renderer = Y.createDiffRenderer(v1, ydoc)
|
||||
const c1 = ytext.toDelta({ renderer })
|
||||
t.compare(c1, delta.create().insert('hello ').insert('world', null, { delete: [] }).done())
|
||||
let calledObserver = false
|
||||
ytext.observe(event => {
|
||||
const d = event.getDelta(am)
|
||||
const d = event.getDelta({ renderer })
|
||||
t.compare(d, delta.create().retain(11).insert('!', null, { insert: [] }).done())
|
||||
calledObserver = true
|
||||
})
|
||||
ytext.applyDelta(delta.create().retain(11).insert('!').done(), am)
|
||||
ytext.applyDelta(delta.create().retain(11).insert('!').done(), { renderer })
|
||||
t.assert(calledObserver)
|
||||
}
|
||||
|
||||
@@ -63,10 +63,10 @@ export const testInsertionsMindingAttributedContent = _tc => {
|
||||
ydoc.transact(() => {
|
||||
ytext.delete(6, 5)
|
||||
})
|
||||
const am = Y.createAttributionManagerFromDiff(v1, ydoc)
|
||||
const c1 = ytext.toDelta(am)
|
||||
const renderer = Y.createDiffRenderer(v1, ydoc)
|
||||
const c1 = ytext.toDelta({ renderer })
|
||||
t.compare(c1, delta.create().insert('hello ').insert('world', null, { delete: [] }).done())
|
||||
ytext.applyDelta(delta.create().retain(11).insert('content').done(), am)
|
||||
ytext.applyDelta(delta.create().retain(11).insert('content').done(), { renderer })
|
||||
t.assert(ytext.toString() === 'hello content')
|
||||
}
|
||||
|
||||
@@ -81,10 +81,10 @@ export const testInsertionsIntoAttributedContent = _tc => {
|
||||
ydoc.transact(() => {
|
||||
ytext.insert(6, 'word')
|
||||
})
|
||||
const am = Y.createAttributionManagerFromDiff(v1, ydoc)
|
||||
const c1 = ytext.toDelta(am)
|
||||
const renderer = Y.createDiffRenderer(v1, ydoc)
|
||||
const c1 = ytext.toDelta({ renderer })
|
||||
t.compare(c1, delta.create().insert('hello ').insert('word', null, { insert: [] }).done())
|
||||
ytext.applyDelta(delta.create().retain(9).insert('l').done(), am)
|
||||
ytext.applyDelta(delta.create().retain(9).insert('l').done(), { renderer })
|
||||
t.assert(ytext.toString() === 'hello world')
|
||||
}
|
||||
|
||||
@@ -151,21 +151,21 @@ export const testAttributionSession1 = tc => {
|
||||
text0.insert(0, 'a')
|
||||
text1.insert(0, 'b')
|
||||
testConnector.flushAllMessages()
|
||||
const d1 = text0.toDelta(Y.createAttributionManagerFromDiff(v1, users[0], { attrs: globalAttributions }))
|
||||
const d1 = text0.toDelta({ renderer: Y.createDiffRenderer(v1, users[0], { attrs: globalAttributions }) })
|
||||
t.compare(d1, delta.create().insert('a', null, { insert: ['0'] }).insert('b', null, { insert: ['1'] }).done())
|
||||
const v2 = Y.cloneDoc(users[0])
|
||||
text0.delete(1, 1)
|
||||
text1.insert(2, 'c')
|
||||
testConnector.flushAllMessages()
|
||||
const d2 = text0.toDelta(Y.createAttributionManagerFromDiff(v2, users[0], { attrs: globalAttributions }))
|
||||
const d2 = text0.toDelta({ renderer: Y.createDiffRenderer(v2, users[0], { attrs: globalAttributions }) })
|
||||
t.compare(d2, delta.create().insert('a').insert('b', null, { delete: ['0'] }).insert('c', null, { insert: ['1'] }).done())
|
||||
|
||||
const onlyUser0ChangesAttributed = {
|
||||
inserts: Y.filterIdMap(globalAttributions.inserts, attrs => attrs.some(attr => attr.name === 'insert' && attr.val === '0')),
|
||||
deletes: Y.filterIdMap(globalAttributions.deletes, attrs => attrs.some(attr => attr.name === 'delete' && attr.val === '0'))
|
||||
}
|
||||
const amUser0 = new Y.TwosetAttributionManager(onlyUser0ChangesAttributed.inserts, onlyUser0ChangesAttributed.deletes)
|
||||
const d3 = text0.toDelta(amUser0)
|
||||
const rendererUser0 = new Y.TwosetRenderer(onlyUser0ChangesAttributed.inserts, onlyUser0ChangesAttributed.deletes)
|
||||
const d3 = text0.toDelta({ renderer: rendererUser0 })
|
||||
t.compare(d3, delta.create().insert('a', null, { insert: ['0'] }).insert('b', null, { delete: ['0'] }).insert('c').done())
|
||||
Y.undoContentIds(users[0], Y.createContentIdsFromContentMap(onlyUser0ChangesAttributed))
|
||||
|
||||
@@ -179,10 +179,10 @@ export const testAttributionEvent = () => {
|
||||
// <p>hi</p>
|
||||
ytype.applyDelta(delta.create().insert([delta.create('p').insert('hi').done()]).done())
|
||||
const ydocBase = Y.cloneDoc(ydoc)
|
||||
const am = Y.createAttributionManagerFromDiff(ydocBase, ydoc)
|
||||
const renderer = Y.createDiffRenderer(ydocBase, ydoc)
|
||||
let called = false
|
||||
ytype.observeDeep(event => {
|
||||
const change = event.getDelta(am)
|
||||
const change = event.getDelta({ renderer })
|
||||
const expectedChange = delta.create().modify(delta.create('p').retain(2, null, { delete: [] }), null, { delete: [] }).done()
|
||||
t.compare(
|
||||
change,
|
||||
@@ -201,12 +201,12 @@ export const testAttributionChange = () => {
|
||||
const ytype = ydoc.get()
|
||||
ytype.applyDelta(delta.create().insert('hi').done())
|
||||
const ydocClone = Y.cloneDoc(ydoc)
|
||||
const am = Y.createAttributionManagerFromDiff(ydocClone, ydoc)
|
||||
const renderer = Y.createDiffRenderer(ydocClone, ydoc)
|
||||
ytype.applyDelta(delta.create().retain(2).insert('!').done())
|
||||
let calledHandler = false
|
||||
am.on('change', changes => {
|
||||
renderer.on('change', changes => {
|
||||
calledHandler = true
|
||||
const changeUpdate = ytype.toDelta(am, { deep: true, itemsToRender: changes, retainInserts: true, retainDeletes: true })
|
||||
const changeUpdate = ytype.toDelta({ renderer, deep: true, itemsToRender: changes, retainInserts: true, retainDeletes: true })
|
||||
const expectedUpdate = delta.create().retain(2).retain(1, null, {})
|
||||
t.compare(changeUpdate, expectedUpdate)
|
||||
console.log(changeUpdate.toJSON())
|
||||
|
||||
@@ -168,14 +168,14 @@ export const testAttributions = _tc => {
|
||||
const ytype = ydoc.get('txt')
|
||||
// delete " world" and insert exclamation mark "!".
|
||||
ytype.applyDelta(delta.create().retain(5).delete(6).insert('!').done())
|
||||
const am = Y.createAttributionManagerFromDiff(ydocV1, ydoc)
|
||||
const renderer = Y.createDiffRenderer(ydocV1, ydoc)
|
||||
// get the attributed differences
|
||||
const attributedContent = ytype.toDelta(am)
|
||||
const attributedContent = ytype.toDelta({ renderer })
|
||||
console.log('attributed content', attributedContent.toJSON())
|
||||
t.assert(attributedContent.equals(delta.create().insert('hello').insert(' world', null, { delete: [] }).insert('!', null, { insert: [] }).done()))
|
||||
// for editor bindings, it is also necessary to observe changes and get the attributed changes
|
||||
ytype.observe(event => {
|
||||
const attributedChange = event.getDelta(am)
|
||||
const attributedChange = event.getDelta({ renderer })
|
||||
console.log('the attributed change', attributedChange.toJSON())
|
||||
t.assert(attributedChange.done().equals(delta.create().retain(11).insert('!', null, { insert: [] }).done()))
|
||||
const unattributedChange = event.delta
|
||||
@@ -191,7 +191,7 @@ export const testAttributions = _tc => {
|
||||
* UNattributed: 'world!'
|
||||
*/
|
||||
// Apply a change to the attributed content
|
||||
ytype.applyDelta(delta.create().retain(11).insert('!').done(), am)
|
||||
ytype.applyDelta(delta.create().retain(11).insert('!').done(), { renderer })
|
||||
// // Equivalent to applying a change to the UNattributed content:
|
||||
// ytype.applyDelta(delta.create().retain(5).insert('!'))
|
||||
}
|
||||
|
||||
@@ -467,11 +467,11 @@ export const testAttributedContent = _tc => {
|
||||
*/
|
||||
const yarray = ydoc.get()
|
||||
yarray.insert(0, [1, 2])
|
||||
let attributionManager = Y.noAttributionsManager
|
||||
let renderer = Y.baseRenderer
|
||||
|
||||
ydoc.on('afterTransaction', tr => {
|
||||
// attributionManager = new TwosetAttributionManager(createIdMapFromIdSet(tr.insertSet, [new Y.Attribution('insertAt', 42), new Y.Attribution('insert', 'kevin')]), createIdMapFromIdSet(tr.deleteSet, [new Y.Attribution('delete', 'kevin')]))
|
||||
attributionManager = new Y.TwosetAttributionManager(Y.createIdMapFromIdSet(tr.insertSet, []), Y.createIdMapFromIdSet(tr.deleteSet, []))
|
||||
// renderer = new TwosetRenderer(createIdMapFromIdSet(tr.insertSet, [new Y.Attribution('insertAt', 42), new Y.Attribution('insert', 'kevin')]), createIdMapFromIdSet(tr.deleteSet, [new Y.Attribution('delete', 'kevin')]))
|
||||
renderer = new Y.TwosetRenderer(Y.createIdMapFromIdSet(tr.insertSet, []), Y.createIdMapFromIdSet(tr.deleteSet, []))
|
||||
})
|
||||
t.group('insert / delete', () => {
|
||||
ydoc.transact(() => {
|
||||
@@ -479,7 +479,7 @@ export const testAttributedContent = _tc => {
|
||||
yarray.insert(1, [42])
|
||||
})
|
||||
const expectedContent = delta.create().insert([1], null, { delete: [] }).insert([2]).insert([42], null, { insert: [] })
|
||||
const attributedContent = yarray.toDelta(attributionManager)
|
||||
const attributedContent = yarray.toDelta({ renderer })
|
||||
console.log(attributedContent.toJSON())
|
||||
t.assert(attributedContent.equals(expectedContent))
|
||||
})
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import * as Y from '../src/index.js'
|
||||
import { init, compare, applyRandomTests, Doc } from './testHelper.js' // eslint-disable-line
|
||||
import { noAttributionsManager, TwosetAttributionManager } from '../src/utils/AttributionManager.js'
|
||||
import { baseRenderer, TwosetRenderer } from '../src/utils/Renderer.js'
|
||||
import { createIdMapFromIdSet } from '../src/utils/ids.js'
|
||||
import * as t from 'lib0/testing'
|
||||
import * as prng from 'lib0/prng'
|
||||
@@ -550,35 +550,35 @@ export const testYmapEventHasCorrectValueWhenSettingAPrimitiveFromOtherUser = tc
|
||||
export const testAttributedContent = _tc => {
|
||||
const ydoc = new Y.Doc({ gc: false })
|
||||
const ymap = ydoc.get()
|
||||
let attributionManager = noAttributionsManager
|
||||
let renderer = baseRenderer
|
||||
|
||||
ydoc.on('afterTransaction', tr => {
|
||||
// attributionManager = new TwosetAttributionManager(createIdMapFromIdSet(tr.insertSet, [new Y.Attribution('insertAt', 42), new Y.Attribution('insert', 'kevin')]), createIdMapFromIdSet(tr.deleteSet, [new Y.Attribution('delete', 'kevin')]))
|
||||
attributionManager = new TwosetAttributionManager(createIdMapFromIdSet(tr.insertSet, []), createIdMapFromIdSet(tr.deleteSet, []))
|
||||
// renderer = new TwosetRenderer(createIdMapFromIdSet(tr.insertSet, [new Y.Attribution('insertAt', 42), new Y.Attribution('insert', 'kevin')]), createIdMapFromIdSet(tr.deleteSet, [new Y.Attribution('delete', 'kevin')]))
|
||||
renderer = new TwosetRenderer(createIdMapFromIdSet(tr.insertSet, []), createIdMapFromIdSet(tr.deleteSet, []))
|
||||
})
|
||||
t.group('initial value', () => {
|
||||
ymap.setAttr('test', 42)
|
||||
const expectedContent = { test: delta.$deltaMapChangeJson.expect({ type: 'insert', value: 42, attribution: { insert: [] } }) }
|
||||
const attributedContent = ymap.toDelta(attributionManager)
|
||||
const attributedContent = ymap.toDelta({ renderer })
|
||||
console.log(attributedContent.toJSON())
|
||||
t.compare(expectedContent, attributedContent.toJSON().attrs)
|
||||
})
|
||||
t.group('overwrite value', () => {
|
||||
ymap.setAttr('test', 'fourtytwo')
|
||||
const expectedContent = { test: delta.$deltaMapChangeJson.expect({ type: 'insert', value: 'fourtytwo', attribution: { insert: [] } }) }
|
||||
const attributedContent = ymap.toDelta(attributionManager)
|
||||
const attributedContent = ymap.toDelta({ renderer })
|
||||
console.log(attributedContent)
|
||||
t.compare(expectedContent, attributedContent.toJSON().attrs)
|
||||
})
|
||||
t.group('delete value', () => {
|
||||
ymap.deleteAttr('test')
|
||||
// Snapshot-mode `toDelta(am)` (no `itemsToRender` opt) must not emit
|
||||
// Snapshot-mode `toDelta(renderer)` (no `itemsToRender` opt) must not emit
|
||||
// `DeleteAttrOp`. An attribute deleted under attribution is still
|
||||
// observable in the rendered state with its prior value and a `delete`
|
||||
// attribution marker - symmetric with how soft-deleted content children
|
||||
// surface as `InsertOp` with `{ delete: [] }` rather than `DeleteOp`.
|
||||
const expectedContent = { test: delta.$deltaMapChangeJson.expect({ type: 'insert', value: 'fourtytwo', attribution: { delete: [] } }) }
|
||||
const attributedContent = ymap.toDelta(attributionManager)
|
||||
const attributedContent = ymap.toDelta({ renderer })
|
||||
console.log(attributedContent.toJSON())
|
||||
t.compare(expectedContent, attributedContent.toJSON().attrs)
|
||||
})
|
||||
|
||||
@@ -4,7 +4,7 @@ import * as prng from 'lib0/prng'
|
||||
import * as math from 'lib0/math'
|
||||
import * as delta from 'lib0/delta'
|
||||
import { createIdMapFromIdSet } from '../src/utils/ids.js'
|
||||
import { noAttributionsManager, TwosetAttributionManager, createAttributionManagerFromSnapshots } from '../src/utils/AttributionManager.js'
|
||||
import { baseRenderer, TwosetRenderer, createSnapshotRenderer } from '../src/utils/Renderer.js'
|
||||
|
||||
const { init, compare } = Y
|
||||
|
||||
@@ -1476,11 +1476,11 @@ export const testSnapshot = tc => {
|
||||
.insert('x')
|
||||
.delete(1)
|
||||
)
|
||||
const state1 = text0.toDelta(createAttributionManagerFromSnapshots(snapshot1))
|
||||
const state1 = text0.toDelta({ renderer: createSnapshotRenderer(snapshot1) })
|
||||
t.compare(state1, delta.create().insert('abcd').done())
|
||||
const state2 = text0.toDelta(createAttributionManagerFromSnapshots(snapshot2))
|
||||
const state2 = text0.toDelta({ renderer: createSnapshotRenderer(snapshot2) })
|
||||
t.compare(state2, delta.create().insert('axcd').done())
|
||||
const state2Diff = text0.toDelta(createAttributionManagerFromSnapshots(snapshot1, snapshot2))
|
||||
const state2Diff = text0.toDelta({ renderer: createSnapshotRenderer(snapshot1, snapshot2) })
|
||||
t.compare(
|
||||
state2Diff,
|
||||
delta.create()
|
||||
@@ -1509,7 +1509,7 @@ export const testSnapshotDeleteAfter = tc => {
|
||||
.insert('e')
|
||||
.done()
|
||||
)
|
||||
const state1 = text0.toDelta(createAttributionManagerFromSnapshots(snapshot1))
|
||||
const state1 = text0.toDelta({ renderer: createSnapshotRenderer(snapshot1) })
|
||||
t.compare(state1, delta.create().insert('abcd').done())
|
||||
}
|
||||
|
||||
@@ -1900,23 +1900,23 @@ export const testAttributedContent = _tc => {
|
||||
const ydoc = new Y.Doc({ gc: false })
|
||||
const ytext = ydoc.get()
|
||||
ytext.insert(0, 'Hello World!')
|
||||
let attributionManager = noAttributionsManager
|
||||
let renderer = baseRenderer
|
||||
|
||||
ydoc.on('afterTransaction', tr => {
|
||||
// attributionManager = new TwosetAttributionManager(createIdMapFromIdSet(tr.insertSet, [new Y.Attribution('insertAt', 42), new Y.Attribution('insert', 'kevin')]), createIdMapFromIdSet(tr.deleteSet, [new Y.Attribution('delete', 'kevin')]))
|
||||
attributionManager = new TwosetAttributionManager(createIdMapFromIdSet(tr.insertSet, []), createIdMapFromIdSet(tr.deleteSet, []))
|
||||
// renderer = new TwosetRenderer(createIdMapFromIdSet(tr.insertSet, [new Y.Attribution('insertAt', 42), new Y.Attribution('insert', 'kevin')]), createIdMapFromIdSet(tr.deleteSet, [new Y.Attribution('delete', 'kevin')]))
|
||||
renderer = new TwosetRenderer(createIdMapFromIdSet(tr.insertSet, []), createIdMapFromIdSet(tr.deleteSet, []))
|
||||
})
|
||||
t.group('insert / delete / format', () => {
|
||||
ytext.applyDelta(delta.create().retain(4, { italic: true }).retain(2).delete(5).insert('attributions').done())
|
||||
const expectedContent = delta.create().insert('Hell', { italic: true }, { format: { italic: [] } }).insert('o ').insert('World', {}, { delete: [] }).insert('attributions', {}, { insert: [] }).insert('!')
|
||||
const attributedContent = ytext.toDelta(attributionManager)
|
||||
const attributedContent = ytext.toDelta({ renderer })
|
||||
console.log(attributedContent.toJSON())
|
||||
t.assert(attributedContent.equals(expectedContent))
|
||||
})
|
||||
t.group('unformat', () => {
|
||||
ytext.applyDelta(delta.create().retain(5, { italic: null }))
|
||||
const expectedContent = delta.create().insert('Hell', null, { format: { italic: [] } }).insert('o attributions!')
|
||||
const attributedContent = ytext.toDelta(attributionManager)
|
||||
const attributedContent = ytext.toDelta({ renderer })
|
||||
console.log(attributedContent.toJSON())
|
||||
t.assert(attributedContent.equals(expectedContent))
|
||||
})
|
||||
@@ -1944,10 +1944,10 @@ export const testAttributedDiffing = _tc => {
|
||||
const attributedInsertions = createIdMapFromIdSet(insertionSetDiff, [Y.createContentAttribute('insert', 'Bob')])
|
||||
const attributedDeletions = createIdMapFromIdSet(deleteSetDiff, [Y.createContentAttribute('delete', 'Bob')])
|
||||
// now we can define an attribution manager that maps these changes to output. One of the
|
||||
// implementations is the TwosetAttributionManager
|
||||
const attributionManager = new TwosetAttributionManager(attributedInsertions, attributedDeletions)
|
||||
// we render the attributed content with the attributionManager
|
||||
const attributedContent = ytext.toDelta(attributionManager)
|
||||
// implementations is the TwosetRenderer
|
||||
const renderer = new TwosetRenderer(attributedInsertions, attributedDeletions)
|
||||
// we render the attributed content with the renderer
|
||||
const attributedContent = ytext.toDelta({ renderer })
|
||||
console.log(JSON.stringify(attributedContent.toJSON(), null, 2))
|
||||
const expectedContent = delta.create().insert('Hell', { italic: true }, { format: { italic: ['Bob'] } }).insert('o ').insert('World', {}, { delete: ['Bob'] }).insert('attributions', {}, { insert: ['Bob'] }).insert('!')
|
||||
t.assert(attributedContent.equals(expectedContent))
|
||||
@@ -2187,7 +2187,7 @@ const checkResult = result => {
|
||||
*
|
||||
* @param {t.TestCase} tc
|
||||
*/
|
||||
export const testAttributionManagerDefaultPerformance = tc => {
|
||||
export const testRendererDefaultPerformance = tc => {
|
||||
const N = 10000
|
||||
const MaxDeletionLength = 5 // 25% chance of deletion
|
||||
const MaxInsertionLength = 5
|
||||
@@ -2212,7 +2212,7 @@ export const testAttributionManagerDefaultPerformance = tc => {
|
||||
ytext.toString()
|
||||
}
|
||||
})
|
||||
t.measureTime(`toDelta(attributionManager) performance <executed ${M} times>`, () => {
|
||||
t.measureTime(`toDelta(renderer) performance <executed ${M} times>`, () => {
|
||||
for (let i = 0; i < M; i++) {
|
||||
ytext.toDelta()
|
||||
}
|
||||
|
||||
@@ -139,10 +139,10 @@ export const testFragmentAttributedContent = _tc => {
|
||||
const elem3 = Y.Type.from(delta.create().insert('world'))
|
||||
yfragment.insert(0, [elem1, elem2])
|
||||
ydoc.get().insert(0, [yfragment])
|
||||
let attributionManager = Y.noAttributionsManager
|
||||
let renderer = Y.baseRenderer
|
||||
ydoc.on('afterTransaction', tr => {
|
||||
// attributionManager = new TwosetAttributionManager(createIdMapFromIdSet(tr.insertSet, [new Y.Attribution('insertAt', 42), new Y.Attribution('insert', 'kevin')]), createIdMapFromIdSet(tr.deleteSet, [new Y.Attribution('delete', 'kevin')]))
|
||||
attributionManager = new Y.TwosetAttributionManager(Y.createIdMapFromIdSet(tr.insertSet, []), Y.createIdMapFromIdSet(tr.deleteSet, []))
|
||||
// renderer = new TwosetRenderer(createIdMapFromIdSet(tr.insertSet, [new Y.Attribution('insertAt', 42), new Y.Attribution('insert', 'kevin')]), createIdMapFromIdSet(tr.deleteSet, [new Y.Attribution('delete', 'kevin')]))
|
||||
renderer = new Y.TwosetRenderer(Y.createIdMapFromIdSet(tr.insertSet, []), Y.createIdMapFromIdSet(tr.deleteSet, []))
|
||||
})
|
||||
t.group('insert / delete', () => {
|
||||
ydoc.transact(() => {
|
||||
@@ -150,10 +150,10 @@ export const testFragmentAttributedContent = _tc => {
|
||||
yfragment.insert(1, [elem3])
|
||||
})
|
||||
const expectedContent = delta.create().insert([elem1], null, { delete: [] }).insert([elem2]).insert([elem3], null, { insert: [] })
|
||||
const attributedContent = yfragment.toDelta(attributionManager)
|
||||
const attributedContent = yfragment.toDelta({ renderer })
|
||||
console.log(attributedContent.toJSON())
|
||||
t.assert(attributedContent.equals(expectedContent))
|
||||
t.compare(elem1.toDelta(attributionManager).toJSON(), delta.create().insert('hello', null, { delete: [] }).toJSON())
|
||||
t.compare(elem1.toDelta({ renderer }).toJSON(), delta.create().insert('hello', null, { delete: [] }).toJSON())
|
||||
})
|
||||
}
|
||||
|
||||
@@ -167,10 +167,10 @@ export const testElementAttributedContent = _tc => {
|
||||
const elem2 = delta.create('span').done()
|
||||
const elem3 = delta.create().insert('world').done()
|
||||
yelement.insert(0, [elem1, elem2])
|
||||
let attributionManager = Y.noAttributionsManager
|
||||
let renderer = Y.baseRenderer
|
||||
ydoc.on('afterTransaction', tr => {
|
||||
// attributionManager = new TwosetAttributionManager(createIdMapFromIdSet(tr.insertSet, [new Y.Attribution('insertAt', 42), new Y.Attribution('insert', 'kevin')]), createIdMapFromIdSet(tr.deleteSet, [new Y.Attribution('delete', 'kevin')]))
|
||||
attributionManager = new Y.TwosetAttributionManager(Y.createIdMapFromIdSet(tr.insertSet, []), Y.createIdMapFromIdSet(tr.deleteSet, []))
|
||||
// renderer = new TwosetRenderer(createIdMapFromIdSet(tr.insertSet, [new Y.Attribution('insertAt', 42), new Y.Attribution('insert', 'kevin')]), createIdMapFromIdSet(tr.deleteSet, [new Y.Attribution('delete', 'kevin')]))
|
||||
renderer = new Y.TwosetRenderer(Y.createIdMapFromIdSet(tr.insertSet, []), Y.createIdMapFromIdSet(tr.deleteSet, []))
|
||||
})
|
||||
t.group('insert / delete', () => {
|
||||
ydoc.transact(() => {
|
||||
@@ -183,7 +183,7 @@ export const testElementAttributedContent = _tc => {
|
||||
.insert([elem2])
|
||||
.insert([delta.create().insert('world', null, { insert: [] })], null, { insert: [] })
|
||||
.setAttr('key', '42', { insert: [] })
|
||||
const attributedContent = yelement.toDeltaDeep(attributionManager)
|
||||
const attributedContent = yelement.toDeltaDeep({ renderer })
|
||||
console.log('retrieved content', attributedContent.toJSON())
|
||||
t.assert(attributedContent.equals(expectedContent))
|
||||
t.compare(attributedContent.toJSON().attrs, { key: { type: 'insert', value: '42', attribution: { insert: [] } } })
|
||||
@@ -206,9 +206,9 @@ export const testElementAttributedContentViaDiffer = _tc => {
|
||||
yelement.insert(1, [elem3])
|
||||
yelement.setAttr('key', '42')
|
||||
})
|
||||
const attributionManager = Y.createAttributionManagerFromDiff(ydocV1, ydoc)
|
||||
const renderer = Y.createDiffRenderer(ydocV1, ydoc)
|
||||
const expectedContent = delta.create().insert([delta.create().insert('hello')], null, { delete: [] }).insert([elem2.toDeltaDeep()]).insert([delta.create().insert('world', null, { insert: [] })], null, { insert: [] }).setAttr('key', '42', { insert: [] })
|
||||
const attributedContent = yelement.toDeltaDeep(attributionManager)
|
||||
const attributedContent = yelement.toDeltaDeep({ renderer })
|
||||
console.log('children', attributedContent.toJSON().children)
|
||||
console.log('attributes', attributedContent.toJSON().attrs)
|
||||
t.compare(attributedContent.toJSON(), expectedContent.toJSON())
|
||||
@@ -226,7 +226,7 @@ export const testElementAttributedContentViaDiffer = _tc => {
|
||||
delta.create().insert('world', null, { insert: [] })
|
||||
], null, { insert: [] })
|
||||
.setAttr('key', '42', { insert: [] })
|
||||
const attributedContent = yelement.toDeltaDeep(attributionManager)
|
||||
const attributedContent = yelement.toDeltaDeep({ renderer })
|
||||
console.log('children', JSON.stringify(attributedContent.toJSON().children, null, 2))
|
||||
console.log('cs expec', JSON.stringify(expectedContent.toJSON(), null, 2))
|
||||
console.log('attributes', attributedContent.toJSON().attrs)
|
||||
@@ -238,7 +238,7 @@ export const testElementAttributedContentViaDiffer = _tc => {
|
||||
elem3.insert(0, 'big')
|
||||
})
|
||||
t.group('test getContentDeep after some more updates', () => {
|
||||
t.info('expecting diffingAttributionManager to auto update itself')
|
||||
t.info('expecting DiffRenderer to auto update itself')
|
||||
const expectedContent = delta.create()
|
||||
.insert(
|
||||
[delta.create().insert('hello')],
|
||||
@@ -250,7 +250,7 @@ export const testElementAttributedContentViaDiffer = _tc => {
|
||||
delta.create().insert('bigworld', null, { insert: [] })
|
||||
], null, { insert: [] })
|
||||
.setAttr('key', '42', { insert: [] })
|
||||
const attributedContent = yelement.toDeltaDeep(attributionManager)
|
||||
const attributedContent = yelement.toDeltaDeep({ renderer })
|
||||
console.log('children', JSON.stringify(attributedContent.toJSON().children, null, 2))
|
||||
console.log('cs expec', JSON.stringify(expectedContent.toJSON(), null, 2))
|
||||
console.log('attributes', attributedContent.toJSON().attrs)
|
||||
@@ -260,11 +260,11 @@ export const testElementAttributedContentViaDiffer = _tc => {
|
||||
})
|
||||
Y.applyUpdate(ydocV1, Y.encodeStateAsUpdate(ydoc))
|
||||
t.group('test getContentDeep both docs synced', () => {
|
||||
t.info('expecting diffingAttributionManager to auto update itself')
|
||||
t.info('expecting DiffRenderer to auto update itself')
|
||||
const expectedContent = delta.create().insert([delta.create('span')]).insert([
|
||||
delta.create().insert('bigworld')
|
||||
]).setAttr('key', '42')
|
||||
const attributedContent = yelement.toDeltaDeep(attributionManager)
|
||||
const attributedContent = yelement.toDeltaDeep({ renderer })
|
||||
console.log('children', JSON.stringify(attributedContent.toJSON().children, null, 2))
|
||||
console.log('cs expec', JSON.stringify(expectedContent.toJSON(), null, 2))
|
||||
console.log('attributes', attributedContent.toJSON().attrs)
|
||||
@@ -277,7 +277,7 @@ export const testElementAttributedContentViaDiffer = _tc => {
|
||||
/**
|
||||
* @param {t.TestCase} _tc
|
||||
*/
|
||||
export const testAttributionManagerSimpleExample = _tc => {
|
||||
export const testRendererSimpleExample = _tc => {
|
||||
const ydoc = new Y.Doc()
|
||||
ydoc.clientID = 0
|
||||
// create some initial content
|
||||
@@ -295,7 +295,7 @@ export const testAttributionManagerSimpleExample = _tc => {
|
||||
ytext.delete(11, 8)
|
||||
ytext.insert(11, '!')
|
||||
// highlight the changes
|
||||
console.log(JSON.stringify(ydocFork.get().toDeltaDeep(Y.createAttributionManagerFromDiff(ydoc, ydocFork)), null, 2))
|
||||
console.log(JSON.stringify(ydocFork.get().toDeltaDeep({ renderer: Y.createDiffRenderer(ydoc, ydocFork) }), null, 2))
|
||||
/* =>
|
||||
{
|
||||
"children": {
|
||||
@@ -390,7 +390,7 @@ const collectForbiddenOps = (d, forbidden, path = '$', acc = []) => {
|
||||
|
||||
/**
|
||||
* Reproduces the y-prosemirror issue #247 contract violation at the @y/y
|
||||
* level: `ytype.toDeltaDeep(am)` is supposed to surface soft-deleted content
|
||||
* level: `ytype.toDeltaDeep({ renderer })` is supposed to surface soft-deleted content
|
||||
* as positive ops (`SetAttrOp` / `InsertOp`) carrying attribution metadata,
|
||||
* never as `DeleteAttrOp` / `DeleteOp`. Today, when a parent YXmlElement is
|
||||
* itself soft-deleted under attribution, `typeMapGetDelta` (ytype.js:1928)
|
||||
@@ -398,7 +398,7 @@ const collectForbiddenOps = (d, forbidden, path = '$', acc = []) => {
|
||||
* cascaded child setAttr / content items - which downstream consumers
|
||||
* (lib0/delta `diff`, y-prosemirror's PM mapper) cannot handle.
|
||||
*
|
||||
* Expected after fix: walking the delta returned by `parent.toDeltaDeep(am)`
|
||||
* Expected after fix: walking the delta returned by `parent.toDeltaDeep({ renderer })`
|
||||
* finds zero `DeleteAttrOp` entries in any `attrs` map and zero `DeleteOp`
|
||||
* entries in any `children` list, at every nesting level.
|
||||
*
|
||||
@@ -424,8 +424,8 @@ export const testToDeltaDeepEmitsNoDeleteOpsForSoftDeletedParent = _tc => {
|
||||
parent.delete(0, 1)
|
||||
})
|
||||
|
||||
const am = Y.createAttributionManagerFromDiff(ydocV1, ydoc)
|
||||
const rendered = parent.toDeltaDeep(am)
|
||||
const renderer = Y.createDiffRenderer(ydocV1, ydoc)
|
||||
const rendered = parent.toDeltaDeep({ renderer })
|
||||
|
||||
// The cascade should surface as positive ops with attribution, not as
|
||||
// delete ops. Find any DeleteAttrOp / DeleteOp anywhere in the tree.
|
||||
@@ -439,7 +439,7 @@ export const testToDeltaDeepEmitsNoDeleteOpsForSoftDeletedParent = _tc => {
|
||||
}
|
||||
t.assert(
|
||||
offenders.length === 0,
|
||||
`toDeltaDeep(am) emitted ${offenders.length} forbidden delete op(s) for a soft-deleted parent (issue #247 / y-prosemirror)`
|
||||
`toDeltaDeep(renderer) emitted ${offenders.length} forbidden delete op(s) for a soft-deleted parent (issue #247 / y-prosemirror)`
|
||||
)
|
||||
}
|
||||
|
||||
@@ -460,8 +460,8 @@ export const testToDeltaDeepRendersExplicitDeleteAttrAsSetAttrWithAttribution =
|
||||
ydoc.transact(() => {
|
||||
ydoc.get('p').deleteAttr('id')
|
||||
})
|
||||
const am = Y.createAttributionManagerFromDiff(ydocV1, ydoc)
|
||||
const rendered = ydoc.get('p').toDeltaDeep(am)
|
||||
const renderer = Y.createDiffRenderer(ydocV1, ydoc)
|
||||
const rendered = ydoc.get('p').toDeltaDeep({ renderer })
|
||||
|
||||
const offenders = collectForbiddenOps(rendered, ['DeleteAttrOp', 'DeleteOp'])
|
||||
t.assert(offenders.length === 0, 'no DeleteAttrOp / DeleteOp from explicit deleteAttr under diff AM')
|
||||
|
||||
Reference in New Issue
Block a user