diff options
| author | Stephen Blott | 2015-01-06 12:04:19 +0000 |
|---|---|---|
| committer | Stephen Blott | 2015-01-06 12:04:19 +0000 |
| commit | f19f21f7114c6cdc2c62b69e0f6dafac68fd84a0 (patch) | |
| tree | 79cb394c5bd3482b88d136aa615d5e3cdfd46373 | |
| parent | b0f56ca439af45b62b23efd8c19c3838945f21f4 (diff) | |
| download | vimium-f19f21f7114c6cdc2c62b69e0f6dafac68fd84a0.tar.bz2 | |
Mode; simplify InsertModeBlocker logic.
| -rw-r--r-- | content_scripts/mode.coffee | 11 | ||||
| -rw-r--r-- | content_scripts/mode_find.coffee | 15 | ||||
| -rw-r--r-- | content_scripts/mode_insert.coffee | 42 | ||||
| -rw-r--r-- | content_scripts/vimium_frontend.coffee | 2 |
4 files changed, 33 insertions, 37 deletions
diff --git a/content_scripts/mode.coffee b/content_scripts/mode.coffee index b81a4ede..df833c51 100644 --- a/content_scripts/mode.coffee +++ b/content_scripts/mode.coffee @@ -153,16 +153,15 @@ class ExitOnEscapeMode extends SingletonMode event: event @suppressEvent -# This mode exits when @constrainingElement (if defined) loses the focus. +# This mode exits when element (if defined) loses the focus. class ConstrainedMode extends ExitOnEscapeMode - constructor: (@constrainingElement, singleton, options) -> + constructor: (element, singleton=null, options={}) -> super singleton, options - if @constrainingElement - @constrainingElement.focus() + if element?.focus? + element.focus() @push - "blur": (event) => @alwaysContinueBubbling => - @exit() if event.srcElement == @constrainingElement + "blur": (event) => @alwaysContinueBubbling => @exit() if event.srcElement == element # 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 diff --git a/content_scripts/mode_find.coffee b/content_scripts/mode_find.coffee index 85cdc6c5..9a0086a1 100644 --- a/content_scripts/mode_find.coffee +++ b/content_scripts/mode_find.coffee @@ -32,11 +32,16 @@ class PostFindMode extends InsertModeBlocker # Install various ways in which we can leave this mode. @push - DOMActive: (event) => @alwaysContinueBubbling => @exit() - click: (event) => @alwaysContinueBubbling => @exit() - focus: (event) => @alwaysContinueBubbling => @exit() - blur: (event) => @alwaysContinueBubbling => @exit() - keydown: (event) => @alwaysContinueBubbling => @exit() if document.activeElement != element + DOMActive: (event, extra) => @alwaysContinueBubbling => @exit extra + click: (event, extra) => @alwaysContinueBubbling => @exit extra + focus: (event, extra) => @alwaysContinueBubbling => @exit extra + blur: (event, extra) => @alwaysContinueBubbling => @exit extra + keydown: (event, extra) => @alwaysContinueBubbling => @exit extra if document.activeElement != element + + # Inform handlers further down the stack that PostFindMode exited on this event. + exit: (extra) -> + extra.postFindModeExited = true if extra + super() root = exports ? window root.PostFindMode = PostFindMode diff --git a/content_scripts/mode_insert.coffee b/content_scripts/mode_insert.coffee index 24442928..c6f9d5b1 100644 --- a/content_scripts/mode_insert.coffee +++ b/content_scripts/mode_insert.coffee @@ -44,7 +44,10 @@ class InsertMode extends ConstrainedMode # Trigger insert mode: # - On a keydown event in a contentEditable element. # - When a focusable element receives the focus. -# Can be suppressed by setting extra.suppressInsertModeTrigger. +# - When an editable activeElement is clicked. We cannot rely exclusively on focus events for triggering +# insert mode. With find mode, an editable element can be active, but we're not in insert mode (see +# PostFindMode), and no focus event will be generated. In this case, clicking on the element should +# activate insert mode (even if the insert-mode blocker is active). # # This mode is permanently installed fairly low down on the handler stack. class InsertModeTrigger extends Mode @@ -53,53 +56,42 @@ class InsertModeTrigger extends Mode name: "insert-trigger" keydown: (event, extra) => @alwaysContinueBubbling => - unless extra.suppressInsertModeTrigger? + unless InsertModeBlocker.isActive() # Some sites (e.g. inbox.google.com) change the contentEditable attribute on the fly (see #1245); # and unfortunately, the focus event happens *before* the change is made. Therefore, we need to # check again whether the active element is contentEditable. - # NOTE. There's no need to check InsertMode.isActive() here since, if insert mode *is* active, - # then we wouldn't be receiving this keyboard event. new InsertMode document.activeElement if document.activeElement?.isContentEditable @push focus: (event, extra) => @alwaysContinueBubbling => - unless InsertMode.isActive() - unless extra.suppressInsertModeTrigger? - new InsertMode event.target if isFocusable event.target + unless InsertMode.isActive() or InsertModeBlocker.isActive() + new InsertMode event.target if isFocusable event.target click: (event, extra) => @alwaysContinueBubbling => unless InsertMode.isActive() - # We cannot rely exclusively on focus events for triggering insert mode. With find mode, an - # editable element can be active, but we're not in insert mode (see PostFindMode), and no focus - # event will be generated. In this case, clicking on the element should activate insert mode. - if document.activeElement == event.target and isEditable event.target - new InsertMode event.target + # We cannot check InsertModeBlocker.isActive(). PostFindMode exits on clicks, so will already have + # gone. So, instead, it sets an extra we can check. + if extra?.postFindModeExited + if document.activeElement == event.target and isEditable event.target + new InsertMode event.target # We may already have focussed something, so check. new InsertMode document.activeElement if document.activeElement and isFocusable document.activeElement - @suppress: (extra) -> - extra.suppressInsertModeTrigger = true - # Disables InsertModeTrigger. Used by find mode and findFocus to prevent unintentionally dropping into insert # mode on focusable elements. -# If @element is provided, then don't suppress focus events, and suppress keydown events only on @element. class InsertModeBlocker extends SingletonMode - constructor: (@element=null, options={}) -> + constructor: (element, options={}) -> options.name ||= "insert-blocker" super InsertModeBlocker, options - unless @element? - @push - focus: (event, extra) => @alwaysContinueBubbling => InsertModeTrigger.suppress extra + @push + "blur": (event) => @alwaysContinueBubbling => @exit() if element? and event.srcElement == element - if @element?.isContentEditable - @push - keydown: (event, extra) => - @alwaysContinueBubbling => - InsertModeTrigger.suppress extra if event.srcElement == @element + # Static method. Return whether the insert-mode blocker is currently active or not. + @isActive: (singleton) -> SingletonMode.isActive InsertModeBlocker root = exports ? window root.InsertMode = InsertMode diff --git a/content_scripts/vimium_frontend.coffee b/content_scripts/vimium_frontend.coffee index ea3791dd..77738f59 100644 --- a/content_scripts/vimium_frontend.coffee +++ b/content_scripts/vimium_frontend.coffee @@ -378,7 +378,7 @@ extend window, new class FocusSelector extends InsertModeBlocker constructor: -> - super InsertModeBlocker, null, + super null, name: "focus-selector" badge: "?" keydown: (event) => |
