From 933111f75dce686be932b989164e0530d1e562db Mon Sep 17 00:00:00 2001 From: Kevin Jahns Date: Sun, 7 Dec 2025 02:13:04 +0100 Subject: [PATCH] fixed nested delta edge case --- src/types/AbstractType.js | 10 ++++++---- tests/attribution.tests.js | 24 ++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/types/AbstractType.js b/src/types/AbstractType.js index f450837d..49b2e9b6 100644 --- a/src/types/AbstractType.js +++ b/src/types/AbstractType.js @@ -479,7 +479,8 @@ export class AbstractType { * @type {EventDelta extends delta.Delta ? delta.DeltaBuilder : never} */ const d = /** @type {any} */ (delta.create(/** @type {any} */ (this).nodeName || null)) - typeMapGetDelta(d, /** @type {any} */ (this), renderAttrs, am, deep, modified, deletedItems, itemsToRender, opts) + const optsAll = modified == null ? opts : object.assign({}, opts, { modified: null }) + typeMapGetDelta(d, /** @type {any} */ (this), renderAttrs, am, deep, modified, deletedItems, itemsToRender, opts, optsAll) if (renderChildren) { /** * @type {delta.FormattingAttributes} @@ -571,7 +572,7 @@ export class AbstractType { if (c.deleted ? retainDeletes : retainInserts) { d.retain(c.content.getLength(), null, attribution ?? {}) } else if (deep && c.content.constructor === ContentType) { - d.insert([/** @type {any} */(c.content).type.getContent(am, opts)], null, attribution) + d.insert([/** @type {any} */(c.content).type.getContent(am, optsAll)], null, attribution) } else { d.insert(c.content.getContent(), null, attribution) } @@ -1314,11 +1315,12 @@ export const typeMapGetAll = (parent) => { * @param {import('../utils/IdSet.js').IdSet?} [deletedItems] * @param {import('../utils/IdSet.js').IdSet?} [itemsToRender] * @param {any} [opts] + * @param {any} [optsAll] * * @private * @function */ -export const typeMapGetDelta = (d, parent, attrsToRender, am, deep, modified, deletedItems, itemsToRender, opts) => { +export const typeMapGetDelta = (d, parent, attrsToRender, am, deep, modified, deletedItems, itemsToRender, opts, optsAll) => { // @todo support modified ops! /** * @param {Item} item @@ -1348,7 +1350,7 @@ export const typeMapGetDelta = (d, parent, attrsToRender, am, deep, modified, de } const prevValue = (prevContentItem !== item && itemsToRender?.hasId(prevContentItem.lastId)) ? array.last(prevContentItem.content.getContent()) : undefined if (deep && c instanceof AbstractType) { - c = /** @type {any} */(c).getContent(am) + c = /** @type {any} */(c).getContent(am, optsAll) } d.set(key, c, attribution, prevValue) } diff --git a/tests/attribution.tests.js b/tests/attribution.tests.js index c8892c1e..02f43348 100644 --- a/tests/attribution.tests.js +++ b/tests/attribution.tests.js @@ -107,3 +107,27 @@ export const testYdocDiff = () => { .update('map', delta.create().set('newk', 42, { insert: [] }).update('nested', delta.create().insert([1], null, { insert: [] }))) ) } + +export const testChildListContent = () => { + const ydocStart = new Y.Doc() + const ydocUpdated = Y.cloneDoc(ydocStart) + const yf = new Y.XmlElement('test') + let calledEvent = 0 + yf.applyDelta(delta.create().insert('test content').set('k', 'v')) + + const yarray = ydocUpdated.getArray('array') + yarray.observeDeep((events, tr) => { + calledEvent++ + const event = events.find(event => event.target === yarray) || new Y.YEvent(yarray, tr, new Set(null)) + const d = event.deltaDeep + const expectedD = delta.create().insert([delta.create('test').insert('test content').set('k', 'v')]) + t.compare(d, expectedD) + }) + ydocUpdated.getArray('array').insert(0, [yf]) + t.assert(calledEvent === 1) + const d = Y.diffDocsToDelta(ydocStart, ydocUpdated) + console.log('calculated diff', d.toJSON()) + t.compare(d, delta.create() + .update('array', delta.create().insert([delta.create('test').insert('test content', null, { insert: [] }).set('k', 'v', { insert: [] })], null, { insert: [] })) + ) +}