diff options
| author | Stephen Blott | 2015-01-09 10:51:19 +0000 |
|---|---|---|
| committer | Stephen Blott | 2015-01-09 11:22:04 +0000 |
| commit | 2e6eb69e99f29acc432b750501168d2a15116e6f (patch) | |
| tree | 345ccca18c55aa9893f94e09b6236a8f94b15d88 /content_scripts | |
| parent | 5d653d8fbab350ae7737d6f91a93df10477b172d (diff) | |
| download | vimium-2e6eb69e99f29acc432b750501168d2a15116e6f.tar.bz2 | |
Modes; various changes...
- Refactor insert-mode constructor.
- Gneralise focusInput.
Diffstat (limited to 'content_scripts')
| -rw-r--r-- | content_scripts/mode_find.coffee | 3 | ||||
| -rw-r--r-- | content_scripts/mode_insert.coffee | 42 | ||||
| -rw-r--r-- | content_scripts/vimium_frontend.coffee | 19 |
3 files changed, 41 insertions, 23 deletions
diff --git a/content_scripts/mode_find.coffee b/content_scripts/mode_find.coffee index 40245d14..3b9f951e 100644 --- a/content_scripts/mode_find.coffee +++ b/content_scripts/mode_find.coffee @@ -35,7 +35,8 @@ class PostFindMode extends InsertModeBlocker keydown: (event) -> if element == document.activeElement and KeyboardUtils.isEscape event self.exit() - new InsertMode element + new InsertMode + targetElement: element DomUtils.suppressKeyupAfterEscape handlerStack return false @remove() diff --git a/content_scripts/mode_insert.coffee b/content_scripts/mode_insert.coffee index bfc79aa9..c0a61d31 100644 --- a/content_scripts/mode_insert.coffee +++ b/content_scripts/mode_insert.coffee @@ -1,8 +1,8 @@ # This mode is installed when insert mode is active. class InsertMode extends Mode - constructor: (@insertModeLock = null) -> - super + constructor: (options = {}) -> + defaults = name: "insert" badge: "I" singleton: InsertMode @@ -10,18 +10,23 @@ class InsertMode extends Mode keypress: (event) => @stopBubblingAndTrue keyup: (event) => @stopBubblingAndTrue exitOnEscape: true - exitOnBlur: @insertModeLock + blurOnExit: true + + options = extend defaults, options + options.exitOnBlur = options.targetElement || null + super options exit: (event = null) -> super() - 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() + 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. @@ -39,18 +44,21 @@ class InsertModeTrigger extends Mode # and unfortunately, the focus event happens *before* the change is made. Therefore, we need to # check again whether the active element is contentEditable. return @continueBubbling unless document.activeElement?.isContentEditable - new InsertMode document.activeElement + new InsertMode + targetElement: document.activeElement @stopBubblingAndTrue @push focus: (event) => triggerSuppressor.unlessSuppressed => return unless DomUtils.isFocusable event.target - new InsertMode event.target + new InsertMode + targetElement: event.target # We may already have focussed an input, so check. if document.activeElement and DomUtils.isEditable document.activeElement - new InsertMode document.activeElement + new InsertMode + targetElement: document.activeElement # Used by InsertModeBlocker to suppress InsertModeTrigger; see below. triggerSuppressor = new Utils.Suppressor true @@ -61,6 +69,7 @@ class InsertModeBlocker extends Mode constructor: (options = {}) -> triggerSuppressor.suppress() options.name ||= "insert-blocker" + options.onClickMode ||= InsertMode super options @onExit -> triggerSuppressor.unsuppress() @@ -72,10 +81,11 @@ class InsertModeBlocker extends Mode # However, there's a corner case. If the active element is focusable, then we would have been in # insert mode had we not been blocking the trigger. Now, clicking on the element will not generate # a new focus event, so the insert-mode trigger will not fire. We have to handle this case - # specially. + # specially. @options.onClickMode is the mode to use. if document.activeElement and event.target == document.activeElement and DomUtils.isEditable document.activeElement - new InsertMode document.activeElement + new @options.onClickMode + targetElement: document.activeElement root = exports ? window root.InsertMode = InsertMode diff --git a/content_scripts/vimium_frontend.coffee b/content_scripts/vimium_frontend.coffee index 97d4cd73..99fe4990 100644 --- a/content_scripts/vimium_frontend.coffee +++ b/content_scripts/vimium_frontend.coffee @@ -6,7 +6,7 @@ # passKeysMode = null -insertModeLock = null +targetElement = null findMode = false findModeQuery = { rawQuery: "", matchCount: 0 } findModeQueryHasResults = false @@ -342,10 +342,11 @@ extend window, enterVisualMode: => new VisualMode() - focusInput: (count) -> + focusInput: (count, targetMode = InsertMode) -> # Focus the first input element on the page, and create overlays to highlight all the input elements, with # the currently-focused element highlighted specially. Tabbing will shift focus to the next input element. # Pressing any other key will remove the overlays and the special tab behavior. + # targetMode is the mode we want to enter. resultSet = DomUtils.evaluateXPath(textInputXPath, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE) visibleInputs = for i in [0...resultSet.snapshotLength] by 1 @@ -382,6 +383,8 @@ extend window, # Be a singleton. It doesn't make any sense to have two instances active at the same time; and that # shouldn't happen anyway. However, it does no harm to enforce it. singleton: FocusSelector + targetMode: targetMode + onClickMode: targetMode # For InsertModeBlocker super-class. keydown: (event) => if event.keyCode == KeyboardUtils.keyCodes.tab hints[selectedInputIndex].classList.remove 'internalVimiumSelectedInputHint' @@ -404,8 +407,12 @@ extend window, super() DomUtils.removeElement hintContainingDiv if document.activeElement == visibleInputs[selectedInputIndex].element - # InsertModeBlocker handles the "click" case. - new InsertMode document.activeElement unless event?.type == "click" + # The InsertModeBlocker super-class handles the "click" case. + unless event?.type == "click" + # In the legacy (and probably common) case, we're entering insert mode here. However, it could be + # some other mode. + new @options.targetMode + targetElement: document.activeElement # Decide whether this keyChar should be passed to the underlying page. # Keystrokes are *never* considered passKeys if the keyQueue is not empty. So, for example, if 't' is a @@ -634,8 +641,8 @@ isEditable = (target) -> # # We cannot count on 'focus' and 'blur' events to happen sequentially. For example, if blurring element A # causes element B to come into focus, we may get "B focus" before "A blur". Thus we only leave insert mode -# when the last editable element that came into focus -- which insertModeLock points to -- has been blurred. -# If insert mode is entered manually (via pressing 'i'), then we set insertModeLock to 'undefined', and only +# when the last editable element that came into focus -- which targetElement points to -- has been blurred. +# If insert mode is entered manually (via pressing 'i'), then we set targetElement to 'undefined', and only # leave insert mode when the user presses <ESC>. # Note. This returns the truthiness of target, which is required by isInsertMode. # |
