From 32dc2bf3bf5c28ff44fff89d2436a76bb7bba925 Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Sat, 15 Oct 2016 12:01:15 +0100 Subject: enterNormalMode; new command - implementation Here's the problem... Many sites define their own keyboard shortcuts, for example Google Play Music defines `gh` for "go home". On such sites, it's natural to set up pass keys for `g` and `h`. But that makes any Vimium key bindings which begin with `g` inaccessible. Here, we add a new command `enterNormalMode` which installs a new normal-mode instance (without any pass keys). This executes a single normal-mode command then exits. Example: map \ enterNormalMode map | enterNormalMode count=999999 Assuming `g` and `o` are pass keys: - `gh` or `o` - use the page's binding - `\gg` - scroll to top - `2\ggo` - scroll to the top and open the Vomnibar - `\go` - open the Vomnibar - `\o` - use the page's bindings - `\\\\\\o` - use the page's bindings (new normal-mode instances displace previous ones) This required some changes to the scroller. Previously, we only ever had one normal-mode instance, and could arrange statically that the scroller's key listeners were above normal-mode's key listeners in the handler stack. Here, we fix this by adding and removing the scroller's listeners dynamically, so they're always at the top of the handler stack. --- content_scripts/vimium_frontend.coffee | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'content_scripts/vimium_frontend.coffee') diff --git a/content_scripts/vimium_frontend.coffee b/content_scripts/vimium_frontend.coffee index fcca98ab..64e13852 100644 --- a/content_scripts/vimium_frontend.coffee +++ b/content_scripts/vimium_frontend.coffee @@ -111,11 +111,13 @@ handlerStack.push class NormalMode extends KeyHandlerMode constructor: (options = {}) -> - super extend options, + defaults = name: "normal" - indicator: false # There is no mode indicator in normal mode. + indicator: false # There is normally no mode indicator in normal mode. commandHandler: @commandHandler.bind this + super extend defaults, options + chrome.storage.local.get "normalModeKeyStateMapping", (items) => @setKeyMapping items.normalModeKeyStateMapping @@ -123,10 +125,6 @@ class NormalMode extends KeyHandlerMode if area == "local" and changes.normalModeKeyStateMapping?.newValue @setKeyMapping changes.normalModeKeyStateMapping.newValue - # Initialize components which normal mode depends upon. - Scroller.init() - FindModeHistory.init() - commandHandler: ({command: registryEntry, count}) -> count *= registryEntry.options.count ? 1 count = 1 if registryEntry.noRepeat @@ -150,6 +148,9 @@ installModes = -> # Install the permanent modes. The permanently-installed insert mode tracks focus/blur events, and # activates/deactivates itself accordingly. normalMode = new NormalMode + # Initialize components upon which normal mode depends. + Scroller.init() + FindModeHistory.init() new InsertMode permanent: true new GrabBackFocus if isEnabledForUrl normalMode # Return the normalMode object (for the tests). @@ -386,6 +387,9 @@ extend window, passNextKey: (count) -> new PassNextKeyMode count + enterNormalMode: (count) -> + new NormalMode exitOnEscape: true, indicator: "Normal mode", count: count, singleton: "enterNormalMode" + focusInput: do -> # Track the most recently focused input element. recentlyFocusedElement = null -- cgit v1.2.3