aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--content_scripts/mode.coffee9
-rw-r--r--content_scripts/mode_find.coffee78
-rw-r--r--content_scripts/vimium_frontend.coffee15
3 files changed, 39 insertions, 63 deletions
diff --git a/content_scripts/mode.coffee b/content_scripts/mode.coffee
index 9f820469..cc1250b4 100644
--- a/content_scripts/mode.coffee
+++ b/content_scripts/mode.coffee
@@ -177,14 +177,6 @@ class Mode
@top: ->
@modes[@modes.length-1]
-# InputController is a super-class for modes which control insert mode: PostFindMode and FocusSelector. It's
-# a singleton, so no two instances may be active at the same time.
-class InputController extends Mode
- constructor: (options) ->
- defaults =
- singleton: InputController
- super extend defaults, options
-
# BadgeMode is a pseudo 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 choice of the other modes. We create the the one-and-only instance here.
@@ -212,4 +204,3 @@ new class BadgeMode extends Mode
root = exports ? window
root.Mode = Mode
-root.InputController = InputController
diff --git a/content_scripts/mode_find.coffee b/content_scripts/mode_find.coffee
index f151b8cd..cfcd18b5 100644
--- a/content_scripts/mode_find.coffee
+++ b/content_scripts/mode_find.coffee
@@ -1,45 +1,42 @@
# NOTE(smblott). Ultimately, all of the FindMode-related code should be moved to this file.
+# This is Used as a sub-class to PostFindMode. It prevents printable characters from being passed through to
+# underlying input element; see #1415. Note, also, that the "Range" condition in the keyup handler
+# implmements option 5c from #1415.
+class SuppressPrintable extends Mode
+ constructor: (options) ->
+ super options
+ handler = (event) => if KeyboardUtils.isPrintable event then @suppressEvent else @continueBubbling
+
+ # Note: we use unshift here. We see events *after* normal mode, so we only see unmapped keys.
+ @unshift
+ _name: "mode-#{@id}/suppressPrintableEvents"
+ keydown: handler
+ keypress: handler
+ keyup: (event) =>
+ if document.getSelection().type.toLowerCase() != "range" then @exit() else handler event
+
# When we use find mode, the selection/focus can land in a focusable/editable element. In this situation,
# special considerations apply. We implement three special cases:
-# 1. Disable keyboard events in insert mode, because the user hasn't asked to enter insert mode.
-# 2. Prevent printable keyboard events from propagating to the page; see #1415.
+# 1. Disable insert mode, because the user hasn't asked to enter insert mode. We do this by using
+# InsertMode.suppressEvent.
+# 2. Prevent printable keyboard events from propagating to the page; see #1415. We do this by inheriting
+# from SuppressPrintable.
# 3. If the very-next keystroke is Escape, then drop immediately into insert mode.
#
-class PostFindMode extends InputController
+class PostFindMode extends SuppressPrintable
constructor: (findModeAnchorNode) ->
- # Locate the element we need to protect. In most cases, it's just the active element.
- element =
- if document.activeElement and DomUtils.isEditable document.activeElement
- document.activeElement
- else
- # For contentEditable elements, chrome does not focus them, although they are activated by keystrokes.
- # We need to find the element ourselves.
- element = findModeAnchorNode
- element = element.parentElement while element.parentElement?.isContentEditable
- if element.isContentEditable
- if DomUtils.isDOMDescendant element, findModeAnchorNode
- # TODO(smblott). We shouldn't really need to focus the element, here. Need to look into why this
- # is necessary.
- element.focus()
- element
-
- return unless element
+ element = document.activeElement
+ return unless element and DomUtils.isEditable element
super
name: "post-find"
+ singleton: PostFindMode
exitOnBlur: element
exitOnClick: true
- keydown: (event) -> InsertMode.suppressEvent event # Truthy.
- keypress: (event) -> InsertMode.suppressEvent event # Truthy.
- keyup: (event) =>
- @alwaysContinueBubbling =>
- if document.getSelection().type != "Range"
- # If the selection is no longer a range, then the user is interacting with the element, so get out
- # of the way. See Option 5c from #1415.
- @exit()
- else
- InsertMode.suppressEvent event
+ keydown: (event) -> InsertMode.suppressEvent event # Always truthy, so always continues bubbling.
+ keypress: (event) -> InsertMode.suppressEvent event
+ keyup: (event) -> InsertMode.suppressEvent event
# If the very-next keydown is Esc, drop immediately into insert mode.
self = @
@@ -54,25 +51,8 @@ class PostFindMode extends InputController
@remove()
true # Continue bubbling.
- # Prevent printable keyboard events from propagating to the page; see #1415.
- do =>
- handler = (event) =>
- if event.srcElement == element and KeyboardUtils.isPrintable event
- @suppressEvent
- else
- @continueBubbling
-
- # Note. We use unshift here, instead of push. We see events *after* normal mode, so we only see
- # unmapped keys.
- @unshift
- _name: "mode-#{@id}/suppressPrintableEvents"
- keydown: handler
- keypress: handler
- keyup: handler
-
- chooseBadge: (badge) ->
- # If PostFindMode is active, then we don't want the "I" badge from insert mode.
- InsertMode.suppressEvent badge
+ # If PostFindMode is active, then we suppress the "I" badge from insert mode.
+ chooseBadge: (badge) -> InsertMode.suppressEvent badge
root = exports ? window
root.PostFindMode = PostFindMode
diff --git a/content_scripts/vimium_frontend.coffee b/content_scripts/vimium_frontend.coffee
index 7d24e714..3049784e 100644
--- a/content_scripts/vimium_frontend.coffee
+++ b/content_scripts/vimium_frontend.coffee
@@ -364,11 +364,14 @@ extend window,
id: "vimiumInputMarkerContainer"
className: "vimiumReset"
- new class FocusSelector extends InputController
+ new class FocusSelector extends Mode
constructor: ->
super
name: "focus-selector"
badge: "?"
+ # We share a singleton with PostFindMode. That way, a new FocusSelector displaces any existing
+ # PostFindMode.
+ singleton: PostFindMode
exitOnClick: true
keydown: (event) =>
if event.keyCode == KeyboardUtils.keyCodes.tab
@@ -805,10 +808,12 @@ executeFind = (query, options) ->
# preventDefault()
findModeAnchorNode = document.getSelection().anchorNode
- # If the anchor node is outside of the active element, then blur the active element. We don't want to leave
- # behind an inappropriate active element. This fixes #1412.
- if document.activeElement and not DomUtils.isDOMDescendant findModeAnchorNode, document.activeElement
- document.activeElement.blur()
+ # TODO(smblott). Disabled. This is the wrong test. Should be reinstated when we have the right test, which
+ # looks like it should be "isSelected" from #1431.
+ # # If the anchor node not a descendent of the active element, then blur the active element. We don't want to
+ # # leave behind an inappropriate active element. This fixes #1412.
+ # if document.activeElement and not DomUtils.isDOMDescendant document.activeElement, findModeAnchorNode
+ # document.activeElement.blur()
result