diff options
| author | Stephen Blott | 2015-01-03 15:10:06 +0000 |
|---|---|---|
| committer | Stephen Blott | 2015-01-03 16:17:07 +0000 |
| commit | 7889b3c2c68354d377c31121d6fb94f528e0454c (patch) | |
| tree | a3bac7bfef47d9439934d883bfb0a5b9a46975d4 | |
| parent | baccd7c5cef14480e21e41519e20ee19fa238655 (diff) | |
| download | vimium-7889b3c2c68354d377c31121d6fb94f528e0454c.tar.bz2 | |
Modes; simplify PostFindMode.
| -rw-r--r-- | content_scripts/mode.coffee | 5 | ||||
| -rw-r--r-- | content_scripts/mode_insert.coffee | 2 | ||||
| -rw-r--r-- | content_scripts/vimium_frontend.coffee | 87 |
3 files changed, 58 insertions, 36 deletions
diff --git a/content_scripts/mode.coffee b/content_scripts/mode.coffee index 9e886a63..9126a824 100644 --- a/content_scripts/mode.coffee +++ b/content_scripts/mode.coffee @@ -1,4 +1,6 @@ +count = 0 + class Mode # Static members. @modes: [] @@ -20,6 +22,8 @@ class Mode constructor: (options) -> Mode.modes.unshift @ extend @, options + @count = ++count + console.log @count, "create:", @name @handlers = [] @handlers.push handlerStack.push @@ -29,6 +33,7 @@ class Mode updateBadge: (badge) => handlerStack.alwaysContinueBubbling => @chooseBadge badge exit: -> + console.log @count, "exit:", @name handlerStack.remove handlerId for handlerId in @handlers Mode.modes = Mode.modes.filter (mode) => mode != @ Mode.updateBadge() diff --git a/content_scripts/mode_insert.coffee b/content_scripts/mode_insert.coffee index 6d7cdb89..cffb8735 100644 --- a/content_scripts/mode_insert.coffee +++ b/content_scripts/mode_insert.coffee @@ -86,7 +86,7 @@ class InsertMode extends Mode # Activate this mode to prevent a focused, editable element from triggering insert mode. class InsertModeSuppressFocusTrigger extends Mode constructor: -> - super() + super {name: "suppress-focus-trigger"} @handlers.push handlerStack.push focus: => @suppressEvent diff --git a/content_scripts/vimium_frontend.coffee b/content_scripts/vimium_frontend.coffee index da479781..e20dafc4 100644 --- a/content_scripts/vimium_frontend.coffee +++ b/content_scripts/vimium_frontend.coffee @@ -200,13 +200,9 @@ initializeWhenEnabled = (newPassKeys) -> if (!installedListeners) # Key event handlers fire on window before they do on document. Prefer window for key events so the page # can't set handlers to grab the keys before us. - for type in ["keydown", "keypress", "keyup"] + for type in ["keydown", "keypress", "keyup", "click", "focus", "blur"] do (type) -> installListener window, type, (event) -> handlerStack.bubbleEvent type, event - # installListener document, "focus", onFocusCapturePhase # No longer needed. - installListener document, "blur", onBlurCapturePhase installListener document, "DOMActivate", onDOMActivate - installListener document, "focusin", onFocus - installListener document, "blur", onBlur enterInsertModeIfElementIsFocused() installedListeners = true @@ -360,6 +356,13 @@ extend window, selectedInputIndex = Math.min(count - 1, visibleInputs.length - 1) + # We need to make sure that the following .focus() actually does generate a "focus" event. We need such + # an event: + # - to trigger insert mode, and + # - to kick any PostFindMode listeners out of the way. + # Unfortunately, if the element is already focused (as may happen following a find), then no "focus" event + # is generated. So, here, we first generate a psuedo "focus" event. + PostFindMode.fakeFocus visibleInputs[selectedInputIndex].element visibleInputs[selectedInputIndex].element.focus() return if visibleInputs.length == 1 @@ -761,44 +764,56 @@ class FindMode extends Mode Mode.updateBadge() -# If find lands in an editable element then: -# - "Esc" drops us into insert mode. -# - Subsequent command keypresses should not cause us to drop into insert mode. -count = 0 +# Handle various special cases which arise when find finds a match within a focusable element. class PostFindMode extends SingletonMode constructor: -> element = document.activeElement - handleKeydownEscape = true - super PostFindMode, - keydown: (event) => - if handleKeydownEscape and KeyboardUtils.isEscape event - DomUtils.simulateSelect document.activeElement - insertMode.activate element - @exit() - return @suppressEvent # we have "consumed" this event, so do not propagate - console.log "suppress", event - handleKeydownEscape = false - InsertMode.suppressKeydownTrigger event - # We can safely exit if element is contentEditable. Keystrokes will never cause us to drop into - # insert mode anyway. - @exit() if element.isContentEditable - @continueBubbling - keypress: => @continueBubbling - keyup: => @continueBubbling - - console.log ++count, "PostFindMode create" + + # Special cases only arise if the active element is focusable. So, exit immediately if it is not. canTakeInput = element and DomUtils.isSelectable(element) and isDOMDescendant findModeAnchorNode, element canTakeInput ||= element?.isContentEditable - return @exit() unless canTakeInput + return unless canTakeInput + + super PostFindMode, {name: "post-find-mode"} + if element.isContentEditable + # Prevent InsertMode from activating on keydown. + @handlers.push handlerStack.push + keydown: (event) => + InsertMode.suppressKeydownTrigger event + @continueBubbling + + # If the next key is Esc, then drop into insert mode. + @handlers.push handlerStack.push + keydown: (event) -> + @remove() + return true unless KeyboardUtils.isEscape event + DomUtils.simulateSelect document.activeElement + insertMode.activate element + return false + + # We can stop watching on any change of focus or user click. + # FIXME(smblott). This is broken. If there is a text area, and the text area is focused with + # find, then clicking within that text area does *not* generate a useful event, and therefore does not + # disable PostFindMode mode, and therefore does not allow us to enter insert mode. @handlers.push handlerStack.push - DOMActive: (event) => @exit() - focus: (event) => @exit() - blur: (event) => @exit() + DOMActive: (event) => handlerStack.alwaysContinueBubbling => + console.log "ACTIVATE" + @exit() + click: (event) => + handlerStack.alwaysContinueBubbling => + console.log "CLICK" + @exit() + focus: (event) => handlerStack.alwaysContinueBubbling => + console.log "FOCUS" + @exit() + blur: (event) => + console.log "BLUR" + handlerStack.alwaysContinueBubbling => @exit() - exit: -> - console.log ++count, "exit PostFindMode" - super() + # This removes any PostFindMode modes on the stack and triggers a "focus" event for InsertMode. + @fakeFocus: (element) -> + handlerStack.bubbleEvent "focus", {target: element} performFindInPlace = -> cachedScrollX = window.scrollX @@ -1015,7 +1030,9 @@ window.enterFindMode = -> findModeQuery = { rawQuery: "" } # window.findMode = true # Same hack, see comment at window.findMode definition. HUD.show("/") + console.log "aaa" new FindMode() + console.log "bbb" exitFindMode = -> window.findMode = false # Same hack, see comment at window.findMode definition. |
