diff options
Diffstat (limited to 'content_scripts/mode_find.coffee')
| -rw-r--r-- | content_scripts/mode_find.coffee | 48 |
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 |
