diff options
Diffstat (limited to 'content_scripts/mode_insert.coffee')
| -rw-r--r-- | content_scripts/mode_insert.coffee | 105 | 
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  | 
