blob: 7f1d5ddc480bcca5a8a3cf6a8594c92206b4d5fe (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
# 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 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 fairly low down 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 again whether the active element is contentEditable.
return @continueBubbling unless document.activeElement?.isContentEditable
new InsertMode document.activeElement
@stopBubblingAndTrue
@push
focus: (event) =>
triggerSuppressor.unlessSuppressed =>
return unless DomUtils.isFocusable event.target
new InsertMode event.target
# We may already have focussed an input, so check.
if document.activeElement and DomUtils.isEditable document.activeElement
new InsertMode document.activeElement
# Used by InsertModeBlocker to suppress InsertModeTrigger; see below.
triggerSuppressor = new Utils.Suppressor true
# 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 = {}) ->
triggerSuppressor.suppress()
options.name ||= "insert-blocker"
super options
@onExit -> triggerSuppressor.unsuppress()
root = exports ? window
root.InsertMode = InsertMode
root.InsertModeTrigger = InsertModeTrigger
root.InsertModeBlocker = InsertModeBlocker
|