mobiledoc-kit
Advanced tools
Comparing version 0.10.19 to 0.10.20
@@ -175,3 +175,3 @@ 'use strict'; | ||
var upperCharacter = character.toUpperCase(); | ||
var special = _utilsKey.SPECIAL_KEYS[upperCharacter]; | ||
var special = (0, _utilsKey.specialCharacterToCode)(upperCharacter); | ||
if (special) { | ||
@@ -178,0 +178,0 @@ return special; |
@@ -6,2 +6,3 @@ 'use strict'; | ||
exports.modifierMask = modifierMask; | ||
exports.specialCharacterToCode = specialCharacterToCode; | ||
@@ -12,2 +13,4 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } | ||
var _keys = require('./keys'); | ||
var _utilsCharacters = require('../utils/characters'); | ||
@@ -68,3 +71,6 @@ | ||
exports.SPECIAL_KEYS = SPECIAL_KEYS; | ||
function specialCharacterToCode(specialCharacter) { | ||
return SPECIAL_KEYS[specialCharacter]; | ||
} | ||
// heuristic for determining if `event` is a key event | ||
@@ -85,2 +91,3 @@ function isKeyEvent(event) { | ||
this.key = event.key; | ||
this.keyCode = event.keyCode; | ||
@@ -100,6 +107,24 @@ this.charCode = event.charCode; | ||
} | ||
// See https://caniuse.com/#feat=keyboardevent-key for browser support. | ||
}, { | ||
key: 'isKeySupported', | ||
value: function isKeySupported() { | ||
return this.key; | ||
} | ||
}, { | ||
key: 'isKey', | ||
value: function isKey(identifier) { | ||
if (this.isKeySupported()) { | ||
(0, _assert['default'])('Must define Keys.' + identifier + '.', _keys['default'][identifier]); | ||
return this.key === _keys['default'][identifier]; | ||
} else { | ||
(0, _assert['default'])('Must define Keycodes.' + identifier + '.', _keycodes['default'][identifier]); | ||
return this.keyCode === _keycodes['default'][identifier]; | ||
} | ||
} | ||
}, { | ||
key: 'isEscape', | ||
value: function isEscape() { | ||
return this.keyCode === _keycodes['default'].ESC; | ||
return this.isKey('ESC'); | ||
} | ||
@@ -109,3 +134,3 @@ }, { | ||
value: function isDelete() { | ||
return this.keyCode === _keycodes['default'].BACKSPACE || this.keyCode === _keycodes['default'].DELETE; | ||
return this.isKey('BACKSPACE') || this.isForwardDelete(); | ||
} | ||
@@ -115,3 +140,3 @@ }, { | ||
value: function isForwardDelete() { | ||
return this.keyCode === _keycodes['default'].DELETE; | ||
return this.isKey('DELETE'); | ||
} | ||
@@ -126,3 +151,3 @@ }, { | ||
value: function isHorizontalArrow() { | ||
return this.keyCode === _keycodes['default'].LEFT || this.keyCode === _keycodes['default'].RIGHT; | ||
return this.isLeftArrow() || this.isRightArrow(); | ||
} | ||
@@ -137,3 +162,3 @@ }, { | ||
value: function isVerticalArrow() { | ||
return this.keyCode === _keycodes['default'].UP || this.keyCode === _keycodes['default'].DOWN; | ||
return this.isKey('UP') || this.isKey('DOWN'); | ||
} | ||
@@ -143,3 +168,3 @@ }, { | ||
value: function isLeftArrow() { | ||
return this.keyCode === _keycodes['default'].LEFT; | ||
return this.isKey('LEFT'); | ||
} | ||
@@ -149,3 +174,3 @@ }, { | ||
value: function isRightArrow() { | ||
return this.keyCode === _keycodes['default'].RIGHT; | ||
return this.isKey('RIGHT'); | ||
} | ||
@@ -155,3 +180,3 @@ }, { | ||
value: function isHome() { | ||
return this.keyCode === _keycodes['default'].HOME; | ||
return this.isKey('HOME'); | ||
} | ||
@@ -161,3 +186,3 @@ }, { | ||
value: function isEnd() { | ||
return this.keyCode === _keycodes['default'].END; | ||
return this.isKey('END'); | ||
} | ||
@@ -167,3 +192,3 @@ }, { | ||
value: function isPageUp() { | ||
return this.keyCode === _keycodes['default'].PAGEUP; | ||
return this.isKey('PAGEUP'); | ||
} | ||
@@ -173,3 +198,3 @@ }, { | ||
value: function isPageDown() { | ||
return this.keyCode === _keycodes['default'].PAGEDOWN; | ||
return this.isKey('PAGEDOWN'); | ||
} | ||
@@ -179,3 +204,3 @@ }, { | ||
value: function isInsert() { | ||
return this.keyCode === _keycodes['default'].INS; | ||
return this.isKey('INS'); | ||
} | ||
@@ -185,3 +210,3 @@ }, { | ||
value: function isClear() { | ||
return this.keyCode === _keycodes['default'].CLEAR; | ||
return this.isKey('CLEAR'); | ||
} | ||
@@ -191,3 +216,3 @@ }, { | ||
value: function isPause() { | ||
return this.keyCode === _keycodes['default'].PAUSE; | ||
return this.isKey('PAUSE'); | ||
} | ||
@@ -197,10 +222,11 @@ }, { | ||
value: function isSpace() { | ||
return this.keyCode === _keycodes['default'].SPACE; | ||
return this.isKey('SPACE'); | ||
} | ||
// In Firefox, pressing ctrl-TAB will switch to another open browser tab, but it will | ||
// also fire a keydown event for the tab+modifier (ctrl). This causes Mobiledoc | ||
// to erroneously insert a tab character before FF switches to the new browser tab. | ||
// Chrome doesn't fire this event so the issue doesn't arise there. | ||
// Fix this by returning false when the TAB key event includes a modifier. | ||
// In Firefox, pressing ctrl-TAB will switch to another open browser tab, but | ||
// it will also fire a keydown event for the tab+modifier (ctrl). This causes | ||
// Mobiledoc to erroneously insert a tab character before FF switches to the | ||
// new browser tab. Chrome doesn't fire this event so the issue doesn't | ||
// arise there. Fix this by returning false when the TAB key event includes a | ||
// modifier. | ||
// See: https://github.com/bustle/mobiledoc-kit/issues/565 | ||
@@ -210,3 +236,3 @@ }, { | ||
value: function isTab() { | ||
return !this.hasAnyModifier() && this.keyCode === _keycodes['default'].TAB; | ||
return !this.hasAnyModifier() && this.isKey('TAB'); | ||
} | ||
@@ -216,19 +242,5 @@ }, { | ||
value: function isEnter() { | ||
return this.keyCode === _keycodes['default'].ENTER; | ||
return this.isKey('ENTER'); | ||
} | ||
/** | ||
* If the shift key is depressed. | ||
* For example, while holding down meta+shift, pressing the "v" | ||
* key would result in an event whose `Key` had `isShift()` with a truthy value, | ||
* because the shift key is down when pressing the "v". | ||
* @see {isShiftKey} which checks if the key is actually the shift key itself. | ||
* @return {bool} | ||
*/ | ||
}, { | ||
key: 'isShift', | ||
value: function isShift() { | ||
return this.shiftKey; | ||
} | ||
/* | ||
@@ -243,3 +255,3 @@ * If the key is the actual shift key. This is false when the shift key | ||
value: function isShiftKey() { | ||
return this.keyCode === _keycodes['default'].SHIFT; | ||
return this.isKey('SHIFT'); | ||
} | ||
@@ -255,3 +267,3 @@ | ||
value: function isAltKey() { | ||
return this.keyCode === _keycodes['default'].ALT; | ||
return this.isKey('ALT'); | ||
} | ||
@@ -267,5 +279,26 @@ | ||
value: function isCtrlKey() { | ||
return this.keyCode === _keycodes['default'].CTRL; | ||
return this.isKey('CTRL'); | ||
} | ||
}, { | ||
key: 'isIME', | ||
value: function isIME() { | ||
// FIXME the IME action seems to get lost when we issue an | ||
// `editor.deleteSelection` before it (in Chrome) | ||
return this.keyCode === _keycodes['default'].IME; | ||
} | ||
}, { | ||
key: 'isShift', | ||
/** | ||
* If the shift key is depressed. | ||
* For example, while holding down meta+shift, pressing the "v" | ||
* key would result in an event whose `Key` had `isShift()` with a truthy value, | ||
* because the shift key is down when pressing the "v". | ||
* @see {isShiftKey} which checks if the key is actually the shift key itself. | ||
* @return {bool} | ||
*/ | ||
value: function isShift() { | ||
return this.shiftKey; | ||
} | ||
}, { | ||
key: 'hasModifier', | ||
@@ -285,2 +318,34 @@ value: function hasModifier(modifier) { | ||
} | ||
}, { | ||
key: 'isNumberKey', | ||
value: function isNumberKey() { | ||
if (this.isKeySupported()) { | ||
return this.key >= '0' && this.key <= '9'; | ||
} else { | ||
var code = this.keyCode; | ||
return code >= _keycodes['default']['0'] && code <= _keycodes['default']['9'] || code >= _keycodes['default'].NUMPAD_0 && code <= _keycodes['default'].NUMPAD_9; // numpad keys | ||
} | ||
} | ||
}, { | ||
key: 'isLetterKey', | ||
value: function isLetterKey() { | ||
if (this.isKeySupported()) { | ||
var key = this.key; | ||
return key >= 'a' && key <= 'z' || key >= 'A' && key <= 'Z'; | ||
} else { | ||
var code = this.keyCode; | ||
return code >= _keycodes['default'].A && code <= _keycodes['default'].Z || code >= _keycodes['default'].a && code <= _keycodes['default'].z; | ||
} | ||
} | ||
}, { | ||
key: 'isPunctuation', | ||
value: function isPunctuation() { | ||
if (this.isKeySupported()) { | ||
var key = this.key; | ||
return key >= ';' && key <= '`' || key >= '[' && key <= '"'; | ||
} else { | ||
var code = this.keyCode; | ||
return code >= _keycodes['default'][';'] && code <= _keycodes['default']['`'] || code >= _keycodes['default']['['] && code <= _keycodes['default']['"']; | ||
} | ||
} | ||
@@ -298,4 +363,2 @@ /** | ||
var code = this.keyCode; | ||
// Firefox calls keypress events for some keys that should not be printable | ||
@@ -306,10 +369,3 @@ if (!this.isPrintableKey()) { | ||
return code !== 0 || this.toString().length > 0 || code >= _keycodes['default']['0'] && code <= _keycodes['default']['9'] || // number keys | ||
this.isSpace() || this.isTab() || this.isEnter() || code >= _keycodes['default'].A && code <= _keycodes['default'].Z || // letter keys | ||
code >= _keycodes['default'].a && code <= _keycodes['default'].z || code >= _keycodes['default'].NUMPAD_0 && code <= _keycodes['default'].NUMPAD_9 || // numpad keys | ||
code >= _keycodes['default'][';'] && code <= _keycodes['default']['`'] || // punctuation | ||
code >= _keycodes['default']['['] && code <= _keycodes['default']['"'] || | ||
// FIXME the IME action seems to get lost when we issue an `editor.deleteSelection` | ||
// before it (in Chrome) | ||
code === _keycodes['default'].IME; | ||
return this.keyCode !== 0 || this.toString().length > 0 || this.isNumberKey() || this.isSpace() || this.isTab() || this.isEnter() || this.isLetterKey() || this.isPunctuation() || this.isIME(); | ||
} | ||
@@ -316,0 +372,0 @@ }, { |
'use strict'; | ||
exports['default'] = '0.10.19'; | ||
exports['default'] = '0.10.20'; |
{ | ||
"name": "mobiledoc-kit", | ||
"version": "0.10.19", | ||
"version": "0.10.20", | ||
"description": "A toolkit for building WYSIWYG editors with Mobiledoc", | ||
@@ -8,3 +8,3 @@ "repository": "https://github.com/bustle/mobiledoc-kit", | ||
"start": "broccoli serve --host 0.0.0.0", | ||
"test:ci": "PATH=node_modules/phantomjs-prebuilt/bin/:$PATH npm run build:docs && npm run build && testem ci -f testem-ci.json", | ||
"test:ci": "npm run build:docs && npm run build && testem ci -f testem-ci.json", | ||
"test": "npm run build:docs && npm run build && testem ci -f testem.json", | ||
@@ -11,0 +11,0 @@ "build": "rm -rf dist && broccoli build dist", |
@@ -229,3 +229,3 @@ # Mobiledoc Kit | ||
For more details on the lifecycle hooks, see the [Editor documentation](https://bustlelabs.github.io/mobiledoc-kit/demo/docs/Editor.html). | ||
For more details on the lifecycle hooks, see the [Editor documentation](https://bustle.github.io/mobiledoc-kit/demo/docs/Editor.html). | ||
@@ -232,0 +232,0 @@ ### Programmatic Post Editing |
import Key from '../utils/key'; | ||
import { MODIFIERS, SPECIAL_KEYS } from '../utils/key'; | ||
import { MODIFIERS, specialCharacterToCode } from '../utils/key'; | ||
import { filter, reduce } from '../utils/array-utils'; | ||
@@ -150,3 +150,3 @@ import assert from '../utils/assert'; | ||
const upperCharacter = character.toUpperCase(); | ||
const special = SPECIAL_KEYS[upperCharacter]; | ||
const special = specialCharacterToCode(upperCharacter); | ||
if (special) { | ||
@@ -153,0 +153,0 @@ return special; |
import Keycodes from './keycodes'; | ||
import Keys from './keys'; | ||
import { TAB } from 'mobiledoc-kit/utils/characters'; | ||
@@ -36,3 +37,3 @@ | ||
export const SPECIAL_KEYS = { | ||
const SPECIAL_KEYS = { | ||
BACKSPACE: Keycodes.BACKSPACE, | ||
@@ -55,2 +56,6 @@ TAB: Keycodes.TAB, | ||
export function specialCharacterToCode(specialCharacter) { | ||
return SPECIAL_KEYS[specialCharacter]; | ||
} | ||
// heuristic for determining if `event` is a key event | ||
@@ -68,2 +73,3 @@ function isKeyEvent(event) { | ||
constructor(event) { | ||
this.key = event.key; | ||
this.keyCode = event.keyCode; | ||
@@ -86,13 +92,27 @@ this.charCode = event.charCode; | ||
// See https://caniuse.com/#feat=keyboardevent-key for browser support. | ||
isKeySupported() { | ||
return this.key; | ||
} | ||
isKey(identifier) { | ||
if (this.isKeySupported()) { | ||
assert(`Must define Keys.${identifier}.`, Keys[identifier]); | ||
return this.key === Keys[identifier]; | ||
} else { | ||
assert(`Must define Keycodes.${identifier}.`, Keycodes[identifier]); | ||
return this.keyCode === Keycodes[identifier]; | ||
} | ||
} | ||
isEscape() { | ||
return this.keyCode === Keycodes.ESC; | ||
return this.isKey('ESC'); | ||
} | ||
isDelete() { | ||
return this.keyCode === Keycodes.BACKSPACE || | ||
this.keyCode === Keycodes.DELETE; | ||
return this.isKey('BACKSPACE') || this.isForwardDelete(); | ||
} | ||
isForwardDelete() { | ||
return this.keyCode === Keycodes.DELETE; | ||
return this.isKey('DELETE'); | ||
} | ||
@@ -105,4 +125,3 @@ | ||
isHorizontalArrow() { | ||
return this.keyCode === Keycodes.LEFT || | ||
this.keyCode === Keycodes.RIGHT; | ||
return this.isLeftArrow() || this.isRightArrow(); | ||
} | ||
@@ -116,81 +135,60 @@ | ||
isVerticalArrow() { | ||
return this.keyCode === Keycodes.UP || | ||
this.keyCode === Keycodes.DOWN; | ||
return this.isKey('UP') || this.isKey('DOWN'); | ||
} | ||
isLeftArrow() { | ||
return this.keyCode === Keycodes.LEFT; | ||
return this.isKey('LEFT'); | ||
} | ||
isRightArrow() { | ||
return this.keyCode === Keycodes.RIGHT; | ||
return this.isKey('RIGHT'); | ||
} | ||
isHome() { | ||
return this.keyCode === Keycodes.HOME; | ||
return this.isKey('HOME'); | ||
} | ||
isEnd() { | ||
return this.keyCode === Keycodes.END; | ||
return this.isKey('END'); | ||
} | ||
isPageUp() { | ||
return this.keyCode === Keycodes.PAGEUP; | ||
return this.isKey('PAGEUP'); | ||
} | ||
isPageDown() { | ||
return this.keyCode === Keycodes.PAGEDOWN; | ||
return this.isKey('PAGEDOWN'); | ||
} | ||
isInsert() { | ||
return this.keyCode === Keycodes.INS; | ||
return this.isKey('INS'); | ||
} | ||
isClear() { | ||
return this.keyCode === Keycodes.CLEAR; | ||
return this.isKey('CLEAR'); | ||
} | ||
isPause() { | ||
return this.keyCode === Keycodes.PAUSE; | ||
return this.isKey('PAUSE'); | ||
} | ||
get direction() { | ||
switch (true) { | ||
case this.isDelete(): | ||
return this.isForwardDelete() ? DIRECTION.FORWARD : DIRECTION.BACKWARD; | ||
case this.isHorizontalArrow(): | ||
return this.isRightArrow() ? DIRECTION.FORWARD : DIRECTION.BACKWARD; | ||
} | ||
} | ||
isSpace() { | ||
return this.keyCode === Keycodes.SPACE; | ||
return this.isKey('SPACE'); | ||
} | ||
// In Firefox, pressing ctrl-TAB will switch to another open browser tab, but it will | ||
// also fire a keydown event for the tab+modifier (ctrl). This causes Mobiledoc | ||
// to erroneously insert a tab character before FF switches to the new browser tab. | ||
// Chrome doesn't fire this event so the issue doesn't arise there. | ||
// Fix this by returning false when the TAB key event includes a modifier. | ||
// In Firefox, pressing ctrl-TAB will switch to another open browser tab, but | ||
// it will also fire a keydown event for the tab+modifier (ctrl). This causes | ||
// Mobiledoc to erroneously insert a tab character before FF switches to the | ||
// new browser tab. Chrome doesn't fire this event so the issue doesn't | ||
// arise there. Fix this by returning false when the TAB key event includes a | ||
// modifier. | ||
// See: https://github.com/bustle/mobiledoc-kit/issues/565 | ||
isTab() { | ||
return !this.hasAnyModifier() && this.keyCode === Keycodes.TAB; | ||
return !this.hasAnyModifier() && this.isKey('TAB'); | ||
} | ||
isEnter() { | ||
return this.keyCode === Keycodes.ENTER; | ||
return this.isKey('ENTER'); | ||
} | ||
/** | ||
* If the shift key is depressed. | ||
* For example, while holding down meta+shift, pressing the "v" | ||
* key would result in an event whose `Key` had `isShift()` with a truthy value, | ||
* because the shift key is down when pressing the "v". | ||
* @see {isShiftKey} which checks if the key is actually the shift key itself. | ||
* @return {bool} | ||
*/ | ||
isShift() { | ||
return this.shiftKey; | ||
} | ||
/* | ||
@@ -203,3 +201,3 @@ * If the key is the actual shift key. This is false when the shift key | ||
isShiftKey() { | ||
return this.keyCode === Keycodes.SHIFT; | ||
return this.isKey('SHIFT'); | ||
} | ||
@@ -213,3 +211,3 @@ | ||
isAltKey() { | ||
return this.keyCode === Keycodes.ALT; | ||
return this.isKey('ALT'); | ||
} | ||
@@ -223,5 +221,32 @@ | ||
isCtrlKey() { | ||
return this.keyCode === Keycodes.CTRL; | ||
return this.isKey('CTRL'); | ||
} | ||
isIME() { | ||
// FIXME the IME action seems to get lost when we issue an | ||
// `editor.deleteSelection` before it (in Chrome) | ||
return this.keyCode === Keycodes.IME; | ||
} | ||
get direction() { | ||
switch (true) { | ||
case this.isDelete(): | ||
return this.isForwardDelete() ? DIRECTION.FORWARD : DIRECTION.BACKWARD; | ||
case this.isHorizontalArrow(): | ||
return this.isRightArrow() ? DIRECTION.FORWARD : DIRECTION.BACKWARD; | ||
} | ||
} | ||
/** | ||
* If the shift key is depressed. | ||
* For example, while holding down meta+shift, pressing the "v" | ||
* key would result in an event whose `Key` had `isShift()` with a truthy value, | ||
* because the shift key is down when pressing the "v". | ||
* @see {isShiftKey} which checks if the key is actually the shift key itself. | ||
* @return {bool} | ||
*/ | ||
isShift() { | ||
return this.shiftKey; | ||
} | ||
hasModifier(modifier) { | ||
@@ -261,2 +286,36 @@ return modifier & this.modifierMask; | ||
isNumberKey() { | ||
if (this.isKeySupported()) { | ||
return this.key >= '0' && this.key <= '9'; | ||
} else { | ||
const code = this.keyCode; | ||
return (code >= Keycodes['0'] && code <= Keycodes['9']) || | ||
(code >= Keycodes.NUMPAD_0 && code <= Keycodes.NUMPAD_9); // numpad keys | ||
} | ||
} | ||
isLetterKey() { | ||
if (this.isKeySupported()) { | ||
const key = this.key; | ||
return (key >= 'a' && key <= 'z') || | ||
(key >= 'A' && key <= 'Z'); | ||
} else { | ||
const code = this.keyCode; | ||
return (code >= Keycodes.A && code <= Keycodes.Z) || | ||
(code >= Keycodes.a && code <= Keycodes.z); | ||
} | ||
} | ||
isPunctuation() { | ||
if (this.isKeySupported()) { | ||
const key = this.key; | ||
return (key >= ';' && key <= '`') || | ||
(key >= '[' && key <= '"'); | ||
} else { | ||
const code = this.keyCode; | ||
return (code >= Keycodes[';'] && code <= Keycodes['`']) || | ||
(code >= Keycodes['['] && code <= Keycodes['"']); | ||
} | ||
} | ||
/** | ||
@@ -271,4 +330,2 @@ * See https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode#Printable_keys_in_standard_position | ||
const {keyCode:code} = this; | ||
// Firefox calls keypress events for some keys that should not be printable | ||
@@ -280,18 +337,11 @@ if (!this.isPrintableKey()) { | ||
return ( | ||
code !== 0 || | ||
this.keyCode !== 0 || | ||
this.toString().length > 0 || | ||
(code >= Keycodes['0'] && code <= Keycodes['9']) || // number keys | ||
this.isNumberKey() || | ||
this.isSpace() || | ||
this.isTab() || | ||
this.isEnter() || | ||
( | ||
(code >= Keycodes.A && code <= Keycodes.Z) || // letter keys | ||
(code >= Keycodes.a && code <= Keycodes.z) | ||
) || | ||
(code >= Keycodes.NUMPAD_0 && code <= Keycodes.NUMPAD_9) || // numpad keys | ||
(code >= Keycodes[';'] && code <= Keycodes['`']) || // punctuation | ||
(code >= Keycodes['['] && code <= Keycodes['"']) || | ||
// FIXME the IME action seems to get lost when we issue an `editor.deleteSelection` | ||
// before it (in Chrome) | ||
code === Keycodes.IME | ||
this.isLetterKey() || | ||
this.isPunctuation() || | ||
this.isIME() | ||
); | ||
@@ -298,0 +348,0 @@ } |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
3290342
170
47426