Skip to content

Commit

Permalink
Start implementation of keyboard shortcut availability. Fix #32
Browse files Browse the repository at this point in the history
  • Loading branch information
thibaudcolas committed Jan 12, 2017
1 parent c6e948c commit 8cc1eab
Show file tree
Hide file tree
Showing 7 changed files with 103 additions and 65 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html
### Fixed

- Fix erratic behavior of list nesting changes with tab and shift+tab shortcuts. #34
- Fix keyboard shortcuts giving access to unallowed formatting. #32

### Removed

Expand Down
22 changes: 11 additions & 11 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,19 @@ We support most of the common keyboard shortcuts users would expect to find in t

Here are the most important shortcuts:

|Shortcut|Function|
|Shortcut|Function (if enabled)|
|--------|--------|
|Cmd + B | Bolden text (if enabled) |
|Cmd + I | Italicise text (if enabled) |
|Cmd + U | Underline text (if enabled) |
|Cmd + J | Format as code (if enabled) |
|Cmd + B | Bold |
|Cmd + I | Italicize |
|Cmd + U | Underline |
|Cmd + J | Monospace (code) |
|Option + Shift + 5 | Strikethrough |
|Cmd + Z | Undo |
|Cmd + Maj + Z | Redo |
|Cmd + Left | Move selection to start of block |
|Cmd + Right | Move selection to end of block |
|Cmd + Tab|Increase indentation of list items|
|Cmd + Maj + Tab|Decrease indentation of list items|
|Cmd + Shift + Z | Redo |
|Cmd + Left | Move focus to start of block |
|Cmd + Right | Move focus to end of block |
|Cmd + Tab |Increase indentation of list items |
|Cmd + Shift + Tab |Decrease indentation of list items |

Other shortcuts we would like to support in the future:

Expand Down Expand Up @@ -71,7 +72,6 @@ For all browser versions defined as "latest", we will ensure support by using a
| IE | Desktop | 9 | |
| IE | Desktop | 8 | |


## R&D notes

### Other Draft.js editors
Expand Down
1 change: 1 addition & 0 deletions examples/basic.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const options = {
INLINE_STYLES: [
{ label: 'Bold', style: INLINE_STYLE.BOLD, icon: 'icon-bold' },
{ label: 'Italic', style: INLINE_STYLE.ITALIC, icon: 'icon-italic' },
{ label: 'Strikethrough', style: INLINE_STYLE.STRIKETHROUGH, icon: 'icon-pacman' },
],
};

Expand Down
79 changes: 78 additions & 1 deletion lib/api/config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
import { Map } from 'immutable';
import { DefaultDraftBlockRenderMap } from 'draft-js';
import {
DefaultDraftBlockRenderMap,
getDefaultKeyBinding,
KeyBindingUtil,
} from 'draft-js';

import { INLINE_STYLE, KEY_CODES } from '../api/constants';

const { isOptionKeyCommand, hasCommandModifier } = KeyBindingUtil;

// Maximum level of nesting for unordered and ordered lists.
export const MAX_LIST_NESTING = 1;
Expand Down Expand Up @@ -43,4 +51,73 @@ export default {

return blockStyleFn;
},

/**
* Configure key binding function from available blocks, styles, entities.
*/
getKeyBindingFn(BLOCK_TYPES = [], INLINE_STYLES = []) {
const isStyleAvailable = style => INLINE_STYLES.find(item => item.style === style);

const isAvailable = Object.keys(INLINE_STYLE).reduce((available, style) => {
// eslint-disable-next-line no-param-reassign
available[style] = isStyleAvailable(style);

return available;
}, {});

// Emits key commands to use in `handleKeyCommand` in `Editor`.
const keyBindingFn = (e) => {
switch (e.keyCode) {
case KEY_CODES.B:
return isAvailable.BOLD && hasCommandModifier(e) ? 'bold' : null;
case KEY_CODES.I:
return isAvailable.ITALIC && hasCommandModifier(e) ? 'italic' : null;
case KEY_CODES.J:
return isAvailable.CODE && hasCommandModifier(e) ? 'code' : null;
case KEY_CODES.U:
return isAvailable.UNDERLINE && hasCommandModifier(e) ? 'underline' : null;
case KEY_CODES[5]:
return isAvailable.STRIKETHROUGH && e.shiftKey && isOptionKeyCommand(e) ? 'strikethrough' : null;
default:
}

// if (e.altKey === true && !e.ctrlKey) {
// if (e.shiftKey === true) {
// switch (e.which) {
// // Alt + Shift + A
// // case 65: return addNewBlock();
// default: return getDefaultKeyBinding(e);
// }
// }

// switch (e.which) {
// // // 1
// // case 49: return changeType('ordered-list-item');
// // // @
// // case 50: return showLinkInput();
// // // #
// // case 51: return changeType('header-three');
// // // *
// // case 56: return changeType('unordered-list-item');
// // // <
// // case 188: return changeType('caption');
// // // // -
// // // case 189: return 'changetype:caption';
// // // >
// // case 190: return changeType('unstyled');
// // // "
// // case 222: return changeType('blockquote');
// default: return getDefaultKeyBinding(e);
// }
// }

// if (e.keyCode === 46 && !e.ctrlKey) {
// return KEY_COMMANDS.deleteBlock();
// }
return getDefaultKeyBinding(e);
};

return keyBindingFn;
},

};
13 changes: 11 additions & 2 deletions lib/api/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,17 @@ export const ENTITY_TYPE = {
// Originally from https://github.com/draft-js-utils/draft-js-utils/blob/master/src/Constants.js.
export const INLINE_STYLE = {
BOLD: 'BOLD',
CODE: 'CODE',
ITALIC: 'ITALIC',
STRIKETHROUGH: 'STRIKETHROUGH',
CODE: 'CODE',
UNDERLINE: 'UNDERLINE',
STRIKETHROUGH: 'STRIKETHROUGH',
};

// Originally from https://github.com/facebook/draft-js/blob/master/src/component/utils/getDefaultKeyBinding.js.
export const KEY_CODES = {
B: 66,
U: 85,
J: 74,
I: 73,
5: 53,
};
4 changes: 1 addition & 3 deletions lib/components/DraftailEditor.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ import config, { MAX_LIST_NESTING, STATE_SAVE_INTERVAL } from '../api/config';
import DraftUtils from '../api/DraftUtils';
import conversion from '../api/conversion';

import keyBindingFn from '../utils/keybindings';

import BlockControls from '../components/BlockControls';
import InlineStyleControls from '../components/InlineStyleControls';
import Button from '../components/Button';
Expand Down Expand Up @@ -506,7 +504,7 @@ class DraftailEditor extends Component {
readOnly={readOnly}
handleReturn={this.handleReturn}
handleKeyCommand={this.handleKeyCommand}
keyBindingFn={keyBindingFn}
keyBindingFn={config.getKeyBindingFn(options.BLOCK_TYPES, options.INLINE_STYLES)}
onTab={this.handleTabCommand}
spellCheck={false}
blockRendererFn={this.blockRenderer}
Expand Down
48 changes: 0 additions & 48 deletions lib/utils/keybindings.js

This file was deleted.

0 comments on commit 8cc1eab

Please sign in to comment.