diff options
| author | Stephen Blott | 2015-01-14 12:43:41 +0000 |
|---|---|---|
| committer | Stephen Blott | 2015-01-14 13:31:29 +0000 |
| commit | 3e0378d0bc5d85ffec0ef49f7c421edbe9c073ec (patch) | |
| tree | 9198362c577df8f90f76791ef4471cd6ba51596a /content_scripts/mode_find.coffee | |
| parent | 9b0a48955c61c262cc4428b2360938d4b54d2d41 (diff) | |
| download | vimium-3e0378d0bc5d85ffec0ef49f7c421edbe9c073ec.tar.bz2 | |
Modes; rework PostFindMode (again).
Diffstat (limited to 'content_scripts/mode_find.coffee')
| -rw-r--r-- | content_scripts/mode_find.coffee | 36 |
1 files changed, 21 insertions, 15 deletions
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 |
