aboutsummaryrefslogtreecommitdiffstats
path: root/lib/handler_stack.coffee
diff options
context:
space:
mode:
authorStephen Blott2015-01-10 00:00:11 +0000
committerStephen Blott2015-01-10 07:23:47 +0000
commitac90db47aa2671cd663cc6a9cdf783dc30a582e9 (patch)
treea80cafd3af5c43ac20620e3c8d9dabd0addd9b7b /lib/handler_stack.coffee
parentd97e7786cb04dbbe5cae8e4b86e25437f66eb799 (diff)
downloadvimium-ac90db47aa2671cd663cc6a9cdf783dc30a582e9.tar.bz2
Modes; more changes...
- Better comments. - Strip unnecessary handlers for leaving post-find mode. - Simplify passKeys. - focusInput now re-bubbles its triggering keydown event.
Diffstat (limited to 'lib/handler_stack.coffee')
-rw-r--r--lib/handler_stack.coffee37
1 files changed, 20 insertions, 17 deletions
diff --git a/lib/handler_stack.coffee b/lib/handler_stack.coffee
index 97e189c5..44c7538b 100644
--- a/lib/handler_stack.coffee
+++ b/lib/handler_stack.coffee
@@ -14,6 +14,11 @@ class HandlerStack
# processing should take place.
@stopBubblingAndFalse = new Object()
+ # A handler should return this value to indicate that bubbling should be restarted. Typically, this is
+ # used when, while bubbling an event, a new mode is pushed onto the stack. See `focusInput` for an
+ # example.
+ @restartBubbling = new Object()
+
# Adds a handler to the top of the stack. Returns a unique ID for that handler that can be used to remove it
# later.
push: (handler) ->
@@ -30,30 +35,26 @@ class HandlerStack
# event's propagation by returning a falsy value, or stop bubbling by returning @stopBubblingAndFalse or
# @stopBubblingAndTrue.
bubbleEvent: (type, event) ->
- # extra is passed to each handler. This allows handlers to pass information down the stack.
- extra = {}
- # We take a copy of the array, here, in order to avoid interference from concurrent removes (for example,
- # to avoid calling the same handler twice).
+ # We take a copy of the array in order to avoid interference from concurrent removes (for example, to
+ # avoid calling the same handler twice, because elements have been spliced out of the array by remove).
for handler in @stack[..].reverse()
- # A handler may have been removed (handler.id == null).
- if handler and handler.id
+ # A handler may have been removed (handler.id == null), so check.
+ if handler?.id and handler[type]
@currentId = handler.id
- # A handler can register a handler for type "all", which will be invoked on all events. Such an "all"
- # handler will be invoked first.
- for func in [ handler.all, handler[type] ]
- if func
- passThrough = func.call @, event, extra
- if not passThrough
- DomUtils.suppressEvent(event) if @isChromeEvent event
- return false
- return true if passThrough == @stopBubblingAndTrue
- return false if passThrough == @stopBubblingAndFalse
+ result = handler[type].call @, event
+ if not result
+ DomUtils.suppressEvent(event) if @isChromeEvent event
+ return false
+ return true if result == @stopBubblingAndTrue
+ return false if result == @stopBubblingAndFalse
+ return @bubbleEvent type, event if result == @restartBubbling
true
remove: (id = @currentId) ->
for i in [(@stack.length - 1)..0] by -1
handler = @stack[i]
if handler.id == id
+ # Mark the handler as removed.
handler.id = null
@stack.splice(i, 1)
break
@@ -63,7 +64,9 @@ class HandlerStack
isChromeEvent: (event) ->
event?.preventDefault? or event?.stopImmediatePropagation?
- # Convenience wrappers.
+ # Convenience wrappers. Handlers must return an approriate value. These are wrappers which handlers can
+ # use to always return the same value. This then means that the handler itself can be implemented without
+ # regard to its return value.
alwaysContinueBubbling: (handler) ->
handler()
true