From d6a3e637e0158ddfdafa238db2086ed4625f00f2 Mon Sep 17 00:00:00 2001 From: Kevin Jahns Date: Wed, 11 Jun 2025 00:00:07 +0200 Subject: [PATCH] fixes for accepting / rejecting suggestions --- src/types/YText.js | 1 - src/utils/AttributionManager.js | 25 ++++++++++++++++++++++--- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/types/YText.js b/src/types/YText.js index 25eadf4c..7bde7754 100644 --- a/src/types/YText.js +++ b/src/types/YText.js @@ -1081,7 +1081,6 @@ export class YText extends AbstractType { */ const formattingAttribution = object.assign({}, d.usedAttribution) const attributesChanged = /** @type {{ [key: string]: Array }} */ (formattingAttribution.attributes = object.assign({}, formattingAttribution.attributes ?? {})) - debugger if (value === null) { delete attributesChanged[key] } else { diff --git a/src/utils/AttributionManager.js b/src/utils/AttributionManager.js index 0f333e83..d1f90364 100644 --- a/src/utils/AttributionManager.js +++ b/src/utils/AttributionManager.js @@ -26,7 +26,8 @@ import { getItemCleanStart, Transaction, StructStore, - intersectSets + intersectSets, + ContentFormat } from '../internals.js' import * as error from 'lib0/error' @@ -249,7 +250,7 @@ const getItemContent = (store, client, clock, len) => { if (diffStart > 0) { content = content.splice(diffStart) } - if (len > 0) { + if (len < content.getLength()) { content.splice(len) } return content @@ -266,14 +267,24 @@ const collectSuggestedChanges = (tr, am, start, end, collectAll) => { const inserts = createIdSet() const deletes = createIdSet() const store = am._nextDoc.store + /** + * make sure to collect suggestions until all formats are closed + * @type {Set} + */ + const openedCollectedFormats = new Set() /** * @type {Item?} */ let item = getItem(store, start) const endItem = start === end ? item : (end == null ? null : getItem(store, end)) + // walk to the left and find first un-attributed change that is rendered while (item.left != null) { item = item.left + if (item.content instanceof ContentFormat && item.content.value == null) { + item = item.right + break + } if (!item.deleted) { const slice = am.inserts.slice(item.id.client, item.id.clock, item.length) if (slice.some(s => s.attrs === null)) { @@ -312,11 +323,19 @@ const collectSuggestedChanges = (tr, am, start, end, collectAll) => { } } } else { + if (item.content instanceof ContentFormat) { + const {key, value} = item.content + if (value == null) { + openedCollectedFormats.delete(key) + } else { + openedCollectedFormats.add(key) + } + } for (let i = 0; i < slice.length; i++) { const s = slice[i] if (s.attrs != null) { inserts.add(itemClient, s.clock, s.len) - } else if (foundEndItem) { + } else if (foundEndItem && openedCollectedFormats.size === 0) { break itemLoop } }