-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
Handle undo / redo keyboard events #1943
Conversation
096fab5
to
079a306
Compare
Rebased and force pushed with consideration for #1944 |
blocks/index.js
Outdated
@@ -17,5 +17,6 @@ export { default as AlignmentToolbar } from './alignment-toolbar'; | |||
export { default as BlockControls } from './block-controls'; | |||
export { default as BlockDescription } from './block-description'; | |||
export { default as Editable } from './editable'; | |||
export { default as EditableProvider } from './editable/provider'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this something we want to make accessible?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The minimum requirement is that the editor provides the context assumed to exist by the Editable
component. This could be implemented within editor
and not exposed, but then the coupling between Editable
and its context becomes unclear.
Personally I think it should be left here. If we want to discourage particular exports, maybe we could do so merely by omitting documentation
} else { | ||
onUndo(); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the purpose of the prevent default here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the purpose of the prevent default here?
It ensures that the browser default undo behavior is overridden by our custom implementation.
It's likely browser specific, but at least in Chrome I notice some differences in how undo stacks are generated with contenteditable
vs. our save intervals with Editable changes.
@aduth should we make the undo / redo buttons operate the same way? |
I like this, looks good to merge after fixing the conflicts. It'd also be nice to make sure the behaviour of the UI buttons and the keyboard shortcuts was the same. |
Are you referring to the ones in the header? Both those and the keyboard handlers added here operate on the same |
They don't seem to behave equally, with the top level looking disabled sometimes when command+z still works. |
Do you have specific steps to reproduce? |
079a306
to
eb38597
Compare
Even with these changes I'm finding that undo could still do for some refining, particularly in undoing / redoing changes which have been saved. |
Codecov Report
@@ Coverage Diff @@
## master #1943 +/- ##
==========================================
+ Coverage 20.24% 20.26% +0.01%
==========================================
Files 130 131 +1
Lines 4184 4205 +21
Branches 711 715 +4
==========================================
+ Hits 847 852 +5
- Misses 2812 2826 +14
- Partials 525 527 +2
Continue to review full report at Codecov.
|
I am ok with getting this as is and refining. |
eb38597
to
bc765e5
Compare
bc765e5
to
3eaed9a
Compare
Closes #627
This pull request seeks to implement Cmd/Ctrl+Z (undo) and Cmd/Ctrl+Shift+Z (redo) behaviors.
Implementation notes:
The implementation is similar to the compromise proposed by @youknowriad at #627 (comment) with some modification. Because we do not sync the TinyMCE value to state until a change event occurs, we allow TinyMCE to handle undo history while the Editable field is focused. If there is no TinyMCE undo history, we propagate the event to be handled by the editor's
UNDO
action behavior. This works largely because we calleditor.save
during the change event handler to reset undo history.Included in these changes is a proposed EditorProvider component which leverages React context (like
react-redux
) to allow the Editable to communicate with its wrapping editor render hierarchy. This allows Editable to continue to be unaware of the editor or any specific editor instance, while allowing it to propagate the Undo callback without block implementer intervention. I'm curious to apply this pattern to other behaviors as well, such as focus handling.Testing instructions:
Verify that global Undo handler works as expected:
Verify that TinyMCE undo handler works as expected: