aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Blott2015-01-06 12:04:19 +0000
committerStephen Blott2015-01-06 12:04:19 +0000
commitf19f21f7114c6cdc2c62b69e0f6dafac68fd84a0 (patch)
tree79cb394c5bd3482b88d136aa615d5e3cdfd46373
parentb0f56ca439af45b62b23efd8c19c3838945f21f4 (diff)
downloadvimium-f19f21f7114c6cdc2c62b69e0f6dafac68fd84a0.tar.bz2
Mode; simplify InsertModeBlocker logic.
-rw-r--r--content_scripts/mode.coffee11
-rw-r--r--content_scripts/mode_find.coffee15
-rw-r--r--content_scripts/mode_insert.coffee42
-rw-r--r--content_scripts/vimium_frontend.coffee2
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) =>