diff options
| author | Stephen Blott | 2015-01-05 14:25:08 +0000 |
|---|---|---|
| committer | Stephen Blott | 2015-01-05 15:40:28 +0000 |
| commit | 94586418ffd92246551c26ff00f0d80b0e2289fa (patch) | |
| tree | 2f7f716810766668d8485f2d4bef6fecfc1d84cc /content_scripts/mode.coffee | |
| parent | f2cc3b3e870e3c0c6946a675b7971e128bf9e824 (diff) | |
| download | vimium-94586418ffd92246551c26ff00f0d80b0e2289fa.tar.bz2 | |
Modes; more minor tweeks.
Diffstat (limited to 'content_scripts/mode.coffee')
| -rw-r--r-- | content_scripts/mode.coffee | 93 |
1 files changed, 45 insertions, 48 deletions
diff --git a/content_scripts/mode.coffee b/content_scripts/mode.coffee index e5795190..adc5439d 100644 --- a/content_scripts/mode.coffee +++ b/content_scripts/mode.coffee @@ -1,15 +1,16 @@ # Modes. # -# A mode implements a number of event handlers which are pushed onto the handler stack when the mode starts, -# and poped when the mode exits. The Mode base takes as single argument options which can defined: +# A mode implements a number of keyboard event handlers which are pushed onto the handler stack when the mode +# starts, and poped when the mode exits. The Mode base class takes as single argument options which can +# define: # # name: # A name for this mode. # # badge: # A badge (to appear on the browser popup) for this mode. -# Optional. Define a badge is the badge is constant. Otherwise, do not set a badge and override the -# chooseBadge method instead. Or, if the mode *never* shows a bade, then do neither. +# Optional. Define a badge is the badge is constant. Otherwise, do not define a badge and override the +# chooseBadge method instead. Or, if the mode *never* shows a badge, then do neither. # # keydown: # keypress: @@ -24,9 +25,10 @@ # # New mode types are created by inheriting from Mode or one of its sub-classes. Some generic cub-classes are # provided below: -# SingletonMode: ensures that at most one instance of the mode should be active at any time. -# ConstrainedMode: exits the mode if the user clicks outside of the given element. -# ExitOnEscapeMode: exits the mode if the user types Esc. +# +# SingletonMode: ensures that at most one instance of the mode is active at any one time. +# ConstrainedMode: exits the mode if the an indicated element loses the focus. +# ExitOnEscapeMode: exits the mode on escape. # StateMode: tracks the current Vimium state in @enabled and @passKeys. # # To install and existing mode, use: @@ -37,13 +39,12 @@ # @exit() # internally triggered (more common). # -# Debug only; to be stripped out. +# For debug only; to be stripped out. count = 0 class Mode - # Static members. + # Static. @modes: [] - @current: -> Mode.modes[0] # Constants; readable shortcuts for event-handler return values. continueBubbling: true @@ -54,7 +55,7 @@ class Mode # Default values. name: "" badge: "" - keydown: null + keydown: null # null will be ignored by handlerStack (so it's a safe default). keypress: null keyup: null @@ -70,7 +71,7 @@ class Mode keydown: @keydown keypress: @keypress keyup: @keyup - updateBadge: (badge) => handlerStack.alwaysContinueBubbling => @chooseBadge badge + updateBadge: (badge) => @alwaysContinueBubbling => @chooseBadge badge Mode.updateBadge() if @badge @@ -80,21 +81,22 @@ class Mode exit: -> if @modeIsActive console.log @count, "exit:", @name - # We reverse @handlers, here. That way, handlers are popped in the opposite order to that in which they - # were pushed. - handlerStack.remove handlerId for handlerId in @handlers.reverse() + handlerStack.remove handlerId for handlerId in @handlers Mode.modes = Mode.modes.filter (mode) => mode != @ Mode.updateBadge() @modeIsActive = false # The badge is chosen by bubbling an "updateBadge" event down the handler stack allowing each mode the - # opportunity to choose a badge. chooseBadge, here, is the default: choose the current mode's badge unless - # one has already been chosen. This is overridden in sub-classes. + # opportunity to choose a badge. chooseBadge, here, is the default. It is overridden in sub-classes. chooseBadge: (badge) -> badge.badge ||= @badge + # Shorthand for a long name. + alwaysContinueBubbling: (func) -> handlerStack.alwaysContinueBubbling func + # Static method. Used externally and internally to initiate bubbling of an updateBadge event and to send - # the resulting badge to the background page. We only update the badge if this document has the focus. + # the resulting badge to the background page. We only update the badge if this document (hence this frame) + # has the focus. @updateBadge: -> if document.hasFocus() handlerStack.bubbleEvent "updateBadge", badge = {badge: ""} @@ -102,36 +104,37 @@ class Mode handler: "setBadge" badge: badge.badge - # Temporarily install a mode. + # Temporarily install a mode to call a function. @runIn: (mode, func) -> mode = new mode() func() mode.exit() # A SingletonMode is a Mode of which there may be at most one instance (of @singleton) active at any one time. -# New instances cancel previous instances on startup. +# New instances cancel previously-active instances on startup. class SingletonMode extends Mode @instances: {} exit: -> - delete SingletonMode.instances[@singleton] + delete SingletonMode.instances[@singleton] if @singleton? super() constructor: (@singleton, options={}) -> - SingletonMode.kill @singleton - SingletonMode.instances[@singleton] = @ + if @singleton? + SingletonMode.kill @singleton + SingletonMode.instances[@singleton] = @ super options - # Static method. If there's a singleton instance running, then kill it. + # Static method. If there's a singleton instance active, then kill it. @kill: (singleton) -> SingletonMode.instances[singleton].exit() if SingletonMode.instances[singleton] -# The mode exits when the user hits Esc. +# This mode exits when the user hits Esc. class ExitOnEscapeMode extends SingletonMode constructor: (singleton, options) -> super singleton, options - # This handler ends up above the mode's own key handlers on the handler stack, so it takes priority. + # NOTE. This handler ends up above the mode's own key handlers on the handler stack, so it takes priority. @push "keydown": (event) => return @continueBubbling unless KeyboardUtils.isEscape event @@ -140,7 +143,7 @@ class ExitOnEscapeMode extends SingletonMode event: event @suppressEvent -# Exit mode when @constrainingElement (if defined) loses the focus. +# This mode exits when @constrainingElement (if defined) loses the focus. class ConstrainedMode extends ExitOnEscapeMode constructor: (@constrainingElement, singleton, options) -> super singleton, options @@ -148,24 +151,22 @@ class ConstrainedMode extends ExitOnEscapeMode if @constrainingElement @constrainingElement.focus() @push - "blur": (event) => - handlerStack.alwaysContinueBubbling => - @exit() if event.srcElement == @constrainingElement + "blur": (event) => @alwaysContinueBubbling => + @exit() if event.srcElement == @constrainingElement -# The state mode tracks the enabled state in @enabled and @passKeys, and its initialized state in -# @initialized. It calls @registerStateChange() whenever the state changes. +# The state mode tracks the enabled state in @enabled and @passKeys. It calls @registerStateChange() whenever +# the state changes. The state is distributed by bubbling a "registerStateChange" event down the handler +# stack. class StateMode extends Mode constructor: (options) -> - @stateInitialized = false @enabled = false @passKeys = "" super options @push "registerStateChange": ({enabled: enabled, passKeys: passKeys}) => - handlerStack.alwaysContinueBubbling => - if enabled != @enabled or passKeys != @passKeys or not @stateInitialized - @stateInitialized = true + @alwaysContinueBubbling => + if enabled != @enabled or passKeys != @passKeys @enabled = enabled @passKeys = passKeys @registerStateChange() @@ -173,28 +174,24 @@ class StateMode extends Mode # Overridden by sub-classes. registerStateChange: -> -# BadgeMode is a psuedo mode for managing badge updates on focus changes and state updates. It sits at the -# bottom of the handler stack, and so it receives state changes *after* all other modes. -class BadgeMode extends StateMode +# BadgeMode is a psuedo mode for triggering badge updates on focus changes and state updates. It sits at the +# bottom of the handler stack, and so it receives state changes *after* all other modes, and can override the +# badge choices of all other modes. +new class BadgeMode extends StateMode constructor: (options) -> - options.name ||= "badge" - super options + super + name: "badge" @push - "focus": => - handlerStack.alwaysContinueBubbling => - Mode.updateBadge() + "focus": => @alwaysContinueBubbling => Mode.updateBadge() chooseBadge: (badge) -> - # If we're not enabled, then post an empty badge (so, no badge at all). + # If we're not enabled, then post an empty badge. badge.badge = "" unless @enabled registerStateChange: -> Mode.updateBadge() -# Install a single BadgeMode instance. -new BadgeMode {} - root = exports ? window root.Mode = Mode root.SingletonMode = SingletonMode |
