]> git.gir.st - VimFx.git/blob - extension/packages/events.coffee
Merge pull request #137 from ctype/delocale
[VimFx.git] / extension / packages / events.coffee
1 utils = require 'utils'
2 keyUtils = require 'key-utils'
3 { getCommand } = require 'commands'
4 { Vim } = require 'vim'
5 { getPref } = require 'prefs'
6 { setWindowBlacklisted } = require 'button'
7
8 { interfaces: Ci } = Components
9
10 vimBucket = new utils.Bucket utils.getWindowId, (obj) -> new Vim obj
11
12 suppressEvent = (event) ->
13 event.preventDefault()
14 event.stopPropagation()
15
16 # *************************
17 # NB! TODO! All this shit needs to be redone!!
18 # *************************
19
20 keyStrFromEvent = (event) ->
21
22 { ctrlKey: ctrl, metaKey: meta, altKey: alt, shiftKey: shift } = event
23
24 if !meta and !alt
25 if keyChar = keyUtils.keyCharFromCode(event.keyCode, shift)
26 keyStr = keyUtils.applyModifiers(keyChar, ctrl, alt, meta)
27
28 return keyStr
29
30 # Passthrough mode is activated when VimFx should temporarily stop processking
31 # keyboard input. For example when a context menu is whown
32 passthrough = false
33
34 # The following listeners are installed on every top level Chrome window
35 windowsListener =
36 keydown: (event) ->
37
38 if passthrough or getPref('disabled')
39 return
40
41 try
42 isEditable = utils.isElementEditable(event.originalTarget)
43
44 keyStr = keyStrFromEvent(event)
45
46 # We only handle the key if it's recognized by `keyCharFromCode`
47 # and if there is no focused editable element # or if it's the *Esc* key,
48 # which will remove the focus from the currently focused element
49 if keyStr and (not isEditable or keyStr == 'Esc')
50 if window = utils.getCurrentTabWindow(event)
51 if vim = vimBucket.get(window)
52 # No action if blacklisted
53 if vim.blacklisted
54 return
55
56 if vim.handleKeyDown(event, keyStr) and keyStr != 'Esc'
57 suppressEvent event
58 catch err
59 console.log(err, 'keydown')
60 console.stacktrace()
61
62 keypress: (event) ->
63
64 if passthrough or getPref('disabled')
65 return
66
67 try
68 isEditable = utils.isElementEditable(event.originalTarget)
69
70 # Try to execute keys that were accumulated so far.
71 # Suppress event if there is a matching command.
72 if window = utils.getCurrentTabWindow(event)
73 if vim = vimBucket.get(window)
74
75 # No action on blacklisted locations
76 if vim.blacklisted
77 return
78
79 # Blur from any active element on Esc. Calling before `handleKeyPress`
80 # because `vim.keys` will be reset afterwards`
81 blur_on_esc = vim.lastKeyStr == 'Esc' and getPref('blur_on_esc')
82
83 # Process event if there is no editable element in focus
84 # Or last key was Esc key
85 if not isEditable or vim.lastKeyStr == 'Esc'
86 result = vim.handleKeyPress(event)
87
88 # If there was some processing done then suppress the eveng
89 # unless it's the Esc key
90 if result and vim.lastKeyStr != 'Esc'
91 suppressEvent(event)
92
93 # Calling after the command has been executed
94 if blur_on_esc
95 cb = -> event.originalTarget?.ownerDocument?.activeElement?.blur()
96 window.setTimeout(cb, 0)
97
98 catch err
99 console.log(err, 'keypress')
100 console.stacktrace()
101
102 keyup: (event) ->
103 if window = utils.getCurrentTabWindow event
104 if vim = vimBucket.get(window)
105 if vim.lastKeyStr and vim.lastKeyStr != 'Esc'
106 suppressEvent(event)
107
108 vim.lastKeyStr = null
109
110 popupshown: (event) ->
111 if event.target.tagName in [ 'menupopup', 'panel' ]
112 passthrough = true
113
114
115 popuphidden: (event) ->
116 if event.target.tagName in [ 'menupopup', 'panel' ]
117 passthrough = false
118
119 # When the top level window closes we should release all Vims that were
120 # associated with tabs in this window
121 DOMWindowClose: (event) ->
122 if gBrowser = event.originalTarget.gBrowser
123 for tab in gBrowser.tabs
124 if browser = gBrowser.getBrowserForTab(tab)
125 vimBucket.forget(browser.contentWindow)
126
127 TabClose: (event) ->
128 if gBrowser = utils.getEventTabBrowser(event)
129 if browser = gBrowser.getBrowserForTab(event.originalTarget)
130 vimBucket.forget(browser.contentWindow)
131
132 # Update the toolbar button icon to reflect the blacklisted state
133 TabSelect: (event) ->
134 if vim = vimBucket.get(event.originalTarget?.linkedBrowser?.contentDocument?.defaultView)
135 if rootWindow = utils.getRootWindow(vim.window)
136 setWindowBlacklisted(rootWindow, vim.blacklisted)
137
138 # This listener works on individual tabs within Chrome Window
139 # User for: listening for location changes and disabling the extension
140 # on black listed urls
141 tabsListener =
142 onLocationChange: (browser, webProgress, request, location) ->
143 blacklisted = utils.isBlacklisted(location.spec, getPref('black_list'))
144 if vim = vimBucket.get(browser.contentWindow)
145 vim.enterNormalMode()
146 vim.blacklisted = blacklisted
147 if rootWindow = utils.getRootWindow(vim.window)
148 setWindowBlacklisted(rootWindow, vim.blacklisted)
149
150 addEventListeners = (window) ->
151 for name, listener of windowsListener
152 window.addEventListener(name, listener, true)
153
154 # Install onLocationChange listener
155 window.gBrowser.addTabsProgressListener(tabsListener)
156
157 removeEventListeners = ->
158 for name, listener of windowsListener
159 window.removeEventListener(name, listener, true)
160
161 unload ->
162 removeEventListeners(window)
163 window.gBrowser.removeTabsProgressListener(tabsListener)
164
165 exports.addEventListeners = addEventListeners
Imprint / Impressum