diff --git a/content_scripts/vimium_frontend.coffee b/content_scripts/vimium_frontend.coffee index 2de612d40..e821355ca 100644 --- a/content_scripts/vimium_frontend.coffee +++ b/content_scripts/vimium_frontend.coffee @@ -19,11 +19,17 @@ keyPort = null # are passed through to the underlying page. isEnabledForUrl = true passKeys = null +splitPassKeys = [] keyQueue = null # The user's operating system. currentCompletionKeys = null validFirstKeys = null +# Keys are either literal characters, or "named" - for example (alt+b), (left arrow) or +# This regular expression captures two groups: the first is a named key, the second is the remainder of +# the string. +namedKeyRegex = /^(<(?:[amc]-.|(?:[amc]-)?[a-z0-9]{2,5})>)$/ + # The types in that we consider for focusInput command. Right now this is recalculated in # each content script. Alternatively we could calculate it once in the background page and use a request to # fetch it each time. @@ -149,7 +155,7 @@ installListener = (element, event, callback) -> installedListeners = false initializeWhenEnabled = (newPassKeys) -> isEnabledForUrl = true - passKeys = newPassKeys + setPassKeys newPassKeys if (!installedListeners) # Key event handlers fire on window before they do on document. Prefer window for key events so the page # can't set handlers to grab the keys before us. @@ -165,7 +171,7 @@ initializeWhenEnabled = (newPassKeys) -> setState = (request) -> initializeWhenEnabled(request.passKeys) if request.enabled isEnabledForUrl = request.enabled - passKeys = request.passKeys + setPassKeys request.passKeys # # The backend needs to know which frame has focus. @@ -345,8 +351,18 @@ extend window, # Decide whether this keyChar should be passed to the underlying page. # Keystrokes are *never* considered passKeys if the keyQueue is not empty. So, for example, if 't' is a # passKey, then 'gt' and '99t' will neverthless be handled by vimium. -isPassKey = ( keyChar ) -> - return !keyQueue and passKeys and 0 <= passKeys.indexOf(keyChar) +isPassKey = (keyChar) -> + not keyQueue and splitPassKeys and 0 <= splitPassKeys.indexOf(keyChar) + +setPassKeys = (newPassKeys) -> + passKeys = newPassKeys + passKeyGroups = passKeys.split " " + splitPassKeys = [] + for passKeyGroup in passKeyGroups + if namedKeyRegex.test passKeyGroup # The current space delimited group is a single named key. + splitPassKeys.push passKeyGroup # Push this to as a single key + else + splitPassKeys = splitPassKeys.concat passKeyGroup.split "" # Pass all the characters as seperate keys. # Track which keydown events we have handled, so that we can subsequently suppress the corresponding keyup # event. @@ -473,6 +489,8 @@ onKeydown = (event) -> else if (!isInsertMode() && !findMode) if (keyChar) + if isPassKey keyChar + return undefined if (currentCompletionKeys.indexOf(keyChar) != -1 or isValidFirstKey(keyChar)) DomUtils.suppressEvent event KeydownEvents.push event diff --git a/pages/options.html b/pages/options.html index 8e6853041..158eac187 100644 --- a/pages/options.html +++ b/pages/options.html @@ -253,6 +253,10 @@

If "Keys" is left empty, then vimium is wholly disabled. Otherwise, just the listed keys are disabled (they are passed through). +

+ To enter complex keys such as +
<c-[>, <a-f>, <c-a-A>
+ simply seperate them from other passkeys with a space.