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 gBrowser.selectedTab = chromeWindow.gBrowser.addTab()
30 if urlbar = chromeWindow.document.getElementById('urlbar')
33 # Copy current URL to the clipboard
35 vim.markers = injectHints vim.window.document
36 if vim.markers.length > 0
37 # This callback will be called with the selected marker as argument
39 if url = marker.element.href
40 utils.writeToClipboard vim.window, url
44 # Copy current URL to the clipboard
46 utils.writeToClipboard vim.window, vim.window.location.toString()
48 # Reload the page, possibly from cache
50 vim.window.location.reload(false)
52 # Reload the page from the server
54 vim.window.location.reload(true)
56 # Scroll to the top of the page
58 vim.window.scrollTo(0, 0)
60 # Scroll to the bottom of the page
62 if document = vim.window.document
63 # Workaround the pages where body isn't the scrollable element.
64 # In this case we try to scroll 100k pixels
65 vim.window.scrollTo(0, Math.max(document.body.scrollHeight, 100000))
68 command_j_ce = (vim) ->
69 utils.smoothScroll vim.window, 0, (getPref 'scroll_step'), getPref 'scroll_time'
72 command_k_cy = (vim) ->
73 utils.smoothScroll vim.window, 0, -(getPref 'scroll_step'), getPref 'scroll_time'
77 utils.smoothScroll vim.window, -(getPref 'scroll_step'), 0, getPref 'scroll_time'
81 utils.smoothScroll vim.window, (getPref 'scroll_step'), 0, getPref 'scroll_time'
83 # Scroll down half a page
85 utils.smoothScroll vim.window, 0, vim.window.innerHeight / 2, getPref 'scroll_time'
87 # Scroll up half a page
89 utils.smoothScroll vim.window, 0, -vim.window.innerHeight / 2, getPref 'scroll_time'
91 # Scroll down full a page
93 vim.window.scrollByPages(1)
95 # Scroll up full a page
97 vim.window.scrollByPages(-1)
99 # Activate previous tab
100 command_J_gT = (vim) ->
101 if rootWindow = utils.getRootWindow vim.window
102 rootWindow.gBrowser.tabContainer.advanceSelectedTab(-1, true);
105 command_K_gt = (vim) ->
106 if rootWindow = utils.getRootWindow vim.window
107 rootWindow.gBrowser.tabContainer.advanceSelectedTab(1, true);
109 # Go to the first tab
110 command_gH_g0 = (vim) ->
111 if rootWindow = utils.getRootWindow vim.window
112 rootWindow.gBrowser.tabContainer.selectedIndex = 0;
115 command_gL_g$ = (vim) ->
116 if rootWindow = utils.getRootWindow vim.window
117 itemCount = rootWindow.gBrowser.tabContainer.itemCount;
118 rootWindow.gBrowser.tabContainer.selectedIndex = itemCount - 1;
122 vim.window.history.back()
124 # Go forward in history
126 vim.window.history.forward()
130 if rootWindow = utils.getRootWindow vim.window
131 rootWindow.gBrowser.removeCurrentTab()
133 # Restore last closed tab
135 if rootWindow = utils.getRootWindow vim.window
136 ss = utils.getSessionStore()
137 if ss and ss.getClosedTabCount(rootWindow) > 0
138 ss.undoCloseTab rootWindow, 0
140 # Follow links with hint markers
142 if document = vim.window.document
143 vim.markers = injectHints document
144 if vim.markers.length > 0
145 # This callback will be called with the selected marker as argument
147 marker.element.focus()
148 utils.simulateClick marker.element
152 # Follow links in a new Tab with hint markers
154 vim.markers = injectHints vim.window.document
155 if vim.markers.length > 0
156 # This callback will be called with the selected marker as argument
158 marker.element.focus()
159 utils.simulateClick marker.element, { metaKey: true, ctrlKey: true }
163 # Move current tab to the left
164 command_cJ = (vim) ->
165 if gBrowser = utils.getRootWindow(vim.window)?.gBrowser
166 if tab = gBrowser.selectedTab
167 index = gBrowser.tabContainer.selectedIndex
168 total = gBrowser.tabContainer.itemCount
170 # `total` is added to deal with negative offset
171 gBrowser.moveTabTo tab, (total + index - 1) % total
173 # Move current tab to the right
174 command_cK = (vim) ->
175 if gBrowser = utils.getRootWindow(vim.window)?.gBrowser
176 if tab = gBrowser.selectedTab
177 index = gBrowser.tabContainer.selectedIndex
178 total = gBrowser.tabContainer.itemCount
180 gBrowser.moveTabTo tab, (index + 1) % total
182 # Display the Help Dialog
183 command_help = (vim) ->
184 showHelp vim.window.document, commandsHelp
186 # Close the Help dialog and cancel the pending hint marker action
187 command_Esc = (vim) ->
188 # Blur active element if it's editable. Other elements
189 # aren't blurred - we don't want to interfere with
190 # the browser too much
191 activeElement = vim.window.document.activeElement
192 if utils.isElementEditable activeElement
196 removeHints vim.window.document
198 hideHelp vim.window.document
199 # Finally enter normal mode
200 vim.enterNormalMode()
204 'p': [ command_p, _('help_command_p') ]
205 'P': [ command_P, _('help_command_P') ]
206 'y,f': [ command_yf, _('help_command_yf') ]
207 'y,y': [ command_yy, _('help_command_yy') ]
208 'r': [ command_r, _('help_command_r') ]
209 'R': [ command_R, _('help_command_R') ]
211 'g,g': [ command_gg , _('help_command_gg') ]
212 'G': [ command_G, _('help_command_G') ]
213 'j|c-e': [ command_j_ce, _('help_command_j_ce') ]
214 'k|c-y': [ command_k_cy, _('help_command_k_cy') ]
215 'h': [ command_h, _('help_command_h') ]
216 'l': [ command_l , _('help_command_l') ]
217 'd': [ command_d, _('help_command_d') ]
218 # Can't use c-u because it's generally used for viewing sources
219 'u': [ command_u, _('help_command_u') ]
220 # Can't use c-f because it's generally used for viewing sources
221 #'c-f': [ command_cf, _('help_command_cf') ]
222 #'c-b': [ command_cb, _('help_command_cb') ]
224 't': [ command_t, _('help_command_t') ]
225 'J|g,T': [ command_J_gT, _('help_command_J_gT') ]
226 'K|g,t': [ command_K_gt, _('help_command_K_gt') ]
227 'c-J': [ command_cJ, _('help_command_cJ') ]
228 'c-K': [ command_cK, _('help_command_cK') ]
229 'g,H|g,0': [ command_gH_g0, _('help_command_gH_g0') ]
230 'g,L|g,$': [ command_gL_g$, _('help_command_gL_g$') ]
231 'x': [ command_x, _('help_command_x') ]
232 'X': [ command_X, _('help_command_X') ]
234 'f': [ command_f, _('help_command_f') ]
235 'F': [ command_F, _('help_command_F') ]
236 'H': [ command_H, _('help_command_H') ]
237 'L': [ command_L, _('help_command_L') ]
239 # `>` is added to help command mapping to hack around russian keyboard layout
240 # See key-utils.coffee for more info
241 '?|>': [ command_help, _('help_command_help') ]
242 'Esc': [ command_Esc, _('help_command_Esc') ]
244 # Merge groups and split command pipes into individual commands
245 commands = do (commandGroups) ->
247 for group, commandsList of commandGroups
248 for keys, command of commandsList
249 for key in keys.split '|'
250 newCommands[key] = command[0]
254 # Extract the help text from the commands preserving groups formation
255 commandsHelp = do (commandGroups) ->
257 for group, commandsList of commandGroups
259 for keys, command of commandsList
260 key = keys.replace(/,/g, '').replace('|', ', ')
261 helpGroup[key] = command[1]
263 help[group] = helpGroup
266 # Called in hints mode. Will process the char, update and hide/show markers
267 hintCharHandler = (vim, char) ->
268 # First count how many markers will match with the new character entered
269 preMatch = vim.markers.reduce ((v, marker) -> v + marker.willMatch char), 0
271 # If prematch is greater than 0, then proceed with matching, else ignore the new char
273 for marker in vim.markers
274 marker.matchHintChar char
276 if marker.isMatched()
278 removeHints vim.window.document
279 vim.enterNormalMode()
282 exports.hintCharHandler = hintCharHandler
283 exports.commands = commands
284 exports.commandsHelp = commandsHelp