aboutsummaryrefslogtreecommitdiffstats
path: root/content_scripts/mode_find.coffee
diff options
context:
space:
mode:
Diffstat (limited to 'content_scripts/mode_find.coffee')
-rw-r--r--content_scripts/mode_find.coffee48
1 files changed, 18 insertions, 30 deletions
diff --git a/content_scripts/mode_find.coffee b/content_scripts/mode_find.coffee
index d6d1ff33..795e7a14 100644
--- a/content_scripts/mode_find.coffee
+++ b/content_scripts/mode_find.coffee
@@ -1,37 +1,35 @@
# NOTE(smblott). Ultimately, all of the FindMode-related code should be moved to this file.
-# When we use find mode, the selection/focus can end up in a focusable/editable element. Subsequent keyboard
-# events could drop us into insert mode, which is a bad user experience. The PostFindMode mode is installed
-# after find events to prevent this.
+# When we use find mode, the selection/focus can end up in a focusable/editable element. In this situation,
+# PostFindMode handles two special cases:
+# 1. Suppress InsertModeTrigger. This presents keyboard events from dropping us unintentionaly into insert
+# mode. Here, this is achieved by inheriting PostFindMode from InsertModeBlocker.
+# 2. If the very-next keystroke is Escape, then drop immediately into insert mode.
#
-# PostFindMode also maps Esc (on the next keystroke) to immediately drop into insert mode.
-class PostFindMode extends SingletonMode
- constructor: (insertMode, findModeAnchorNode) ->
+class PostFindMode extends InsertModeBlocker
+ constructor: (findModeAnchorNode) ->
element = document.activeElement
- return unless element
+
+ super PostFindMode, element,
+ name: "post-find"
+
+ return @exit() unless element and findModeAnchorNode
# Special cases only arise if the active element is focusable. So, exit immediately if it is not.
canTakeInput = DomUtils.isSelectable(element) and DomUtils.isDOMDescendant findModeAnchorNode, element
- canTakeInput ||= element?.isContentEditable
- return unless canTakeInput
-
- super PostFindMode,
- name: "post-find"
+ canTakeInput ||= element.isContentEditable
+ return @exit() unless canTakeInput
- # If the very next key is Esc, then drop straight into insert mode.
+ self = @
@push
keydown: (event) ->
- @remove()
if element == document.activeElement and KeyboardUtils.isEscape event
- PostFindMode.exitModeAndEnterInsert insertMode, element
+ self.exit()
+ new InsertMode element
return false
+ @remove()
true
- if element.isContentEditable
- # Prevent InsertMode from activating on keydown.
- @push
- keydown: (event) -> handlerStack.alwaysContinueBubbling -> InsertMode.suppressKeydownTrigger event
-
# Install various ways in which we can leave this mode.
@push
DOMActive: (event) => handlerStack.alwaysContinueBubbling => @exit()
@@ -40,15 +38,5 @@ class PostFindMode extends SingletonMode
blur: (event) => handlerStack.alwaysContinueBubbling => @exit()
keydown: (event) => handlerStack.alwaysContinueBubbling => @exit() if document.activeElement != element
- # There's feature interference between PostFindMode, InsertMode and focusInput. PostFindMode prevents
- # InsertMode from triggering on keyboard events. And FindMode prevents InsertMode from triggering on focus
- # events. This means that an input element can already be focused, but InsertMode is not active. When that
- # element is then (again) focused by focusInput, no new focus event is generated, so we don't drop into
- # InsertMode as expected.
- # This hack fixes this.
- @exitModeAndEnterInsert: (insertMode, element) ->
- SingletonMode.kill PostFindMode
- insertMode.activate insertMode, element
-
root = exports ? window
root.PostFindMode = PostFindMode