diff options
| author | Stephen Blott | 2015-01-02 15:59:58 +0000 | 
|---|---|---|
| committer | Stephen Blott | 2015-01-02 17:17:34 +0000 | 
| commit | 2d8c478e8086abf80b206d0fd8abc488a035b5cd (patch) | |
| tree | 6587ee3d4f11aef54b5a2c5ccb0989307f865eeb | |
| parent | b7d5e25e353010505db7754e97d4387c8aa6b8fc (diff) | |
| download | vimium-2d8c478e8086abf80b206d0fd8abc488a035b5cd.tar.bz2 | |
Modes; incorporate find mode.
| -rw-r--r-- | background_scripts/main.coffee | 2 | ||||
| -rw-r--r-- | content_scripts/mode.coffee | 16 | ||||
| -rw-r--r-- | content_scripts/mode_passkeys.coffee | 11 | ||||
| -rw-r--r-- | content_scripts/vimium_frontend.coffee | 54 | ||||
| -rw-r--r-- | lib/handler_stack.coffee | 10 | 
5 files changed, 71 insertions, 22 deletions
| diff --git a/background_scripts/main.coffee b/background_scripts/main.coffee index 8d36de95..fc0a792f 100644 --- a/background_scripts/main.coffee +++ b/background_scripts/main.coffee @@ -352,7 +352,7 @@ setBadge = (request) ->  root.updateActiveState = updateActiveState = (tabId) ->    enabledIcon = "icons/browser_action_enabled.png"    disabledIcon = "icons/browser_action_disabled.png" -  partialIcon = enabledIcon # Let's try diabling that while we're playing with badges... "icons/browser_action_partial.png" +  partialIcon = "icons/browser_action_partial.png"    chrome.tabs.get tabId, (tab) ->      chrome.tabs.sendMessage tabId, { name: "getActiveState" }, (response) ->        if response diff --git a/content_scripts/mode.coffee b/content_scripts/mode.coffee index 7ca818b4..a2a8b8b0 100644 --- a/content_scripts/mode.coffee +++ b/content_scripts/mode.coffee @@ -9,11 +9,11 @@ class Mode    @propagate = true    # Default values. -  name: ""             # The name of this mode. -  badge: ""            # A badge to display on the popup when this mode is active. -  keydown: "suppress"  # A function, or "suppress" or "pass"; the latter are replaced with suitable functions. -  keypress: "suppress" # A function, or "suppress" or "pass"; the latter are replaced with suitable functions. -  keyup: "suppress"    # A function, or "suppress" or "pass"; the latter are replaced with suitable functions. +  name: ""         # The name of this mode. +  badge: ""        # A badge to display on the popup when this mode is active. +  keydown: "pass"  # A function, or "suppress" or "pass"; the latter are replaced with suitable handlers. +  keypress: "pass" # A function, or "suppress" or "pass"; the latter are replaced with suitable handlers. +  keyup: "pass"    # A function, or "suppress" or "pass"; the latter are replaced with suitable handlers.    constructor: (options) ->      extend @, options @@ -73,5 +73,11 @@ class Mode    @sendBadge: (badge) ->      chrome.runtime.sendMessage({ handler: "setBadge", badge: badge }) +  # Install a mode, call a function, and exit the mode again. +  @runIn: (mode, func) -> +    mode = new mode() +    func() +    mode.exit() +  root = exports ? window  root.Mode = Mode diff --git a/content_scripts/mode_passkeys.coffee b/content_scripts/mode_passkeys.coffee index a953deca..9e922104 100644 --- a/content_scripts/mode_passkeys.coffee +++ b/content_scripts/mode_passkeys.coffee @@ -7,9 +7,6 @@ class PassKeysMode extends Mode    # 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.    isPassKey: (keyChar) -> -    # FIXME(smblott).  Temporary hack: attach findMode to the window (so passKeysMode can see it).  This will be -    # fixed when find mode is rationalized or #1401 is merged. -    return false if window.findMode      not @keyQueue and 0 <= @passKeys.indexOf(keyChar)    handlePassKeyEvent: (event) -> @@ -24,12 +21,12 @@ class PassKeysMode extends Mode    setState: (request) ->      if request.isEnabledForUrl?        @passKeys = (request.isEnabledForUrl and request.passKeys) or "" +      Mode.updateBadge()      if request.enabled?        @passKeys = (request.enabled and request.passKeys) or "" +      Mode.updateBadge()      if request.keyQueue?        @keyQueue = request.keyQueue -    @badge = if @passKeys and not @keyQueue then "P" else "" -    Mode.updateBadge()    constructor: ->      super @@ -38,5 +35,9 @@ class PassKeysMode extends Mode        keypress: (event) => @handlePassKeyEvent event        keyup: -> Mode.propagate +  updateBadgeForMode: (badge) -> +    @badge = if @passKeys and not @keyQueue then "P" else "" +    super badge +  root = exports ? window  root.PassKeysMode = PassKeysMode diff --git a/content_scripts/vimium_frontend.coffee b/content_scripts/vimium_frontend.coffee index 2df2e226..c0f98d85 100644 --- a/content_scripts/vimium_frontend.coffee +++ b/content_scripts/vimium_frontend.coffee @@ -8,9 +8,7 @@  insertMode = null  passKeysMode = null  insertModeLock = null -# FIXME(smblott).  Temporary hack: attach findMode to the window (so passKeysMode can see it).  This will be -# fixed when find mode is rationalized or #1401 is merged. -window.findMode = false +findMode = false  findModeQuery = { rawQuery: "", matchCount: 0 }  findModeQueryHasResults = false  findModeAnchorNode = null @@ -729,6 +727,42 @@ handleEnterForFindMode = ->    document.body.classList.add("vimiumFindMode")    settings.set("findModeRawQuery", findModeQuery.rawQuery) +class FindMode extends Mode +  constructor: -> +    super +      name: "find" +      badge: "F" + +      keydown: (event) => +        if KeyboardUtils.isEscape event +          handleEscapeForFindMode() +          @exit() +          Mode.suppressPropagation +        else if (event.keyCode == keyCodes.backspace || event.keyCode == keyCodes.deleteKey) +          handleDeleteForFindMode() +          Mode.suppressPropagation +        else if (event.keyCode == keyCodes.enter) +          handleEnterForFindMode() +          @exit() +          Mode.suppressPropagation +        else +          DomUtils.suppressPropagation(event) +          handlerStack.eventConsumed + +      keypress: (event) -> +        handlerStack.neverPropagate -> +          if event.keyCode > 31 +            keyChar = String.fromCharCode event.charCode +            handleKeyCharForFindMode keyChar if keyChar + +      keyup: (event) -> handlerStack.neverPropagate -> false + +    # Prevent insert mode from detecting a focused editable element. +    @handlers.push handlerStack.push +      focus: (event) -> handlerStack.neverPropagate (event) -> + +    Mode.updateBadge() +  performFindInPlace = ->    cachedScrollX = window.scrollX    cachedScrollY = window.scrollY @@ -747,25 +781,21 @@ performFindInPlace = ->  # :options is an optional dict. valid parameters are 'caseSensitive' and 'backwards'.  executeFind = (query, options) -> +  result = null    options = options || {} -  # rather hacky, but this is our way of signalling to the insertMode listener not to react to the focus -  # changes that find() induces. -  oldFindMode = findMode -  window.findMode = true # Same hack, see comment at window.findMode definition. -    document.body.classList.add("vimiumFindMode")    # prevent find from matching its own search query in the HUD    HUD.hide(true)    # ignore the selectionchange event generated by find()    document.removeEventListener("selectionchange",restoreDefaultSelectionHighlight, true) -  result = window.find(query, options.caseSensitive, options.backwards, true, false, true, false) +  Mode.runIn FindMode, -> +    result = window.find(query, options.caseSensitive, options.backwards, true, false, true, false)    setTimeout(      -> document.addEventListener("selectionchange", restoreDefaultSelectionHighlight, true)      0) -  window.findMode = oldFindMode # Same hack, see comment at window.findMode definition.    # we need to save the anchor node here because <esc> seems to nullify it, regardless of whether we do    # preventDefault()    findModeAnchorNode = document.getSelection().anchorNode @@ -839,6 +869,7 @@ findAndFocus = (backwards) ->          if (KeyboardUtils.isEscape(event))            DomUtils.simulateSelect(document.activeElement)            enterInsertModeWithoutShowingIndicator(document.activeElement) +          insertMode.activate()            return false # we have "consumed" this event, so do not propagate          return true      }) @@ -958,8 +989,9 @@ showFindModeHUDForQuery = ->  window.enterFindMode = ->    findModeQuery = { rawQuery: "" } -  window.findMode = true # Same hack, see comment at window.findMode definition. +  # window.findMode = true # Same hack, see comment at window.findMode definition.    HUD.show("/") +  new FindMode()  exitFindMode = ->    window.findMode = false # Same hack, see comment at window.findMode definition. diff --git a/lib/handler_stack.coffee b/lib/handler_stack.coffee index f56683f1..764461e7 100644 --- a/lib/handler_stack.coffee +++ b/lib/handler_stack.coffee @@ -6,6 +6,7 @@ class HandlerStack      @stack = []      @counter = 0      @passDirectlyToPage = new Object() # Used only as a constant, distinct from any other value. +    @eventConsumed = new Object() # Used only as a constant, distinct from any other value.    genId: -> @counter = ++@counter @@ -32,6 +33,10 @@ class HandlerStack          # event through to the underlying page.  The event is not suppresssed.          if passThrough == @passDirectlyToPage            return false +        # If the constant @eventConsumed is returned, then discontinue further bubbling and +        # return false. +        if passThrough == @eventConsumed +          return false      true    remove: (id = @currentId) -> @@ -51,5 +56,10 @@ class HandlerStack      handler()      true +  # Convenience wrapper for handlers which never continue propagation. +  neverPropagate: (handler) -> +    handler() +    false +  root.HandlerStack = HandlerStack  root.handlerStack = new HandlerStack | 
