From b3e8a037eb347d3c196fe975594dd161b8cd2d0d Mon Sep 17 00:00:00 2001 From: Simon Lydell Date: Thu, 3 Dec 2015 08:20:43 +0100 Subject: [PATCH] Fix text selection when forusing text inputs When using one of the `f` commands to focus a text input, the previous selection or caret position should be retained, just as if you had clicked it. However, before this commit all of their text was accidentally selected (as if you had pressed `` to foucs). This also improves the `gi` command. Previously, it _always_ selected all text. Now it does so only if you use a count, or use `gi` to re-focus an input after a prevented autofocus. In those cases you likely want to replace what's in the input, but otherwise you're likely returning to the text input after a temporary leave and want to continue typing where you left off. --- extension/lib/commands-frame.coffee | 18 ++++++++++-------- extension/lib/events-frame.coffee | 2 ++ extension/lib/utils.coffee | 6 ++++-- extension/lib/vim-frame.coffee | 1 + 4 files changed, 17 insertions(+), 10 deletions(-) diff --git a/extension/lib/commands-frame.coffee b/extension/lib/commands-frame.coffee index 1fbe9a2..f6ea85f 100644 --- a/extension/lib/commands-frame.coffee +++ b/extension/lib/commands-frame.coffee @@ -286,14 +286,16 @@ commands.focus_text_input = ({vim, count = null}) -> inputs.push(lastFocusedTextInput) return unless inputs.length > 0 inputs.sort((a, b) -> a.tabIndex - b.tabIndex) - unless count? - count = - if lastFocusedTextInput - inputs.indexOf(lastFocusedTextInput) + 1 - else - 1 - index = Math.min(count, inputs.length) - 1 - utils.focusElement(inputs[index], {select: true}) + num = switch + when count? + count + when lastFocusedTextInput + inputs.indexOf(lastFocusedTextInput) + 1 + else + 1 + index = Math.min(num, inputs.length) - 1 + select = (count? or vim.state.autofocusPrevented) + utils.focusElement(inputs[index], {select}) vim.state.inputs = inputs commands.clear_inputs = ({vim}) -> diff --git a/extension/lib/events-frame.coffee b/extension/lib/events-frame.coffee index c69263d..8dc933c 100644 --- a/extension/lib/events-frame.coffee +++ b/extension/lib/events-frame.coffee @@ -189,6 +189,7 @@ class FrameEventManager @numFocusToSuppress-- return + @vim.state.autofocusPrevented = false sendFocusType() # Reset `hasInteraction` when (re-)selecting a tab, or coming back from @@ -233,6 +234,7 @@ class FrameEventManager # are suppressed. @listenOnce('blur', utils.suppressEvent) target.blur() + @vim.state.autofocusPrevented = true ) @listen('blur', (event) => diff --git a/extension/lib/utils.coffee b/extension/lib/utils.coffee index d931899..8d7c325 100644 --- a/extension/lib/utils.coffee +++ b/extension/lib/utils.coffee @@ -125,11 +125,13 @@ blurActiveBrowserElement = (vim) -> ) # Focus an element and tell Firefox that the focus happened because of a user -# keypress (not just because some random programmatic focus). +# action (not just because some random programmatic focus). `.FLAG_BYKEY` might +# look more appropriate, but it unconditionally selects all text, which +# `.FLAG_BYMOUSE` does not. focusElement = (element, options = {}) -> focusManager = Cc['@mozilla.org/focus-manager;1'] .getService(Ci.nsIFocusManager) - focusManager.setFocus(element, focusManager.FLAG_BYKEY) + focusManager.setFocus(element, focusManager.FLAG_BYMOUSE) element.select?() if options.select getFocusType = (element) -> switch diff --git a/extension/lib/vim-frame.coffee b/extension/lib/vim-frame.coffee index f84d707..26a7951 100644 --- a/extension/lib/vim-frame.coffee +++ b/extension/lib/vim-frame.coffee @@ -52,6 +52,7 @@ class VimFrame hasInteraction: false shouldRefocus: false marks: {} + autofocusPrevented: false lastFocusedTextInput: null scrollableElements: new ScrollableElements(@content, MINIMUM_SCROLL) markerElements: [] -- 2.39.3