diff options
| author | Stephen Blott | 2016-02-18 10:29:51 +0000 |
|---|---|---|
| committer | Stephen Blott | 2016-02-18 10:29:51 +0000 |
| commit | f91fb7b9e11095cbb59174601096f0239501f6a0 (patch) | |
| tree | d0ac44c1ee050c256e3e03de244a3b0efb50d02f | |
| parent | 8e3ac1867b7577814865bf1cb40d0b865de30b1a (diff) | |
| parent | 38509ce26afd1df7288255bfbcae1705f7bf9d86 (diff) | |
| download | vimium-f91fb7b9e11095cbb59174601096f0239501f6a0.tar.bz2 | |
Merge pull request #1985 from smblott-github/pass-next-key
New command: Pass next key
| -rw-r--r-- | background_scripts/commands.coffee | 12 | ||||
| -rw-r--r-- | content_scripts/mode_insert.coffee | 33 | ||||
| -rw-r--r-- | content_scripts/vimium_frontend.coffee | 51 | ||||
| -rw-r--r-- | lib/keyboard_utils.coffee | 28 | ||||
| -rw-r--r-- | lib/settings.coffee | 1 |
5 files changed, 85 insertions, 40 deletions
diff --git a/background_scripts/commands.coffee b/background_scripts/commands.coffee index db8cc60f..80ca0f96 100644 --- a/background_scripts/commands.coffee +++ b/background_scripts/commands.coffee @@ -67,6 +67,13 @@ Commands = when "unmapAll" @keyToCommandRegistry = {} + # Push the key mapping for passNextKey into Settings so that it's available in the front end for insert + # mode. We exclude single-key mappings (that is, printable keys) because when users press printable keys + # in insert mode they expect the character to be input, not to be droppped into some special Vimium + # mode. + Settings.set "passNextKeyKeys", + (key for own key of @keyToCommandRegistry when @keyToCommandRegistry[key].command == "passNextKey" and 1 < key.length) + clearKeyMappingsAndSetDefaults: -> @keyToCommandRegistry = {} @mapKeyToCommand { key, command } for own key, command of defaultKeyMappings @@ -96,6 +103,7 @@ Commands = "goUp", "goToRoot", "enterInsertMode", + "passNextKey", "enterVisualMode", "enterVisualLineMode", "focusInput", @@ -164,7 +172,8 @@ Commands = "moveTabRight", "closeTabsOnLeft", "closeTabsOnRight", - "closeOtherTabs"] + "closeOtherTabs", + "passNextKey"] defaultKeyMappings = "?": "showHelp" @@ -277,6 +286,7 @@ commandDescriptions = openCopiedUrlInNewTab: ["Open the clipboard's URL in a new tab", { background: true, repeatLimit: 20 }] enterInsertMode: ["Enter insert mode", { noRepeat: true }] + passNextKey: ["Pass the next key to Chrome", { passCountToFunction: true }] enterVisualMode: ["Enter visual mode", { noRepeat: true }] enterVisualLineMode: ["Enter visual line mode", { noRepeat: true }] diff --git a/content_scripts/mode_insert.coffee b/content_scripts/mode_insert.coffee index 0b040e5d..a35633ac 100644 --- a/content_scripts/mode_insert.coffee +++ b/content_scripts/mode_insert.coffee @@ -10,6 +10,12 @@ class InsertMode extends Mode handleKeyEvent = (event) => return @continueBubbling unless @isActive event + + # Check for a pass-next-key key. + if KeyboardUtils.getKeyCharString(event) in Settings.get "passNextKeyKeys" + new PassNextKeyMode + return false + return @stopBubblingAndTrue unless event.type == 'keydown' and KeyboardUtils.isEscape event DomUtils.suppressKeyupAfterEscape handlerStack target = event.srcElement @@ -98,5 +104,32 @@ class InsertMode extends Mode @suppressedEvent: null @suppressEvent: (event) -> @suppressedEvent = event +# This implements the pasNexKey command. +class PassNextKeyMode extends Mode + constructor: (count = 1) -> + seenKeyDown = false + keyDownCount = 0 + + super + name: "pass-next-key" + indicator: "Pass next key." + # We exit on blur because, once we lose the focus, we can no longer track key events. + exitOnBlur: window + keypress: => + @stopBubblingAndTrue + + keydown: => + seenKeyDown = true + keyDownCount += 1 + @stopBubblingAndTrue + + keyup: => + if seenKeyDown + unless 0 < --keyDownCount + unless 0 < --count + @exit() + @stopBubblingAndTrue + root = exports ? window root.InsertMode = InsertMode +root.PassNextKeyMode = PassNextKeyMode diff --git a/content_scripts/vimium_frontend.coffee b/content_scripts/vimium_frontend.coffee index f78b79b0..eb52e4ee 100644 --- a/content_scripts/vimium_frontend.coffee +++ b/content_scripts/vimium_frontend.coffee @@ -368,6 +368,9 @@ extend window, enterVisualLineMode: -> new VisualLineMode + passNextKey: (count) -> + new PassNextKeyMode count + focusInput: do -> # Track the most recently focused input element. recentlyFocusedElement = null @@ -486,50 +489,20 @@ handlerStack.push # # @/this, here, is the the normal-mode Mode object. onKeypress = (event) -> - keyChar = "" - - # Ignore modifier keys by themselves. - if (event.keyCode > 31) - keyChar = String.fromCharCode(event.charCode) + keyChar = KeyboardUtils.getKeyCharString event + if keyChar + if currentCompletionKeys.indexOf(keyChar) != -1 or isValidFirstKey keyChar + DomUtils.suppressEvent(event) + keyPort.postMessage keyChar:keyChar, frameId:frameId + return @stopBubblingAndTrue - if (keyChar) - if currentCompletionKeys.indexOf(keyChar) != -1 or isValidFirstKey(keyChar) - DomUtils.suppressEvent(event) - keyPort.postMessage({ keyChar:keyChar, frameId:frameId }) - return @stopBubblingAndTrue - - keyPort.postMessage({ keyChar:keyChar, frameId:frameId }) + keyPort.postMessage keyChar:keyChar, frameId:frameId return @continueBubbling # @/this, here, is the the normal-mode Mode object. onKeydown = (event) -> - keyChar = "" - - # handle special keys, and normal input keys with modifiers being pressed. don't handle shiftKey alone (to - # avoid / being interpreted as ? - if (((event.metaKey || event.ctrlKey || event.altKey) && event.keyCode > 31) || ( - # TODO(philc): some events don't have a keyidentifier. How is that possible? - event.keyIdentifier && event.keyIdentifier.slice(0, 2) != "U+")) - keyChar = KeyboardUtils.getKeyChar(event) - # Again, ignore just modifiers. Maybe this should replace the keyCode>31 condition. - if (keyChar != "") - modifiers = [] - - if (event.shiftKey) - keyChar = keyChar.toUpperCase() - if (event.metaKey) - modifiers.push("m") - if (event.ctrlKey) - modifiers.push("c") - if (event.altKey) - modifiers.push("a") - - for own i of modifiers - keyChar = modifiers[i] + "-" + keyChar - - if (modifiers.length > 0 || keyChar.length > 1) - keyChar = "<" + keyChar + ">" + keyChar = KeyboardUtils.getKeyCharString event if (HelpDialog.showing && KeyboardUtils.isEscape(event)) HelpDialog.hide() @@ -557,7 +530,7 @@ onKeydown = (event) -> # Subject to internationalization issues since we're using keyIdentifier instead of charCode (in keypress). # # TOOD(ilya): Revisit this. Not sure it's the absolute best approach. - if keyChar == "" && + if not keyChar && (currentCompletionKeys.indexOf(KeyboardUtils.getKeyChar(event)) != -1 || isValidFirstKey(KeyboardUtils.getKeyChar(event))) DomUtils.suppressPropagation(event) diff --git a/lib/keyboard_utils.coffee b/lib/keyboard_utils.coffee index f123f75a..10b5f46e 100644 --- a/lib/keyboard_utils.coffee +++ b/lib/keyboard_utils.coffee @@ -66,6 +66,34 @@ KeyboardUtils = @getKeyChar event keyChar.length == 1 + # Return the Vimium key representation for this keyboard event. Return a falsy value (the empty string or + # undefined) when no Vimium representation is appropriate. + getKeyCharString: (event) -> + switch event.type + when "keypress" + # Ignore modifier keys by themselves. + if 31 < event.keyCode + String.fromCharCode event.charCode + + when "keydown" + # handle special keys, and normal input keys with modifiers being pressed. don't handle shiftKey alone (to + # avoid / being interpreted as ? + if (((event.metaKey || event.ctrlKey || event.altKey) && event.keyCode > 31) || ( + # TODO(philc): some events don't have a keyidentifier. How is that possible? + event.keyIdentifier && event.keyIdentifier.slice(0, 2) != "U+")) + keyChar = @getKeyChar event + # Again, ignore just modifiers. Maybe this should replace the keyCode>31 condition. + if 0 < keyChar.length + modifiers = [] + + keyChar = keyChar.toUpperCase() if event.shiftKey + modifiers.push "m" if event.metaKey + modifiers.push "c" if event.ctrlKey + modifiers.push "a" if event.altKey + + keyChar = [modifiers..., keyChar].join "-" + if 1 < keyChar.length then "<#{keyChar}>" else keyChar + KeyboardUtils.init() root = exports ? window diff --git a/lib/settings.coffee b/lib/settings.coffee index 31aad7ad..79ee04a9 100644 --- a/lib/settings.coffee +++ b/lib/settings.coffee @@ -174,6 +174,7 @@ Settings = settingsVersion: Utils.getCurrentVersion() helpDialog_showAdvancedCommands: false optionsPage_showAdvancedOptions: false + passNextKeyKeys: [] Settings.init() |
