|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this file, |
|
3 * You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 |
|
5 XPCOMUtils.defineLazyModuleGetter(this, "DownloadsCommon", |
|
6 "resource:///modules/DownloadsCommon.jsm"); |
|
7 |
|
8 var gMainPane = { |
|
9 /** |
|
10 * Initialization of this. |
|
11 */ |
|
12 init: function () |
|
13 { |
|
14 // set up the "use current page" label-changing listener |
|
15 this._updateUseCurrentButton(); |
|
16 window.addEventListener("focus", this._updateUseCurrentButton.bind(this), false); |
|
17 |
|
18 this.updateBrowserStartupLastSession(); |
|
19 |
|
20 // Notify observers that the UI is now ready |
|
21 Components.classes["@mozilla.org/observer-service;1"] |
|
22 .getService(Components.interfaces.nsIObserverService) |
|
23 .notifyObservers(window, "main-pane-loaded", null); |
|
24 |
|
25 #ifdef XP_WIN |
|
26 // Functionality for "Show tabs in taskbar" on Windows 7 and up. |
|
27 |
|
28 try { |
|
29 let sysInfo = Cc["@mozilla.org/system-info;1"]. |
|
30 getService(Ci.nsIPropertyBag2); |
|
31 let ver = parseFloat(sysInfo.getProperty("version")); |
|
32 let showTabsInTaskbar = document.getElementById("showTabsInTaskbar"); |
|
33 showTabsInTaskbar.hidden = ver < 6.1; |
|
34 } catch (ex) {} |
|
35 |
|
36 #endif |
|
37 |
|
38 }, |
|
39 |
|
40 // HOME PAGE |
|
41 |
|
42 /* |
|
43 * Preferences: |
|
44 * |
|
45 * browser.startup.homepage |
|
46 * - the user's home page, as a string; if the home page is a set of tabs, |
|
47 * this will be those URLs separated by the pipe character "|" |
|
48 * browser.startup.page |
|
49 * - what page(s) to show when the user starts the application, as an integer: |
|
50 * |
|
51 * 0: a blank page |
|
52 * 1: the home page (as set by the browser.startup.homepage pref) |
|
53 * 2: the last page the user visited (DEPRECATED) |
|
54 * 3: windows and tabs from the last session (a.k.a. session restore) |
|
55 * |
|
56 * The deprecated option is not exposed in UI; however, if the user has it |
|
57 * selected and doesn't change the UI for this preference, the deprecated |
|
58 * option is preserved. |
|
59 */ |
|
60 |
|
61 syncFromHomePref: function () |
|
62 { |
|
63 let homePref = document.getElementById("browser.startup.homepage"); |
|
64 |
|
65 // If the pref is set to about:home, set the value to "" to show the |
|
66 // placeholder text (about:home title). |
|
67 if (homePref.value.toLowerCase() == "about:home") |
|
68 return ""; |
|
69 |
|
70 // If the pref is actually "", show about:blank. The actual home page |
|
71 // loading code treats them the same, and we don't want the placeholder text |
|
72 // to be shown. |
|
73 if (homePref.value == "") |
|
74 return "about:blank"; |
|
75 |
|
76 // Otherwise, show the actual pref value. |
|
77 return undefined; |
|
78 }, |
|
79 |
|
80 syncToHomePref: function (value) |
|
81 { |
|
82 // If the value is "", use about:home. |
|
83 if (value == "") |
|
84 return "about:home"; |
|
85 |
|
86 // Otherwise, use the actual textbox value. |
|
87 return undefined; |
|
88 }, |
|
89 |
|
90 /** |
|
91 * Sets the home page to the current displayed page (or frontmost tab, if the |
|
92 * most recent browser window contains multiple tabs), updating preference |
|
93 * window UI to reflect this. |
|
94 */ |
|
95 setHomePageToCurrent: function () |
|
96 { |
|
97 let homePage = document.getElementById("browser.startup.homepage"); |
|
98 let tabs = this._getTabsForHomePage(); |
|
99 function getTabURI(t) t.linkedBrowser.currentURI.spec; |
|
100 |
|
101 // FIXME Bug 244192: using dangerous "|" joiner! |
|
102 if (tabs.length) |
|
103 homePage.value = tabs.map(getTabURI).join("|"); |
|
104 }, |
|
105 |
|
106 /** |
|
107 * Displays a dialog in which the user can select a bookmark to use as home |
|
108 * page. If the user selects a bookmark, that bookmark's name is displayed in |
|
109 * UI and the bookmark's address is stored to the home page preference. |
|
110 */ |
|
111 setHomePageToBookmark: function () |
|
112 { |
|
113 var rv = { urls: null, names: null }; |
|
114 openDialog("chrome://browser/content/preferences/selectBookmark.xul", |
|
115 "Select Bookmark", "resizable=yes, modal=yes", rv); |
|
116 if (rv.urls && rv.names) { |
|
117 var homePage = document.getElementById("browser.startup.homepage"); |
|
118 |
|
119 // XXX still using dangerous "|" joiner! |
|
120 homePage.value = rv.urls.join("|"); |
|
121 } |
|
122 }, |
|
123 |
|
124 /** |
|
125 * Switches the "Use Current Page" button between its singular and plural |
|
126 * forms. |
|
127 */ |
|
128 _updateUseCurrentButton: function () { |
|
129 let useCurrent = document.getElementById("useCurrent"); |
|
130 |
|
131 |
|
132 let tabs = this._getTabsForHomePage(); |
|
133 |
|
134 if (tabs.length > 1) |
|
135 useCurrent.label = useCurrent.getAttribute("label2"); |
|
136 else |
|
137 useCurrent.label = useCurrent.getAttribute("label1"); |
|
138 |
|
139 // In this case, the button's disabled state is set by preferences.xml. |
|
140 if (document.getElementById |
|
141 ("pref.browser.homepage.disable_button.current_page").locked) |
|
142 return; |
|
143 |
|
144 useCurrent.disabled = !tabs.length |
|
145 }, |
|
146 |
|
147 _getTabsForHomePage: function () |
|
148 { |
|
149 var win; |
|
150 var tabs = []; |
|
151 |
|
152 const Cc = Components.classes, Ci = Components.interfaces; |
|
153 var wm = Cc["@mozilla.org/appshell/window-mediator;1"] |
|
154 .getService(Ci.nsIWindowMediator); |
|
155 win = wm.getMostRecentWindow("navigator:browser"); |
|
156 |
|
157 if (win && win.document.documentElement |
|
158 .getAttribute("windowtype") == "navigator:browser") { |
|
159 // We should only include visible & non-pinned tabs |
|
160 |
|
161 tabs = win.gBrowser.visibleTabs.slice(win.gBrowser._numPinnedTabs); |
|
162 |
|
163 tabs = tabs.filter(this.isAboutPreferences); |
|
164 } |
|
165 |
|
166 return tabs; |
|
167 }, |
|
168 |
|
169 /** |
|
170 * Check to see if a tab is not about:preferences |
|
171 */ |
|
172 isAboutPreferences: function (aElement, aIndex, aArray) |
|
173 { |
|
174 return (aElement.linkedBrowser.currentURI.spec != "about:preferences"); |
|
175 }, |
|
176 |
|
177 /** |
|
178 * Restores the default home page as the user's home page. |
|
179 */ |
|
180 restoreDefaultHomePage: function () |
|
181 { |
|
182 var homePage = document.getElementById("browser.startup.homepage"); |
|
183 homePage.value = homePage.defaultValue; |
|
184 }, |
|
185 |
|
186 // DOWNLOADS |
|
187 |
|
188 /* |
|
189 * Preferences: |
|
190 * |
|
191 * browser.download.useDownloadDir - bool |
|
192 * True - Save files directly to the folder configured via the |
|
193 * browser.download.folderList preference. |
|
194 * False - Always ask the user where to save a file and default to |
|
195 * browser.download.lastDir when displaying a folder picker dialog. |
|
196 * browser.download.dir - local file handle |
|
197 * A local folder the user may have selected for downloaded files to be |
|
198 * saved. Migration of other browser settings may also set this path. |
|
199 * This folder is enabled when folderList equals 2. |
|
200 * browser.download.lastDir - local file handle |
|
201 * May contain the last folder path accessed when the user browsed |
|
202 * via the file save-as dialog. (see contentAreaUtils.js) |
|
203 * browser.download.folderList - int |
|
204 * Indicates the location users wish to save downloaded files too. |
|
205 * It is also used to display special file labels when the default |
|
206 * download location is either the Desktop or the Downloads folder. |
|
207 * Values: |
|
208 * 0 - The desktop is the default download location. |
|
209 * 1 - The system's downloads folder is the default download location. |
|
210 * 2 - The default download location is elsewhere as specified in |
|
211 * browser.download.dir. |
|
212 * browser.download.downloadDir |
|
213 * deprecated. |
|
214 * browser.download.defaultFolder |
|
215 * deprecated. |
|
216 */ |
|
217 |
|
218 /** |
|
219 * Enables/disables the folder field and Browse button based on whether a |
|
220 * default download directory is being used. |
|
221 */ |
|
222 readUseDownloadDir: function () |
|
223 { |
|
224 var downloadFolder = document.getElementById("downloadFolder"); |
|
225 var chooseFolder = document.getElementById("chooseFolder"); |
|
226 var preference = document.getElementById("browser.download.useDownloadDir"); |
|
227 downloadFolder.disabled = !preference.value; |
|
228 chooseFolder.disabled = !preference.value; |
|
229 |
|
230 // don't override the preference's value in UI |
|
231 return undefined; |
|
232 }, |
|
233 |
|
234 /** |
|
235 * Displays a file picker in which the user can choose the location where |
|
236 * downloads are automatically saved, updating preferences and UI in |
|
237 * response to the choice, if one is made. |
|
238 */ |
|
239 chooseFolder: function () |
|
240 { |
|
241 const nsIFilePicker = Components.interfaces.nsIFilePicker; |
|
242 const nsILocalFile = Components.interfaces.nsILocalFile; |
|
243 |
|
244 let bundlePreferences = document.getElementById("bundlePreferences"); |
|
245 let title = bundlePreferences.getString("chooseDownloadFolderTitle"); |
|
246 let folderListPref = document.getElementById("browser.download.folderList"); |
|
247 let currentDirPref = this._indexToFolder(folderListPref.value); // file |
|
248 let defDownloads = this._indexToFolder(1); // file |
|
249 let fp = Components.classes["@mozilla.org/filepicker;1"]. |
|
250 createInstance(nsIFilePicker); |
|
251 let fpCallback = function fpCallback_done(aResult) { |
|
252 if (aResult == nsIFilePicker.returnOK) { |
|
253 let file = fp.file.QueryInterface(nsILocalFile); |
|
254 let downloadDirPref = document.getElementById("browser.download.dir"); |
|
255 |
|
256 downloadDirPref.value = file; |
|
257 folderListPref.value = this._folderToIndex(file); |
|
258 // Note, the real prefs will not be updated yet, so dnld manager's |
|
259 // userDownloadsDirectory may not return the right folder after |
|
260 // this code executes. displayDownloadDirPref will be called on |
|
261 // the assignment above to update the UI. |
|
262 } |
|
263 }.bind(this); |
|
264 |
|
265 fp.init(window, title, nsIFilePicker.modeGetFolder); |
|
266 fp.appendFilters(nsIFilePicker.filterAll); |
|
267 // First try to open what's currently configured |
|
268 if (currentDirPref && currentDirPref.exists()) { |
|
269 fp.displayDirectory = currentDirPref; |
|
270 } // Try the system's download dir |
|
271 else if (defDownloads && defDownloads.exists()) { |
|
272 fp.displayDirectory = defDownloads; |
|
273 } // Fall back to Desktop |
|
274 else { |
|
275 fp.displayDirectory = this._indexToFolder(0); |
|
276 } |
|
277 fp.open(fpCallback); |
|
278 }, |
|
279 |
|
280 /** |
|
281 * Initializes the download folder display settings based on the user's |
|
282 * preferences. |
|
283 */ |
|
284 displayDownloadDirPref: function () |
|
285 { |
|
286 var folderListPref = document.getElementById("browser.download.folderList"); |
|
287 var bundlePreferences = document.getElementById("bundlePreferences"); |
|
288 var downloadFolder = document.getElementById("downloadFolder"); |
|
289 var currentDirPref = document.getElementById("browser.download.dir"); |
|
290 |
|
291 // Used in defining the correct path to the folder icon. |
|
292 var ios = Components.classes["@mozilla.org/network/io-service;1"] |
|
293 .getService(Components.interfaces.nsIIOService); |
|
294 var fph = ios.getProtocolHandler("file") |
|
295 .QueryInterface(Components.interfaces.nsIFileProtocolHandler); |
|
296 var iconUrlSpec; |
|
297 |
|
298 // Display a 'pretty' label or the path in the UI. |
|
299 if (folderListPref.value == 2) { |
|
300 // Custom path selected and is configured |
|
301 downloadFolder.label = this._getDisplayNameOfFile(currentDirPref.value); |
|
302 iconUrlSpec = fph.getURLSpecFromFile(currentDirPref.value); |
|
303 } else if (folderListPref.value == 1) { |
|
304 // 'Downloads' |
|
305 // In 1.5, this pointed to a folder we created called 'My Downloads' |
|
306 // and was available as an option in the 1.5 drop down. On XP this |
|
307 // was in My Documents, on OSX it was in User Docs. In 2.0, we did |
|
308 // away with the drop down option, although the special label was |
|
309 // still supported for the folder if it existed. Because it was |
|
310 // not exposed it was rarely used. |
|
311 // With 3.0, a new desktop folder - 'Downloads' was introduced for |
|
312 // platforms and versions that don't support a default system downloads |
|
313 // folder. See nsDownloadManager for details. |
|
314 downloadFolder.label = bundlePreferences.getString("downloadsFolderName"); |
|
315 iconUrlSpec = fph.getURLSpecFromFile(this._indexToFolder(1)); |
|
316 } else { |
|
317 // 'Desktop' |
|
318 downloadFolder.label = bundlePreferences.getString("desktopFolderName"); |
|
319 iconUrlSpec = fph.getURLSpecFromFile(desk); |
|
320 } |
|
321 downloadFolder.image = "moz-icon://" + iconUrlSpec + "?size=16"; |
|
322 |
|
323 // don't override the preference's value in UI |
|
324 return undefined; |
|
325 }, |
|
326 |
|
327 /** |
|
328 * Returns the textual path of a folder in readable form. |
|
329 */ |
|
330 _getDisplayNameOfFile: function (aFolder) |
|
331 { |
|
332 // TODO: would like to add support for 'Downloads on Macintosh HD' |
|
333 // for OS X users. |
|
334 return aFolder ? aFolder.path : ""; |
|
335 }, |
|
336 |
|
337 /** |
|
338 * Returns the Downloads folder. If aFolder is "Desktop", then the Downloads |
|
339 * folder returned is the desktop folder; otherwise, it is a folder whose name |
|
340 * indicates that it is a download folder and whose path is as determined by |
|
341 * the XPCOM directory service via the download manager's attribute |
|
342 * defaultDownloadsDirectory. |
|
343 * |
|
344 * @throws if aFolder is not "Desktop" or "Downloads" |
|
345 */ |
|
346 _getDownloadsFolder: function (aFolder) |
|
347 { |
|
348 switch (aFolder) { |
|
349 case "Desktop": |
|
350 var fileLoc = Components.classes["@mozilla.org/file/directory_service;1"] |
|
351 .getService(Components.interfaces.nsIProperties); |
|
352 return fileLoc.get("Desk", Components.interfaces.nsILocalFile); |
|
353 break; |
|
354 case "Downloads": |
|
355 var dnldMgr = Components.classes["@mozilla.org/download-manager;1"] |
|
356 .getService(Components.interfaces.nsIDownloadManager); |
|
357 return dnldMgr.defaultDownloadsDirectory; |
|
358 break; |
|
359 } |
|
360 throw "ASSERTION FAILED: folder type should be 'Desktop' or 'Downloads'"; |
|
361 }, |
|
362 |
|
363 /** |
|
364 * Determines the type of the given folder. |
|
365 * |
|
366 * @param aFolder |
|
367 * the folder whose type is to be determined |
|
368 * @returns integer |
|
369 * 0 if aFolder is the Desktop or is unspecified, |
|
370 * 1 if aFolder is the Downloads folder, |
|
371 * 2 otherwise |
|
372 */ |
|
373 _folderToIndex: function (aFolder) |
|
374 { |
|
375 if (!aFolder || aFolder.equals(this._getDownloadsFolder("Desktop"))) |
|
376 return 0; |
|
377 else if (aFolder.equals(this._getDownloadsFolder("Downloads"))) |
|
378 return 1; |
|
379 return 2; |
|
380 }, |
|
381 |
|
382 /** |
|
383 * Converts an integer into the corresponding folder. |
|
384 * |
|
385 * @param aIndex |
|
386 * an integer |
|
387 * @returns the Desktop folder if aIndex == 0, |
|
388 * the Downloads folder if aIndex == 1, |
|
389 * the folder stored in browser.download.dir |
|
390 */ |
|
391 _indexToFolder: function (aIndex) |
|
392 { |
|
393 switch (aIndex) { |
|
394 case 0: |
|
395 return this._getDownloadsFolder("Desktop"); |
|
396 case 1: |
|
397 return this._getDownloadsFolder("Downloads"); |
|
398 } |
|
399 var currentDirPref = document.getElementById("browser.download.dir"); |
|
400 return currentDirPref.value; |
|
401 }, |
|
402 |
|
403 /** |
|
404 * Returns the value for the browser.download.folderList preference. |
|
405 */ |
|
406 getFolderListPref: function () |
|
407 { |
|
408 var folderListPref = document.getElementById("browser.download.folderList"); |
|
409 switch (folderListPref.value) { |
|
410 case 0: // Desktop |
|
411 case 1: // Downloads |
|
412 return folderListPref.value; |
|
413 break; |
|
414 case 2: // Custom |
|
415 var currentDirPref = document.getElementById("browser.download.dir"); |
|
416 if (currentDirPref.value) { |
|
417 // Resolve to a known location if possible. We are writing out |
|
418 // to prefs on this call, so now would be a good time to do it. |
|
419 return this._folderToIndex(currentDirPref.value); |
|
420 } |
|
421 return 0; |
|
422 break; |
|
423 } |
|
424 }, |
|
425 |
|
426 /** |
|
427 * Hide/show the "Show my windows and tabs from last time" option based |
|
428 * on the value of the browser.privatebrowsing.autostart pref. |
|
429 */ |
|
430 updateBrowserStartupLastSession: function() |
|
431 { |
|
432 let pbAutoStartPref = document.getElementById("browser.privatebrowsing.autostart"); |
|
433 let startupPref = document.getElementById("browser.startup.page"); |
|
434 let menu = document.getElementById("browserStartupPage"); |
|
435 let option = document.getElementById("browserStartupLastSession"); |
|
436 if (pbAutoStartPref.value) { |
|
437 option.setAttribute("disabled", "true"); |
|
438 if (option.selected) { |
|
439 menu.selectedItem = document.getElementById("browserStartupHomePage"); |
|
440 } |
|
441 } else { |
|
442 option.removeAttribute("disabled"); |
|
443 startupPref.updateElements(); // select the correct index in the startup menulist |
|
444 } |
|
445 }, |
|
446 |
|
447 // TABS |
|
448 |
|
449 /* |
|
450 * Preferences: |
|
451 * |
|
452 * browser.link.open_newwindow - int |
|
453 * Determines where links targeting new windows should open. |
|
454 * Values: |
|
455 * 1 - Open in the current window or tab. |
|
456 * 2 - Open in a new window. |
|
457 * 3 - Open in a new tab in the most recent window. |
|
458 * browser.tabs.loadInBackground - bool |
|
459 * True - Whether browser should switch to a new tab opened from a link. |
|
460 * browser.tabs.warnOnClose - bool |
|
461 * True - If when closing a window with multiple tabs the user is warned and |
|
462 * allowed to cancel the action, false to just close the window. |
|
463 * browser.tabs.warnOnOpen - bool |
|
464 * True - Whether the user should be warned when trying to open a lot of |
|
465 * tabs at once (e.g. a large folder of bookmarks), allowing to |
|
466 * cancel the action. |
|
467 * browser.taskbar.previews.enable - bool |
|
468 * True - Tabs are to be shown in Windows 7 taskbar. |
|
469 * False - Only the window is to be shown in Windows 7 taskbar. |
|
470 */ |
|
471 |
|
472 /** |
|
473 * Determines where a link which opens a new window will open. |
|
474 * |
|
475 * @returns |true| if such links should be opened in new tabs |
|
476 */ |
|
477 readLinkTarget: function() { |
|
478 var openNewWindow = document.getElementById("browser.link.open_newwindow"); |
|
479 return openNewWindow.value != 2; |
|
480 }, |
|
481 |
|
482 /** |
|
483 * Determines where a link which opens a new window will open. |
|
484 * |
|
485 * @returns 2 if such links should be opened in new windows, |
|
486 * 3 if such links should be opened in new tabs |
|
487 */ |
|
488 writeLinkTarget: function() { |
|
489 var linkTargeting = document.getElementById("linkTargeting"); |
|
490 return linkTargeting.checked ? 3 : 2; |
|
491 } |
|
492 }; |