Conversation
|
This also fixes #8960 |
| return ( | ||
| keyCode && | ||
| ![ | ||
| KeyCodes.RIGHT, |
There was a problem hiding this comment.
I think this it potentially worth rethinking to make it more flexible. I can see people wanting to add shortcuts that work in move mode. For example the i shortcut should possibly work in move mode.
An easy change would be to move this list of "shortcuts that are allowed to work in move mode" to a protected class member as well, so that it can be customized. But it's a little odd that it works based off the keycode and not the name of the shortcut.
There was a problem hiding this comment.
Are you thinking that we'd also make this registerable?
There was a problem hiding this comment.
discussed offline, will not make it registrable since it's the analog to Gesture which is also not registrable. You can customize a lot of the behavior in drag strategies. Aaron will add a method to add more keyboard shortcuts to the allow list so that keyboard shortcuts can exempt themselves from this behavior.
There was a problem hiding this comment.
Done; added methods to get and set the list of allowlisted shortcuts, and a test. Also switched everything that was protected to private, since there's no useful ability to subclass this if we're not making it registerable.
maribethb
left a comment
There was a problem hiding this comment.
everything so far lgtm, will review again for the changes we discussed offline
…ves at non-default zoom levels
The basics
The details
Proposed Changes
This PR backports the support for moving blocks, workspace comments, and bubbles using the keyboard from the blockly-keyboard-experimentation repo to core Blockly. These interactions have been proved out through user testing, and are an important foundational aspect of making Blockly more accessible. Toward this end, the following changes have been made:
IDragger,IDraggableandIDragStrategyinterfaces have been revised to put less of an emphasis on mouse events and clean up some other issues that using them in practice has revealed. See the Breaking Changes section below for more details.KeyboardMoverclass has been introduced. An object of this class is used to coordinate keyboard-driven movement between keyboard shortcuts and the dragging system. Although Blockly is generally moving away from global singletons in favor of per-workspace objects, KeyboardMover is one because (a) only one drag can be in progress at a given time, (b) drags can cross workspaces, for example dragging out of the flyout into the main workspace and (c) this opens the door for cross-workspace drags more broadly, or one toolbox that serves multiple workspaces.Future Work
At present, it is not possible to insert blocks from the flyout using the keyboard. This is now feasible, but in the interest of avoiding scope creep and preventing this PR from becoming even larger I will include it in a followup PR.
Additionally, the remaining functionality from the blockly-keyboard-experimentation repo still needs to be backported to core.
Test Coverage
Tests have been added that exercise each kind of built-in movable entity (blocks, workspace comments, and bubbles). Additionally, the test suite for constrained movement of blocks from the blockly-keyboard-experimentation repo has been backported.
Breaking Changes
If your application has custom code that implements the
IDragger,IDraggable, orIDragStrategyinterfaces, you may need to make some changes. Specifically:IDragStrategy.startDrag(),IDraggable.startDrag()andIDragger.onDragStart()need to return anIDraggable & ISelectable & IBoundedElementthat the rest of the drag process will act on. Typically,IDraggables should just return themselves. In cases where you want a drag to act on a different element than the one the drag started on, you can return the object you actually want the drag to act on.PointerEventnow need to handle receiving aPointerEvent | KeyboardEvent. In keyboard-driven drags, this will be aKeyboardEvent.IDraggernow need to implementIDragger.onDragRevert(). This method differs fromonDragEnd()in that it is invoked when a drag is cancelled or reverted by the user; generally, the item being dragged should be moved back to its starting position. If a drag is reverted,onDragEnd()will still be invoked afteronDragRevert()has been called, so common cleanup can be reliably handled there.IDraggerhave been made optional, consistent withIDraggableandIDragStrategy. Your code should not rely on them being present, although they typically will be for both mouse- and keyboard-driven drags.