Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[lexical-history][lexical-selection][lexical-react] Fix: #6409 TextNode change detection #6420

Merged
merged 5 commits into from
Jul 22, 2024

Conversation

etrepum
Copy link
Collaborator

@etrepum etrepum commented Jul 18, 2024

Description

  • Targeted fix for lexical-history's TextNode change detection when only one text leaf is dirty but unchanged
  • Add delay option to HistoryPlugin
  • Fix $cloneWithProperties - the previous implementation did not correctly handle __textFormat from ParagraphNode. Also updated the very incorrect doc string.
  • Clean up lint and test warning issues elsewhere
  • Move $cloneWithProperties to the lexical package because the correct implementation was already inlined in LexicalNode.getWritable()

A more general fix may be possible, it's unclear whether this hack is really necessary for MaxLengthPlugin but other text node transforms may have similar issues so removing the hack could be backwards incompatible.

Closes #6409

Test plan

Before

History's TextNode change detection did not work correctly for subclasses where only properties that did not exist on TextNode changed.

After

The tests show that the behavior is consistent with expectations

@facebook-github-bot facebook-github-bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Jul 18, 2024
Copy link

vercel bot commented Jul 18, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
lexical ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jul 19, 2024 2:35pm
lexical-playground ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jul 19, 2024 2:35pm

Copy link

github-actions bot commented Jul 18, 2024

size-limit report 📦

Path Size
lexical - cjs 28.76 KB (0%)
lexical - esm 28.61 KB (0%)
@lexical/rich-text - cjs 37.2 KB (0%)
@lexical/rich-text - esm 28.21 KB (0%)
@lexical/plain-text - cjs 35.85 KB (0%)
@lexical/plain-text - esm 25.5 KB (0%)
@lexical/react - cjs 39.12 KB (0%)
@lexical/react - esm 29.49 KB (0%)

etrepum added 3 commits July 18, 2024 15:56
Add delay option to HistoryPlugin
Add test for facebook#6409
Fix lint issues
Fix $cloneWithProperties and test expectations
Targeted fix for TextNode leaf change
Comment on lines -89 to -91
if ($isParagraphNode(node) && $isParagraphNode(clone)) {
return $updateParagraphNodeProperties(clone, node);
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This was wrong because ParagraphNode is always an ElementNode and the exit already happened. This was implemented correctly in LexicalNode.getWritable() so I extracted and exported that implementation instead

Comment on lines -450 to -453
if ($isTextNode(clone)) {
invariant($isTextNode(node), 'Expected node be a TextNode');
clone.__text = node.__text;
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I could not find any possible reason for this code to be here, TextNode.clone already guarantees clone.__text === node.__text

@@ -51,6 +51,6 @@ export function useFilteredExamples(examples: Array<Example>) {
searchName,
tags,
}),
[examples, searchName],
[examples, searchName, tags],
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

eslint fix

cloneNotNeeded.add(key);
mutableNode.__key = key;
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This was not necessary because Node.clone must already do this, I added an invariant to guarantee it

@@ -2272,42 +2272,44 @@ describe('LexicalSelection tests', () => {
it('adjust offset for inline elements text formatting', async () => {
await init();

await editor!.update(() => {
const root = $getRoot();
await ReactTestUtils.act(async () => {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Wrapping this is necessary because the update causes a react update

@@ -17,13 +17,15 @@ export {createEmptyHistoryState} from '@lexical/history';
export type {HistoryState};

export function HistoryPlugin({
delay,
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Seemed reasonable to fix this missing option while I was in here

@@ -15,7 +15,6 @@ import {forwardRef, Ref, useLayoutEffect, useState} from 'react';
import {ContentEditableElement} from './shared/LexicalContentEditableElement';
import {useCanShowPlaceholder} from './shared/useCanShowPlaceholder';

/* eslint-disable @typescript-eslint/ban-types */
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Could not find a reason for this, if there's an internal meta reason we should sync the eslint config to match whatever that rule is

@etrepum etrepum marked this pull request as ready for review July 18, 2024 23:12
@etrepum
Copy link
Collaborator Author

etrepum commented Jul 18, 2024

I don't see the typical Lexical Tests checks running on this PR? /cc @potatowagon @Sahejkm

mutableNode.__mode = latestNode.__mode;
mutableNode.__detail = latestNode.__detail;
}
if (__DEV__) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I moved this to a __DEV__ because it's a new invariant in a relatively hot code path but we might want to run it unconditionally?

@potatowagon
Copy link
Contributor

I don't see the typical Lexical Tests checks running on this PR? /cc @potatowagon @Sahejkm

thats strange, why are the jobs skipped, will investigate

@potatowagon potatowagon added the extended-tests Run extended e2e tests on a PR label Jul 19, 2024
@potatowagon
Copy link
Contributor

it seems like the core test runs are missing

@potatowagon
Copy link
Contributor

it seems like the core test runs are missing

think its because of this:

- 'packages/lexical-website/**'

could be its ignoring core test trigger because this PR modifies the lexical website path. will fix it

@potatowagon
Copy link
Contributor

it seems like the core test runs are missing

think its because of this:

- 'packages/lexical-website/**'

could be its ignoring core test trigger because this PR modifies the lexical website path. will fix it

fixed in #6423

@potatowagon
Copy link
Contributor

potatowagon commented Jul 19, 2024

it seems like the core test runs are missing

think its because of this:

- 'packages/lexical-website/**'

could be its ignoring core test trigger because this PR modifies the lexical website path. will fix it

fixed in #6423

prolly not the reason since core tests are triggered on #6425. im not sure what else is causing the core test jobs to not trigger on this PR. could it be a transient issue? at least on test PR #6425 the core tests are triggering

Copy link
Contributor

@potatowagon potatowagon left a comment

Choose a reason for hiding this comment

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

thankyou for the fix! changes look fine according to e2e test results

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. extended-tests Run extended e2e tests on a PR
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Bug: history should work with custom TextNodes containing non-standard properties
5 participants