diff options
| author | Stephen Blott | 2015-02-12 09:15:30 +0000 | 
|---|---|---|
| committer | Stephen Blott | 2015-02-12 09:33:16 +0000 | 
| commit | 0ea060ca5b45acf42eb892cf900b8b7e04fc3397 (patch) | |
| tree | 5af5c01e6664ce818a9faf01bb2ee7bb8f168724 | |
| parent | 51a4748f80490e0433c5387171fb28b88adf0ea5 (diff) | |
| download | vimium-0ea060ca5b45acf42eb892cf900b8b7e04fc3397.tar.bz2 | |
Initial grab-back-focus.
If an input grabs the focus before the user interacts with the page
(keydown, mousedown), then grab back the focus.
TBD:
  1 This requires a new option, which has not yet been added.  For now,
    it's just permanently enabled.
  2 There's a race condition between the setting being loaded and the
    element being focused.  Currently, this defaults to being activated.
    This is the wrong thing to do.  The solution is probably to use
    chrome.storage for the setting.
  3 The tests fail (because of TBD-2, above).
| -rw-r--r-- | content_scripts/vimium_frontend.coffee | 28 | 
1 files changed, 27 insertions, 1 deletions
| diff --git a/content_scripts/vimium_frontend.coffee b/content_scripts/vimium_frontend.coffee index 050a271e..ddc19d3a 100644 --- a/content_scripts/vimium_frontend.coffee +++ b/content_scripts/vimium_frontend.coffee @@ -96,6 +96,31 @@ settings =  #  frameId = Math.floor(Math.random()*999999999) +# If an input grabs the focus before the user has interacted with the page, then grab it back. +class GrabBackFocus extends Mode +  constructor: (@insertMode) -> +    return if @shouldBeDeactivated() +    super name: "grab-focus", keydown: => @alwaysContinueBubbling => @exit() + +    @push +      _name: "grab-focus-handlers" +      mousedown: => @alwaysContinueBubbling => @exit() +      focus: (event) => @grabBackFocus event.target + +    # An input may already be focused. If so, grab back the focus. +    @grabBackFocus document.activeElement if document.activeElement + +  grabBackFocus: (element) -> +    if DomUtils.isEditable(element) and not @shouldBeDeactivated() +      element.blur() +      @insertMode.exit null, element +      return @suppressEvent +    @exit() if @shouldBeDeactivated() +    @continueBubbling + +  shouldBeDeactivated: -> +    false and settings.isLoaded and not settings.get "grabBackFocus" +  # Only exported for tests.  window.initializeModes = ->    class NormalMode extends Mode @@ -114,6 +139,7 @@ window.initializeModes = ->    new NormalMode    new PassKeysMode    new InsertMode permanent: true +  new GrabBackFocus InsertMode.permanentInstance  #  # Complete initialization work that sould be done prior to DOMReady. @@ -179,7 +205,7 @@ window.initializeWhenEnabled = ->    unless 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. -    for type in ["keydown", "keypress", "keyup", "click", "focus", "blur"] +    for type in [ "keydown", "keypress", "keyup", "click", "focus", "blur", "mousedown" ]        do (type) -> installListener window, type, (event) -> handlerStack.bubbleEvent type, event      installListener document, "DOMActivate", (event) -> handlerStack.bubbleEvent 'DOMActivate', event      installedListeners = true | 
