diff options
Diffstat (limited to 'content_scripts/mode_insert.coffee')
| -rw-r--r-- | content_scripts/mode_insert.coffee | 82 |
1 files changed, 40 insertions, 42 deletions
diff --git a/content_scripts/mode_insert.coffee b/content_scripts/mode_insert.coffee index b80a78ee..41d82add 100644 --- a/content_scripts/mode_insert.coffee +++ b/content_scripts/mode_insert.coffee @@ -17,34 +17,7 @@ isEmbed =(element) -> isFocusable =(element) -> isEditable(element) or isEmbed element -# This mode is installed when insert mode is active. -class InsertMode extends Mode - constructor: (@insertModeLock = null) -> - super - name: "insert" - badge: "I" - keydown: (event) => @stopBubblingAndTrue - keypress: (event) => @stopBubblingAndTrue - keyup: (event) => @stopBubblingAndTrue - singleton: InsertMode - exitOnEscape: true - exitOnBlur: @insertModeLock - - exit: (event = null) -> - super() - if @insertModeLock and event?.srcElement == @insertModeLock - if isFocusable @insertModeLock - # 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. - @insertModeLock.blur() - - # Static method. Check whether insert mode is currently active. - @isActive: (extra) -> extra?.insertModeIsActive - -# Trigger insert mode: +# Automatically trigger insert mode: # - On a keydown event in a contentEditable element. # - When a focusable element receives the focus. # @@ -53,8 +26,8 @@ class InsertModeTrigger extends Mode constructor: -> super name: "insert-trigger" - keydown: (event, extra) => - return @continueBubbling if InsertModeTrigger.isDisabled extra + keydown: (event) => + return @continueBubbling if InsertModeTrigger.isSuppressed() # Some sites (e.g. inbox.google.com) change the contentEditable attribute on the fly (see #1245); # and unfortunately, the focus event happens *before* the change is made. Therefore, we need to # check again whether the active element is contentEditable. @@ -63,31 +36,56 @@ class InsertModeTrigger extends Mode @stopBubblingAndTrue @push - focus: (event, extra) => + focus: (event) => @alwaysContinueBubbling => - return @continueBubbling if InsertModeTrigger.isDisabled extra + return @continueBubbling if InsertModeTrigger.isSuppressed() return if not isFocusable event.target new InsertMode event.target # We may already have focussed an input, so check. new InsertMode document.activeElement if document.activeElement and isEditable document.activeElement - # Allow other modes to disable this trigger. Static. - @disable: (extra) -> extra.disableInsertModeTrigger = true - @isDisabled: (extra) -> extra?.disableInsertModeTrigger + # Allow other modes (notably InsertModeBlocker, below) to suppress this trigger. All static. + @suppressors: 0 + @isSuppressed: -> 0 < @suppressors + @suppress: -> @suppressors += 1 + @unsuppress: -> @suppressors -= 1 -# Disables InsertModeTrigger. This is used by find mode and by findFocus to prevent unintentionally dropping -# into insert mode on focusable elements. +# Suppresses InsertModeTrigger. This is used by various modes (usually by inheritance) to prevent +# unintentionally dropping into insert mode on focusable elements. class InsertModeBlocker extends Mode constructor: (options = {}) -> + InsertModeTrigger.suppress() options.name ||= "insert-blocker" super options - @push - "focus": (event, extra) => @alwaysContinueBubbling -> InsertModeTrigger.disable extra - "keydown": (event, extra) => @alwaysContinueBubbling -> InsertModeTrigger.disable extra - "keypress": (event, extra) => @alwaysContinueBubbling -> InsertModeTrigger.disable extra - "keyup": (event, extra) => @alwaysContinueBubbling -> InsertModeTrigger.disable extra + exit: -> + super() + InsertModeTrigger.unsuppress() + +# This mode is installed when insert mode is active. +class InsertMode extends Mode + constructor: (@insertModeLock = null) -> + super + name: "insert" + badge: "I" + singleton: InsertMode + keydown: (event) => @stopBubblingAndTrue + keypress: (event) => @stopBubblingAndTrue + keyup: (event) => @stopBubblingAndTrue + exitOnEscape: true + exitOnBlur: @insertModeLock + + exit: (event = null) -> + super() + element = event?.srcElement + if element and isFocusable element + # 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. + element.blur() root = exports ? window root.InsertMode = InsertMode |
