aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Blott2015-01-15 06:41:59 +0000
committerStephen Blott2015-01-15 09:21:09 +0000
commit0afb3d08d58e45d8392ed153f7043726125d7a45 (patch)
tree983e71550b858bba7929df1356f9aa6fe8761cfe
parentb594caa3eb792dfeb9d423c81a5136102a013b0a (diff)
downloadvimium-0afb3d08d58e45d8392ed153f7043726125d7a45.tar.bz2
Modes; tweaks and fiddles.
-rw-r--r--content_scripts/link_hints.coffee1
-rw-r--r--content_scripts/mode.coffee9
-rw-r--r--content_scripts/mode_find.coffee22
-rw-r--r--content_scripts/mode_insert.coffee5
-rw-r--r--content_scripts/vimium_frontend.coffee15
5 files changed, 29 insertions, 23 deletions
diff --git a/content_scripts/link_hints.coffee b/content_scripts/link_hints.coffee
index 5e95ef99..3c8240c0 100644
--- a/content_scripts/link_hints.coffee
+++ b/content_scripts/link_hints.coffee
@@ -271,6 +271,7 @@ LinkHints =
# TODO(philc): Ignore keys that have modifiers.
if (KeyboardUtils.isEscape(event))
+ DomUtils.suppressKeyupAfterEscape handlerStack
@deactivateMode()
else
keyResult = @getMarkerMatcher().matchHintsByKey(hintMarkers, event)
diff --git a/content_scripts/mode.coffee b/content_scripts/mode.coffee
index 79559e35..d14778a8 100644
--- a/content_scripts/mode.coffee
+++ b/content_scripts/mode.coffee
@@ -194,6 +194,14 @@ class Mode
@top: ->
@modes[@modes.length-1]
+# UIMode is a mode for Vimium UI components. They share a common singleton, so new UI components displace
+# previously-active UI components. For example, the FocusSelector mode displaces PostFindMode.
+class UIMode extends Mode
+ constructor: (options) ->
+ defaults =
+ singleton: UIMode
+ 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 active modes.
@@ -222,3 +230,4 @@ new class BadgeMode extends Mode
root = exports ? window
root.Mode = Mode
+root.UIMode = UIMode
diff --git a/content_scripts/mode_find.coffee b/content_scripts/mode_find.coffee
index 4906d363..e79bc0dd 100644
--- a/content_scripts/mode_find.coffee
+++ b/content_scripts/mode_find.coffee
@@ -4,29 +4,29 @@
# special considerations apply. We implement three special cases:
# 1. Prevent keyboard events from dropping us unintentionally into insert mode.
# 2. Prevent all printable keypress events on the active element from propagating beyond normal mode. See
-# #1415. This implements Option 2 from there.
+# #1415.
# 3. If the very-next keystroke is Escape, then drop immediately into insert mode.
#
-class PostFindMode extends Mode
+class PostFindMode extends UIMode
constructor: (findModeAnchorNode) ->
- # Locate the element we need to protect and focus it. Usually, we can just rely on insert mode to have
- # picked it up (when it received the focus).
+ # Locate the element we need to protect and focus it, if necessary. Usually, we can just rely on insert
+ # mode to have picked it up (when it received the focus).
element = InsertMode.permanentInstance.insertModeLock
unless element?
- # If insert mode hasn't picked up the element, then it could be content editable. As a heuristic, we
- # start at findModeAnchorNode and walk up the DOM, stopping at the last node encountered which is
- # contentEditable. If that node is a descendent of the active element, then we use it.
+ # For contentEditable elements, chrome does not leave them focused, so insert mode does not pick them
+ # up. We start at findModeAnchorNode and walk up the DOM, stopping at the last node encountered which is
+ # contentEditable.
element = findModeAnchorNode
element = element.parentElement while element?.parentElement?.isContentEditable
return unless element?.isContentEditable
+ # The element might be disabled (and therefore unable to receive focus), we use the approximate
+ # heuristic of checking that element is an ancestor of the active element.
return unless document.activeElement and DomUtils.isDOMDescendant document.activeElement, element
- element.focus()
+ element.focus()
super
name: "post-find"
badge: "N" # Pretend to be normal mode (because we don't want the insert-mode badge).
- # Be a singleton. That way, we don't have to keep track of any currently-active instance.
- singleton: PostFindMode
exitOnBlur: element
exitOnClick: true
keydown: (event) -> InsertMode.suppressEvent event # Truthy.
@@ -53,7 +53,7 @@ class PostFindMode extends Mode
@remove()
true # Continue bubbling.
- # Prevent printable keyboard events from propagating to to the page; see Option 2 from #1415.
+ # Prevent printable keyboard events from propagating to to the page; see #1415.
do =>
handler = (event) =>
if event.srcElement == element and KeyboardUtils.isPrintable event
diff --git a/content_scripts/mode_insert.coffee b/content_scripts/mode_insert.coffee
index d26f2568..f815090a 100644
--- a/content_scripts/mode_insert.coffee
+++ b/content_scripts/mode_insert.coffee
@@ -25,9 +25,8 @@ class InsertMode extends Mode
"focus": (event) => @alwaysContinueBubbling =>
@insertModeLock = event.target if DomUtils.isFocusable event.target
- if @insertModeLock == null
- # We may already have focused an input element, so check.
- @insertModeLock = event.target if document.activeElement and DomUtils.isFocusable document.activeElement
+ # We may already have focused an input element, so check.
+ @insertModeLock = document.activeElement if document.activeElement and DomUtils.isEditable document.activeElement
isActive: ->
return true if @insertModeLock != null or @global
diff --git a/content_scripts/vimium_frontend.coffee b/content_scripts/vimium_frontend.coffee
index 3dc8b93d..e536ebbc 100644
--- a/content_scripts/vimium_frontend.coffee
+++ b/content_scripts/vimium_frontend.coffee
@@ -369,7 +369,7 @@ extend window,
id: "vimiumInputMarkerContainer"
className: "vimiumReset"
- new class FocusSelector extends Mode
+ new class FocusSelector extends UIMode
constructor: ->
super
name: "focus-selector"
@@ -387,15 +387,12 @@ extend window,
@exit()
@continueBubbling
+ @onExit -> DomUtils.removeElement hintContainingDiv
visibleInputs[selectedInputIndex].element.focus()
- return @exit() if visibleInputs.length == 1
- hints[selectedInputIndex].classList.add 'internalVimiumSelectedInputHint'
-
- exit: ->
- DomUtils.removeElement hintContainingDiv
- super()
- new InsertMode
- targetElement: visibleInputs[selectedInputIndex].element
+ if visibleInputs.length == 1
+ @exit()
+ else
+ hints[selectedInputIndex].classList.add 'internalVimiumSelectedInputHint'
# Decide whether this keyChar should be passed to the underlying page.
# Keystrokes are *never* considered passKeys if the keyQueue is not empty. So, for example, if 't' is a