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

Block Toolbar: Refactor using KeyboardShorcuts component #3031

Closed
wants to merge 4 commits into from

Conversation

aduth
Copy link
Member

@aduth aduth commented Oct 16, 2017

Related: #2960 (specifically #2960 (comment))
Cherry-picks 334351c from #2863

This pull request seeks to refactor keyboard event handling introduced in #2960 to use the KeyboardShortcuts component, which abstracts many of the complexities of keyboard combinations and OS-varying modifiers.

The main challenge with this implementation is that Mousetrap (the underlying library behind KeyboardShortcuts) does not trigger callbacks if the keyboard combination is fired while within an input, except via its global binding extension. Since this was already implemented for #2863 (work-in-progress), it was merely cherry-picked for this pull request.

This pull request does not seek to implement any of the follow-up tasks from #2960. It is purely a refactor of existing behaviors.

Testing instructions:

Repeat testing instructions from #2960, verifying no regressions. From what I can tell from the discussion of #2960, this means: Pressing Ctrl (Windows) or Cmd (Mac) or a combination of Alt+F10 while a block is focused should move focus to the toolbar.

@aduth aduth added the [Focus] Accessibility (a11y) Changes that impact accessibility and need corresponding review (e.g. markup changes). label Oct 16, 2017
@codecov
Copy link

codecov bot commented Oct 16, 2017

Codecov Report

Merging #3031 into master will increase coverage by 0.16%.
The diff coverage is 37.5%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #3031      +/-   ##
==========================================
+ Coverage   32.76%   32.92%   +0.16%     
==========================================
  Files         203      203              
  Lines        5951     5940      -11     
  Branches     1052     1049       -3     
==========================================
+ Hits         1950     1956       +6     
+ Misses       3375     3362      -13     
+ Partials      626      622       -4
Impacted Files Coverage Δ
editor/utils/dom.js 40.47% <ø> (+0.94%) ⬆️
editor/block-toolbar/index.js 0% <0%> (ø) ⬆️
components/keyboard-shortcuts/index.js 85.71% <100%> (+85.71%) ⬆️
blocks/library/button/index.js 20% <0%> (ø) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 588ccd3...2601680. Read the comment docs.

this.mousetrap.bindGlobal( key, callback );
} else {
this.mousetrap.bind( key, callback );
}
} );
Copy link
Contributor

Choose a reason for hiding this comment

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

Do you think the shortcuts prop could change over time? Should we implement componentWillReceivePorps or not?

Copy link
Member Author

Choose a reason for hiding this comment

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

Do you think the shortcuts prop could change over time? Should we implement componentWillReceivePorps or not?

Potentially, though the effect could be imitated by rendering separate KeyboardShortcuts components (or changing the key of an existing one). Doesn't seem like a need we currently have, but then again, could be a potential source of confusion for future usage.

Copy link
Member Author

Choose a reason for hiding this comment

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

I started looking at this, and realized that there may be some non-trivial checks to consider whether keyboard bindings need to be updated.

https://gist.github.com/aduth/52f5c4ff561723c2d71b7e9d7fc142e7

Instead, and since there's currently no need, I improved documentation to note that shortcuts changes won't take effect and a suggested workaround (2601680).

<KeyboardShortcuts shortcuts={ {
mod: [ this.focusToolbar, true ],
'alt+f10': [ this.focusToolbar, true ],
} } />
Copy link
Contributor

Choose a reason for hiding this comment

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

Nice refactoring 👍

Copy link
Contributor

Choose a reason for hiding this comment

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

Can we handle the "escape" key as well onToolbarKeyDown?

Copy link
Member Author

Choose a reason for hiding this comment

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

Can we handle the "escape" key as well onToolbarKeyDown?

We can, but to recreate the handling of these keys only taking effect while within the toolbar, we'd want to introduce child scoping for KeyboardShortcuts. I mentioned this in #1944, and should probably be done as a separate refactoring step.

Copy link
Contributor

@youknowriad youknowriad left a comment

Choose a reason for hiding this comment

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

There are two differences with the previous behavior:

  • This fires on key down
  • This also fires when we try a combination (command + c) since it's on key down. I think we need to protect against this, we do not want to lose the focus on an input if we copy/paste...

@aduth
Copy link
Member Author

aduth commented Oct 17, 2017

There are two differences with the previous behavior:

Mousetrap does appear to support specifying the event to bind as a third argument:

https://craig.is/killing/mice

Will take a look to see how best we can expose this, especially considering we now expose a global option, and an array sequence is probably not very obvious / scalable.

@aduth
Copy link
Member Author

aduth commented Oct 17, 2017

In latest commits (which are delayed to show by GitHub service interruption) I've refactored global binding and specifying an event name to separate props of KeyboardShortcuts. This allows handling the events on keyup instead of keydown, to avoid the issue with modifier key firing the callback too early.

@youknowriad
Copy link
Contributor

Mmm, it looks like it's catching "command+*" key presses even on key up. This is a blocker IMO. Unless we change the "command" key (use "alt" or something else), I don't know how we can fix this and still use the KeyboardShortcuts component

@aduth
Copy link
Member Author

aduth commented Oct 18, 2017

@youknowriad Yeah, I've dug around a bit and there doesn't appear to be an obvious way to bind to just the modifier alone: keydown and keypress are too early since it could be the start of a combination, and keyup also fires for combinations.

Related: ccampbell/mousetrap#216

@aduth
Copy link
Member Author

aduth commented Oct 27, 2017

Going to close this as not solvable with Mousetrap currently, though it would be a nice refactor.

Changes here around adding a new bindGlobal prop to KeyboardShortcuts are likely to serve useful elsewhere.

@aduth aduth closed this Oct 27, 2017
@aduth aduth deleted the update/keyboard-shortcuts-toolbar branch October 27, 2017 13:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Focus] Accessibility (a11y) Changes that impact accessibility and need corresponding review (e.g. markup changes).
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants