diff options
author | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
---|---|---|
committer | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
commit | 5f8de423f190bbb79a62f804151bc24824fa32d8 (patch) | |
tree | 10027f336435511475e392454359edea8e25895d /devtools/client/shared/test/browser_key_shortcuts.js | |
parent | 49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff) | |
download | UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip |
Add m-esr52 at 52.6.0
Diffstat (limited to 'devtools/client/shared/test/browser_key_shortcuts.js')
-rw-r--r-- | devtools/client/shared/test/browser_key_shortcuts.js | 425 |
1 files changed, 425 insertions, 0 deletions
diff --git a/devtools/client/shared/test/browser_key_shortcuts.js b/devtools/client/shared/test/browser_key_shortcuts.js new file mode 100644 index 000000000..c88782f85 --- /dev/null +++ b/devtools/client/shared/test/browser_key_shortcuts.js @@ -0,0 +1,425 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +var isOSX = Services.appinfo.OS === "Darwin"; + +add_task(function* () { + let shortcuts = new KeyShortcuts({ + window + }); + + yield testSimple(shortcuts); + yield testNonLetterCharacter(shortcuts); + yield testPlusCharacter(shortcuts); + yield testFunctionKey(shortcuts); + yield testMixup(shortcuts); + yield testLooseDigits(shortcuts); + yield testExactModifiers(shortcuts); + yield testLooseShiftModifier(shortcuts); + yield testStrictLetterShiftModifier(shortcuts); + yield testAltModifier(shortcuts); + yield testCommandOrControlModifier(shortcuts); + yield testCtrlModifier(shortcuts); + yield testInvalidShortcutString(shortcuts); + yield testCmdShiftShortcut(shortcuts); + shortcuts.destroy(); + + yield testTarget(); +}); + +// Test helper to listen to the next key press for a given key, +// returning a promise to help using Tasks. +function once(shortcuts, key, listener) { + let called = false; + return new Promise(done => { + let onShortcut = (key2, event) => { + shortcuts.off(key, onShortcut); + ok(!called, "once listener called only once (i.e. off() works)"); + is(key, key2, "listener first argument match the key we listen"); + called = true; + listener(key2, event); + done(); + }; + shortcuts.on(key, onShortcut); + }); +} + +function* testSimple(shortcuts) { + info("Test simple key shortcuts"); + + let onKey = once(shortcuts, "0", (key, event) => { + is(event.key, "0"); + + // Display another key press to ensure that once() correctly stop listening + EventUtils.synthesizeKey("0", {}, window); + }); + + EventUtils.synthesizeKey("0", {}, window); + yield onKey; +} + +function* testNonLetterCharacter(shortcuts) { + info("Test non-naive character key shortcuts"); + + let onKey = once(shortcuts, "[", (key, event) => { + is(event.key, "["); + }); + + EventUtils.synthesizeKey("[", {}, window); + yield onKey; +} + +function* testFunctionKey(shortcuts) { + info("Test function key shortcuts"); + + let onKey = once(shortcuts, "F12", (key, event) => { + is(event.key, "F12"); + }); + + EventUtils.synthesizeKey("F12", { keyCode: 123 }, window); + yield onKey; +} + +// Plus is special. It's keycode is the one for "=". That's because it requires +// shift to be pressed and is behind "=" key. So it should be considered as a +// character key +function* testPlusCharacter(shortcuts) { + info("Test 'Plus' key shortcuts"); + + let onKey = once(shortcuts, "Plus", (key, event) => { + is(event.key, "+"); + }); + + EventUtils.synthesizeKey("+", { keyCode: 61, shiftKey: true }, window); + yield onKey; +} + +// Test they listeners are not mixed up between shortcuts +function* testMixup(shortcuts) { + info("Test possible listener mixup"); + + let hitFirst = false, hitSecond = false; + let onFirstKey = once(shortcuts, "0", (key, event) => { + is(event.key, "0"); + hitFirst = true; + }); + let onSecondKey = once(shortcuts, "Alt+A", (key, event) => { + is(event.key, "a"); + ok(event.altKey); + hitSecond = true; + }); + + // Dispatch the first shortcut and expect only this one to be notified + ok(!hitFirst, "First shortcut isn't notified before firing the key event"); + EventUtils.synthesizeKey("0", {}, window); + yield onFirstKey; + ok(hitFirst, "Got the first shortcut notified"); + ok(!hitSecond, "No mixup, second shortcut is still not notified (1/2)"); + + // Wait an extra time, just to be sure this isn't racy + yield new Promise(done => { + window.setTimeout(done, 0); + }); + ok(!hitSecond, "No mixup, second shortcut is still not notified (2/2)"); + + // Finally dispatch the second shortcut + EventUtils.synthesizeKey("a", { altKey: true }, window); + yield onSecondKey; + ok(hitSecond, "Got the second shortcut notified once it is actually fired"); +} + +// On azerty keyboard, digits are only available by pressing Shift/Capslock, +// but we accept them even if we omit doing that. +function* testLooseDigits(shortcuts) { + info("Test Loose digits"); + let onKey = once(shortcuts, "0", (key, event) => { + is(event.key, "à"); + ok(!event.altKey); + ok(!event.ctrlKey); + ok(!event.metaKey); + ok(!event.shiftKey); + }); + // Simulate a press on the "0" key, without shift pressed on a french + // keyboard + EventUtils.synthesizeKey( + "à", + { keyCode: 48 }, + window); + yield onKey; + + onKey = once(shortcuts, "0", (key, event) => { + is(event.key, "0"); + ok(!event.altKey); + ok(!event.ctrlKey); + ok(!event.metaKey); + ok(event.shiftKey); + }); + // Simulate the same press with shift pressed + EventUtils.synthesizeKey( + "0", + { keyCode: 48, shiftKey: true }, + window); + yield onKey; +} + +// Test that shortcuts is notified only when the modifiers match exactly +function* testExactModifiers(shortcuts) { + info("Test exact modifiers match"); + + let hit = false; + let onKey = once(shortcuts, "Alt+A", (key, event) => { + is(event.key, "a"); + ok(event.altKey); + ok(!event.ctrlKey); + ok(!event.metaKey); + ok(!event.shiftKey); + hit = true; + }); + + // Dispatch with unexpected set of modifiers + ok(!hit, "Shortcut isn't notified before firing the key event"); + EventUtils.synthesizeKey("a", + { accelKey: true, altKey: true, shiftKey: true }, + window); + EventUtils.synthesizeKey( + "a", + { accelKey: true, altKey: false, shiftKey: false }, + window); + EventUtils.synthesizeKey( + "a", + { accelKey: false, altKey: false, shiftKey: true }, + window); + EventUtils.synthesizeKey( + "a", + { accelKey: false, altKey: false, shiftKey: false }, + window); + + // Wait an extra time to let a chance to call the listener + yield new Promise(done => { + window.setTimeout(done, 0); + }); + ok(!hit, "Listener isn't called when modifiers aren't exactly matching"); + + // Dispatch the expected modifiers + EventUtils.synthesizeKey("a", { accelKey: false, altKey: true, shiftKey: false}, + window); + yield onKey; + ok(hit, "Got shortcut notified once it is actually fired"); +} + +// Some keys are only accessible via shift and listener should also be called +// even if the key didn't explicitely requested Shift modifier. +// For example, `%` on french keyboards is only accessible via Shift. +// Same thing for `@` on US keybords. +function* testLooseShiftModifier(shortcuts) { + info("Test Loose shift modifier"); + let onKey = once(shortcuts, "%", (key, event) => { + is(event.key, "%"); + ok(!event.altKey); + ok(!event.ctrlKey); + ok(!event.metaKey); + ok(event.shiftKey); + }); + EventUtils.synthesizeKey( + "%", + { accelKey: false, altKey: false, ctrlKey: false, shiftKey: true}, + window); + yield onKey; + + onKey = once(shortcuts, "@", (key, event) => { + is(event.key, "@"); + ok(!event.altKey); + ok(!event.ctrlKey); + ok(!event.metaKey); + ok(event.shiftKey); + }); + EventUtils.synthesizeKey( + "@", + { accelKey: false, altKey: false, ctrlKey: false, shiftKey: true}, + window); + yield onKey; +} + +// But Shift modifier is strict on all letter characters (a to Z) +function* testStrictLetterShiftModifier(shortcuts) { + info("Test strict shift modifier on letters"); + let hitFirst = false; + let onKey = once(shortcuts, "a", (key, event) => { + is(event.key, "a"); + ok(!event.altKey); + ok(!event.ctrlKey); + ok(!event.metaKey); + ok(!event.shiftKey); + hitFirst = true; + }); + let onShiftKey = once(shortcuts, "Shift+a", (key, event) => { + is(event.key, "a"); + ok(!event.altKey); + ok(!event.ctrlKey); + ok(!event.metaKey); + ok(event.shiftKey); + }); + EventUtils.synthesizeKey( + "a", + { shiftKey: true}, + window); + yield onShiftKey; + ok(!hitFirst, "Didn't fire the explicit shift+a"); + + EventUtils.synthesizeKey( + "a", + { shiftKey: false}, + window); + yield onKey; +} + +function* testAltModifier(shortcuts) { + info("Test Alt modifier"); + let onKey = once(shortcuts, "Alt+F1", (key, event) => { + is(event.keyCode, window.KeyboardEvent.DOM_VK_F1); + ok(event.altKey); + ok(!event.ctrlKey); + ok(!event.metaKey); + ok(!event.shiftKey); + }); + EventUtils.synthesizeKey( + "VK_F1", + { altKey: true }, + window); + yield onKey; +} + +function* testCommandOrControlModifier(shortcuts) { + info("Test CommandOrControl modifier"); + let onKey = once(shortcuts, "CommandOrControl+F1", (key, event) => { + is(event.keyCode, window.KeyboardEvent.DOM_VK_F1); + ok(!event.altKey); + if (isOSX) { + ok(!event.ctrlKey); + ok(event.metaKey); + } else { + ok(event.ctrlKey); + ok(!event.metaKey); + } + ok(!event.shiftKey); + }); + let onKeyAlias = once(shortcuts, "CmdOrCtrl+F1", (key, event) => { + is(event.keyCode, window.KeyboardEvent.DOM_VK_F1); + ok(!event.altKey); + if (isOSX) { + ok(!event.ctrlKey); + ok(event.metaKey); + } else { + ok(event.ctrlKey); + ok(!event.metaKey); + } + ok(!event.shiftKey); + }); + if (isOSX) { + EventUtils.synthesizeKey( + "VK_F1", + { metaKey: true }, + window); + } else { + EventUtils.synthesizeKey( + "VK_F1", + { ctrlKey: true }, + window); + } + yield onKey; + yield onKeyAlias; +} + +function* testCtrlModifier(shortcuts) { + info("Test Ctrl modifier"); + let onKey = once(shortcuts, "Ctrl+F1", (key, event) => { + is(event.keyCode, window.KeyboardEvent.DOM_VK_F1); + ok(!event.altKey); + ok(event.ctrlKey); + ok(!event.metaKey); + ok(!event.shiftKey); + }); + let onKeyAlias = once(shortcuts, "Control+F1", (key, event) => { + is(event.keyCode, window.KeyboardEvent.DOM_VK_F1); + ok(!event.altKey); + ok(event.ctrlKey); + ok(!event.metaKey); + ok(!event.shiftKey); + }); + EventUtils.synthesizeKey( + "VK_F1", + { ctrlKey: true }, + window); + yield onKey; + yield onKeyAlias; +} + +function* testCmdShiftShortcut(shortcuts) { + if (!isOSX) { + // This test is OSX only (Bug 1300458). + return; + } + + let onCmdKey = once(shortcuts, "CmdOrCtrl+[", (key, event) => { + is(event.key, "["); + ok(!event.altKey); + ok(!event.ctrlKey); + ok(event.metaKey); + ok(!event.shiftKey); + }); + let onCmdShiftKey = once(shortcuts, "CmdOrCtrl+Shift+[", (key, event) => { + is(event.key, "["); + ok(!event.altKey); + ok(!event.ctrlKey); + ok(event.metaKey); + ok(event.shiftKey); + }); + + EventUtils.synthesizeKey( + "[", + { metaKey: true, shiftKey: true }, + window); + EventUtils.synthesizeKey( + "[", + { metaKey: true }, + window); + + yield onCmdKey; + yield onCmdShiftKey; +} + +function* testTarget() { + info("Test KeyShortcuts with target argument"); + + let target = document.createElementNS("http://www.w3.org/1999/xhtml", + "input"); + document.documentElement.appendChild(target); + target.focus(); + + let shortcuts = new KeyShortcuts({ + window, + target + }); + let onKey = once(shortcuts, "0", (key, event) => { + is(event.key, "0"); + is(event.target, target); + }); + EventUtils.synthesizeKey("0", {}, window); + yield onKey; + + target.remove(); + + shortcuts.destroy(); +} + +function testInvalidShortcutString(shortcuts) { + info("Test wrong shortcut string"); + + let shortcut = KeyShortcuts.parseElectronKey(window, "Cmmd+F"); + ok(!shortcut, "Passing a invalid shortcut string should return a null object"); + + shortcuts.on("Cmmd+F", function () {}); + ok(true, "on() shouldn't throw when passing invalid shortcut string"); +} |