diff options
Diffstat (limited to 'content_scripts')
| -rw-r--r-- | content_scripts/mode.coffee | 4 | ||||
| -rw-r--r-- | content_scripts/mode_find.coffee | 36 | ||||
| -rw-r--r-- | content_scripts/mode_insert.coffee | 13 | ||||
| -rw-r--r-- | content_scripts/vimium_frontend.coffee | 18 |
4 files changed, 36 insertions, 35 deletions
diff --git a/content_scripts/mode.coffee b/content_scripts/mode.coffee index ebb3e8bc..2b35f0de 100644 --- a/content_scripts/mode.coffee +++ b/content_scripts/mode.coffee @@ -101,9 +101,7 @@ class Mode if @options.exitOnClick @push _name: "mode-#{@id}/exitOnClick" - "click": (event) => @alwaysContinueBubbling => - @clickEvent = event - @exit() + "click": (event) => @alwaysContinueBubbling => @exit event # If @options.trackState is truthy, then the mode mainatins the current state in @enabled and @passKeys, # and calls @registerStateChange() (if defined) whenever the state changes. diff --git a/content_scripts/mode_find.coffee b/content_scripts/mode_find.coffee index 08bc9e5d..4906d363 100644 --- a/content_scripts/mode_find.coffee +++ b/content_scripts/mode_find.coffee @@ -9,18 +9,28 @@ # class PostFindMode extends Mode constructor: (findModeAnchorNode) -> - element = document.activeElement + # 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). + 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. + element = findModeAnchorNode + element = element.parentElement while element?.parentElement?.isContentEditable + return unless element?.isContentEditable + return unless document.activeElement and DomUtils.isDOMDescendant document.activeElement, element + 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. Any active - # instance is automatically deactivated when a new instance is activated. + # 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 - keypress: (event) -> InsertMode.suppressEvent event + keydown: (event) -> InsertMode.suppressEvent event # Truthy. + keypress: (event) -> InsertMode.suppressEvent event # Truthy. keyup: (event) => @alwaysContinueBubbling => if document.getSelection().type != "Range" @@ -30,15 +40,6 @@ class PostFindMode extends Mode else InsertMode.suppressEvent event - return @exit() unless element and findModeAnchorNode - - # Special considerations only arise if the active element can take input. So, exit immediately if it - # cannot. - canTakeInput = DomUtils.isSelectable(element) and DomUtils.isDOMDescendant findModeAnchorNode, element - canTakeInput ||= element.isContentEditable - canTakeInput ||= findModeAnchorNode.parentElement?.isContentEditable # FIXME(smblott) This is too specific. - return @exit() unless canTakeInput - # If the very-next keydown is Esc, drop immediately into insert mode. self = @ @push @@ -60,7 +61,7 @@ class PostFindMode extends Mode else @continueBubbling - # Note. We use unshift here, instead of push; therefore we see events *after* normal mode, and so only + # 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" @@ -68,5 +69,10 @@ class PostFindMode extends Mode keypress: handler keyup: handler +# NOTE. There's a problem with this approach when a find/search lands in a contentEditable element. Chrome +# generates a focus event triggering insert mode (good), then immediately generates a "blur" event, disabling +# insert mode again. Nevertheless, unmapped keys *do* result in the element being focused again. +# So, asking insert mode whether it's active is giving us the wrong answer. + root = exports ? window root.PostFindMode = PostFindMode diff --git a/content_scripts/mode_insert.coffee b/content_scripts/mode_insert.coffee index 4be9c589..89077c6a 100644 --- a/content_scripts/mode_insert.coffee +++ b/content_scripts/mode_insert.coffee @@ -1,6 +1,11 @@ class InsertMode extends Mode + # There is one permanently-installed instance of InsertMode. This allows PostFindMode to query its state. + @permanentInstance: null + constructor: (options = {}) -> + InsertMode.permanentInstance ||= @ + defaults = name: "insert" keydown: (event) => @handleKeydownEvent event @@ -51,12 +56,8 @@ class InsertMode extends Mode exit: (target) -> if target == undefined or target == @insertModeLock - if @options.targetElement? - super() - else - # If @options.targetElement isn't set, then this is the permanently-installed instance from the front - # end. So, we don't actually exit; instead, we just reset ourselves. - @insertModeLock = null + # If this is the permanently-installed instance, then we don't actually exit; instead, we just reset. + if @ == InsertMode.permanentInstance then @insertModeLock = null else super() chooseBadge: (badge) -> badge.badge ||= "I" if @isActive() diff --git a/content_scripts/vimium_frontend.coffee b/content_scripts/vimium_frontend.coffee index 00d90e81..e14813f7 100644 --- a/content_scripts/vimium_frontend.coffee +++ b/content_scripts/vimium_frontend.coffee @@ -389,7 +389,6 @@ extend window, visibleInputs[selectedInputIndex].element.focus() return @exit() if visibleInputs.length == 1 - hints[selectedInputIndex].classList.add 'internalVimiumSelectedInputHint' exit: -> @@ -747,6 +746,7 @@ class FindMode extends Mode name: "find" badge: "/" exitOnEscape: true + exitOnClick: true keydown: (event) => if event.keyCode == keyCodes.backspace || event.keyCode == keyCodes.deleteKey @@ -772,8 +772,8 @@ class FindMode extends Mode super() handleEscapeForFindMode() if event?.type == "keydown" and KeyboardUtils.isEscape event handleEscapeForFindMode() if event?.type == "click" - # If event?.type == "click", then the InsertModeBlocker super-class will be dropping us into insert mode. - new PostFindMode findModeAnchorNode unless event?.type == "click" + if findModeQueryHasResults and event?.type != "click" + new PostFindMode findModeAnchorNode performFindInPlace = -> cachedScrollX = window.scrollX @@ -863,15 +863,11 @@ findAndFocus = (backwards) -> findModeQueryHasResults = executeFind(query, { backwards: backwards, caseSensitive: !findModeQuery.ignoreCase }) - if (!findModeQueryHasResults) + if findModeQueryHasResults + focusFoundLink() + new PostFindMode findModeAnchorNode if findModeQueryHasResults + else HUD.showForDuration("No matches for '" + findModeQuery.rawQuery + "'", 1000) - return - - # if we have found an input element via 'n', pressing <esc> immediately afterwards sends us into insert - # mode - new PostFindMode findModeAnchorNode - - focusFoundLink() window.performFind = -> findAndFocus() |
