blob: 82dbf74a50d6ec97e744920717e051a44093f961 (
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
|
class Mode
# Static members.
@modes: []
@current: -> Mode.modes[0]
# Constants. Static.
@suppressPropagation = false
@propagate = true
# Default values.
name: "" # The name of this mode.
badge: "" # A badge to display on the popup when this mode is active.
keydown: "suppress" # A function, or "suppress" or "pass"; the latter are replaced with suitable functions.
keypress: "suppress" # A function, or "suppress" or "pass"; the latter are replaced with suitable functions.
keyup: "suppress" # A function, or "suppress" or "pass"; the latter are replaced with suitable functions.
constructor: (options) ->
extend @, options
@handlerId = handlerStack.push
keydown: @checkForBuiltInHandler "keydown", @keydown
keypress: @checkForBuiltInHandler "keypress", @keypress
keyup: @checkForBuiltInHandler "keyup", @keyup
Mode.modes.unshift @
Mode.setBadge()
# Allow the strings "suppress" and "pass" to be used as proxies for the built-in handlers.
checkForBuiltInHandler: (type, handler) ->
switch handler
when "suppress" then @generateSuppressPropagation type
when "pass" then @generatePassThrough type
else handler
# Generate a default handler which always passes through to the underlying page; except Esc, which pops the
# current mode.
generatePassThrough: (type) ->
(event) =>
if type == "keydown" and KeyboardUtils.isEscape event
@exit()
return Mode.suppressPropagation
handlerStack.passDirectlyToPage
# Generate a default handler which always suppresses propagation; except Esc, which pops the current mode.
generateSuppressPropagation: (type) ->
handler = @generatePassThrough type
(event) -> handler(event) and Mode.suppressPropagation # Always falsy.
exit: ->
handlerStack.remove @handlerId
Mode.modes = Mode.modes.filter (mode) => mode != @
Mode.setBadge()
# Set the badge on the browser popup to indicate the current mode; static method.
@setBadge: ->
chrome.runtime.sendMessage({ handler: "setBadge", badge: Mode.getBadge() })
# Static convenience methods.
@is: (mode) -> Mode.current()?.name == mode
@getBadge: -> Mode.current()?.badge || ""
@isInsert: -> Mode.is "insert"
root = exports ? window
root.Mode = Mode
|