diff options
| -rw-r--r-- | content_scripts/mode.coffee | 3 | ||||
| -rw-r--r-- | content_scripts/mode_find.coffee | 3 | ||||
| -rw-r--r-- | content_scripts/mode_insert.coffee | 3 | ||||
| -rw-r--r-- | content_scripts/mode_key_handler.coffee | 18 | ||||
| -rw-r--r-- | content_scripts/scroller.coffee | 18 | ||||
| -rw-r--r-- | content_scripts/vimium_frontend.coffee | 27 | ||||
| -rw-r--r-- | lib/dom_utils.coffee | 1 |
7 files changed, 53 insertions, 20 deletions
diff --git a/content_scripts/mode.coffee b/content_scripts/mode.coffee index 6508627e..c1dea59a 100644 --- a/content_scripts/mode.coffee +++ b/content_scripts/mode.coffee @@ -81,9 +81,8 @@ class Mode _name: "mode-#{@id}/exitOnEscape" "keydown": (event) => return @continueBubbling unless KeyboardUtils.isEscape event - DomUtils.suppressKeyupAfterEscape handlerStack @exit event, event.srcElement - @suppressEvent + DomUtils.suppressKeyupAfterEscape handlerStack # If @options.exitOnBlur is truthy, then it should be an element. The mode will exit when that element # loses the focus. diff --git a/content_scripts/mode_find.coffee b/content_scripts/mode_find.coffee index 8621edf8..0178527b 100644 --- a/content_scripts/mode_find.coffee +++ b/content_scripts/mode_find.coffee @@ -47,9 +47,8 @@ class PostFindMode extends SuppressPrintable _name: "mode-#{@id}/handle-escape" keydown: (event) => if KeyboardUtils.isEscape event - DomUtils.suppressKeyupAfterEscape handlerStack @exit() - @suppressEvent + DomUtils.suppressKeyupAfterEscape handlerStack else handlerStack.remove() @continueBubbling diff --git a/content_scripts/mode_insert.coffee b/content_scripts/mode_insert.coffee index 4cb0a39e..d5d98297 100644 --- a/content_scripts/mode_insert.coffee +++ b/content_scripts/mode_insert.coffee @@ -17,7 +17,6 @@ class InsertMode extends Mode return @suppressEvent return @passEventToPage unless event.type == 'keydown' and KeyboardUtils.isEscape event - DomUtils.suppressKeyupAfterEscape handlerStack target = event.srcElement if target and DomUtils.isFocusable target # Remove the focus, so the user can't just get back into insert mode by typing in the same input box. @@ -26,7 +25,7 @@ class InsertMode extends Mode # An editable element in a shadow DOM is focused; blur it. @insertModeLock.blur() @exit event, event.srcElement - @suppressEvent + DomUtils.suppressKeyupAfterEscape handlerStack defaults = name: "insert" diff --git a/content_scripts/mode_key_handler.coffee b/content_scripts/mode_key_handler.coffee index 480a79af..9b5a1fef 100644 --- a/content_scripts/mode_key_handler.coffee +++ b/content_scripts/mode_key_handler.coffee @@ -36,6 +36,18 @@ class KeyHandlerMode extends Mode @mapKeyRegistry = {} Utils.monitorChromeStorage "mapKeyRegistry", (value) => @mapKeyRegistry = value + if options.exitOnEscape + # If we're part way through a command's key sequence, then a first Escape should reset the key state, + # and only a second Escape should actually exit this mode. + @push + _name: "key-handler-escape-listener" + keydown: (event) => + if KeyboardUtils.isEscape(event) and not @isInResetState() + @reset() + DomUtils.suppressKeyupAfterEscape handlerStack + else + @continueBubbling + onKeydown: (event) -> keyChar = KeyboardUtils.getKeyCharString event keyChar = @mapKeyRegistry[keyChar] ? keyChar @@ -92,7 +104,10 @@ class KeyHandlerMode extends Mode # Keystrokes are *never* considered pass keys if the user has begun entering a command. So, for example, if # 't' is a passKey, then the "t"-s of 'gt' and '99t' are neverthless handled as regular keys. isPassKey: (keyChar) -> - @countPrefix == 0 and @keyState.length == 1 and keyChar in (@passKeys ? "") + @isInResetState() and keyChar in (@passKeys ? "") + + isInResetState: -> + @countPrefix == 0 and @keyState.length == 1 handleKeyChar: (keyChar) -> bgLog "handle key #{keyChar} (#{@name})" @@ -106,6 +121,7 @@ class KeyHandlerMode extends Mode bgLog " invoke #{command.command} count=#{count} " @reset() @commandHandler {command, count} + @exit() if @options.count? and --@options.count <= 0 @suppressEvent root = exports ? window diff --git a/content_scripts/scroller.coffee b/content_scripts/scroller.coffee index 3a1b3772..a533c161 100644 --- a/content_scripts/scroller.coffee +++ b/content_scripts/scroller.coffee @@ -128,13 +128,15 @@ checkVisibility = (element) -> CoreScroller = init: -> @time = 0 - @lastEvent = null - @keyIsDown = false + @lastEvent = @keyIsDown = @cancelEventListenerId = null + # This installs listeners for events which should cancel smooth scrolling. + installCanceEventListener: -> + @removeCancelEventListener() # NOTE(smblott) With extreme keyboard configurations, Chrome sometimes does not get a keyup event for # every keydown, in which case tapping "j" scrolls indefinitely. This appears to be a Chrome/OS/XOrg bug # of some kind. See #1549. - handlerStack.push + @cancelEventListenerId = handlerStack.push _name: 'scroller/track-key-status' keydown: (event) => handlerStack.alwaysContinueBubbling => @@ -149,6 +151,10 @@ CoreScroller = handlerStack.alwaysContinueBubbling => @time += 1 if event.target == window + removeCancelEventListener: -> + handlerStack.remove @cancelEventListenerId if @cancelEventListenerId? + @cancelEventListenerId = @lastEvent = @keyIsDown = null + # Return true if CoreScroller would not initiate a new scroll right now. wouldNotInitiateScroll: -> @lastEvent?.repeat and Settings.get "smoothScroll" @@ -175,7 +181,7 @@ CoreScroller = return if @lastEvent?.repeat activationTime = ++@time - myKeyIsStillDown = => @time == activationTime and @keyIsDown + myKeyIsStillDown = => @time == activationTime and @keyIsDown ? true # Store amount's sign and make amount positive; the arithmetic is clearer when amount is positive. sign = getSign amount @@ -215,13 +221,15 @@ CoreScroller = requestAnimationFrame animate else # We're done. + @removeCancelEventListener() checkVisibility element # If we've been asked not to be continuous, then we advance time, so the myKeyIsStillDown test always # fails. ++@time unless continuous - # Launch animator. + # Start scrolling. + @installCanceEventListener() requestAnimationFrame animate # Scroller contains the two main scroll functions which are used by clients. diff --git a/content_scripts/vimium_frontend.coffee b/content_scripts/vimium_frontend.coffee index 21826944..6447092b 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). @@ -383,8 +384,18 @@ extend window, enterVisualLineMode: -> new VisualLineMode userLaunchedMode: true - passNextKey: (count) -> - new PassNextKeyMode count + passNextKey: (count, options) -> + if options.registryEntry.options.normal + enterNormalMode count + else + new PassNextKeyMode count + + enterNormalMode: (count) -> + new NormalMode + indicator: "Normal mode (pass keys disabled)" + exitOnEscape: true + singleton: "enterNormalMode" + count: count focusInput: do -> # Track the most recently focused input element. diff --git a/lib/dom_utils.coffee b/lib/dom_utils.coffee index 82c13287..fad5ffbf 100644 --- a/lib/dom_utils.coffee +++ b/lib/dom_utils.coffee @@ -310,6 +310,7 @@ DomUtils = return true unless KeyboardUtils.isEscape event @remove() false + handlerStack.suppressEvent # Adapted from: http://roysharon.com/blog/37. # This finds the element containing the selection focus. |
