Skip to content

Commit

Permalink
meta+a to select all blocks after fully selected input field
Browse files Browse the repository at this point in the history
  • Loading branch information
ellatrix committed Jan 19, 2018
1 parent df24fd0 commit 1c39a63
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 3 deletions.
21 changes: 18 additions & 3 deletions editor/components/writing-flow/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*/
import { connect } from 'react-redux';
import 'element-closest';
import { find, last, reverse } from 'lodash';
import { find, first, last, reverse } from 'lodash';
/**
* WordPress dependencies
*/
Expand All @@ -20,6 +20,7 @@ import {
isVerticalEdge,
placeCaretAtHorizontalEdge,
placeCaretAtVerticalEdge,
isFullySelected,
} from '../../utils/dom';
import {
getBlockUids,
Expand All @@ -33,7 +34,7 @@ import { multiSelect, appendDefaultBlock } from '../../store/actions';
/**
* Module Constants
*/
const { UP, DOWN, LEFT, RIGHT } = keycodes;
const { UP, DOWN, LEFT, RIGHT, isMeta } = keycodes;

function isElementNonEmpty( el ) {
return !! el.innerText.trim();
Expand Down Expand Up @@ -148,7 +149,7 @@ class WritingFlow extends Component {
}

onKeyDown( event ) {
const { selectedBlock, selectionStart, selectionEnd, blocks, hasMultiSelection } = this.props;
const { selectedBlock, selectionStart, selectionEnd, blocks, hasMultiSelection, onMultiSelect } = this.props;

const { keyCode, target } = event;
const isUp = keyCode === UP;
Expand Down Expand Up @@ -193,6 +194,20 @@ class WritingFlow extends Component {
) {
this.props.onBottomReached();
}

// We have to check early, by the time both keys are pressed,
// selection already happened.
if ( isMeta( event ) ) {
this.activeElementFullySelected = isFullySelected( document.activeElement );
}

if ( isMeta( event, 'a' ) ) {
if ( this.activeElementFullySelected ) {
onMultiSelect( first( blocks ), last( blocks ) );
}

this.activeElementFullySelected = isFullySelected( document.activeElement );
}
}

render() {
Expand Down
26 changes: 26 additions & 0 deletions editor/utils/dom.js
Original file line number Diff line number Diff line change
Expand Up @@ -341,3 +341,29 @@ export function documentHasSelection() {

return range && ! range.collapsed;
}

export function isFullySelected( element ) {
if ( includes( [ 'INPUT', 'TEXTAREA' ], element.nodeName ) ) {
return element.selectionStart === 0 && element.value.length === element.selectionEnd;
}

if ( ! element.isContentEditable ) {
return true;
}

const selection = window.getSelection();
const range = selection.rangeCount ? selection.getRangeAt( 0 ) : null;

if ( ! range ) {
return true;
}

const { startContainer, endContainer, startOffset, endOffset } = range;

return (
startContainer === element &&
endContainer === element &&
startOffset === 0 &&
endOffset === element.childNodes.length
);
}
28 changes: 28 additions & 0 deletions utils/keycodes.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
/**
* Browser dependencies
*/
const { userAgent } = window.navigator;

const isMac = userAgent.indexOf( 'Mac' ) !== -1;

export const BACKSPACE = 8;
export const TAB = 9;
export const ENTER = 13;
Expand All @@ -10,3 +17,24 @@ export const DOWN = 40;
export const DELETE = 46;

export const F10 = 121;

/**
* Check if the meta key and the given character are presssed.
*
* @param {KeyboardEvent} event The event object.
* @param {String} character The character to check.
* @return {Boolean} True if the combination is pressed, false if not.
*/
export function isMeta( event, character ) {
const meta = isMac ? 'Meta' : 'Ctrl';

if ( ! event[ meta.toLowerCase() + 'Key' ] ) {
return false;
}

if ( ! character ) {
return event.key === meta;
}

return event.key === character;
}

0 comments on commit 1c39a63

Please sign in to comment.