]> git.gir.st - VimFx.git/blob - extension/packages/events.coffee
Move special handling of Esc into events.coffee
[VimFx.git] / extension / packages / events.coffee
1 utils = require 'utils'
2 keyUtils = require 'key-utils'
3 { Vim } = require 'vim'
4 { getPref } = require 'prefs'
5 { updateToolbarButton } = require 'button'
6 { unload } = require 'unload'
7
8 { interfaces: Ci } = Components
9
10 vimBucket = new utils.Bucket(utils.getWindowId, (w) -> new Vim(w))
11
12 keyStrFromEvent = (event) ->
13 { ctrlKey: ctrl, metaKey: meta, altKey: alt, shiftKey: shift } = event
14
15 if !meta and !alt
16 return unless keyChar = keyUtils.keyCharFromCode(event.keyCode, shift)
17 keyStr = keyUtils.applyModifiers(keyChar, ctrl, alt, meta)
18 return keyStr
19
20 return null
21
22 # Passthrough mode is activated when VimFx should temporarily stop processing keyboard input, for
23 # example when a menu is shown.
24 passthrough = false
25 checkPassthrough = (event) ->
26 if event.target.nodeName in ['menupopup', 'panel']
27 passthrough = switch event.type
28 when 'popupshown' then true
29 when 'popuphidden' then false
30
31 suppress = false
32 keyListener = (event) ->
33 try
34 return if passthrough or getPref('disabled')
35 return unless window = utils.getEventCurrentTabWindow(event)
36 return unless vim = vimBucket.get(window)
37 return if vim.blacklisted
38
39 if event.type == 'keydown'
40 suppress = false
41
42 return unless keyStr = keyStrFromEvent(event)
43
44 isEditable = utils.isElementEditable(event.originalTarget)
45
46 suppress = vim.onInput(keyStr, event, {autoInsertMode: isEditable})
47 if vim.mode == 'normal' and keyStr == 'Esc'
48 suppress = false
49
50 if suppress
51 event.preventDefault()
52 event.stopPropagation()
53
54 catch error
55 console.log("#{ error } (in #{ event.type })\n#{ error.stack.replace(/@.+-> /g, '@') }")
56
57 removeVimFromTab = (tab, gBrowser) ->
58 return unless browser = gBrowser.getBrowserForTab(tab)
59 vimBucket.forget(browser.contentWindow)
60
61 updateButton = (vim) ->
62 return unless rootWindow = utils.getRootWindow(vim.window)
63 updateToolbarButton(rootWindow, {blacklisted: vim.blacklisted, insertMode: vim.mode == 'insert'})
64
65 # The following listeners are installed on every top level Chrome window
66 windowsListeners =
67 keydown: keyListener
68 keypress: keyListener
69 keyup: keyListener
70 popupshown: checkPassthrough
71 popuphidden: checkPassthrough
72
73 # When the top level window closes we should release all Vims that were
74 # associated with tabs in this window
75 DOMWindowClose: (event) ->
76 return unless { gBrowser } = event.originalTarget
77 for tab in gBrowser.tabs
78 removeVimFromTab(tab, gBrowser)
79
80 TabClose: (event) ->
81 return unless { gBrowser } = utils.getEventRootWindow(event) ? {}
82 tab = event.originalTarget
83 removeVimFromTab(tab, gBrowser)
84
85 # Update the toolbar button icon to reflect the blacklisted state
86 TabSelect: (event) ->
87 return unless window = event.originalTarget?.linkedBrowser?.contentDocument?.defaultView
88 return unless vim = vimBucket.get(window)
89 updateButton(vim)
90
91 # This listener works on individual tabs within Chrome Window
92 tabsListener =
93 # Listenfor location changes and disable the extension on blacklisted urls
94 onLocationChange: (browser, webProgress, request, location) ->
95 return unless vim = vimBucket.get(browser.contentWindow)
96
97 # If the location changes when in hints mode (for example because the reload button has been
98 # clicked), we're going to end up in hints mode without any markers. So switch back to normal
99 # mode in that case.
100 if vim.mode == 'hints'
101 vim.enterMode('normal')
102
103 vim.blacklisted = utils.isBlacklisted(location.spec)
104 updateButton(vim)
105
106 addEventListeners = (window) ->
107 for name, listener of windowsListeners
108 window.addEventListener(name, listener, true)
109
110 window.gBrowser.addTabsProgressListener(tabsListener)
111
112 unload ->
113 for name, listener of windowsListeners
114 window.removeEventListener(name, listener, true)
115
116 window.gBrowser.removeTabsProgressListener(tabsListener)
117
118 exports.addEventListeners = addEventListeners
Imprint / Impressum