Wed, 31 Dec 2014 13:27:57 +0100
Ignore runtime configuration files generated during quality assurance.
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/. */
5 XPCOMUtils.defineLazyModuleGetter(this, "DownloadsCommon",
6 "resource:///modules/DownloadsCommon.jsm");
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);
18 this.updateBrowserStartupLastSession();
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);
25 #ifdef XP_WIN
26 // Functionality for "Show tabs in taskbar" on Windows 7 and up.
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) {}
36 #endif
38 },
40 // HOME PAGE
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 */
61 syncFromHomePref: function ()
62 {
63 let homePref = document.getElementById("browser.startup.homepage");
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 "";
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";
76 // Otherwise, show the actual pref value.
77 return undefined;
78 },
80 syncToHomePref: function (value)
81 {
82 // If the value is "", use about:home.
83 if (value == "")
84 return "about:home";
86 // Otherwise, use the actual textbox value.
87 return undefined;
88 },
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;
101 // FIXME Bug 244192: using dangerous "|" joiner!
102 if (tabs.length)
103 homePage.value = tabs.map(getTabURI).join("|");
104 },
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");
119 // XXX still using dangerous "|" joiner!
120 homePage.value = rv.urls.join("|");
121 }
122 },
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");
132 let tabs = this._getTabsForHomePage();
134 if (tabs.length > 1)
135 useCurrent.label = useCurrent.getAttribute("label2");
136 else
137 useCurrent.label = useCurrent.getAttribute("label1");
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;
144 useCurrent.disabled = !tabs.length
145 },
147 _getTabsForHomePage: function ()
148 {
149 var win;
150 var tabs = [];
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");
157 if (win && win.document.documentElement
158 .getAttribute("windowtype") == "navigator:browser") {
159 // We should only include visible & non-pinned tabs
161 tabs = win.gBrowser.visibleTabs.slice(win.gBrowser._numPinnedTabs);
163 tabs = tabs.filter(this.isAboutPreferences);
164 }
166 return tabs;
167 },
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 },
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 },
186 // DOWNLOADS
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 */
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;
230 // don't override the preference's value in UI
231 return undefined;
232 },
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;
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");
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);
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 },
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");
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;
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";
323 // don't override the preference's value in UI
324 return undefined;
325 },
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 },
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 },
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 },
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 },
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 },
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 },
447 // TABS
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 */
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 },
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 };