aboutsummaryrefslogtreecommitdiffstats
path: root/content_scripts/mode_insert.coffee
diff options
context:
space:
mode:
authorStephen Blott2015-01-01 12:02:16 +0000
committerStephen Blott2015-01-01 16:22:47 +0000
commit2d047e7ee7e77a02ccb29658ada953a092cee20a (patch)
tree9dee44c265595c4864376fd2c736c4cab2508739 /content_scripts/mode_insert.coffee
parentaed5e2b5e1015a2e581edadbc5dd2d1b5a2719f4 (diff)
downloadvimium-2d047e7ee7e77a02ccb29658ada953a092cee20a.tar.bz2
Modes; implement insert mode.
Diffstat (limited to 'content_scripts/mode_insert.coffee')
-rw-r--r--content_scripts/mode_insert.coffee70
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