aboutsummaryrefslogtreecommitdiffstats
path: root/content_scripts/mode_find.coffee
diff options
context:
space:
mode:
authorStephen Blott2015-01-14 12:43:41 +0000
committerStephen Blott2015-01-14 13:31:29 +0000
commit3e0378d0bc5d85ffec0ef49f7c421edbe9c073ec (patch)
tree9198362c577df8f90f76791ef4471cd6ba51596a /content_scripts/mode_find.coffee
parent9b0a48955c61c262cc4428b2360938d4b54d2d41 (diff)
downloadvimium-3e0378d0bc5d85ffec0ef49f7c421edbe9c073ec.tar.bz2
Modes; rework PostFindMode (again).
Diffstat (limited to 'content_scripts/mode_find.coffee')
-rw-r--r--content_scripts/mode_find.coffee36
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