1 { classes: Cc, interfaces: Ci, utils: Cu } = Components
3 utils = require 'utils'
4 { getPref } = require 'prefs'
15 # Navigate to the address that is currently stored in the system clipboard
17 vim.window.location.assign utils.readFromClipboard(vim.window)
19 # Open new tab and navigate to the address that is currently stored in the system clipboard
21 if chromeWindow = utils.getRootWindow vim.window
22 if gBrowser = chromeWindow.gBrowser
23 gBrowser.selectedTab = gBrowser.addTab utils.readFromClipboard(vim.window)
25 # Open new tab and focus the address bar
27 if chromeWindow = utils.getRootWindow vim.window
28 if gBrowser = chromeWindow.gBrowser
29 # Get the default url for the new tab
30 newtab_url = Services.prefs.getCharPref 'browser.newtab.url'
31 gBrowser.addTab newtab_url
32 # Focus the address bar
33 chromeWindow.focusAndSelectUrlBar()
35 # Copy current URL to the clipboard
37 vim.markers = injectHints vim.window.document
38 if vim.markers.length > 0
39 # This callback will be called with the selected marker as argument
41 if url = marker.element.href
42 utils.writeToClipboard vim.window, url
46 # Copy current URL to the clipboard
48 utils.writeToClipboard vim.window, vim.window.location.toString()
50 # Reload the page, possibly from cache
52 vim.window.location.reload(false)
54 # Reload the page from the server
56 vim.window.location.reload(true)
58 # Scroll to the top of the page
60 vim.window.scrollTo(0, 0)
62 # Scroll to the bottom of the page
64 if document = vim.window.document
65 # Workaround the pages where body isn't the scrollable element.
66 # In this case we try to scroll 100k pixels
67 vim.window.scrollTo(0, Math.max(document.body.scrollHeight, 100000))
70 command_j_ce = (vim) ->
71 utils.smoothScroll vim.window, 0, (getPref 'scroll_step'), getPref 'scroll_time'
74 command_k_cy = (vim) ->
75 utils.smoothScroll vim.window, 0, -(getPref 'scroll_step'), getPref 'scroll_time'
79 utils.smoothScroll vim.window, -(getPref 'scroll_step'), 0, getPref 'scroll_time'
83 utils.smoothScroll vim.window, (getPref 'scroll_step'), 0, getPref 'scroll_time'
85 # Scroll down half a page
87 utils.smoothScroll vim.window, 0, vim.window.innerHeight / 2, getPref 'scroll_time'
89 # Scroll up half a page
91 utils.smoothScroll vim.window, 0, -vim.window.innerHeight / 2, getPref 'scroll_time'
93 # Scroll down full a page
95 vim.window.scrollByPages(1)
97 # Scroll up full a page
99 vim.window.scrollByPages(-1)
101 # Activate previous tab
102 command_J_gT = (vim) ->
103 if rootWindow = utils.getRootWindow vim.window
104 rootWindow.gBrowser.tabContainer.advanceSelectedTab(-1, true);
107 command_K_gt = (vim) ->
108 if rootWindow = utils.getRootWindow vim.window
109 rootWindow.gBrowser.tabContainer.advanceSelectedTab(1, true);
111 # Go to the first tab
112 command_gH_g0 = (vim) ->
113 if rootWindow = utils.getRootWindow vim.window
114 rootWindow.gBrowser.tabContainer.selectedIndex = 0;
117 command_gL_g$ = (vim) ->
118 if rootWindow = utils.getRootWindow vim.window
119 itemCount = rootWindow.gBrowser.tabContainer.itemCount;
120 rootWindow.gBrowser.tabContainer.selectedIndex = itemCount - 1;
124 vim.window.history.back()
126 # Go forward in history
128 vim.window.history.forward()
132 if rootWindow = utils.getRootWindow vim.window
133 rootWindow.gBrowser.removeCurrentTab()
135 # Restore last closed tab
137 if rootWindow = utils.getRootWindow vim.window
138 ss = utils.getSessionStore()
139 if ss and ss.getClosedTabCount(rootWindow) > 0
140 ss.undoCloseTab rootWindow, 0
142 # Follow links with hint markers
144 if document = vim.window.document
145 vim.markers = injectHints document
146 if vim.markers.length > 0
147 # This callback will be called with the selected marker as argument
149 marker.element.focus()
150 utils.simulateClick marker.element
154 # Follow links in a new Tab with hint markers
156 vim.markers = injectHints vim.window.document
157 if vim.markers.length > 0
158 # This callback will be called with the selected marker as argument
160 marker.element.focus()
161 utils.simulateClick marker.element, { metaKey: true, ctrlKey: true }
165 # Move current tab to the left
166 command_cJ = (vim) ->
167 if gBrowser = utils.getRootWindow(vim.window)?.gBrowser
168 if tab = gBrowser.selectedTab
169 index = gBrowser.tabContainer.selectedIndex
170 total = gBrowser.tabContainer.itemCount
172 # `total` is added to deal with negative offset
173 gBrowser.moveTabTo tab, (total + index - 1) % total
175 # Move current tab to the right
176 command_cK = (vim) ->
177 if gBrowser = utils.getRootWindow(vim.window)?.gBrowser
178 if tab = gBrowser.selectedTab
179 index = gBrowser.tabContainer.selectedIndex
180 total = gBrowser.tabContainer.itemCount
182 gBrowser.moveTabTo tab, (index + 1) % total
184 # Display the Help Dialog
185 command_help = (vim) ->
186 showHelp vim.window.document, commandsHelp
188 # Close the Help dialog and cancel the pending hint marker action
189 command_Esc = (vim) ->
190 # Blur active element if it's editable. Other elements
191 # aren't blurred - we don't want to interfere with
192 # the browser too much
193 activeElement = vim.window.document.activeElement
194 if utils.isElementEditable activeElement
198 removeHints vim.window.document
200 hideHelp vim.window.document
201 # Finally enter normal mode
202 vim.enterNormalMode()
206 'p': [ command_p, _('help_command_p') ]
207 'P': [ command_P, _('help_command_P') ]
208 'y,f': [ command_yf, _('help_command_yf') ]
209 'y,y': [ command_yy, _('help_command_yy') ]
210 'r': [ command_r, _('help_command_r') ]
211 'R': [ command_R, _('help_command_R') ]
213 'g,g': [ command_gg , _('help_command_gg') ]
214 'G': [ command_G, _('help_command_G') ]
215 'j|c-e': [ command_j_ce, _('help_command_j_ce') ]
216 'k|c-y': [ command_k_cy, _('help_command_k_cy') ]
217 'h': [ command_h, _('help_command_h') ]
218 'l': [ command_l , _('help_command_l') ]
220 # Can't use c-u/c-d because it's generally used for viewing sources
221 'd': [ command_d, _('help_command_d') ]
222 'u': [ command_u, _('help_command_u') ]
224 # Can't use c-f because it's generally used for viewing sources
225 #'c-f': [ command_cf, _('help_command_cf') ]
226 #'c-b': [ command_cb, _('help_command_cb') ]
228 't': [ command_t, _('help_command_t') ]
229 'J|g,T': [ command_J_gT, _('help_command_J_gT') ]
230 'K|g,t': [ command_K_gt, _('help_command_K_gt') ]
231 'c-J': [ command_cJ, _('help_command_cJ') ]
232 'c-K': [ command_cK, _('help_command_cK') ]
233 'g,H|g,0': [ command_gH_g0, _('help_command_gH_g0') ]
234 'g,L|g,$': [ command_gL_g$, _('help_command_gL_g$') ]
235 'x': [ command_x, _('help_command_x') ]
236 'X': [ command_X, _('help_command_X') ]
238 'f': [ command_f, _('help_command_f') ]
239 'F': [ command_F, _('help_command_F') ]
240 'H': [ command_H, _('help_command_H') ]
241 'L': [ command_L, _('help_command_L') ]
243 # `>` is added to help command mapping to hack around russian keyboard layout
244 # See key-utils.coffee for more info
245 '?|>': [ command_help, _('help_command_help') ]
246 'Esc': [ command_Esc, _('help_command_Esc') ]
248 # Merge groups and split command pipes into individual commands
249 commands = do (commandGroups) ->
251 for group, commandsList of commandGroups
252 for keys, command of commandsList
253 for key in keys.split '|'
254 newCommands[key] = command[0]
258 # Extract the help text from the commands preserving groups formation
259 commandsHelp = do (commandGroups) ->
261 for group, commandsList of commandGroups
263 for keys, command of commandsList
264 key = keys.replace(/,/g, '').replace('|', ', ')
265 helpGroup[key] = command[1]
267 help[group] = helpGroup
270 # Called in hints mode. Will process the char, update and hide/show markers
271 hintCharHandler = (vim, char) ->
272 # First count how many markers will match with the new character entered
273 preMatch = vim.markers.reduce ((v, marker) -> v + marker.willMatch char), 0
275 # If prematch is greater than 0, then proceed with matching, else ignore the new char
277 for marker in vim.markers
278 marker.matchHintChar char
280 if marker.isMatched()
282 removeHints vim.window.document
283 vim.enterNormalMode()
286 exports.hintCharHandler = hintCharHandler
287 exports.commands = commands
288 exports.commandsHelp = commandsHelp