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

RichText: own undo signalling #10650

Merged
merged 4 commits into from
Nov 15, 2018
Merged

RichText: own undo signalling #10650

merged 4 commits into from
Nov 15, 2018

Conversation

ellatrix
Copy link
Member

@ellatrix ellatrix commented Oct 16, 2018

Description

This is a proposal for the RichText component to handle undo signalling in favour of listening to the TinyMCE change event.

RichText will signal that an undo level should be created:

  • When the user changes the value, except when it comes from the input event (typing).
  • When there is over a second pause between input events (typing).

Why?

It's not always clear when the change event exactly triggers and we do not always want it to create an undo level. The change event also no longer accounts for formatting changes, as these are no longer done by TinyMCE. It's easier to just do it ourselves so we can fine-tune and not rely on the TinyMCE event.

How has this been tested?

Test undoing and redoing changes from RichText components.

Screenshots

Types of changes

Checklist:

  • My code is tested.
  • My code follows the WordPress code style.
  • My code follows the accessibility standards.
  • My code has proper inline documentation.

@ellatrix ellatrix added [Feature] Rich Text Related to the Rich Text component that allows developers to render a contenteditable [Status] In Progress Tracking issues with work in progress [Feature] Writing Flow Block selection, navigation, splitting, merging, deletion... labels Oct 16, 2018
@ellatrix
Copy link
Member Author

@ellatrix ellatrix force-pushed the try/own-richtext-undo branch 2 times, most recently from bfc721d to 7c9ffa8 Compare November 1, 2018 13:31
@ellatrix

This comment has been minimized.

@aduth

This comment has been minimized.

@ellatrix

This comment has been minimized.

@ellatrix ellatrix force-pushed the try/own-richtext-undo branch from b1b60d4 to 0233a47 Compare November 2, 2018 08:33
@ellatrix ellatrix force-pushed the try/own-richtext-undo branch 3 times, most recently from 7cf30f6 to aa4740d Compare November 2, 2018 12:09
@ellatrix ellatrix requested review from a team, mcsf and aduth November 2, 2018 12:19
@ellatrix ellatrix added this to the 4.3 milestone Nov 2, 2018
@ellatrix ellatrix requested a review from a team November 2, 2018 15:51
@ellatrix ellatrix removed the [Status] In Progress Tracking issues with work in progress label Nov 9, 2018
packages/editor/src/components/rich-text/index.js Outdated Show resolved Hide resolved

await pressWithModifier( META_KEY, 'z' );

expect( await getEditedPostContent() ).toMatchSnapshot();
Copy link
Member

Choose a reason for hiding this comment

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

We should ideally test caret position here too. Because it resets to the beginning of the field unexpectedly. Apparently this also occurs in the latest plugin release, so not strictly a regression.

Copy link
Member Author

Choose a reason for hiding this comment

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

It's always been like this. We'll probably need to save selection to the editor state. Seems like material for a separate PR.

test/e2e/specs/blocks/__snapshots__/quote.test.js.snap Outdated Show resolved Hide resolved
test/e2e/specs/__snapshots__/undo.test.js.snap Outdated Show resolved Hide resolved
@aduth
Copy link
Member

aduth commented Nov 9, 2018

The Undo behavior feels particularly heavy-handed (destroying all of a paragraph I've written if I don't move my mouse), but I guess this aligns with the previous behavior as well.

@youknowriad youknowriad modified the milestones: 4.3, 4.4 Nov 9, 2018
@ellatrix
Copy link
Member Author

The Undo behavior feels particularly heavy-handed (destroying all of a paragraph I've written if I don't move my mouse), but I guess this aligns with the previous behavior as well.

It should behave roughly the same as before. With this change we can also fine tune it ourselves. Ideas for other triggers are welcome. Not sure what else we can do, maybe a typing pause could trigger an undo level? I don't think we can rely on punctuation as that's not universal.

@ellatrix ellatrix force-pushed the try/own-richtext-undo branch from 41ed725 to 1cfd664 Compare November 13, 2018 16:05
@ellatrix
Copy link
Member Author

@aduth I went for adding an undo level after a one second pause in input. We can adjust this value if it's too high or low.

@ellatrix ellatrix requested a review from a team November 13, 2018 17:44
@youknowriad youknowriad modified the milestones: 4.4, 4.5 Nov 15, 2018
@ellatrix ellatrix force-pushed the try/own-richtext-undo branch from 77da162 to 78c1a1c Compare November 15, 2018 10:25
@ellatrix ellatrix modified the milestones: 4.5, 4.4 Nov 15, 2018
@@ -612,7 +573,7 @@ export class RichText extends Component {
// The input event does not fire when the whole field is selected and
// BACKSPACE is pressed.
if ( keyCode === BACKSPACE ) {
this.onChange( this.createRecord(), true );
Copy link
Member

Choose a reason for hiding this comment

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

I don't understand why this change has been made.

Copy link
Member Author

Choose a reason for hiding this comment

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

We used to skip applying changes back to the live DOM, and so did we here. Since #11595 we no longer do that, but it hasn't been updated here. I've removed it here while revising the parameters for this.onChange.

await clickBlockAppender();

await page.keyboard.type( 'before pause' );
await new Promise( ( resolve ) => setTimeout( resolve, 1000 ) );
Copy link
Member

Choose a reason for hiding this comment

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

I wish we could emulate this without actually slowing our test run by one full second.

@@ -114,6 +99,9 @@ class EditorGlobalKeyboardShortcuts extends Component {
bindGlobal
shortcuts={ {
[ rawShortcut.primary( 's' ) ]: this.save,
[ rawShortcut.primary( 'z' ) ]: flow( preventDefault, onUndo ),
Copy link
Member

Choose a reason for hiding this comment

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

By moving this into bindGlobal, we're now preventing default behavior for all inputs in the page, not just RichText, right? We'd then rely on all of those inputs to be fully controlled by state values governed by history? I'm not sure I feel particularly confident we can trust that.

Copy link
Member

Choose a reason for hiding this comment

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

Example:

  1. Navigate to Posts > Add New
  2. Insert a reusable block
  3. Click Edit in the Reusable Block's heading
  4. Make some changes to the title
  5. Press Cmd+Z

In 4.3: Input undoes changes
In this branch: The block is removed (presumably undo'ing the block addition to the editor)

Copy link
Member Author

Choose a reason for hiding this comment

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

Which input fields on the page would not be included in our history? Maybe it would be better then for those to opt-in vs opt-out? Currently undoing any changes with the browser actually adds to the history, not removes.

Copy link
Member Author

Choose a reason for hiding this comment

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

Why is the title not part of the history?

Copy link
Member

Choose a reason for hiding this comment

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

Non-exhaustive set of others:

  • Embed placeholder URL input
  • Table placeholder columns / rows inputs
  • Media placeholders URL input
  • Post permalink
  • Categories search

(Discovered via onSubmit= Find in Files search)

Copy link
Member Author

Choose a reason for hiding this comment

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

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, for now I think we might just need to have two KeyboardShortcuts for handling these keys, one top-level but not applied to inputs, the other specific to when a RichText is selected.

tl;dr I think that's what we had in the prior revision you're referring to?

Copy link
Member Author

Choose a reason for hiding this comment

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

Right, I just restored your revision :)

@ellatrix ellatrix force-pushed the try/own-richtext-undo branch from 04430fc to dc4f688 Compare November 15, 2018 17:40
const HANDLED_SHORTCUTS = [
rawShortcut.primary( 'z' ),
rawShortcut.primaryShift( 'z' ),
rawShortcut.primary( 'y' ),
Copy link
Member

Choose a reason for hiding this comment

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

Not necessary here, but if we're going to support Cmd+Y , we should probably do so consistently between RichText and the top-level handler.

Copy link
Member Author

Choose a reason for hiding this comment

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

We're only removing the browser shortcut here, not adding any support. But maybe we should add support everywhere?

Copy link
Member

Choose a reason for hiding this comment

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

Hmm, in that case, is the line even necessary if we're not handling it anyways?

@ellatrix ellatrix force-pushed the try/own-richtext-undo branch from dc4f688 to 9dba9e5 Compare November 15, 2018 18:20
@ellatrix
Copy link
Member Author

Thanks a lot @aduth for the review!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Rich Text Related to the Rich Text component that allows developers to render a contenteditable [Feature] Writing Flow Block selection, navigation, splitting, merging, deletion...
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants