Skip to content

Fixed MapperCache cache invalidation when view item is inserted at a beginning of a non-tracked element#18728

Merged
niegowski merged 1 commit intoreleasefrom
ck/18727-mapper-cache-incorrect-invalidation
Jun 17, 2025
Merged

Fixed MapperCache cache invalidation when view item is inserted at a beginning of a non-tracked element#18728
niegowski merged 1 commit intoreleasefrom
ck/18727-mapper-cache-incorrect-invalidation

Conversation

@scofalik
Copy link
Copy Markdown
Contributor

Suggested merge commit message (convention)

Fix (engine): Fixed editor crash that happened in a specific scenario, when editing heavily formatted text, text with multiple comments, or text with comments and formatting. Closes #18727.

Internal (engine): Renames in MapperCache methods so names correctly reflect what the methods do.

…_clearCacheInsideParent` as the former actually did not correctly clear cache starting from before the specified node.

Renamed `MapperCache#_clearCacheFromIndex` to `MapperCache#_clearCacheFromCacheIndex` to underline that the index means cache list index, not view index.
Renamed `MapperCache#_clearCacheStartingBefore` to `MapperCache#_clearCacheAfter` as the method was incorrectly named and didn't do what it said.
Changes in API docs and in-code comments.
@scofalik scofalik requested a review from niegowski June 17, 2025 13:10
Comment on lines +1124 to +1125
// Since it is not a tracked element, it has to have a parent.
this._clearCacheInsideParent( ( viewParent as ViewElement ).parent!, ( viewParent as ViewElement ).index! );
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR includes some renames and changes in comments/API docs, but this is the place where the actual change/fix happens.

Instead of using this._clearCacheStartingBefore( viewNode ) we use this._clearCacheInsideParent( viewNode.parent, viewNode.index ).

It turned out that _clearCacheStartingBefore() does not really do what it says. Instead, this method guarantees only that all cache after the node is cleared, so it's more like _clearCacheAfter(), and hence it was renamed too.

It actually does something in the middle, because it takes the cached mapping after the node, and clears from there including that mapping. For simple structures this is the same as "clear cache before", however for more complex structures, like from the example:

<p>ab<span>^cd<em><b>e</b>f</em></span>gh</p>

It didn't clear starting from before <span>. Instead it clears starting from "f" --- more or less.

Hence, it was incorrectly used here. Instead of using the method now renamed to clearCacheAfter we invoke _clearCacheInsideParent which correctly clears cache from given view position.

//
if ( !this._cachedMapping.has( viewParent ) ) {
this._clearCacheStartingBefore( viewParent );
this._clearCacheInsideParent( viewParent.parent!, viewParent.index! );
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is another place where the same fix was introduced, although given the latest changes in Mapper it seems that this code may not be reachable outside of artificial unit tests crafted for MapperCache. As in "TODO" above, it may be a dead code.

@scofalik
Copy link
Copy Markdown
Contributor Author

This fix leads to another +3-4% of performance overhead for certain scenarios (inline styles and tables).

@niegowski niegowski merged commit bcb74fe into release Jun 17, 2025
11 checks passed
@niegowski niegowski deleted the ck/18727-mapper-cache-incorrect-invalidation branch June 17, 2025 20:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants