From 08250a9a6cb5f53984189237a9a76366535eabb9 Mon Sep 17 00:00:00 2001 From: Noel Levy Date: Tue, 20 Jun 2023 14:23:03 -0700 Subject: [PATCH] skip formatting cleanup when the ytext doesnt have any ContentFormat also skip iterating the deleted structs entirely when none of the changed ytext had ContentFormat --- src/types/YText.js | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/src/types/YText.js b/src/types/YText.js index 79430c1a..75b6ff03 100644 --- a/src/types/YText.js +++ b/src/types/YText.js @@ -508,14 +508,16 @@ export const cleanupYTextAfterTransaction = transaction => { if (item instanceof GC || needFullCleanup.has(/** @type {YText} */ (item.parent))) { return } - const parent = /** @type {YText} */ (item.parent) - if (item.content.constructor === ContentFormat) { - needFullCleanup.add(parent) - } else { - // If no formatting attribute was inserted or deleted, we can make due with contextless - // formatting cleanups. - // Contextless: it is not necessary to compute currentAttributes for the affected position. - cleanupContextlessFormattingGap(t, item) + const parent = item.parent + if (parent instanceof YText && parent._needFormattingCleanup) { + if (item.content.constructor === ContentFormat) { + needFullCleanup.add(parent) + } else { + // If no formatting attribute was inserted or deleted, we can make due with contextless + // formatting cleanups. + // Contextless: it is not necessary to compute currentAttributes for the affected position. + cleanupContextlessFormattingGap(t, item) + } } }) // If a formatting item was inserted, we simply clean the whole type. @@ -862,6 +864,7 @@ export class YText extends AbstractType { * @type {Array} */ this._searchMarker = [] + this._needFormattingCleanup = false } /** @@ -910,9 +913,18 @@ export class YText extends AbstractType { super._callObserver(transaction, parentSubs) const event = new YTextEvent(this, transaction, parentSubs) callTypeObservers(this, transaction, event) + this._needFormattingCleanup = false // If a remote change happened, we try to cleanup potential formatting duplicates. - if (!transaction.local) { - transaction._needFormattingCleanup = true + if (!transaction.local && !transaction._needFormattingCleanup) { + let item = this._start + while (item) { + if (!item.deleted && item.content.constructor === ContentFormat) { + this._needFormattingCleanup = true + transaction._needFormattingCleanup = true + break + } + item = item.right + } } }