]> git.gir.st - VimFx.git/blob - extension/packages/commands.coffee
Fixed exception firing by marker enabled commands on XUL Documents
[VimFx.git] / extension / packages / commands.coffee
1 { classes: Cc, interfaces: Ci, utils: Cu } = Components
2
3 utils = require 'utils'
4 hints = require 'hints'
5 help = require 'help'
6 find = require 'find'
7
8 { getPref, setPref } = require 'prefs'
9
10 # Focus the Address Bar
11 command_o = (vim) ->
12 if chromeWindow = utils.getRootWindow vim.window
13 chromeWindow.focusAndSelectUrlBar()
14
15 # Navigate to the address that is currently stored in the system clipboard
16 command_p = (vim) ->
17 url = utils.readFromClipboard(vim.window)
18 postData = null
19 if not utils.isURL(url) and submission = utils.browserSearchSubmission url
20 url = submission.uri.spec
21 postData = submission.postData
22
23 if chromeWindow = utils.getRootWindow vim.window
24 chromeWindow.gBrowser.loadURIWithFlags url, null, null, null, postData
25
26 # Open new tab and navigate to the address that is currently stored in the system clipboard
27 command_P = (vim) ->
28 url = utils.readFromClipboard(vim.window)
29 postData = null
30 if not utils.isURL(url) and submission = utils.browserSearchSubmission url
31 url = submission.uri.spec
32 postData = submission.postData
33
34 if chromeWindow = utils.getRootWindow vim.window
35 chromeWindow.gBrowser.selectedTab = chromeWindow.gBrowser.addTab url, null, null, postData, null, false
36
37 # Open new tab and focus the address bar
38 command_t = (vim) ->
39 if chromeWindow = utils.getRootWindow vim.window
40 if gBrowser = chromeWindow.gBrowser
41 # Get the default url for the new tab
42 newtab_url = Services.prefs.getCharPref 'browser.newtab.url'
43 gBrowser.selectedTab = gBrowser.addTab newtab_url
44 # Focus the address bar
45 chromeWindow.focusAndSelectUrlBar()
46
47 # Copy current URL to the clipboard
48 command_yf = (vim) ->
49 markers = hints.injectHints vim.window.document
50 if markers?.length > 0
51 # This callback will be called with the selected marker as argument
52 cb = (marker) ->
53 if url = marker.element.href
54 utils.writeToClipboard vim.window, url
55
56 vim.enterHintsMode(markers, cb)
57
58 # Copy current URL to the clipboard
59 command_yy = (vim) ->
60 utils.writeToClipboard vim.window, vim.window.location.toString()
61
62 # Reload the page, possibly from cache
63 command_r = (vim) ->
64 vim.window.location.reload(false)
65
66 # Reload the page from the server
67 command_R = (vim) ->
68 vim.window.location.reload(true)
69
70 # Reload the page, possibly from cache
71 command_ar = (vim) ->
72 if rootWindow = utils.getRootWindow vim.window
73 if tabs = rootWindow.gBrowser.tabContainer
74 for i in [0...tabs.itemCount]
75 window = tabs.getItemAtIndex(i).linkedBrowser.contentWindow
76 window.location.reload(false)
77
78 # Reload the page from the server
79 command_aR = (vim) ->
80 if rootWindow = utils.getRootWindow vim.window
81 if tabs = rootWindow.gBrowser.tabContainer
82 for i in [0...tabs.itemCount]
83 window = tabs.getItemAtIndex(i).linkedBrowser.contentWindow
84 window.location.reload(true)
85
86 # Scroll to the top of the page
87 command_gg = (vim) ->
88 vim.window.scrollTo(0, 0)
89
90 # Scroll to the bottom of the page
91 command_G = (vim) ->
92 if document = vim.window.document
93 # Workaround the pages where body isn't the scrollable element.
94 # In this case we try to scroll 100k pixels
95 vim.window.scrollTo(0, Math.max(document.body.scrollHeight, 100000))
96
97 # Scroll down a bit
98 command_j_ce = (vim) ->
99 utils.smoothScroll vim.window, 0, (getPref 'scroll_step'), getPref 'scroll_time'
100
101 # Scroll up a bit
102 command_k_cy = (vim) ->
103 utils.smoothScroll vim.window, 0, -(getPref 'scroll_step'), getPref 'scroll_time'
104
105 # Scroll left a bit
106 command_h = (vim) ->
107 utils.smoothScroll vim.window, -(getPref 'scroll_step'), 0, getPref 'scroll_time'
108
109 # Scroll right a bit
110 command_l = (vim) ->
111 utils.smoothScroll vim.window, (getPref 'scroll_step'), 0, getPref 'scroll_time'
112
113 # Scroll down half a page
114 command_d = (vim) ->
115 utils.smoothScroll vim.window, 0, vim.window.innerHeight / 2, getPref 'scroll_time'
116
117 # Scroll up half a page
118 command_u = (vim) ->
119 utils.smoothScroll vim.window, 0, -vim.window.innerHeight / 2, getPref 'scroll_time'
120
121 # Scroll down full a page
122 command_cf = (vim) ->
123 step = (vim.window.innerHeight - (getPref 'scroll_step'))
124 utils.smoothScroll vim.window, 0, step, getPref 'scroll_time'
125
126 # Scroll up full a page
127 command_cb = (vim) ->
128 step = - (vim.window.innerHeight - (getPref 'scroll_step'))
129 utils.smoothScroll vim.window, 0, step, getPref 'scroll_time'
130
131 # Activate previous tab
132 command_J_gT = (vim) ->
133 if rootWindow = utils.getRootWindow vim.window
134 rootWindow.gBrowser.tabContainer.advanceSelectedTab(-1, true);
135
136 # Activate next tab
137 command_K_gt = (vim) ->
138 if rootWindow = utils.getRootWindow vim.window
139 rootWindow.gBrowser.tabContainer.advanceSelectedTab(1, true);
140
141 # Go to the first tab
142 command_gH_g0 = (vim) ->
143 if rootWindow = utils.getRootWindow vim.window
144 rootWindow.gBrowser.tabContainer.selectedIndex = 0;
145
146 # Go to the last tab
147 command_gL_g$ = (vim) ->
148 if rootWindow = utils.getRootWindow vim.window
149 itemCount = rootWindow.gBrowser.tabContainer.itemCount;
150 rootWindow.gBrowser.tabContainer.selectedIndex = itemCount - 1;
151
152 # Go back in history
153 command_H = (vim) ->
154 vim.window.history.back()
155
156 # Go forward in history
157 command_L = (vim) ->
158 vim.window.history.forward()
159
160 # Close current tab
161 command_x = (vim) ->
162 if rootWindow = utils.getRootWindow vim.window
163 rootWindow.gBrowser.removeCurrentTab()
164
165 # Restore last closed tab
166 command_X = (vim) ->
167 if rootWindow = utils.getRootWindow vim.window
168 ss = utils.getSessionStore()
169 if ss and ss.getClosedTabCount(rootWindow) > 0
170 ss.undoCloseTab rootWindow, 0
171
172 # Follow links with hint markers
173 command_f = (vim) ->
174 if document = vim.window.document
175 markers = hints.injectHints document
176 if markers?.length > 0
177 # This callback will be called with the selected marker as argument
178 cb = (marker) ->
179 marker.element.focus()
180 utils.simulateClick marker.element
181
182 vim.enterHintsMode markers, cb
183
184 # Follow links in a new Tab with hint markers
185 command_F = (vim) ->
186 markers = hints.injectHints vim.window.document
187 if markers?.length > 0
188 # This callback will be called with the selected marker as argument
189 cb = (marker) ->
190 marker.element.focus()
191 utils.simulateClick marker.element, { metaKey: true, ctrlKey: true }
192
193 vim.enterHintsMode markers, cb
194
195 # Move current tab to the left
196 command_cJ = (vim) ->
197 if gBrowser = utils.getRootWindow(vim.window)?.gBrowser
198 if tab = gBrowser.selectedTab
199 index = gBrowser.tabContainer.selectedIndex
200 total = gBrowser.tabContainer.itemCount
201
202 # `total` is added to deal with negative offset
203 gBrowser.moveTabTo tab, (total + index - 1) % total
204
205 # Move current tab to the right
206 command_cK = (vim) ->
207 if gBrowser = utils.getRootWindow(vim.window)?.gBrowser
208 if tab = gBrowser.selectedTab
209 index = gBrowser.tabContainer.selectedIndex
210 total = gBrowser.tabContainer.itemCount
211
212 gBrowser.moveTabTo tab, (index + 1) % total
213
214 # Display the Help Dialog
215 command_help = (vim) ->
216 help.injectHelp vim.window.document, commandsHelp
217
218 # Switch into find mode
219 command_find = (vim) ->
220 vim.enterFindMode()
221 vim.findStr = ""
222
223 find.injectFind vim.window.document
224
225 # Search for the last pattern
226 command_n = (vim) ->
227 if vim.findStr.length > 0
228 if not find.find vim.window, vim.findStr, false
229 find.flashFind vim.window.document, "#{ vim.findStr } (Not Found)"
230
231 # Search for the last pattern backwards
232 command_N = (vim) ->
233 if vim.findStr.length > 0
234 if not find.find vim.window, vim.findStr, true
235 find.flashFind vim.window.document, "#{ vim.findStr } (Not Found)"
236
237 # Close the Help dialog and cancel the pending hint marker action
238 command_Esc = (vim) ->
239 # Blur active element if it's editable. Other elements
240 # aren't blurred - we don't want to interfere with
241 # the browser too much
242 activeElement = vim.window.document.activeElement
243 if utils.isElementEditable activeElement
244 activeElement.blur()
245
246 #Remove Find input
247 find.removeFind vim.window.document
248
249 # Remove hints
250 hints.removeHints vim.window.document
251
252 # Hide help dialog
253 help.removeHelp vim.window.document
254
255 # Finally enter normal mode
256 vim.enterNormalMode()
257
258 commandGroups =
259 'urls':
260 'o': [ command_o, _('help_command_o') ]
261 'p': [ command_p, _('help_command_p') ]
262 'P': [ command_P, _('help_command_P') ]
263 'y,f': [ command_yf, _('help_command_yf') ]
264 'y,y': [ command_yy, _('help_command_yy') ]
265 'r': [ command_r, _('help_command_r') ]
266 'R': [ command_R, _('help_command_R') ]
267 'a,r': [ command_ar, _('help_command_ar') ]
268 'a,R': [ command_aR, _('help_command_aR') ]
269 'nav':
270 'g,g': [ command_gg , _('help_command_gg') ]
271 'G': [ command_G, _('help_command_G') ]
272 'j|c-e': [ command_j_ce, _('help_command_j_ce') ]
273 'k|c-y': [ command_k_cy, _('help_command_k_cy') ]
274 'h': [ command_h, _('help_command_h') ]
275 'l': [ command_l , _('help_command_l') ]
276 # Can't use c-u/c-d because c-u is widely used for viewing sources
277 'd': [ command_d, _('help_command_d') ]
278 'u': [ command_u, _('help_command_u') ]
279 'c-f': [ command_cf, _('help_command_cf') ]
280 'c-b': [ command_cb, _('help_command_cb') ]
281 'tabs':
282 't': [ command_t, _('help_command_t') ]
283 'J|g,T': [ command_J_gT, _('help_command_J_gT') ]
284 'K|g,t': [ command_K_gt, _('help_command_K_gt') ]
285 'c-J': [ command_cJ, _('help_command_cJ') ]
286 'c-K': [ command_cK, _('help_command_cK') ]
287 "g,H|g,\^": [ command_gH_g0, _('help_command_gH_g0') ]
288 'g,L|g,$': [ command_gL_g$, _('help_command_gL_g$') ]
289 'x': [ command_x, _('help_command_x') ]
290 'X': [ command_X, _('help_command_X') ]
291 'browse':
292 'f': [ command_f, _('help_command_f') ]
293 'F': [ command_F, _('help_command_F') ]
294 'H': [ command_H, _('help_command_H') ]
295 'L': [ command_L, _('help_command_L') ]
296 'misc':
297 # `.` is added to find command mapping to hack around Russian keyboard layout
298 '\.|/': [ command_find, _('help_command_find') ]
299 'n': [ command_n, _('help_command_n') ]
300 'N': [ command_N, _('help_command_N') ]
301 # `>` is added to help command mapping to hack around Russian keyboard layout
302 # See key-utils.coffee for more info
303 '?|>': [ command_help, _('help_command_help') ]
304 'Esc': [ command_Esc, _('help_command_Esc') ]
305
306 # Merge groups and split command pipes into individual commands
307 commands = do (commandGroups) ->
308 newCommands = {}
309 for group, commandsList of commandGroups
310 for keys, command of commandsList
311 for key in keys.split '|'
312 newCommands[key] = command[0]
313
314 return newCommands
315
316 # Extract the help text from the commands preserving groups formation
317 commandsHelp = do (commandGroups) ->
318 helpStrings = {}
319 for group, commandsList of commandGroups
320 helpGroup = {}
321 for keys, command of commandsList
322 helpGroup[keys] = command[1]
323
324 helpStrings[group] = helpGroup
325 return helpStrings
326
327 # Called in hints mode. Will process the char, update and hide/show markers
328 hintCharHandler = (vim, keyStr, charCode) ->
329 if keyStr and charCode > 0
330 # Get char and escape it to avoid problems with String.search
331 key = regexpEscape keyStr
332
333 # First do a pre match - count how many markers will match with the new character entered
334 if vim.markers.reduce ((v, marker) -> v or marker.willMatch key), false
335 for marker in vim.markers
336 marker.matchHintChar key
337
338 if marker.isMatched()
339 vim.cb marker
340 hints.removeHints vim.window.document
341 vim.enterNormalMode()
342 break
343
344 # Called in find mode. Will process charCode, update find, or close the
345 findCharHandler = (vim, keyStr, charCode) ->
346 backwards = false
347
348 toNormalMode = ->
349 find.removeFind vim.window.document
350 vim.enterNormalMode()
351
352 if keyStr and keyStr.match(/.*Return/)
353 return toNormalMode()
354 else if keyStr == 'Backspace'
355 # Delete last available character from the query string
356 if vim.findStr.length > 0
357 vim.findStr = vim.findStr.substr(0, vim.findStr.length - 1)
358 # Leave Find Mode the query string is already empty
359 else
360 return toNormalMode()
361 else if charCode > 0
362 vim.findStr += String.fromCharCode(charCode)
363 else
364 return
365
366 # Update the interface string
367
368 # Clear selection to avoid jumping between matching search results
369 vim.window.getSelection().removeAllRanges()
370
371 # Search only if the query string isn't emply.
372 # Otherwise it will pop up Find dialog
373 if find.find vim.window, vim.findStr, backwards
374 find.setFindStr vim.window.document, vim.findStr
375 else
376 find.setFindStr vim.window.document, "#{ vim.findStr } (Not Found)"
377
378
379 exports.hintCharHandler = hintCharHandler
380 exports.findCharHandler = findCharHandler
381 exports.commands = commands
382 exports.commandsHelp = commandsHelp
Imprint / Impressum