-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
Blocks: Select ALL on Ctrl+A outside editable DOM elements #1211
Conversation
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.
Noting that this takes over select-all for the entire screen, which may be what we're expecting. Try Cmd-A on any page (including this GitHub page) to see the effect I'm illustrating.
editor/modes/visual-editor/index.js
Outdated
|
||
/** | ||
* WordPress dependencies | ||
*/ | ||
import { __ } from 'i18n'; | ||
import { Component, findDOMNode } from 'element'; | ||
import { LETTER_A, SMALL_LETTER_A } from 'utils/keycodes'; |
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.
Two things:
- Maybe
LOWER_LETTER_A
(lowercase, uppercase distinction) - Do we need to capture uppercase A? Cmd-Shift-A is not typically a valid combination for Select All behavior.
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.
Actually, I'm going to use only LETTER_A because there's no difference between the two in keydown events. (The keycode is the same)
editor/modes/visual-editor/index.js
Outdated
@@ -40,6 +52,20 @@ class VisualEditor extends Component { | |||
} | |||
} | |||
|
|||
onKeyDown( event ) { | |||
const { uids } = this.props; | |||
const isEditable = [ 'textarea', 'input', 'select' ].indexOf( document.activeElement.tagName.toLowerCase() ) !== -1 |
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.
Starting to see these conditions pop up in a few PRs with minor variations. Seems prone to edge cases or errors. Tested utilities might be more appropriate.
Wondering if there's another way to test here:
- If there's no
activeElement
(or is the default,document.body
I think) - If there's no focused blocks
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 idea was to enable Ctrl+A even if we're focusing a button or any focusable but not editable. We could restrict to document.body of course.
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.
cc @jasmussen
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.
I'm still a bit hesitant about this logic. Do you think this should be in a utility class, e.g. isActiveElementEditable
, or isEditableElement( document.activeElement )
?
I'd found that in some browsers, window.getSelection()
has a type
property against which we could perhaps test === 'caret'
for reasonable accuracy, but unfortunately not all browsers define this property:
https://developer.mozilla.org/en-US/docs/Web/API/Selection/type
This is really really really nice! Thanks for working on it. ⌘ A inside a block selects all there, ⌘ A outside, selects all blocks.
I could go either way on this one. On the one hand, having it be unrestricted (i.e. ⌘ A no matter what has focus, unless of course it's inside a textarea selects all blocks) is similar to many desktop apps, even ones that have served in part as inspiration for some of our efforts, like Sketch. On the other hand, it's a non-standard web-page behavior. So which are we more, an app, or a web-page? I'm leaning towards the former, i.e. keeping the behavior as is. One thing though — it would be nice (not super important, can be separate PR, low priority), if clicking anywhere outside the selected blocks deselected. Right now you can press the white area outside of the blocks to deselect. It'd be nice if you could also click the empty space under the sidebars. But I'd like a sanity check. @melchoyce @folletto any thoughts? Here's a video where I talk over: https://cloudup.com/csoAyszQ-Bf |
The interaction feels nice! I like the top bar with the number of blocks selected and "delete." Only weird thing IMO is copying the blocks, copies the HTML. I expected it to just copy the text of the blocks so I could paste it into another text editor. |
This has implications, because we want to keep selection if we click the inserter and post settings. I think the "deselection" behaviour should be addressed separately, it's more complex than it seems. Should we merge here? |
I'm okay with merging, if there are no code objections. |
utils/keycodes.js
Outdated
@@ -7,3 +7,4 @@ export const UP = 38; | |||
export const RIGHT = 39; | |||
export const DOWN = 40; | |||
export const DELETE = 46; | |||
export const LETTER_A = 65; |
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.
Where we can, would it be better to calculate for clarity? Also maybe it's better to call it CHAR_A
(broader collection)?
export const CHAR_A = 'A'.charCodeAt(0);
Here is some useful info on using event.keyCode
: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode. Could we use event.key
instead? https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key
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.
I recall discussions about compatibility issues for event.key
in some browsers. cc @aduth
And we're using keyCode
everywhere now.
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.
Related: #1215 (comment)
Not sure what the issues are with IE11 and "non-standard key identifiers", also only available in latest iOS version, which violates documented browser support.
Nice one! 👍 I +1 Mel's comment. ;) |
Yes, Copy/Paste need more ❤️ and is tracked here #943 |
editor/modes/visual-editor/index.js
Outdated
|| document.activeElement.isContentEditable; | ||
if ( | ||
! isEditable && | ||
( event.ctrlKey || event.metaKey ) && |
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.
A bit unexpected that Ctrl-A on Mac will select all (not default behavior), but trying to distinguish by OS seems to devolve into absurdity quite quickly, so I'm not sure we care to spend the effort.
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 event.metaKey
defined by other OSs? If not, we could look at that.
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.
On Windows, it's the Windows key (⊞), and conversely ⊞+a is not a valid "select all" combination.
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.
I suppose in windows, it won't trigger because it triggers the "start" menu?
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.
😱
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.
trying to distinguish by OS seems to devolve into absurdity quite quickly, so I'm not sure we care to spend the effort
😆
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.
Ok let's get this merged then :). An approval?
editor/modes/visual-editor/index.js
Outdated
@@ -40,6 +52,20 @@ class VisualEditor extends Component { | |||
} | |||
} | |||
|
|||
onKeyDown( event ) { | |||
const { uids } = this.props; | |||
const isEditable = [ 'textarea', 'input', 'select' ].indexOf( document.activeElement.tagName.toLowerCase() ) !== -1 |
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.
I'm still a bit hesitant about this logic. Do you think this should be in a utility class, e.g. isActiveElementEditable
, or isEditableElement( document.activeElement )
?
I'd found that in some browsers, window.getSelection()
has a type
property against which we could perhaps test === 'caret'
for reasonable accuracy, but unfortunately not all browsers define this property:
https://developer.mozilla.org/en-US/docs/Web/API/Selection/type
closes #3
So basically, I'm listening to all Ctrl+A and Command+A events and if the active element is not editable (is not an input, textarea, select or contenteditable), I trigger a global multi selection.