diff options
| author | Stephen Blott | 2014-08-23 11:40:25 +0100 |
|---|---|---|
| committer | Stephen Blott | 2014-08-23 14:52:26 +0100 |
| commit | f037e83763b1b62e048e1fc433d52b9564ce3ba0 (patch) | |
| tree | 033ce9610bbfdc7aa65df1dda6bfd259c37cad26 | |
| parent | 43caeb82d91e7cb88b085cb6e33a61a108322875 (diff) | |
| download | vimium-f037e83763b1b62e048e1fc433d52b9564ce3ba0.tar.bz2 | |
Allow passing of keys to the underlying page.
| -rw-r--r-- | background_scripts/main.coffee | 37 | ||||
| -rw-r--r-- | background_scripts/settings.coffee | 4 | ||||
| -rw-r--r-- | content_scripts/vimium_frontend.coffee | 19 | ||||
| -rw-r--r-- | pages/options.html | 25 |
4 files changed, 71 insertions, 14 deletions
diff --git a/background_scripts/main.coffee b/background_scripts/main.coffee index 431d9a31..e32027b6 100644 --- a/background_scripts/main.coffee +++ b/background_scripts/main.coffee @@ -69,17 +69,29 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) -> getCurrentTabUrl = (request, sender) -> sender.tab.url # -# Checks the user's preferences in local storage to determine if Vimium is enabled for the given URL. +# Checks the user's preferences in local storage to determine if Vimium is enabled for the given URL, and +# whether any keys should be passed through to the underlying page. # isEnabledForUrl = (request) -> - # excludedUrls are stored as a series of URL expressions separated by newlines. - excludedUrls = Settings.get("excludedUrls").split("\n") - isEnabled = true - for url in excludedUrls - # The user can add "*" to the URL which means ".*" - regexp = new RegExp("^" + url.replace(/\*/g, ".*") + "$") - isEnabled = false if request.url.match(regexp) - { isEnabledForUrl: isEnabled } + # Excluded URLs are stored as a series of URL expressions and optional passKeys, separated by newlines. + # Lines for which the first non-blank character is "#" are comments. + excludedLines = (line.trim() for line in Settings.get("excludedUrls").split("\n")) + excludedUrls = (line for line in excludedLines when line and line.indexOf("#") != 0) + for spec in excludedUrls + parse = spec.split(/\s+/) + if parse.length + url = parse[0] + # The user can add "*" to the URL which means ".*" + regexp = new RegExp("^" + url.replace(/\*/g, ".*") + "$") + if request.url.match(regexp) + passKeys = parse[1..].join("") + if passKeys + # Enabled, but only for these keys. + return { isEnabledForUrl: true, passKeys: passKeys } + # Disabled. + return { isEnabledForUrl: false } + # Enabled (the default). + { isEnabledForUrl: true } # Called by the popup UI. Strips leading/trailing whitespace and ignores empty strings. root.addExcludedUrl = (url) -> @@ -500,6 +512,13 @@ handleKeyDown = (request, port) -> console.log("checking keyQueue: [", keyQueue + key, "]") keyQueue = checkKeyQueue(keyQueue + key, port.sender.tab.id, request.frameId) console.log("new KeyQueue: " + keyQueue) + # Tell the front end whether there are keys in the queue. If there are, then subsequent keys in passKeys will be + # handled by vimium. + # FIXME: There is a race condition here. The behaviour depends upon whether this message gets back + # to the front end before the next keystroke or not. + chrome.tabs.sendMessage(port.sender.tab.id, + name: "currentKeyQueue", + keyQueue: keyQueue) checkKeyQueue = (keysToCheck, tabId, frameId) -> refreshedCompletionKeys = false diff --git a/background_scripts/settings.coffee b/background_scripts/settings.coffee index 175f3262..34d6e879 100644 --- a/background_scripts/settings.coffee +++ b/background_scripts/settings.coffee @@ -83,7 +83,11 @@ root.Settings = Settings = """ excludedUrls: """ + # Disable Vimium on Gmail: http*://mail.google.com/* + + # Use Facebook's own j/k bindings: + http*://www.facebook.com/* jk """ # NOTE: If a page contains both a single angle-bracket link and a double angle-bracket link, then in # most cases the single bracket link will be "prev/next page" and the double bracket link will be diff --git a/content_scripts/vimium_frontend.coffee b/content_scripts/vimium_frontend.coffee index 565c9e61..70cc5cbb 100644 --- a/content_scripts/vimium_frontend.coffee +++ b/content_scripts/vimium_frontend.coffee @@ -15,6 +15,8 @@ isShowingHelpDialog = false keyPort = null # Users can disable Vimium on URL patterns via the settings page. isEnabledForUrl = true +passKeys = null +keyQueue = null # The user's operating system. currentCompletionKeys = null validFirstKeys = null @@ -115,6 +117,7 @@ initializePreDomReady = -> getScrollPosition: -> scrollX: window.scrollX, scrollY: window.scrollY setScrollPosition: (request) -> setScrollPosition request.scrollX, request.scrollY executePageCommand: executePageCommand + currentKeyQueue: (request) -> keyQueue = request.keyQueue getActiveState: -> { enabled: isEnabledForUrl } disableVimium: disableVimium @@ -321,6 +324,15 @@ extend window, false +# Should this keyChar 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. +# TODO: This currently only works for unmodified keys (so not for '<c-a>', or the like). It's not clear if +# this is a problem or not. I don't recall coming across a web page with modifier key bindings. Such +# bindings might be too likely to conflict with browser bindings. +isPassKey = ( keyChar ) -> + !keyQueue and passKeys and 0 <= passKeys.indexOf keyChar + handledKeydownEvents = [] # @@ -349,6 +361,9 @@ onKeypress = (event) -> handleKeyCharForFindMode(keyChar) DomUtils.suppressEvent(event) else if (!isInsertMode() && !findMode) + # Is this keyChar is to be passed to the underlying page? + if (isPassKey keyChar) + return undefined if (currentCompletionKeys.indexOf(keyChar) != -1) DomUtils.suppressEvent(event) @@ -431,6 +446,9 @@ onKeydown = (event) -> else if (KeyboardUtils.isEscape(event)) keyPort.postMessage({ keyChar:"<ESC>", frameId:frameId }) + else if isPassKey KeyboardUtils.getKeyChar(event) + return undefined + # Added to prevent propagating this event to other listeners if it's one that'll trigger a Vimium command. # The goal is to avoid the scenario where Google Instant Search uses every keydown event to dump us # back into the search box. As a side effect, this should also prevent overriding by other sites. @@ -467,6 +485,7 @@ checkIfEnabledForUrl = -> isEnabledForUrl = response.isEnabledForUrl if (isEnabledForUrl) initializeWhenEnabled() + passKeys = response.passKeys else if (HUD.isReady()) # Quickly hide any HUD we might already be showing, e.g. if we entered insert mode on page load. HUD.hide() diff --git a/pages/options.html b/pages/options.html index b71625e8..fc0f189d 100644 --- a/pages/options.html +++ b/pages/options.html @@ -197,15 +197,30 @@ </tr> <tr> <td colspan="3"> - Excluded URLs<br/> + Excluded URLs and keys<br/> <div class="help"> <div class="example"> - e.g. http*://mail.google.com/*<br/> - This will disable Vimium on Gmail.<br/><br/> - Enter one URL per line.<br/> + <p> + To disable Vimium on a site, use:<br/> + <tt>http*://mail.google.com/*</tt><br/> + This will <i>wholly disable</i> Vimium on Gmail.<br/><br/> + To use Vimium together with a website's own<br/> + key bindings, use:<br/> + <tt>http*://mail.google.com/* jknpc</tt><br/> + This will <i>enable</i> Vimium on Gmail, but pass<br/> + the five listed keys through to Gmail itself.<br/><br/> + One entry per line.<br/> + </p> </div> </div> - <textarea id="excludedUrls"></textarea> + <!-- Hack: fix a minimum size for the text area (below) so that it is + not too much smaller than its help text (above). --> + <!-- FIXME: + This text area should really be broken out into an array + separate inputs. However, the whole options page really + needs a workover, so I'm leaving it like this, for now + (Steve, 23 Aug, 14). --> + <textarea id="excludedUrls" style="min-height:180px"></textarea> </td> </tr> <tbody id='advancedOptions'> |
