From 3594bad00aec580bc837e2b2cc6d4051da149da0 Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Tue, 6 Jan 2015 09:42:28 +0000 Subject: Modes; rework insert blocker. Fix bug whereby clicking on the focused element does not activate insert mode. This bug is also present (though harder to fix) in master. --- content_scripts/mode.coffee | 4 ++++ content_scripts/mode_insert.coffee | 36 ++++++++++++++++++++++++------------ 2 files changed, 28 insertions(+), 12 deletions(-) (limited to 'content_scripts') diff --git a/content_scripts/mode.coffee b/content_scripts/mode.coffee index adc5439d..b3cca56c 100644 --- a/content_scripts/mode.coffee +++ b/content_scripts/mode.coffee @@ -125,6 +125,10 @@ class SingletonMode extends Mode SingletonMode.instances[@singleton] = @ super options + # Static method. Return whether the indicated mode (singleton) is currently active or not. + @isActive: (singleton) -> + @instances[singleton]? + # Static method. If there's a singleton instance active, then kill it. @kill: (singleton) -> SingletonMode.instances[singleton].exit() if SingletonMode.instances[singleton] diff --git a/content_scripts/mode_insert.coffee b/content_scripts/mode_insert.coffee index 51ef3d8b..2b0ebb45 100644 --- a/content_scripts/mode_insert.coffee +++ b/content_scripts/mode_insert.coffee @@ -27,17 +27,19 @@ class InsertMode extends ConstrainedMode keypress: (event) => @stopBubblingAndTrue keyup: (event) => @stopBubblingAndTrue - exit: (extra=null) -> - if extra?.source == ExitOnEscapeMode and extra?.event?.srcElement? - element = extra.event.srcElement - if isFocusable element + exit: (extra={}) -> + super() + if extra.source == ExitOnEscapeMode and extra.event?.srcElement? + if isFocusable extra.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. - element.blur() - super() + extra.event.srcElement.blur() + + # Static method. Return whether insert mode is currently active or not. + @isActive: (singleton) -> SingletonMode.isActive InsertMode # Trigger insert mode: # - On a keydown event in a contentEditable element. @@ -55,13 +57,25 @@ class InsertModeTrigger extends Mode # 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. - new InsertMode() if document.activeElement?.isContentEditable + # NOTE. There's no need to check InsertMode.isActive() here since, if insert mode *is* active, + # then we wouldn't be receiving this keyboard event. + new InsertMode document.activeElement if document.activeElement?.isContentEditable @push focus: (event, extra) => @alwaysContinueBubbling => - unless extra.suppressInsertModeTrigger? - new InsertMode event.target if isFocusable event.target + unless InsertMode.isActive() + unless extra.suppressInsertModeTrigger? + new InsertMode event.target if isFocusable event.target + + click: (event, extra) => + @alwaysContinueBubbling => + unless InsertMode.isActive() + # We cannot rely exclusively on focus events for triggering insert mode. With find mode, an + # editable element can be active, but we're not in insert mode (see PostFindMode), and no focus + # event will be generated. In this case, clicking on the element should activate insert mode. + if document.activeElement == event.target and isEditable event.target + new InsertMode event.target # We may already have focussed something, so check. new InsertMode document.activeElement if document.activeElement and isFocusable document.activeElement @@ -79,9 +93,7 @@ class InsertModeBlocker extends SingletonMode unless @element? @push - focus: (event, extra) => - @alwaysContinueBubbling => - InsertModeTrigger.suppress extra + focus: (event, extra) => @alwaysContinueBubbling => InsertModeTrigger.suppress extra if @element?.isContentEditable @push -- cgit v1.2.3