diff options
| -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 |
