From 800f0304da8534ad0763fcb8bbaa5d7adb344faf Mon Sep 17 00:00:00 2001 From: Kevin Jahns Date: Mon, 21 Apr 2025 15:59:03 +0200 Subject: [PATCH] basic attribution test working --- src/types/YText.js | 4 ++-- src/utils/Delta.js | 22 +++++++++++++++------- tests/y-text.tests.js | 5 +++-- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/types/YText.js b/src/types/YText.js index f9d36394..b42a766c 100644 --- a/src/types/YText.js +++ b/src/types/YText.js @@ -1037,12 +1037,12 @@ export class YText extends AbstractType { } switch (content.constructor) { case ContentString: { - d.insert(/** @type {ContentString} */ (content).str, {}, attributions) + d.insert(/** @type {ContentString} */ (content).str, null, attributions) break } case ContentType: case ContentEmbed: { - d.insert(/** @type {ContentEmbed | ContentType} */ (content).getContent()[0], {}, attributions) + d.insert(/** @type {ContentEmbed | ContentType} */ (content).getContent()[0], null, attributions) break } case ContentFormat: diff --git a/src/utils/Delta.js b/src/utils/Delta.js index 175b047c..9f31fd0a 100644 --- a/src/utils/Delta.js +++ b/src/utils/Delta.js @@ -10,6 +10,8 @@ import * as fun from 'lib0/function' */ /** + * @todo specify this better + * * @typedef {Object} Attribution * @property {boolean} [Attribution.isDeleted] * @property {boolean} [Attribution.isAdded] @@ -124,7 +126,11 @@ export class Delta { * @param {T | null} a * @param {T | null} b */ -const mergeAttrs = (a, b) => a == null ? b : (b == null ? a : object.assign({}, a, b)) +const mergeAttrs = (a, b) => { + const merged = a == null ? b : (b == null ? a : object.assign({}, a, b)) + if (object.isEmpty(merged ?? {})) { return null } + return merged +} export class DeltaBuilder extends Delta { constructor () { @@ -153,7 +159,6 @@ export class DeltaBuilder extends Delta { useAttributes (attributes) { if (this._useAttributes === attributes) return this this._useAttributes = attributes && object.assign({}, attributes) - if (this._lastOp?.constructor !== DeleteOp) this._lastOp = null return this } @@ -163,7 +168,6 @@ export class DeltaBuilder extends Delta { useAttribution (attribution) { if (this._useAttribution === attribution) return this this._useAttribution = attribution && object.assign({}, attribution) - if (this._lastOp?.constructor !== DeleteOp) this._lastOp = null return this } @@ -174,10 +178,12 @@ export class DeltaBuilder extends Delta { * @return {this} */ insert (insert, attributes = null, attribution = null) { - if (attributes === null && attribution === null && this._lastOp instanceof InsertOp) { + const mergedAttributes = mergeAttrs(this._useAttributes, attributes) + const mergedAttribution = mergeAttrs(this._useAttribution, attribution) + if (this._lastOp instanceof InsertOp && fun.equalityDeep(mergedAttributes, this._lastOp.attributes) && fun.equalityDeep(mergedAttribution, this._lastOp.attribution)) { this._lastOp.insert += insert } else { - this.ops.push(this._lastOp = new InsertOp(insert, mergeAttrs(this._useAttributes, attributes), mergeAttrs(this._useAttribution, attribution))) + this.ops.push(this._lastOp = new InsertOp(insert, mergedAttributes, mergedAttribution)) } return this } @@ -189,10 +195,12 @@ export class DeltaBuilder extends Delta { * @return {this} */ retain (retain, attributes = null, attribution = null) { - if (attributes === null && attribution === null && this._lastOp instanceof RetainOp) { + const mergedAttributes = mergeAttrs(this._useAttributes, attributes) + const mergedAttribution = mergeAttrs(this._useAttribution, attribution) + if (this._lastOp instanceof RetainOp && fun.equalityDeep(mergedAttributes, this._lastOp.attributes) && fun.equalityDeep(mergedAttribution, this._lastOp.attribution)) { this._lastOp.retain += retain } else { - this.ops.push(this._lastOp = new RetainOp(retain, mergeAttrs(this._useAttributes, attributes), mergeAttrs(this._useAttribution, attribution))) + this.ops.push(this._lastOp = new RetainOp(retain, mergedAttributes, mergedAttribution)) } return this } diff --git a/tests/y-text.tests.js b/tests/y-text.tests.js index 37c47799..c92c248a 100644 --- a/tests/y-text.tests.js +++ b/tests/y-text.tests.js @@ -2305,7 +2305,7 @@ export const testDeleteFormatting = _tc => { * @param {t.TestCase} tc */ export const testAttributedContent = tc => { - const ydoc = new Y.Doc() + const ydoc = new Y.Doc({ gc: false }) const ytext = ydoc.getText() ytext.insert(0, 'Hello World!') let am = noAttributionsManager @@ -2314,7 +2314,8 @@ export const testAttributedContent = tc => { }) ytext.applyDelta([{ retain: 6 }, { delete: 5 }, { insert: 'attributions' }]) const attributedContent = ytext.getContent(am) - t.assert(attributedContent.equals(delta.create().retain(6).insert('World', {}, { type: 'delete' }).insert('attributions', {}, { type: 'insert' }))) + const expectedContent = delta.create().insert('Hello ').insert('World', {}, { changeType: 'delete' }).insert('attributions', {}, { changeType: 'insert' }).insert('!') + t.assert(attributedContent.equals(expectedContent)) debugger }