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

fix(portable-text-editor): add autoresolving validations and fix normalization issues #6770

Merged
merged 2 commits into from
May 28, 2024

Conversation

skogsmaskin
Copy link
Member

@skogsmaskin skogsmaskin commented May 24, 2024

Description

This will add two auto-resolving validations:

  • Test a block for orphaned markDefs and remove obsolete ones (previously only done through editor normalization).
  • Test a block for orphaned marks and remove obsolete ones (previously a hard validation error).

By introducing these new validations, I found two issues. The first was there before, and the other one occured introducing the new normalization rules of markDefs.

  • Fix issue where deleting block 3, 2 and partially 1 where block 1 contains an remaining annotation (too many validation iterations error).
  • Fix issue where copying an text fragment containing an annotation would not be valid with the new validation code.

What to review

Testing

Should be covered by unit tests.

Notes for release

Improve the validation of content in the Portable Text Editor.

Copy link

vercel bot commented May 24, 2024

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

Name Status Preview Comments Updated (UTC)
page-building-studio ✅ Ready (Inspect) Visit Preview 💬 Add feedback May 27, 2024 0:41am
performance-studio ✅ Ready (Inspect) Visit Preview 💬 Add feedback May 27, 2024 0:41am
test-next-studio ✅ Ready (Inspect) Visit Preview 💬 Add feedback May 27, 2024 0:41am
test-studio ✅ Ready (Inspect) Visit Preview 💬 Add feedback May 27, 2024 0:41am
1 Ignored Deployment
Name Status Preview Comments Updated (UTC)
studio-workshop ⬜️ Ignored (Inspect) Visit Preview May 27, 2024 0:41am

Copy link
Contributor

No changes to documentation

Copy link
Contributor

github-actions bot commented May 24, 2024

Component Testing Report Updated May 27, 2024 12:40 PM (UTC)

File Status Duration Passed Skipped Failed
comments/CommentInput.spec.tsx ✅ Passed (Inspect) 37s 15 0 0
formBuilder/ArrayInput.spec.tsx ✅ Passed (Inspect) 6s 3 0 0
formBuilder/inputs/PortableText/Annotations.spec.tsx ✅ Passed (Inspect) 26s 6 0 0
formBuilder/inputs/PortableText/copyPaste/CopyPaste.spec.tsx ✅ Passed (Inspect) 31s 11 7 0
formBuilder/inputs/PortableText/Decorators.spec.tsx ✅ Passed (Inspect) 14s 6 0 0
formBuilder/inputs/PortableText/DisableFocusAndUnset.spec.tsx ✅ Passed (Inspect) 8s 3 0 0
formBuilder/inputs/PortableText/FocusTracking.spec.tsx ✅ Passed (Inspect) 36s 15 0 0
formBuilder/inputs/PortableText/Input.spec.tsx ✅ Passed (Inspect) 1m 15s 21 0 0
formBuilder/inputs/PortableText/ObjectBlock.spec.tsx ✅ Passed (Inspect) 1m 3s 18 0 0
formBuilder/inputs/PortableText/PresenceCursors.spec.tsx ✅ Passed (Inspect) 7s 3 9 0
formBuilder/inputs/PortableText/RangeDecoration.spec.tsx ✅ Passed (Inspect) 21s 9 0 0
formBuilder/inputs/PortableText/Styles.spec.tsx ✅ Passed (Inspect) 15s 6 0 0
formBuilder/inputs/PortableText/Toolbar.spec.tsx ✅ Passed (Inspect) 30s 12 0 0

@@ -310,7 +310,7 @@ describe('initialization', () => {
_key: 'abc',
_type: 'myTestBlockType',
markDefs: [],
children: [{_key: 'def', _type: 'span', text: 'Test', marks: ['invalid']}],
children: [{_key: 'def', _type: 'span', marks: []}],
Copy link
Member Author

@skogsmaskin skogsmaskin May 24, 2024

Choose a reason for hiding this comment

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

The previous test case is now auto-resolved, so we need another (hard) validation error for this test.

},
{at: focusPath, mode: 'lowest', voids: false},
)
editor.withoutNormalizing(() => {
Copy link
Member Author

@skogsmaskin skogsmaskin May 24, 2024

Choose a reason for hiding this comment

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

This whole transformation must be run without normalizing, as we build up the data (we don't want to be normalizing orphaned data in the intermediate state).

@@ -142,7 +142,7 @@ export function createWithInsertData(
// Validate the result
const validation = validateValue(parsed, schemaTypes, keyGenerator)
// Bail out if it's not valid
if (!validation.valid) {
if (!validation.valid && !validation.resolution?.autoResolve) {
Copy link
Member Author

Choose a reason for hiding this comment

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

Validation errors for pasted fragments that can be auto-resolved should pass.

@@ -276,7 +283,7 @@ export function validateValue(
i18n: {
description: 'inputs.portable-text.invalid-value.orphaned-marks.description',
action: 'inputs.portable-text.invalid-value.orphaned-marks.action',
values: {key: blk._key, orphanedMarks},
values: {key: blk._key, orphanedMarks: orphanedMarks.map((m) => m.toString())},
Copy link
Member Author

Choose a reason for hiding this comment

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

Values for i18n must be strings, so safeguard this map as strings.

['split_node', 'remove_node', 'remove_text', 'merge_node'].includes(op.type),
editor.isTextBlock(node) &&
!editor.operations.some(
(op) => op.type === 'merge_node' && 'markDefs' in op.properties && op.path.length === 1,
Copy link
Member Author

Choose a reason for hiding this comment

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

Because of the new normalization rules, this must be rewritten (as discovered by tests).

Now we do the markDefs normalization here for every operation that is NOT merging two text blocks, as this will be an intermediate state, where potentially new child nodes are added later in the change (next operation). We should do this normalization in the later operations instead.

)
) {
normalizeMarkDefs(editor, types)
Copy link
Member Author

Choose a reason for hiding this comment

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

This is very pretty inefficient as it will do the whole editor, and not the actual nodes that are transformed.

@@ -517,7 +516,6 @@ export function createWithEditableAPI(
})
}
})
normalizeMarkDefs(editor, types)
Copy link
Member Author

Choose a reason for hiding this comment

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

This is now done in the normalization inside withPortableTextMarksModel

@skogsmaskin skogsmaskin marked this pull request as ready for review May 27, 2024 11:19
@skogsmaskin skogsmaskin requested review from a team and RitaDias and removed request for a team May 27, 2024 11:19
…alization issue

This will add up front validation for orphaned marks and markDefs that can be autoresolved through patches.

It will also fix some issues when it comes to adding and removing annotations, which transformations
now must be built up using the withoutNormalization scope.
Copy link
Contributor

@RitaDias RitaDias left a comment

Choose a reason for hiding this comment

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

This is great 👍 :shipit:

@skogsmaskin skogsmaskin added this pull request to the merge queue May 28, 2024
Merged via the queue into next with commit c458289 May 28, 2024
42 checks passed
@skogsmaskin skogsmaskin deleted the fix/pte-normalization-and-validation branch May 28, 2024 08:25
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