diff options
| author | Stephen Blott | 2015-01-01 12:02:16 +0000 |
|---|---|---|
| committer | Stephen Blott | 2015-01-01 16:22:47 +0000 |
| commit | 2d047e7ee7e77a02ccb29658ada953a092cee20a (patch) | |
| tree | 9dee44c265595c4864376fd2c736c4cab2508739 /content_scripts/mode_insert.coffee | |
| parent | aed5e2b5e1015a2e581edadbc5dd2d1b5a2719f4 (diff) | |
| download | vimium-2d047e7ee7e77a02ccb29658ada953a092cee20a.tar.bz2 | |
Modes; implement insert mode.
Diffstat (limited to 'content_scripts/mode_insert.coffee')
| -rw-r--r-- | content_scripts/mode_insert.coffee | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/content_scripts/mode_insert.coffee b/content_scripts/mode_insert.coffee new file mode 100644 index 00000000..4a1d4349 --- /dev/null +++ b/content_scripts/mode_insert.coffee @@ -0,0 +1,70 @@ + +class InsertMode extends Mode + userActivated: false + + # Input or text elements are considered focusable and able to receieve their own keyboard events, and will + # enter insert mode if focused. Also note that the "contentEditable" attribute can be set on any element + # which makes it a rich text editor, like the notes on jjot.com. + isEditable: (element) -> + return true if element.isContentEditable + nodeName = element.nodeName?.toLowerCase() + # Use a blacklist instead of a whitelist because new form controls are still being implemented for html5. + if nodeName == "input" and element.type and not element.type in ["radio", "checkbox"] + return true + nodeName in ["textarea", "select"] + + # Embedded elements like Flash and quicktime players can obtain focus but cannot be programmatically + # unfocused. + isEmbed: (element) -> + element.nodeName?.toLowerCase() in ["embed", "object"] + + canEditElement: (element) -> + element and (@isEditable(element) or @isEmbed element) + + isActive: -> + @userActivated or @canEditElement document.activeElement + + generateKeyHandler: (type) -> + (event) => + return Mode.propagate unless @isActive() + return handlerStack.passThrough unless type == "keydown" and KeyboardUtils.isEscape event + # We're now exiting insert mode. + if @canEditElement event.srcElement + # Remove the focus so the user can't just get himself back into insert mode by typing in the same input + # box. + # NOTE(smblott, 2014/12/22) Including embeds for .blur() here is experimental. It appears to be the + # right thing to do for most common use cases. However, it could also cripple flash-based sites and + # games. See discussion in #1211 and #1194. + event.srcElement.blur() + @userActivated = false + @updateBadge() + Mode.suppressPropagation + + pickBadge: -> + if @isActive() then "I" else "" + + updateBadge: -> + badge = @badge + @badge = @pickBadge() + Mode.setBadge() if badge != @badge + Mode.propagate + + activate: -> + @userActivated = true + @updateBadge() + + constructor: -> + super + name: "insert" + badge: @pickBadge() + keydown: @generateKeyHandler "keydown" + keypress: @generateKeyHandler "keypress" + keyup: @generateKeyHandler "keyup" + + handlerStack.push + DOMActivate: => @updateBadge() + focus: => @updateBadge() + blur: => @updateBadge() + +root = exports ? window +root.InsertMode = InsertMode |
