-
-
Notifications
You must be signed in to change notification settings - Fork 57
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
139 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import { KeyCombo } from "./key-combo"; | ||
|
||
export default function isKey(keyComboOrKeyComboString, keyboardEvent) { | ||
let keyCombo; | ||
if (keyComboOrKeyComboString instanceof KeyCombo) { | ||
keyCombo = keyComboOrKeyComboString; | ||
} else if (typeof keyComboOrKeyComboString === 'string') { | ||
keyCombo = KeyCombo.parse(keyComboOrKeyComboString); | ||
} else { | ||
throw new Error('Expected a `string` or `KeyCombo` as `keyComboOrKeyComboString` argument to `isKey`'); | ||
} | ||
|
||
return modifiersMatch(keyCombo, keyboardEvent) | ||
&& keyOrCodeMatches(keyCombo, keyboardEvent); | ||
} | ||
|
||
function modifiersMatch(keyCombo, keyboardEvent) { | ||
return keyCombo.altKey === keyboardEvent.altKey | ||
&& keyCombo.ctrlKey === keyboardEvent.ctrlKey | ||
&& keyCombo.metaKey === keyboardEvent.metaKey | ||
&& keyCombo.shiftKey === keyboardEvent.shiftKey; | ||
} | ||
|
||
function keyOrCodeMatches(keyCombo, keyboardEvent) { | ||
return keyCombo.keyOrCode === keyboardEvent.code || keyCombo.keyOrCode === keyboardEvent.key; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
export class KeyCombo { | ||
altKey = false; | ||
ctrlKey = false; | ||
shiftKey = false; | ||
metaKey = false; | ||
keyOrCode; | ||
static parse(s) { | ||
let keyCombo = new KeyCombo(); | ||
s.split('+').forEach((part) => { | ||
switch (part) { | ||
case 'alt': | ||
keyCombo.altKey = true; | ||
break; | ||
case 'ctrl': | ||
keyCombo.ctrlKey = true; | ||
break; | ||
case 'meta': | ||
keyCombo.metaKey = true; | ||
break; | ||
case 'shift': | ||
keyCombo.shiftKey = true; | ||
break; | ||
default: | ||
keyCombo.keyOrCode = part; | ||
} | ||
}); | ||
return keyCombo; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
import { module, skip, test } from 'qunit'; | ||
import isKey from 'ember-keyboard/utils/is-key'; | ||
|
||
module('Unit | Utility | isKey', function() { | ||
let table = ` | ||
keyCombo alt ctrl meta shift key code expected pending note | ||
alt+c T F F F c KeyC T F | ||
alt+c T F F F j KeyC F F simulates dvorak j | ||
alt+c T F F F c KeyI T F simulates dvorak c | ||
alt+c T F F F ç KeyC T T simulates Mac alt+c | ||
alt+KeyC T F F F c KeyC T F | ||
alt+c F F F F c KeyC F F alt not pressed | ||
alt+c T F F T c KeyC F F alt+shift pressed | ||
alt+KeyC F F F F c KeyC F F alt not pressed | ||
alt+KeyC T F F T c KeyC F F alt+shift pressed | ||
shift+c F F F T c KeyC T F | ||
shift+KeyC F F F T c KeyC T F | ||
ctrl+shift+t F T F T t KeyT T F | ||
ctrl+shift+KeyT F T F T t KeyT T F | ||
alt+Digit2 T F F F 2 Digit2 T F | ||
shift+Digit2 F F F T @ Digit2 T F | ||
shift+2 F F F T @ Digit2 T T | ||
@ F F F F @ Digit2 T F | ||
? F F F T ? Slash T T | ||
ctrl+? F T F T ? Slash T T | ||
ctrl+Slash F T F F / Slash T F | ||
ctrl+Slash F T F T ? Slash F F | ||
/ F F F F / Slash T F slash key with us language | ||
/ F F F F - Slash F F same key with german language | ||
/ F F F F / Digit7 T F slash key on german keyboard | ||
`; | ||
for (let line of table.split("\n").map(line => line.trim())) { | ||
if (line === '' || line.match(/^keyCombo/)) { continue; } // blank or header row | ||
buildTestFromLine(line); | ||
} | ||
}); | ||
|
||
function stringToBoolean(s) { | ||
if (s === 'T') return true; | ||
if (s === 'F') return false; | ||
throw new Error(`Invalid boolean string value: ${s}. Must be 'T' or 'F'`); | ||
} | ||
|
||
function buildTestFromLine(line) { | ||
let [keyCombo,alt,ctrl,meta,shift,key,code,expected,pending,...note] = line.split(/\s+/); | ||
let altKey = stringToBoolean(alt); | ||
let ctrlKey = stringToBoolean(ctrl); | ||
let metaKey = stringToBoolean(meta); | ||
let shiftKey = stringToBoolean(shift); | ||
let expectedResult = stringToBoolean(expected); | ||
let isPending = stringToBoolean(pending); | ||
let testDescription = `with "${keyCombo}", `; | ||
note = note ? note.join(' ') : null; | ||
testDescription += expectedResult ? 'should ' : 'should not '; | ||
testDescription += `match keydown event with `; | ||
testDescription += `key: ${key}, `; | ||
testDescription += `code: ${code}, `; | ||
testDescription += `with modifiers `; | ||
let modifiers = []; | ||
if (altKey) { | ||
modifiers.push('alt'); | ||
} | ||
if (ctrlKey) { | ||
modifiers.push('ctrl'); | ||
} | ||
if (metaKey) { | ||
modifiers.push('meta'); | ||
} | ||
if (shiftKey) { | ||
modifiers.push('shift'); | ||
} | ||
testDescription += modifiers.join('+'); | ||
let testFunc = isPending ? skip : test; | ||
testFunc(testDescription, async function(assert) { | ||
let fakeEvent = new KeyboardEvent('keydown', { key, code, altKey, ctrlKey, metaKey, shiftKey }); | ||
if (expectedResult) { | ||
let expectedTriggerMessage = `should match${note ? ', ' + note : ''}`; | ||
assert.ok(isKey(keyCombo, fakeEvent), expectedTriggerMessage); | ||
} else { | ||
let expectedNoTriggerMessage = `should not match${note ? ', ' + note : ''}`; | ||
assert.ok(!isKey(keyCombo, fakeEvent), expectedNoTriggerMessage); | ||
} | ||
}); | ||
} |