aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--content_scripts/mode.coffee41
-rw-r--r--content_scripts/mode_insert.coffee6
-rw-r--r--content_scripts/mode_passkeys.coffee11
-rw-r--r--content_scripts/vimium_frontend.coffee10
-rw-r--r--lib/handler_stack.coffee20
5 files changed, 42 insertions, 46 deletions
diff --git a/content_scripts/mode.coffee b/content_scripts/mode.coffee
index a2a8b8b0..24c50561 100644
--- a/content_scripts/mode.coffee
+++ b/content_scripts/mode.coffee
@@ -4,16 +4,18 @@ class Mode
@modes: []
@current: -> Mode.modes[0]
- # Constants. Static.
- @suppressPropagation = false
- @propagate = true
+ # Constants; readable shortcuts for event-handler return values.
+ continueBubbling: true
+ suppressEvent: false
+ stopBubblingAndTrue: handlerStack.stopBubblingAndTrue
+ stopBubblingAndFalse: handlerStack.stopBubblingAndFalse
# Default values.
- 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.
+ 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", "bubble" or "pass"; see checkForBuiltInHandler().
+ keypress: "suppress" # A function, or "suppress", "bubble" or "pass"; see checkForBuiltInHandler().
+ keyup: "suppress" # A function, or "suppress", "bubble" or "pass"; see checkForBuiltInHandler().
constructor: (options) ->
extend @, options
@@ -30,23 +32,18 @@ class Mode
# Allow the strings "suppress" and "pass" to be used as proxies for the built-in handlers.
checkForBuiltInHandler: (type, handler) ->
switch handler
- when "suppress" then @generateSuppressPropagation type
- when "pass" then @generatePassThrough type
+ when "suppress" then @generateHandler type, @suppressEvent
+ when "bubble" then @generateHandler type, @continueBubbling
+ when "pass" then @generateHandler type, @stopBubblingAndTrue
else handler
- # Generate a default handler which always passes through to the underlying page; except Esc, which pops the
- # current mode.
- generatePassThrough: (type) ->
+ # Generate a default handler which always always yields the same result; except Esc, which pops the current
+ # mode.
+ generateHandler: (type, result) ->
(event) =>
- if type == "keydown" and KeyboardUtils.isEscape event
- @exit()
- return Mode.suppressPropagation
- handlerStack.passDirectlyToPage
-
- # Generate a default handler which always suppresses propagation; except Esc, which pops the current mode.
- generateSuppressPropagation: (type) ->
- handler = @generatePassThrough type
- (event) -> handler(event) and Mode.suppressPropagation # Always falsy.
+ return result unless type == "keydown" and KeyboardUtils.isEscape event
+ @exit()
+ @suppressEvent
exit: ->
handlerStack.remove handlerId for handlerId in @handlers
diff --git a/content_scripts/mode_insert.coffee b/content_scripts/mode_insert.coffee
index 9504edfd..ccd93870 100644
--- a/content_scripts/mode_insert.coffee
+++ b/content_scripts/mode_insert.coffee
@@ -44,8 +44,8 @@ class InsertMode extends Mode
generateKeyHandler: (type) ->
(event) =>
- return Mode.propagate unless @isActive()
- return handlerStack.passDirectlyToPage unless type == "keydown" and KeyboardUtils.isEscape event
+ return @continueBubbling unless @isActive()
+ return @stopBubblingAndTrue unless type == "keydown" and KeyboardUtils.isEscape event
# We're now exiting insert mode.
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
@@ -55,7 +55,7 @@ class InsertMode extends Mode
# games. See discussion in #1211 and #1194.
event.srcElement.blur()
@deactivate()
- Mode.suppressPropagation
+ @suppressEvent
constructor: ->
super
diff --git a/content_scripts/mode_passkeys.coffee b/content_scripts/mode_passkeys.coffee
index 9e922104..c7c2c9b7 100644
--- a/content_scripts/mode_passkeys.coffee
+++ b/content_scripts/mode_passkeys.coffee
@@ -11,12 +11,11 @@ class PassKeysMode extends Mode
handlePassKeyEvent: (event) ->
for keyChar in [KeyboardUtils.getKeyChar(event), String.fromCharCode(event.charCode)]
- # A key is passed through to the underlying page by returning handlerStack.passDirectlyToPage.
- return handlerStack.passDirectlyToPage if keyChar and @isPassKey keyChar
- Mode.propagate
+ return @stopBubblingAndTrue if keyChar and @isPassKey keyChar
+ @continueBubbling
- # This is called to set the pass-keys state with various types of request from various sources, so we handle
- # all of these.
+ # This is called to set the pass-keys configuration and state with various types of request from various
+ # sources, so we handle several cases.
# TODO(smblott) Rationalize this.
setState: (request) ->
if request.isEnabledForUrl?
@@ -33,7 +32,7 @@ class PassKeysMode extends Mode
name: "passkeys"
keydown: (event) => @handlePassKeyEvent event
keypress: (event) => @handlePassKeyEvent event
- keyup: -> Mode.propagate
+ keyup: => @continueBubbling
updateBadgeForMode: (badge) ->
@badge = if @passKeys and not @keyQueue then "P" else ""
diff --git a/content_scripts/vimium_frontend.coffee b/content_scripts/vimium_frontend.coffee
index c0f98d85..7950bd42 100644
--- a/content_scripts/vimium_frontend.coffee
+++ b/content_scripts/vimium_frontend.coffee
@@ -456,7 +456,7 @@ onKeypress = (event) ->
DomUtils.suppressEvent(event)
else if (!isInsertMode() && !findMode)
if (isPassKey keyChar)
- return handlerStack.passDirectlyToPage
+ return handlerStack.stopBubblingAndTrue
if (currentCompletionKeys.indexOf(keyChar) != -1 or isValidFirstKey(keyChar))
DomUtils.suppressEvent(event)
@@ -737,17 +737,17 @@ class FindMode extends Mode
if KeyboardUtils.isEscape event
handleEscapeForFindMode()
@exit()
- Mode.suppressPropagation
+ @suppressEvent
else if (event.keyCode == keyCodes.backspace || event.keyCode == keyCodes.deleteKey)
handleDeleteForFindMode()
- Mode.suppressPropagation
+ @suppressEvent
else if (event.keyCode == keyCodes.enter)
handleEnterForFindMode()
@exit()
- Mode.suppressPropagation
+ @suppressEvent
else
DomUtils.suppressPropagation(event)
- handlerStack.eventConsumed
+ handlerStack.stopBubblingAndFalse
keypress: (event) ->
handlerStack.neverPropagate ->
diff --git a/lib/handler_stack.coffee b/lib/handler_stack.coffee
index 764461e7..d2d0672a 100644
--- a/lib/handler_stack.coffee
+++ b/lib/handler_stack.coffee
@@ -5,8 +5,14 @@ class HandlerStack
constructor: ->
@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.
+
+ # A handler should return this value to immediately discontinue bubbling and pass the event on to the
+ # underlying page.
+ @stopBubblingAndTrue = new Object()
+
+ # A handler should return this value to indicate that the event has been consumed, and no further
+ # processing should take place.
+ @stopBubblingAndFalse = new Object()
genId: -> @counter = ++@counter
@@ -29,14 +35,8 @@ class HandlerStack
if not passThrough
DomUtils.suppressEvent(event) if @isChromeEvent event
return false
- # If the constant @passDirectlyToPage is returned, then discontinue further bubbling and pass the
- # 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
+ return true if passThrough == @stopBubblingAndTrue
+ return false if passThrough == @stopBubblingAndFalse
true
remove: (id = @currentId) ->