diff options
| author | Stephen Blott | 2015-01-10 15:05:58 +0000 |
|---|---|---|
| committer | Stephen Blott | 2015-01-10 15:05:58 +0000 |
| commit | c554d1fd5b6d81506864516b6f86a14f8672bec5 (patch) | |
| tree | 5e2d15e17a0344a0882cd57dda1d4d2665a1b9f1 /content_scripts/mode_insert.coffee | |
| parent | 35cb54fec7242fac5c68503a32ef9dd4fea5d9b6 (diff) | |
| download | vimium-c554d1fd5b6d81506864516b6f86a14f8672bec5.tar.bz2 | |
Modes; reinstate key blockers:
- when the selection is contentEditable
- in PostFindMode
Restricted to printable characters.
Diffstat (limited to 'content_scripts/mode_insert.coffee')
| -rw-r--r-- | content_scripts/mode_insert.coffee | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/content_scripts/mode_insert.coffee b/content_scripts/mode_insert.coffee index 5720c901..b907f22e 100644 --- a/content_scripts/mode_insert.coffee +++ b/content_scripts/mode_insert.coffee @@ -96,6 +96,34 @@ class InsertModeBlocker extends Mode new @options.onClickMode targetElement: document.activeElement +# There's an unfortunate feature interaction between chrome's contentEditable handling and our insert mode. +# If the selection is contentEditable and a descendant of the active element, then chrome focuses it on any +# unsuppressed printable keypress. This drops us unintentally into insert mode. See #1415. A single +# instance of this mode sits near the bottom of the handler stack and suppresses each keypress event if: +# - it hasn't been handled by any other mode (so not by normal mode, passkeys, insert, ...), +# - it represents a printable character, +# - the selection is content editable, and +# - the selection is a descendant of the active element. +# This should rarely fire, typically only on fudged keypresses in normal mode. And, even then, only in the +# circumstances outlined above. So, we shouldn't usually be blocking keyboard events for other extensions or +# the page itself. +# There's some controversy as to whether this is the right thing to do. See discussion in #1415. This +# implements Option 2 from there. +new class ContentEditableTrap extends Mode + constructor: -> + super + name: "content-editable-trap" + keypress: (event) => + if @wouldTriggerInsert event then @suppressEvent else @continueBubbling + + # True if the selection is content editable and a descendant of the active element. + wouldTriggerInsert: (event) -> + element = document.getSelection()?.anchorNode?.parentElement + return element?.isContentEditable and + document.activeElement and + DomUtils. isPrintable event and + DomUtils.isDOMDescendant document.activeElement, element + root = exports ? window root.InsertMode = InsertMode root.InsertModeTrigger = InsertModeTrigger |
