diff options
| author | Stephen Blott | 2015-01-02 11:47:42 +0000 | 
|---|---|---|
| committer | Stephen Blott | 2015-01-02 12:08:35 +0000 | 
| commit | 298ee34b1c90b0203a74a2d158858428475bfd95 (patch) | |
| tree | 74a634c247bb0108701adafe7acd7397cf15166f | |
| parent | 6d471844497ff35b83296d7da34830288696f029 (diff) | |
| download | vimium-298ee34b1c90b0203a74a2d158858428475bfd95.tar.bz2 | |
Modes; fix insert mode.
| -rw-r--r-- | content_scripts/mode_insert.coffee | 39 | ||||
| -rw-r--r-- | content_scripts/vimium_frontend.coffee | 1 | ||||
| -rw-r--r-- | lib/handler_stack.coffee | 5 | 
3 files changed, 28 insertions, 17 deletions
| diff --git a/content_scripts/mode_insert.coffee b/content_scripts/mode_insert.coffee index e68bf6ab..c8b05217 100644 --- a/content_scripts/mode_insert.coffee +++ b/content_scripts/mode_insert.coffee @@ -9,7 +9,7 @@ class InsertMode extends Mode      return true if element.isContentEditable      nodeName = element.nodeName?.toLowerCase()      # Use a blacklist instead of a whitelist because new form controls are still being implemented for html5. -    if nodeName == "input" and element.type and not element.type in ["radio", "checkbox"] +    if nodeName == "input" and element.type not in ["radio", "checkbox"]        return true      nodeName in ["textarea", "select"] @@ -18,14 +18,17 @@ class InsertMode extends Mode    isEmbed: (element) ->      element.nodeName?.toLowerCase() in ["embed", "object"] -  canEditElement: (element) -> -    element and (@isEditable(element) or @isEmbed element) +  isFocusable: (element) -> +    (@isEditable(element) or @isEmbed element) -  # Check whether insert mode is active.  Also, activate insert mode if the current element is editable. +  # Check whether insert mode is active.  Also, activate insert mode if the current element is content +  # editable.    isActive: ->      return true if @isInsertMode -    # FIXME(smblott).  Is there a way to (safely) cache the results of these @canEditElement() calls? -    @activate() if @canEditElement document.activeElement +    # Some sites (e.g. inbox.google.com) change the contentEditable attribute on the fly (see #1245); and +    # unfortunately, isEditable() is called *before* the change is made.  Therefore, we need to re-check +    # whether the active element is contentEditable. +    @activate() if document.activeElement?.isContentEditable      @isInsertMode    generateKeyHandler: (type) -> @@ -33,7 +36,7 @@ class InsertMode extends Mode        return Mode.propagate unless @isActive()        return handlerStack.passDirectlyToPage unless type == "keydown" and KeyboardUtils.isEscape event        # We're now exiting insert mode. -      if @canEditElement event.srcElement +      if @isEditable(event.srcElement) or @isEmbed event.srcElement          # Remove the focus so the user can't just get himself back into insert mode by typing in the same input          # box.          # NOTE(smblott, 2014/12/22) Including embeds for .blur() here is experimental.  It appears to be the @@ -45,8 +48,9 @@ class InsertMode extends Mode        Mode.suppressPropagation    activate: -> -    @isInsertMode = true -    Mode.updateBadge() +    unless @isInsertMode +      @isInsertMode = true +      Mode.updateBadge()    # Override (and re-use) updateBadgeForMode() from Mode.updateBadgeForMode().  Use insert-mode badge only if    # we're active and no mode higher in stack has already inserted a badge. @@ -54,11 +58,6 @@ class InsertMode extends Mode      @badge = if @isActive() then "I" else ""      super badge -  checkModeState: -> -    previousState = @isInsertMode -    if @isActive() != previousState -      Mode.updateBadge() -    constructor: ->      super        name: "insert" @@ -68,9 +67,15 @@ class InsertMode extends Mode        keyup: @generateKeyHandler "keyup"      @handlers.push handlerStack.push -      DOMActivate: => @checkModeState() -      focus: => @checkModeState() -      blur: => @checkModeState() +      focus: (event) => +        handlerStack.alwaysPropagate => +          if not @isInsertMode and @isFocusable event.target +            @activate() +      blur: (event) => +        handlerStack.alwaysPropagate => +          if @isInsertMode and @isFocusable event.target +            @isInsertMode = false +            Mode.updateBadge()      # We may already have been dropped into insert mode.  So check.      Mode.updateBadge() diff --git a/content_scripts/vimium_frontend.coffee b/content_scripts/vimium_frontend.coffee index 09e775a6..da1f5de1 100644 --- a/content_scripts/vimium_frontend.coffee +++ b/content_scripts/vimium_frontend.coffee @@ -126,6 +126,7 @@ initializePreDomReady = ->      updateBadgeForMode: (badge) ->        badge.badge ||= @badge        badge.badge = "" unless isEnabledForUrl +      Mode.propagate # Not really necessary, but makes intention clear and does no harm.    # Initialize the scroller. The scroller install a key handler, and this is next on the handler stack,    # immediately above normal mode. diff --git a/lib/handler_stack.coffee b/lib/handler_stack.coffee index 8de6ec12..f56683f1 100644 --- a/lib/handler_stack.coffee +++ b/lib/handler_stack.coffee @@ -46,5 +46,10 @@ class HandlerStack    isChromeEvent: (event) ->      event?.preventDefault? and event?.stopImmediatePropagation? +  # Convenience wrapper for handlers which always continue propagation. +  alwaysPropagate: (handler) -> +    handler() +    true +  root.HandlerStack = HandlerStack  root.handlerStack = new HandlerStack | 
