aboutsummaryrefslogtreecommitdiffstats
path: root/content_scripts/mode_insert.coffee
diff options
context:
space:
mode:
Diffstat (limited to 'content_scripts/mode_insert.coffee')
-rw-r--r--content_scripts/mode_insert.coffee105
1 files changed, 17 insertions, 88 deletions
diff --git a/content_scripts/mode_insert.coffee b/content_scripts/mode_insert.coffee
index dd0c8d16..678e35cc 100644
--- a/content_scripts/mode_insert.coffee
+++ b/content_scripts/mode_insert.coffee
@@ -1,105 +1,34 @@
-# This mode is installed only when insert mode is active. It is a singleton, so a newly-activated instance
-# displaces any active instance.
class InsertMode extends Mode
constructor: (options = {}) ->
defaults =
name: "insert"
- badge: "I"
- singleton: InsertMode
- keydown: (event) => @stopBubblingAndTrue
- keypress: (event) => @stopBubblingAndTrue
- keyup: (event) => @stopBubblingAndTrue
exitOnEscape: true
- blurOnExit: true
- targetElement: null
+ keydown: (event) => @handler event
+ keypress: (event) => @handler event
+ keyup: (event) => @handler event
- # If options.targetElement blurs, we exit.
- options.exitOnBlur ||= options.targetElement
super extend defaults, options
- triggerSuppressor.suppress()
-
- exit: (event = null) ->
- triggerSuppressor.unsuppress()
- super()
- if @options.blurOnExit
- element = event?.srcElement
- if element and DomUtils.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()
-
-# Automatically trigger insert mode:
-# - On a keydown event in a contentEditable element.
-# - When a focusable element receives the focus.
-#
-# The trigger can be suppressed via triggerSuppressor; see InsertModeBlocker, below. This mode is permanently
-# installed (just above normal mode and passkeys mode) on the handler stack.
-class InsertModeTrigger extends Mode
- constructor: ->
- super
- name: "insert-trigger"
- keydown: (event) =>
- triggerSuppressor.unlessSuppressed =>
- # 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 (on every keydown) whether the active element is contentEditable.
- return @continueBubbling unless document.activeElement?.isContentEditable
- new InsertMode
- targetElement: document.activeElement
- @stopBubblingAndTrue
@push
- _name: "mode-#{@id}/activate-on-focus"
- focus: (event) =>
- triggerSuppressor.unlessSuppressed =>
- @alwaysContinueBubbling =>
- if DomUtils.isFocusable event.target
- new InsertMode
- targetElement: event.target
+ "blur": => @exit()
- # We may have already focussed an input element, so check.
- if document.activeElement and DomUtils.isEditable document.activeElement
- new InsertMode
- targetElement: document.activeElement
+ active: ->
+ document.activeElement and DomUtils.isFocusable document.activeElement
-# Used by InsertModeBlocker to suppress InsertModeTrigger; see below.
-triggerSuppressor = new Utils.Suppressor true # Note: true == @continueBubbling
+ handler: (event) ->
+ if @active() then @stopBubblingAndTrue else @continueBubbling
-# Suppresses InsertModeTrigger. This is used by various modes (usually via inheritance) to prevent
-# unintentionally dropping into insert mode on focusable elements.
-class InsertModeBlocker extends Mode
- constructor: (options = {}) ->
- defaults =
- name: "insert-blocker"
- # The user knows best; so, if the user clicks on something, the insert-mode blocker gets out of the way.
- exitOnClick: true
- onClickMode: InsertMode
- super extend defaults, options
- triggerSuppressor.suppress()
-
- @push
- _name: "mode-#{@id}/bail-on-click"
- "click": (event) =>
- @alwaysContinueBubbling =>
- # The user knows best; so, if the user clicks on something, the insert-mode blocker gets out of the
- # way.
+ exit: () ->
+ document.activeElement.blur() if @active()
+ if @options.permanentInsertMode
+ # We don't really exit if we're permanently installed.
+ Mode.updateBadge()
+ else
+ super()
- exit: ->
- super()
- # If the element associated with the event is focusable, then, had we not been blocking the trigger, we
- # would already have been in insert mode. Now, a click on that element will not generate a new focus
- # event, so the insert-mode trigger will not fire. We have to handle this case specially.
- # @options.onClickMode specifies the mode to use (by default, insert mode).
- if @clickEvent?.target? and DomUtils.isFocusable @clickEvent.target
- new @options.onClickMode
- targetElement: event.target
- triggerSuppressor.unsuppress()
+ chooseBadge: (badge) ->
+ badge.badge ||= "I" if @active()
root = exports ? window
root.InsertMode = InsertMode
-root.InsertModeTrigger = InsertModeTrigger
-root.InsertModeBlocker = InsertModeBlocker