Shortcut support

This commit is contained in:
Chi Vinh Le
2018-03-25 22:43:30 +02:00
parent ee9786de02
commit 11051fbdb9
6 changed files with 43 additions and 6 deletions
@@ -126,6 +126,17 @@ class RTE extends React.Component {
});
};
// Allow buttons to handle shortcuts.
handleShortcut = e => {
let handled = false;
this.forEachButton(b => {
if (!handled) {
handled = !!(b.onShortcut && b.onShortcut(e));
}
});
return handled;
};
// Called when Enter was pressed without shift.
// Traverses from bottom to top and calling
// button handlers and stops when one has handled this event.
@@ -209,6 +220,13 @@ class RTE extends React.Component {
return false;
}
if (e.metaKey || e.ctrlKey) {
if (this.handleShortcut(e)) {
e.preventDefault();
return false;
}
}
// Newlines Or Special Enter Behaviors.
if (e.key === 'Enter') {
if (!e.shiftKey && this.handleSpecialEnter()) {
@@ -4,7 +4,7 @@ import {
insertNewLineAfterNode,
insertNodes,
getSelectedNodesExpanded,
outdentNode,
outdentBlock,
selectEndOfNode,
indentNodes,
} from '../lib/dom';
@@ -12,7 +12,7 @@ import {
function execCommand() {
const bq = findIntersecting('BLOCKQUOTE', this.container);
if (bq) {
outdentNode(bq, true);
outdentBlock(bq, true);
} else {
// Expanded selection means we always select whole lines.
const selectedNodes = getSelectedNodesExpanded();
@@ -25,8 +25,16 @@ function isDisabled() {
this.container
);
}
function onShortcut(e) {
if (e.key === 'b') {
if (!isDisabled.apply(this)) {
execCommand.apply(this);
}
return true;
}
}
const Bold = createToggle(execCommand, { isActive, isDisabled });
const Bold = createToggle(execCommand, { isActive, isDisabled, onShortcut });
Bold.defaultProps = {
children: 'Bold',
@@ -23,8 +23,16 @@ function isDisabled() {
this.container
);
}
function onShortcut(e) {
if (e.key === 'i') {
if (!isDisabled.apply(this)) {
execCommand.apply(this);
}
return true;
}
}
const Italic = createToggle(execCommand, { isActive, isDisabled });
const Italic = createToggle(execCommand, { isActive, isDisabled, onShortcut });
Italic.defaultProps = {
children: 'Italic',
@@ -8,7 +8,7 @@ import Button from '../components/Button';
*/
const createToggle = (
execCommand,
{ onEnter, isActive = () => false, isDisabled = () => false } = {}
{ onEnter, onShortcut, isActive = () => false, isDisabled = () => false } = {}
) => {
class Toggle extends React.Component {
state = {
@@ -20,6 +20,8 @@ const createToggle = (
isActive = () => isActive.apply(this.props.api);
isDisabled = () => isDisabled.apply(this.props.api);
onEnter = (...args) => onEnter && onEnter.apply(this.props.api, args);
onShortcut = (...args) =>
onShortcut && onShortcut.apply(this.props.api, args);
unmounted = false;
componentWillUnmount() {
@@ -498,7 +498,7 @@ export function getSelectedChildren(ancestor) {
/**
* Removes node and assimilate its children with the parent.
*/
export function outdentNode(node, changeSelection) {
export function outdentBlock(node, changeSelection) {
// Save previous range.
const selectionWasInside = isSelectionInside(node);
const {
@@ -517,6 +517,7 @@ export function outdentNode(node, changeSelection) {
const needLineAfter =
node.nextSibling &&
!isBlockElement(node.nextSibling) &&
node.lastChild &&
!isBlockElement(node.lastChild);
const needLineBefore =
node.previousSibling &&