nsBrowserGlue.js
Go to the documentation of this file.
1 /*
2 # ***** BEGIN LICENSE BLOCK *****
3 # Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 #
5 # The contents of this file are subject to the Mozilla Public License Version
6 # 1.1 (the "License"); you may not use this file except in compliance with
7 # the License. You may obtain a copy of the License at
8 # http://www.mozilla.org/MPL/
9 #
10 # Software distributed under the License is distributed on an "AS IS" basis,
11 # WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 # for the specific language governing rights and limitations under the
13 # License.
14 #
15 # The Original Code is the Browser Search Service.
16 #
17 # The Initial Developer of the Original Code is
18 # Giorgio Maone
19 # Portions created by the Initial Developer are Copyright (C) 2005
20 # the Initial Developer. All Rights Reserved.
21 #
22 # Contributor(s):
23 # Giorgio Maone <g.maone@informaction.com>
24 # Seth Spitzer <sspitzer@mozilla.com>
25 # Asaf Romano <mano@mozilla.com>
26 # Marco Bonardo <mak77@bonardo.net>
27 # Dietrich Ayala <dietrich@mozilla.com>
28 # Ehsan Akhgari <ehsan.akhgari@gmail.com>
29 # Nils Maier <maierman@web.de>
30 #
31 # Alternatively, the contents of this file may be used under the terms of
32 # either the GNU General Public License Version 2 or later (the "GPL"), or
33 # the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
34 # in which case the provisions of the GPL or the LGPL are applicable instead
35 # of those above. If you wish to allow use of your version of this file only
36 # under the terms of either the GPL or the LGPL, and not to allow others to
37 # use your version of this file under the terms of the MPL, indicate your
38 # decision by deleting the provisions above and replace them with the notice
39 # and other provisions required by the GPL or the LGPL. If you do not delete
40 # the provisions above, a recipient may use your version of this file under
41 # the terms of any one of the MPL, the GPL or the LGPL.
42 #
43 # ***** END LICENSE BLOCK *****
44 */
45 
46 const Ci = Components.interfaces;
47 const Cc = Components.classes;
48 const Cr = Components.results;
49 const Cu = Components.utils;
50 
51 const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
52 
53 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
54 // XXX Songbird: distribution file moved from its old location
55 // Cu.import("resource:///modules/distribution.js");
56 Cu.import("resource://app/jsmodules/Distribution.jsm");
57 
58 const PREF_EM_NEW_ADDONS_LIST = "extensions.newAddons";
59 const PREF_PLUGINS_NOTIFYUSER = "plugins.update.notifyUser";
60 const PREF_PLUGINS_UPDATEURL = "plugins.update.url";
61 
62 // Check to see if bookmarks need backing up once per
63 // day on 1 hour idle.
65 
66 // Backup bookmarks once every 24 hours.
67 const BOOKMARKS_ARCHIVE_INTERVAL = 86400 * 1000;
68 
69 // Factory object
71  _instance: null,
72  createInstance: function (outer, iid)
73  {
74  if (outer != null)
75  throw Components.results.NS_ERROR_NO_AGGREGATION;
76  return this._instance == null ?
77  this._instance = new BrowserGlue() : this._instance;
78  }
79 };
80 
81 // Constructor
82 
83 function BrowserGlue() {
84 
85  this.__defineGetter__("_prefs", function() {
86  delete this._prefs;
87  return this._prefs = Cc["@mozilla.org/preferences-service;1"].
88  getService(Ci.nsIPrefBranch);
89  });
90 
91  this.__defineGetter__("_bundleService", function() {
92  delete this._bundleService;
93  return this._bundleService = Cc["@mozilla.org/intl/stringbundle;1"].
94  getService(Ci.nsIStringBundleService);
95  });
96 
97  this.__defineGetter__("_idleService", function() {
98  delete this._idleService;
99  return this._idleService = Cc["@mozilla.org/widget/idleservice;1"].
100  getService(Ci.nsIIdleService);
101  });
102 
103  this.__defineGetter__("_observerService", function() {
104  delete this._observerService;
105  return this._observerService = Cc['@mozilla.org/observer-service;1'].
106  getService(Ci.nsIObserverService);
107  });
108 
109  this.__defineGetter__("_distributionCustomizer", function() {
110  delete this._distributionCustomizer;
111  // XXX Songbird: allow not having a distribution customizer
112  return this._distributionCustomizer = ("function" == typeof(DistributionCustomizer) ? new DistributionCustomizer() : null);
113  });
114 
115  this._init();
116 }
117 
118 #ifndef XP_MACOSX
119 # OS X has the concept of zero-window sessions and therefore ignores the
120 # browser-lastwindow-close-* topics.
121 #define OBSERVE_LASTWINDOW_CLOSE_TOPICS 1
122 #endif
123 
124 BrowserGlue.prototype = {
125 
126  _saveSession: false,
127 
128  _setPrefToSaveSession: function()
129  {
130  this._prefs.setBoolPref("browser.sessionstore.resume_session_once", true);
131 
132  // This method can be called via [NSApplication terminate:] on Mac, which
133  // ends up causing prefs not to be flushed to disk, so we need to do that
134  // explicitly here. See bug 497652.
135  this._prefs.QueryInterface(Ci.nsIPrefService).savePrefFile(null);
136  },
137 
138  // nsIObserver implementation
139  observe: function(subject, topic, data)
140  {
141  switch(topic) {
142  case "xpcom-shutdown":
143  this._dispose();
144  break;
145  case "prefservice:after-app-defaults":
146  this._onAppDefaults();
147  break;
148  case "final-ui-startup":
149  this._onProfileStartup();
150  break;
151  case "sessionstore-windows-restored":
152  this._onBrowserStartup();
153  break;
154  case "browser:purge-session-history":
155  // reset the console service's error buffer
156  const cs = Cc["@mozilla.org/consoleservice;1"].
157  getService(Ci.nsIConsoleService);
158  cs.logStringMessage(null); // clear the console (in case it's open)
159  cs.reset();
160  break;
161  case "quit-application-requested":
162  this._onQuitRequest(subject, data);
163  break;
164  case "quit-application-granted":
165  if (this._saveSession) {
166  this._setPrefToSaveSession();
167  }
168  // Everything that uses Places during shutdown should be here, since
169  // on quit-application Places database connection will be closed
170  // and history synchronization could fail.
171  this._onProfileShutdown();
172  break;
173 #ifdef OBSERVE_LASTWINDOW_CLOSE_TOPICS
174  case "browser-lastwindow-close-requested":
175  // The application is not actually quitting, but the last full browser
176  // window is about to be closed.
177  this._onQuitRequest(subject, "lastwindow");
178  break;
179  case "browser-lastwindow-close-granted":
180  if (this._saveSession)
181  this._setPrefToSaveSession();
182  break;
183 #endif
184  case "session-save":
185  this._setPrefToSaveSession();
186  subject.QueryInterface(Ci.nsISupportsPRBool);
187  subject.data = true;
188  break;
189  case "places-init-complete":
190  this._initPlaces();
191  this._observerService.removeObserver(this, "places-init-complete");
192  // no longer needed, since history was initialized completely.
193  this._observerService.removeObserver(this, "places-database-locked");
194 
195  // Now apply distribution customized bookmarks.
196  // This should always run after Places initialization.
197  this._distributionCustomizer.applyBookmarks();
198  break;
199  case "places-database-locked":
200  this._isPlacesDatabaseLocked = true;
201  // stop observing, so further attempts to load history service
202  // do not show the prompt.
203  this._observerService.removeObserver(this, "places-database-locked");
204  break;
205  case "idle":
206  if (this._idleService.idleTime > BOOKMARKS_ARCHIVE_IDLE_TIME * 1000) {
207  // Back up bookmarks.
208  this._archiveBookmarks();
209  }
210  break;
211  case "distribution-customization-complete":
212  this._observerService
213  .removeObserver(this, "distribution-customization-complete");
214  // Customization has finished, we don't need the customizer anymore.
215  delete this._distributionCustomizer;
216  break;
217  }
218  },
219 
220  // initialization (called on application startup)
221  _init: function()
222  {
223  // observer registration
224  const osvr = this._observerService;
225  osvr.addObserver(this, "xpcom-shutdown", false);
226  osvr.addObserver(this, "prefservice:after-app-defaults", false);
227  osvr.addObserver(this, "final-ui-startup", false);
228  osvr.addObserver(this, "sessionstore-windows-restored", false);
229  osvr.addObserver(this, "browser:purge-session-history", false);
230  osvr.addObserver(this, "quit-application-requested", false);
231  osvr.addObserver(this, "quit-application-granted", false);
232 #ifdef OBSERVE_LASTWINDOW_CLOSE_TOPICS
233  osvr.addObserver(this, "browser-lastwindow-close-requested", false);
234  osvr.addObserver(this, "browser-lastwindow-close-granted", false);
235 #endif
236  osvr.addObserver(this, "session-save", false);
237  osvr.addObserver(this, "places-init-complete", false);
238  osvr.addObserver(this, "places-database-locked", false);
239  osvr.addObserver(this, "distribution-customization-complete", false);
240  },
241 
242  // cleanup (called on application shutdown)
243  _dispose: function()
244  {
245  // observer removal
246  const osvr = this._observerService;
247  osvr.removeObserver(this, "xpcom-shutdown");
248  osvr.removeObserver(this, "prefservice:after-app-defaults");
249  osvr.removeObserver(this, "final-ui-startup");
250  osvr.removeObserver(this, "sessionstore-windows-restored");
251  osvr.removeObserver(this, "browser:purge-session-history");
252  osvr.removeObserver(this, "quit-application-requested");
253 #ifdef OBSERVE_LASTWINDOW_CLOSE_TOPICS
254  osvr.removeObserver(this, "browser-lastwindow-close-requested");
255  osvr.removeObserver(this, "browser-lastwindow-close-granted");
256 #endif
257  osvr.removeObserver(this, "quit-application-granted");
258  osvr.removeObserver(this, "session-save");
259  },
260 
261  _onAppDefaults: function()
262  {
263  // apply distribution customizations (prefs)
264  // other customizations are applied in _onProfileStartup()
265  // XXX Songbird: allow not having a distribution customizer
266  if (this._distributionCustomizer)
267  this._distributionCustomizer.applyPrefDefaults();
268  },
269 
270  // profile startup handler (contains profile initialization routines)
271  _onProfileStartup: function()
272  {
273  this.Sanitizer.onStartup();
274  // check if we're in safe mode
275  var app = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULAppInfo).
276  QueryInterface(Ci.nsIXULRuntime);
277  if (app.inSafeMode) {
278  var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
279  getService(Ci.nsIWindowWatcher);
280  ww.openWindow(null, "chrome://browser/content/safeMode.xul",
281  "_blank", "chrome,centerscreen,modal,resizable=no", null);
282  }
283 
284  // apply distribution customizations
285  // prefs are applied in _onAppDefaults()
286  // XXX Songbird: allow not having a distribution customizer
287  if (this._distributionCustomizer)
288  this._distributionCustomizer.applyCustomizations();
289 
290  // handle any UI migration
291  this._migrateUI();
292 
293  this._observerService.notifyObservers(null, "browser-ui-startup-complete", "");
294  },
295 
296  // profile shutdown handler (contains profile cleanup routines)
297  _onProfileShutdown: function()
298  {
299 #ifdef WINCE
300  // If there's a pending update, clear cache to free up disk space.
301  try {
302  let um = Cc["@mozilla.org/updates/update-manager;1"].
303  getService(Ci.nsIUpdateManager);
304  if (um.activeUpdate && um.activeUpdate.state == "pending") {
305  let cacheService = Cc["@mozilla.org/network/cache-service;1"].
306  getService(Ci.nsICacheService);
307  cacheService.evictEntries(Ci.nsICache.STORE_ANYWHERE);
308  }
309  } catch (e) { }
310 #endif
311  this._shutdownPlaces();
312  this._idleService.removeIdleObserver(this, BOOKMARKS_ARCHIVE_IDLE_TIME);
313  this.Sanitizer.onShutdown();
314  },
315 
316  // Browser startup complete. All initial windows have opened.
317  _onBrowserStartup: function()
318  {
319  // Show about:rights notification, if needed.
320  if (this._shouldShowRights())
321  this._showRightsNotification();
322 
323  // If new add-ons were installed during startup open the add-ons manager.
324  if (this._prefs.prefHasUserValue(PREF_EM_NEW_ADDONS_LIST)) {
325  var args = Cc["@mozilla.org/supports-array;1"].
326  createInstance(Ci.nsISupportsArray);
327  var str = Cc["@mozilla.org/supports-string;1"].
328  createInstance(Ci.nsISupportsString);
329  str.data = "";
330  args.AppendElement(str);
331  var str = Cc["@mozilla.org/supports-string;1"].
332  createInstance(Ci.nsISupportsString);
333  str.data = this._prefs.getCharPref(PREF_EM_NEW_ADDONS_LIST);
334  args.AppendElement(str);
335  const EMURL = "chrome://mozapps/content/extensions/extensions.xul";
336  const EMFEATURES = "chrome,menubar,extra-chrome,toolbar,dialog=no,resizable";
337  var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
338  getService(Ci.nsIWindowWatcher);
339  ww.openWindow(null, EMURL, "_blank", EMFEATURES, args);
340  this._prefs.clearUserPref(PREF_EM_NEW_ADDONS_LIST);
341  }
342 
343  // Load the "more info" page for a locked places.sqlite
344  // This property is set earlier in the startup process:
345  // nsPlacesDBFlush loads after profile-after-change and initializes
346  // the history service, which sends out places-database-locked
347  // which sets this property.
348  if (this._isPlacesDatabaseLocked) {
349  this._showPlacesLockedNotificationBox();
350  }
351 
352  // If there are plugins installed that are outdated, and the user hasn't
353  // been warned about them yet, open the plugins update page.
354  if (this._prefs.getBoolPref(PREF_PLUGINS_NOTIFYUSER))
355  this._showPluginUpdatePage();
356  },
357 
358  _onQuitRequest: function(aCancelQuit, aQuitType)
359  {
360  // If user has already dismissed quit request, then do nothing
361  if ((aCancelQuit instanceof Ci.nsISupportsPRBool) && aCancelQuit.data)
362  return;
363 
364  var wm = Cc["@mozilla.org/appshell/window-mediator;1"].
365  getService(Ci.nsIWindowMediator);
366 
367  var windowcount = 0;
368  var pagecount = 0;
369  var browserEnum = wm.getEnumerator("navigator:browser");
370  while (browserEnum.hasMoreElements()) {
371  windowcount++;
372 
373  var browser = browserEnum.getNext();
374  var tabbrowser = browser.document.getElementById("content");
375  if (tabbrowser)
376  pagecount += tabbrowser.browsers.length;
377  }
378 
379  this._saveSession = false;
380  if (pagecount < 2)
381  return;
382 
383  if (aQuitType != "restart")
384  aQuitType = "quit";
385 
386  var showPrompt = true;
387  try {
388  // browser.warnOnQuit is a hidden global boolean to override all quit prompts
389  // browser.warnOnRestart specifically covers app-initiated restarts where we restart the app
390  // browser.tabs.warnOnClose is the global "warn when closing multiple tabs" pref
391 
392  var sessionWillBeSaved = this._prefs.getIntPref("browser.startup.page") == 3 ||
393  this._prefs.getBoolPref("browser.sessionstore.resume_session_once");
394  if (sessionWillBeSaved || !this._prefs.getBoolPref("browser.warnOnQuit"))
395  showPrompt = false;
396  else if (aQuitType == "restart")
397  showPrompt = this._prefs.getBoolPref("browser.warnOnRestart");
398  else
399  showPrompt = this._prefs.getBoolPref("browser.tabs.warnOnClose");
400  } catch (ex) {}
401 
402  // Never show a prompt inside the private browsing mode
403  // XXX Songbird: allow not having private browsing support
404  var inPrivateBrowsing = false;
405  if ("@mozilla.org/privatebrowsing;1" in Cc) {
406  inPrivateBrowsing = Cc["@mozilla.org/privatebrowsing;1"].
407  getService(Ci.nsIPrivateBrowsingService).
408  privateBrowsingEnabled;
409  }
410  if (!showPrompt || inPrivateBrowsing)
411  return false;
412 
413  var quitBundle = this._bundleService.createBundle("chrome://browser/locale/quitDialog.properties");
414  var brandBundle = this._bundleService.createBundle("chrome://branding/locale/brand.properties");
415 
416  var appName = brandBundle.GetStringFromName("brandShortName");
417  var quitDialogTitle = quitBundle.formatStringFromName(aQuitType + "DialogTitle",
418  [appName], 1);
419 
420  var message;
421  if (aQuitType == "restart")
422  message = quitBundle.formatStringFromName("messageRestart",
423  [appName], 1);
424  else if (windowcount == 1)
425  message = quitBundle.formatStringFromName("messageNoWindows",
426  [appName], 1);
427  else
428  message = quitBundle.formatStringFromName("message",
429  [appName], 1);
430 
431  var promptService = Cc["@mozilla.org/embedcomp/prompt-service;1"].
432  getService(Ci.nsIPromptService);
433 
434  var flags = promptService.BUTTON_TITLE_IS_STRING * promptService.BUTTON_POS_0 +
435  promptService.BUTTON_TITLE_IS_STRING * promptService.BUTTON_POS_1 +
436  promptService.BUTTON_POS_0_DEFAULT;
437 
438  var neverAsk = {value:false};
439  var button0Title, button2Title;
440  var button1Title = quitBundle.GetStringFromName("cancelTitle");
441  var neverAskText = quitBundle.GetStringFromName("neverAsk");
442 
443  if (aQuitType == "restart")
444  button0Title = quitBundle.GetStringFromName("restartTitle");
445  else {
446  flags += promptService.BUTTON_TITLE_IS_STRING * promptService.BUTTON_POS_2;
447  button0Title = quitBundle.GetStringFromName("saveTitle");
448  button2Title = quitBundle.GetStringFromName("quitTitle");
449  }
450 
451  var mostRecentBrowserWindow = wm.getMostRecentWindow("navigator:browser");
452  var buttonChoice =
453  promptService.confirmEx(mostRecentBrowserWindow, quitDialogTitle, message,
454  flags, button0Title, button1Title, button2Title,
455  neverAskText, neverAsk);
456 
457  switch (buttonChoice) {
458  case 2: // Quit
459  if (neverAsk.value)
460  this._prefs.setBoolPref("browser.tabs.warnOnClose", false);
461  break;
462  case 1: // Cancel
463  aCancelQuit.QueryInterface(Ci.nsISupportsPRBool);
464  aCancelQuit.data = true;
465  break;
466  case 0: // Save & Quit
467  this._saveSession = true;
468  if (neverAsk.value) {
469  if (aQuitType == "restart")
470  this._prefs.setBoolPref("browser.warnOnRestart", false);
471  else {
472  // always save state when shutting down
473  this._prefs.setIntPref("browser.startup.page", 3);
474  }
475  }
476  break;
477  }
478  },
479 
480  /*
481  * _shouldShowRights - Determines if the user should be shown the
482  * about:rights notification. The notification should *not* be shown if
483  * we've already shown the current version, or if the override pref says to
484  * never show it. The notification *should* be shown if it's never been seen
485  * before, if a newer version is available, or if the override pref says to
486  * always show it.
487  */
488  _shouldShowRights : function () {
489  // Look for an unconditional override pref. If set, do what it says.
490  // (true --> never show, false --> always show)
491  try {
492  return !this._prefs.getBoolPref("browser.rights.override");
493  } catch (e) { }
494  // Ditto, for the legacy EULA pref.
495  try {
496  return !this._prefs.getBoolPref("browser.EULA.override");
497  } catch (e) { }
498 
499 #ifndef OFFICIAL_BUILD
500  // Non-official builds shouldn't shouldn't show the notification.
501  return false;
502 #endif
503 
504  // Look to see if the user has seen the current version or not.
505  var currentVersion = this._prefs.getIntPref("browser.rights.version");
506  try {
507  return !this._prefs.getBoolPref("browser.rights." + currentVersion + ".shown");
508  } catch (e) { }
509 
510  // Legacy: If the user accepted a EULA, we won't annoy them with the
511  // equivalent about:rights page until the version changes.
512  try {
513  return !this._prefs.getBoolPref("browser.EULA." + currentVersion + ".accepted");
514  } catch (e) { }
515 
516  // We haven't shown the notification before, so do so now.
517  return true;
518  },
519 
520  _showRightsNotification : function () {
521  // Stick the notification onto the selected tab of the active browser window.
522  var win = this.getMostRecentBrowserWindow();
523  var browser = win.gBrowser; // for closure in notification bar callback
524  var notifyBox = browser.getNotificationBox();
525 
526  var brandBundle = this._bundleService.createBundle("chrome://branding/locale/brand.properties");
527  var rightsBundle = this._bundleService.createBundle("chrome://global/locale/aboutRights.properties");
528 
529  var buttonLabel = rightsBundle.GetStringFromName("buttonLabel");
530  var buttonAccessKey = rightsBundle.GetStringFromName("buttonAccessKey");
531  var productName = brandBundle.GetStringFromName("brandFullName");
532  var notifyRightsText = rightsBundle.formatStringFromName("notifyRightsText", [productName], 1);
533 
534  var buttons = [
535  {
536  label: buttonLabel,
537  accessKey: buttonAccessKey,
538  popup: null,
539  callback: function(aNotificationBar, aButton) {
540  browser.selectedTab = browser.addTab("about:rights");
541  }
542  }
543  ];
544 
545  // Set pref to indicate we've shown the notification.
546  var currentVersion = this._prefs.getIntPref("browser.rights.version");
547  this._prefs.setBoolPref("browser.rights." + currentVersion + ".shown", true);
548 
549  var box = notifyBox.appendNotification(notifyRightsText, "about-rights", null, notifyBox.PRIORITY_INFO_LOW, buttons);
550  box.persistence = 3; // arbitrary number, just so bar sticks around for a bit
551  },
552 
553  _showPluginUpdatePage : function () {
554  this._prefs.setBoolPref(PREF_PLUGINS_NOTIFYUSER, false);
555 
556  var formatter = Cc["@mozilla.org/toolkit/URLFormatterService;1"].
557  getService(Ci.nsIURLFormatter);
558  var updateUrl = formatter.formatURLPref(PREF_PLUGINS_UPDATEURL);
559 
560  var win = this.getMostRecentBrowserWindow();
561  var browser = win.gBrowser;
562  browser.selectedTab = browser.addTab(updateUrl);
563  },
564 
565  // returns the (cached) Sanitizer constructor
566  get Sanitizer()
567  {
568  if(typeof(Sanitizer) != "function") { // we should dynamically load the script
569  Cc["@mozilla.org/moz/jssubscript-loader;1"].
570  getService(Ci.mozIJSSubScriptLoader).
571  loadSubScript("chrome://browser/content/sanitize.js", null);
572  }
573  return Sanitizer;
574  },
575 
596  _initPlaces: function bg__initPlaces() {
597  // XXX Songbird: Songbird does not use Places
598  return;
599 
600  // We must instantiate the history service since it will tell us if we
601  // need to import or restore bookmarks due to first-run, corruption or
602  // forced migration (due to a major schema change).
603  var histsvc = Cc["@mozilla.org/browser/nav-history-service;1"].
604  getService(Ci.nsINavHistoryService);
605 
606  // If the database is corrupt or has been newly created we should
607  // import bookmarks.
608  var databaseStatus = histsvc.databaseStatus;
609  var importBookmarks = databaseStatus == histsvc.DATABASE_STATUS_CREATE ||
610  databaseStatus == histsvc.DATABASE_STATUS_CORRUPT;
611 
612  if (databaseStatus == histsvc.DATABASE_STATUS_CREATE) {
613  // If the database has just been created, but we already have any
614  // bookmark, this is not the initial import. This can happen after a
615  // migration from a different browser since migrators run before us.
616  // In such a case we should not import, unless some pref has been set.
617  var bmsvc = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
618  getService(Ci.nsINavBookmarksService);
619  if (bmsvc.getIdForItemAt(bmsvc.bookmarksMenuFolder, 0) != -1 ||
620  bmsvc.getIdForItemAt(bmsvc.toolbarFolder, 0) != -1)
621  importBookmarks = false;
622  }
623 
624  // Check if user or an extension has required to import bookmarks.html
625  var importBookmarksHTML = false;
626  try {
627  importBookmarksHTML =
628  this._prefs.getBoolPref("browser.places.importBookmarksHTML");
629  if (importBookmarksHTML)
630  importBookmarks = true;
631  } catch(ex) {}
632 
633  // Check if Safe Mode or the user has required to restore bookmarks from
634  // default profile's bookmarks.html
635  var restoreDefaultBookmarks = false;
636  try {
637  restoreDefaultBookmarks =
638  this._prefs.getBoolPref("browser.bookmarks.restore_default_bookmarks");
639  if (restoreDefaultBookmarks) {
640  // Ensure that we already have a bookmarks backup for today
641  this._archiveBookmarks();
642  importBookmarks = true;
643  }
644  } catch(ex) {}
645 
646  // If the user did not require to restore default bookmarks, or import
647  // from bookmarks.html, we will try to restore from JSON
648  if (importBookmarks && !restoreDefaultBookmarks && !importBookmarksHTML) {
649  // get latest JSON backup
650  Cu.import("resource://gre/modules/utils.js");
651  var bookmarksBackupFile = PlacesUtils.getMostRecentBackup();
652  if (bookmarksBackupFile && bookmarksBackupFile.leafName.match("\.json$")) {
653  // restore from JSON backup
654  PlacesUtils.restoreBookmarksFromJSONFile(bookmarksBackupFile);
655  importBookmarks = false;
656  }
657  else {
658  // We have created a new database but we don't have any backup available
659  importBookmarks = true;
660  var dirService = Cc["@mozilla.org/file/directory_service;1"].
661  getService(Ci.nsIProperties);
662  var bookmarksHTMLFile = dirService.get("BMarks", Ci.nsILocalFile);
663  if (bookmarksHTMLFile.exists()) {
664  // If bookmarks.html is available in current profile import it...
665  importBookmarksHTML = true;
666  }
667  else {
668  // ...otherwise we will restore defaults
669  restoreDefaultBookmarks = true;
670  }
671  }
672  }
673 
674  if (!importBookmarks) {
675  // Call it here for Fx3 profiles created before the Places folder
676  // has been added, otherwise it's called during import.
677  this.ensurePlacesDefaultQueriesInitialized();
678  }
679  else {
680  // ensurePlacesDefaultQueriesInitialized() is called by import.
681  // Don't try to recreate smart bookmarks if autoExportHTML is true or
682  // smart bookmarks are disabled.
683  var autoExportHTML = false;
684  try {
685  autoExportHTML = this._prefs.getBoolPref("browser.bookmarks.autoExportHTML");
686  } catch(ex) {}
687  var smartBookmarksVersion = 0;
688  try {
689  smartBookmarksVersion = this._prefs.getIntPref("browser.places.smartBookmarksVersion");
690  } catch(ex) {}
691  if (!autoExportHTML && smartBookmarksVersion != -1)
692  this._prefs.setIntPref("browser.places.smartBookmarksVersion", 0);
693 
694  // Get bookmarks.html file location
695  var dirService = Cc["@mozilla.org/file/directory_service;1"].
696  getService(Ci.nsIProperties);
697 
698  var bookmarksFile = null;
699  if (restoreDefaultBookmarks) {
700  // User wants to restore bookmarks.html file from default profile folder
701  bookmarksFile = dirService.get("profDef", Ci.nsILocalFile);
702  bookmarksFile.append("bookmarks.html");
703  }
704  else
705  bookmarksFile = dirService.get("BMarks", Ci.nsILocalFile);
706 
707  if (bookmarksFile.exists()) {
708  // import the file
709  try {
710  var importer = Cc["@mozilla.org/browser/places/import-export-service;1"].
711  getService(Ci.nsIPlacesImportExportService);
712  importer.importHTMLFromFile(bookmarksFile, true /* overwrite existing */);
713  } catch (err) {
714  // Report the error, but ignore it.
715  Cu.reportError("Bookmarks.html file could be corrupt. " + err);
716  }
717  }
718  else
719  Cu.reportError("Unable to find bookmarks.html file.");
720 
721  // Reset preferences, so we won't try to import again at next run
722  if (importBookmarksHTML)
723  this._prefs.setBoolPref("browser.places.importBookmarksHTML", false);
724  if (restoreDefaultBookmarks)
725  this._prefs.setBoolPref("browser.bookmarks.restore_default_bookmarks",
726  false);
727  }
728 
729  // Initialize bookmark archiving on idle.
730  // Once a day, either on idle or shutdown, bookmarks are backed up.
731  this._idleService.addIdleObserver(this, BOOKMARKS_ARCHIVE_IDLE_TIME);
732  },
733 
742  _shutdownPlaces: function bg__shutdownPlaces() {
743  // Backup and archive Places bookmarks.
744  this._archiveBookmarks();
745 
746  // Backup bookmarks to bookmarks.html to support apps that depend
747  // on the legacy format.
748  var autoExportHTML = false;
749  try {
750  autoExportHTML = this._prefs.getBoolPref("browser.bookmarks.autoExportHTML");
751  } catch(ex) {
752  Components.utils.reportError(ex);
753  }
754 
755  if (autoExportHTML) {
756  Cc["@mozilla.org/browser/places/import-export-service;1"].
757  getService(Ci.nsIPlacesImportExportService).
758  backupBookmarksFile();
759  }
760  },
761 
765  _archiveBookmarks: function nsBrowserGlue__archiveBookmarks() {
766  Cu.import("resource://gre/modules/utils.js");
767 
768  var lastBackup = PlacesUtils.getMostRecentBackup();
769 
770  // Backup bookmarks if there aren't any backups or
771  // they haven't been backed up in the last 24 hrs.
772  if (!lastBackup ||
773  Date.now() - lastBackup.lastModifiedTime > BOOKMARKS_ARCHIVE_INTERVAL) {
774  var maxBackups = 5;
775  try {
776  maxBackups = this._prefs.getIntPref("browser.bookmarks.max_backups");
777  } catch(ex) {}
778 
779  PlacesUtils.archiveBookmarksFile(maxBackups, false /* don't force */);
780  }
781  },
782 
786  _showPlacesLockedNotificationBox: function nsBrowserGlue__showPlacesLockedNotificationBox() {
787  var brandBundle = this._bundleService.createBundle("chrome://branding/locale/brand.properties");
788  var applicationName = brandBundle.GetStringFromName("brandShortName");
789  var placesBundle = this._bundleService.createBundle("chrome://browser/locale/places/places.properties");
790  var title = placesBundle.GetStringFromName("lockPrompt.title");
791  var text = placesBundle.formatStringFromName("lockPrompt.text", [applicationName], 1);
792  var buttonText = placesBundle.GetStringFromName("lockPromptInfoButton.label");
793  var accessKey = placesBundle.GetStringFromName("lockPromptInfoButton.accessKey");
794 
795  var helpTopic = "places-locked";
796  var url = Cc["@mozilla.org/toolkit/URLFormatterService;1"].
797  getService(Components.interfaces.nsIURLFormatter).
798  formatURLPref("app.support.baseURL");
799  url += helpTopic;
800 
801  var browser = this.getMostRecentBrowserWindow().gBrowser;
802 
803  var buttons = [
804  {
805  label: buttonText,
806  accessKey: accessKey,
807  popup: null,
808  callback: function(aNotificationBar, aButton) {
809  browser.selectedTab = browser.addTab(url);
810  }
811  }
812  ];
813 
814  var notifyBox = browser.getNotificationBox();
815  var box = notifyBox.appendNotification(text, title, null,
816  notifyBox.PRIORITY_CRITICAL_MEDIUM,
817  buttons);
818  box.persistence = -1; // Until user closes it
819  },
820 
821  _migrateUI: function bg__migrateUI() {
822  var migration = 0;
823  try {
824  migration = this._prefs.getIntPref("browser.migration.version");
825  } catch(ex) {}
826 
827  if (migration == 0) {
828  // this code should always migrate pre-FF3 profiles to the current UI state
829 
830  // grab the localstore.rdf and make changes needed for new UI
831  this._rdf = Cc["@mozilla.org/rdf/rdf-service;1"].getService(Ci.nsIRDFService);
832  this._dataSource = this._rdf.GetDataSource("rdf:local-store");
833  this._dirty = false;
834 
835  let currentsetResource = this._rdf.GetResource("currentset");
836  let toolbars = ["nav-bar", "toolbar-menubar", "PersonalToolbar"];
837  for (let i = 0; i < toolbars.length; i++) {
838  let toolbar = this._rdf.GetResource("chrome://browser/content/browser.xul#" + toolbars[i]);
839  let currentset = this._getPersist(toolbar, currentsetResource);
840  if (!currentset) {
841  // toolbar isn't customized
842  if (i == 0)
843  // new button is in the defaultset, nothing to migrate
844  break;
845  continue;
846  }
847  if (/(?:^|,)unified-back-forward-button(?:$|,)/.test(currentset))
848  // new button is already there, nothing to migrate
849  break;
850  if (/(?:^|,)back-button(?:$|,)/.test(currentset)) {
851  let newset = currentset.replace(/(^|,)back-button($|,)/,
852  "$1unified-back-forward-button,back-button$2")
853  this._setPersist(toolbar, currentsetResource, newset);
854  // done migrating
855  break;
856  }
857  }
858 
859  // force the RDF to be saved
860  if (this._dirty)
861  this._dataSource.QueryInterface(Ci.nsIRDFRemoteDataSource).Flush();
862 
863  // free up the RDF service
864  this._rdf = null;
865  this._dataSource = null;
866 
867  // update the migration version
868  this._prefs.setIntPref("browser.migration.version", 1);
869  }
870  },
871 
872  _getPersist: function bg__getPersist(aSource, aProperty) {
873  var target = this._dataSource.GetTarget(aSource, aProperty, true);
874  if (target instanceof Ci.nsIRDFLiteral)
875  return target.Value;
876  return null;
877  },
878 
879  _setPersist: function bg__setPersist(aSource, aProperty, aTarget) {
880  this._dirty = true;
881  try {
882  var oldTarget = this._dataSource.GetTarget(aSource, aProperty, true);
883  if (oldTarget) {
884  if (aTarget)
885  this._dataSource.Change(aSource, aProperty, oldTarget, this._rdf.GetLiteral(aTarget));
886  else
887  this._dataSource.Unassert(aSource, aProperty, oldTarget);
888  }
889  else {
890  this._dataSource.Assert(aSource, aProperty, this._rdf.GetLiteral(aTarget), true);
891  }
892  }
893  catch(ex) {}
894  },
895 
896  // ------------------------------
897  // public nsIBrowserGlue members
898  // ------------------------------
899 
900  sanitize: function(aParentWindow)
901  {
902  this.Sanitizer.sanitize(aParentWindow);
903  },
904 
905  ensurePlacesDefaultQueriesInitialized: function() {
906  // This is actual version of the smart bookmarks, must be increased every
907  // time smart bookmarks change.
908  // When adding a new smart bookmark below, its newInVersion property must
909  // be set to the version it has been added in, we will compare its value
910  // to users' smartBookmarksVersion and add new smart bookmarks without
911  // recreating old deleted ones.
912  const SMART_BOOKMARKS_VERSION = 2;
913  const SMART_BOOKMARKS_ANNO = "Places/SmartBookmark";
914  const SMART_BOOKMARKS_PREF = "browser.places.smartBookmarksVersion";
915 
916  // XXX should this be a pref? see bug #399268
917  const MAX_RESULTS = 10;
918 
919  // get current smart bookmarks version
920  // By default, if the pref is not set up, we must create Smart Bookmarks
921  var smartBookmarksCurrentVersion = 0;
922  try {
923  smartBookmarksCurrentVersion = this._prefs.getIntPref(SMART_BOOKMARKS_PREF);
924  } catch(ex) { /* no version set, new profile */ }
925 
926  // bail out if we don't have to create or update Smart Bookmarks
927  if (smartBookmarksCurrentVersion == -1 ||
928  smartBookmarksCurrentVersion >= SMART_BOOKMARKS_VERSION)
929  return;
930 
931  var bmsvc = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
932  getService(Ci.nsINavBookmarksService);
933  var annosvc = Cc["@mozilla.org/browser/annotation-service;1"].
934  getService(Ci.nsIAnnotationService);
935 
936  var callback = {
937  _uri: function(aSpec) {
938  return Cc["@mozilla.org/network/io-service;1"].
939  getService(Ci.nsIIOService).
940  newURI(aSpec, null, null);
941  },
942 
943  runBatched: function() {
944  var smartBookmarks = [];
945  var bookmarksMenuIndex = 0;
946  var bookmarksToolbarIndex = 0;
947 
948  var placesBundle = Cc["@mozilla.org/intl/stringbundle;1"].
949  getService(Ci.nsIStringBundleService).
950  createBundle("chrome://browser/locale/places/places.properties");
951 
952  // MOST VISITED
953  var smart = {queryId: "MostVisited", // don't change this
954  itemId: null,
955  title: placesBundle.GetStringFromName("mostVisitedTitle"),
956  uri: this._uri("place:redirectsMode=" +
957  Ci.nsINavHistoryQueryOptions.REDIRECTS_MODE_TARGET +
958  "&sort=" +
959  Ci.nsINavHistoryQueryOptions.SORT_BY_VISITCOUNT_DESCENDING +
960  "&maxResults=" + MAX_RESULTS),
961  parent: bmsvc.toolbarFolder,
962  position: bookmarksToolbarIndex++,
963  newInVersion: 1 };
964  smartBookmarks.push(smart);
965 
966  // RECENTLY BOOKMARKED
967  smart = {queryId: "RecentlyBookmarked", // don't change this
968  itemId: null,
969  title: placesBundle.GetStringFromName("recentlyBookmarkedTitle"),
970  uri: this._uri("place:folder=BOOKMARKS_MENU" +
971  "&folder=UNFILED_BOOKMARKS" +
972  "&folder=TOOLBAR" +
973  "&queryType=" +
974  Ci.nsINavHistoryQueryOptions.QUERY_TYPE_BOOKMARKS +
975  "&sort=" +
976  Ci.nsINavHistoryQueryOptions.SORT_BY_DATEADDED_DESCENDING +
977  "&excludeItemIfParentHasAnnotation=livemark%2FfeedURI" +
978  "&maxResults=" + MAX_RESULTS +
979  "&excludeQueries=1"),
980  parent: bmsvc.bookmarksMenuFolder,
981  position: bookmarksMenuIndex++,
982  newInVersion: 1 };
983  smartBookmarks.push(smart);
984 
985  // RECENT TAGS
986  smart = {queryId: "RecentTags", // don't change this
987  itemId: null,
988  title: placesBundle.GetStringFromName("recentTagsTitle"),
989  uri: this._uri("place:"+
990  "type=" +
991  Ci.nsINavHistoryQueryOptions.RESULTS_AS_TAG_QUERY +
992  "&sort=" +
993  Ci.nsINavHistoryQueryOptions.SORT_BY_LASTMODIFIED_DESCENDING +
994  "&maxResults=" + MAX_RESULTS),
995  parent: bmsvc.bookmarksMenuFolder,
996  position: bookmarksMenuIndex++,
997  newInVersion: 1 };
998  smartBookmarks.push(smart);
999 
1000  var smartBookmarkItemIds = annosvc.getItemsWithAnnotation(SMART_BOOKMARKS_ANNO, {});
1001  // Set current itemId, parent and position if Smart Bookmark exists,
1002  // we will use these informations to create the new version at the same
1003  // position.
1004  for each(var itemId in smartBookmarkItemIds) {
1005  var queryId = annosvc.getItemAnnotation(itemId, SMART_BOOKMARKS_ANNO);
1006  for (var i = 0; i < smartBookmarks.length; i++){
1007  if (smartBookmarks[i].queryId == queryId) {
1008  smartBookmarks[i].found = true;
1009  smartBookmarks[i].itemId = itemId;
1010  smartBookmarks[i].parent = bmsvc.getFolderIdForItem(itemId);
1011  smartBookmarks[i].position = bmsvc.getItemIndex(itemId);
1012  // remove current item, since it will be replaced
1013  bmsvc.removeItem(itemId);
1014  break;
1015  }
1016  // We don't remove old Smart Bookmarks because user could still
1017  // find them useful, or could have personalized them.
1018  // Instead we remove the Smart Bookmark annotation.
1019  if (i == smartBookmarks.length - 1)
1020  annosvc.removeItemAnnotation(itemId, SMART_BOOKMARKS_ANNO);
1021  }
1022  }
1023 
1024  // create smart bookmarks
1025  for each(var smartBookmark in smartBookmarks) {
1026  // We update or create only changed or new smart bookmarks.
1027  // Also we respect user choices, so we won't try to create a smart
1028  // bookmark if it has been removed.
1029  if (smartBookmarksCurrentVersion > 0 &&
1030  smartBookmark.newInVersion <= smartBookmarksCurrentVersion &&
1031  !smartBookmark.found)
1032  continue;
1033 
1034  smartBookmark.itemId = bmsvc.insertBookmark(smartBookmark.parent,
1035  smartBookmark.uri,
1036  smartBookmark.position,
1037  smartBookmark.title);
1038  annosvc.setItemAnnotation(smartBookmark.itemId,
1039  SMART_BOOKMARKS_ANNO, smartBookmark.queryId,
1040  0, annosvc.EXPIRE_NEVER);
1041  }
1042 
1043  // If we are creating all Smart Bookmarks from ground up, add a
1044  // separator below them in the bookmarks menu.
1045  if (smartBookmarksCurrentVersion == 0 &&
1046  smartBookmarkItemIds.length == 0)
1047  bmsvc.insertSeparator(bmsvc.bookmarksMenuFolder, bookmarksMenuIndex);
1048  }
1049  };
1050 
1051  try {
1052  bmsvc.runInBatchMode(callback, null);
1053  }
1054  catch(ex) {
1055  Components.utils.reportError(ex);
1056  }
1057  finally {
1059  this._prefs.QueryInterface(Ci.nsIPrefService).savePrefFile(null);
1060  }
1061  },
1062 
1063 #ifndef XP_WIN
1064 #define BROKEN_WM_Z_ORDER
1065 #endif
1066 
1067  // this returns the most recent non-popup browser window
1068  getMostRecentBrowserWindow : function ()
1069  {
1070  var wm = Cc["@mozilla.org/appshell/window-mediator;1"].
1071  getService(Components.interfaces.nsIWindowMediator);
1072 
1073 #ifdef BROKEN_WM_Z_ORDER
1074  var win = wm.getMostRecentWindow("navigator:browser", true);
1075 
1076  // if we're lucky, this isn't a popup, and we can just return this
1077  if (win && win.document.documentElement.getAttribute("chromehidden")) {
1078  win = null;
1079  var windowList = wm.getEnumerator("navigator:browser", true);
1080  // this is oldest to newest, so this gets a bit ugly
1081  while (windowList.hasMoreElements()) {
1082  var nextWin = windowList.getNext();
1083  if (!nextWin.document.documentElement.getAttribute("chromehidden"))
1084  win = nextWin;
1085  }
1086  }
1087 #else
1088  var windowList = wm.getZOrderDOMWindowEnumerator("navigator:browser", true);
1089  if (!windowList.hasMoreElements())
1090  return null;
1091 
1092  var win = windowList.getNext();
1093  while (win.document.documentElement.getAttribute("chromehidden")) {
1094  if (!windowList.hasMoreElements())
1095  return null;
1096 
1097  win = windowList.getNext();
1098  }
1099 #endif
1100 
1101  return win;
1102  },
1103 
1104 
1105  // for XPCOM
1106  classDescription: "Firefox Browser Glue Service",
1107  classID: Components.ID("{eab9012e-5f74-4cbc-b2b5-a590235513cc}"),
1108  contractID: "@mozilla.org/browser/browserglue;1",
1109 
1110  QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
1111  Ci.nsISupportsWeakReference,
1112  Ci.nsIBrowserGlue]),
1113 
1114  // redefine the default factory for XPCOMUtils
1115  _xpcom_factory: BrowserGlueServiceFactory,
1116 
1117  // get this contractID registered for certain categories via XPCOMUtils
1119  // make BrowserGlue a startup observer
1120  { category: "app-startup", service: true },
1121  { /* when component registration *didn't* run (i.e. second run), we need
1122  * to get invoked via this topic to be able to apply the default prefs
1123  * before the chrome registry initializes
1124  */
1125  category: "prefservice:after-app-defaults", service: true }
1126  ]
1127 }
1128 
1129 function GeolocationPrompt() {}
1130 
1131 GeolocationPrompt.prototype = {
1132  classDescription: "Geolocation Prompting Component",
1133  classID: Components.ID("{C6E8C44D-9F39-4AF7-BCC0-76E38A8310F5}"),
1134  contractID: "@mozilla.org/geolocation/prompt;1",
1135 
1136  QueryInterface: XPCOMUtils.generateQI([Ci.nsIGeolocationPrompt]),
1137 
1138  prompt: function(request) {
1139  var pm = Cc["@mozilla.org/permissionmanager;1"].getService(Ci.nsIPermissionManager);
1140 
1141  var result = pm.testExactPermission(request.requestingURI, "geo");
1142 
1143  if (result == Ci.nsIPermissionManager.ALLOW_ACTION) {
1144  request.allow();
1145  return;
1146  }
1147 
1148  if (result == Ci.nsIPermissionManager.DENY_ACTION) {
1149  request.cancel();
1150  return;
1151  }
1152 
1153  function setPagePermission(uri, allow) {
1154  if (allow == true)
1155  pm.add(uri, "geo", Ci.nsIPermissionManager.ALLOW_ACTION);
1156  else
1157  pm.add(uri, "geo", Ci.nsIPermissionManager.DENY_ACTION);
1158  }
1159 
1160  function getChromeWindow(aWindow) {
1161  var chromeWin = aWindow
1162  .QueryInterface(Ci.nsIInterfaceRequestor)
1163  .getInterface(Ci.nsIWebNavigation)
1164  .QueryInterface(Ci.nsIDocShellTreeItem)
1165  .rootTreeItem
1166  .QueryInterface(Ci.nsIInterfaceRequestor)
1167  .getInterface(Ci.nsIDOMWindow)
1168  .QueryInterface(Ci.nsIDOMChromeWindow);
1169  return chromeWin;
1170  }
1171 
1172  var requestingWindow = request.requestingWindow.top;
1173  var chromeWindowObject = getChromeWindow(requestingWindow).wrappedJSObject;
1174  var tabbrowser = chromeWindowObject.gBrowser;
1175  var browser = tabbrowser.getBrowserForDocument(requestingWindow.document);
1176  var notificationBox = tabbrowser.getNotificationBox(browser);
1177 
1178  var notification = notificationBox.getNotificationWithValue("geolocation");
1179  if (!notification) {
1180  var bundleService = Cc["@mozilla.org/intl/stringbundle;1"].getService(Ci.nsIStringBundleService);
1181  var browserBundle = bundleService.createBundle("chrome://browser/locale/browser.properties");
1182 
1183  var buttons = [{
1184  label: browserBundle.GetStringFromName("geolocation.shareLocation"),
1185  accessKey: browserBundle.GetStringFromName("geolocation.shareLocation.accesskey"),
1186  callback: function(notification) {
1187  var elements = notification.getElementsByClassName("rememberChoice");
1188  if (elements.length && elements[0].checked)
1189  setPagePermission(request.requestingURI, true);
1190  request.allow();
1191  },
1192  },
1193  {
1194  label: browserBundle.GetStringFromName("geolocation.dontShareLocation"),
1195  accessKey: browserBundle.GetStringFromName("geolocation.dontShareLocation.accesskey"),
1196  callback: function(notification) {
1197  var elements = notification.getElementsByClassName("rememberChoice");
1198  if (elements.length && elements[0].checked)
1199  setPagePermission(request.requestingURI, false);
1200  request.cancel();
1201  },
1202  }];
1203 
1204  var message = browserBundle.formatStringFromName("geolocation.siteWantsToKnow",
1205  [request.requestingURI.host], 1);
1206 
1207  var newBar = notificationBox.appendNotification(message,
1208  "geolocation",
1209  "chrome://browser/skin/Geo.png",
1210  notificationBox.PRIORITY_INFO_HIGH,
1211  buttons);
1212 
1213  // For whatever reason, if we do this immediately
1214  // (eg, without the setTimeout), the "link"
1215  // element does not show up in the notification
1216  // bar.
1217  function geolocation_hacks_to_notification () {
1218 
1219  // Never show a remember checkbox inside the private browsing mode
1220  // XXX Songbird: allow not having private browsing support
1221  var inPrivateBrowsing = false;
1222  if ("@mozilla.org/privatebrowsing;1" in Cc) {
1223  inPrivateBrowsing = Cc["@mozilla.org/privatebrowsing;1"].
1224  getService(Ci.nsIPrivateBrowsingService).
1225  privateBrowsingEnabled;
1226  }
1227  if (!inPrivateBrowsing) {
1228  var checkbox = newBar.ownerDocument.createElementNS(XULNS, "checkbox");
1229  checkbox.className = "rememberChoice";
1230  checkbox.setAttribute("label", browserBundle.GetStringFromName("geolocation.remember"));
1231  checkbox.setAttribute("accesskey", browserBundle.GetStringFromName("geolocation.remember.accesskey"));
1232  newBar.appendChild(checkbox);
1233  }
1234 
1235  var link = newBar.ownerDocument.createElementNS(XULNS, "label");
1236  link.className = "text-link";
1237  link.setAttribute("value", browserBundle.GetStringFromName("geolocation.learnMore"));
1238 
1239  var formatter = Cc["@mozilla.org/toolkit/URLFormatterService;1"].getService(Ci.nsIURLFormatter);
1240  link.href = formatter.formatURLPref("browser.geolocation.warning.infoURL");
1241 
1242  var description = newBar.ownerDocument.getAnonymousElementByAttribute(newBar, "anonid", "messageText");
1243  description.appendChild(link);
1244  };
1245 
1246  chromeWindowObject.setTimeout(geolocation_hacks_to_notification, 0);
1247 
1248  }
1249  },
1250 };
1251 
1252 
1253 //module initialization
1254 function NSGetModule(aCompMgr, aFileSpec) {
1255  /* on runs with component registration (e.g. safe mode), we need to manually
1256  * load the default prefs in order to happen before the chrome registry loads
1257  */
1258  BrowserGlueServiceFactory.createInstance(null)._onAppDefaults();
1259  return XPCOMUtils.generateModule([BrowserGlue, GeolocationPrompt]);
1260 }
var args
Definition: alert.js:8
const SMART_BOOKMARKS_VERSION
const PREF_PLUGINS_NOTIFYUSER
const XULNS
id service()
const Cc
function BrowserGlue()
sbDeviceFirmwareAutoCheckForUpdate prototype flags
const SMART_BOOKMARKS_ANNO
Definition: test_421483.js:71
sbDeviceFirmwareAutoCheckForUpdate prototype contractID
sidebarFactory createInstance
Definition: nsSidebar.js:351
sbOSDControlService prototype QueryInterface
const histsvc
sbDeviceFirmwareAutoCheckForUpdate prototype classDescription
var browserBundle
Definition: xpInstallHat.js:38
getService(Ci.sbIFaceplateManager)
Sanitizer sanitize
Definition: sanitize.js:464
inst settings prompt
this _contentSandbox label
Definition: FeedWriter.js:814
var tabbrowser
const bmsvc
function DistributionCustomizer()
Definition: distribution.js:49
const PREF_EM_NEW_ADDONS_LIST
grep callback
GstMessage * message
const Cr
return null
Definition: FeedWriter.js:1143
const PREF_PLUGINS_UPDATEURL
function newURI(aURLString)
const SMART_BOOKMARKS_PREF
Definition: test_421483.js:72
const BOOKMARKS_ARCHIVE_IDLE_TIME
const cacheService
Definition: pageInfo.js:195
var uri
Definition: FeedWriter.js:1135
function url(spec)
countRef value
Definition: FeedWriter.js:1423
const Ci
let promptService
function restoreDefaultBookmarks()
Definition: safeMode.js:64
Sanitizer _prefs
Definition: sanitize.js:435
observe topic
Definition: FeedWriter.js:1326
sbDeviceFirmwareAutoCheckForUpdate prototype classID
function Sanitizer()
Definition: sanitize.js:42
sbWindowsAutoPlayServiceCfg _xpcom_categories
const BrowserGlueServiceFactory
const Cu
var browser
Definition: openLocation.js:42
__defineGetter__("Application", function(){delete this.Application;return this.Application=Cc["@mozilla.org/fuel/application;1"].getService(Ci.fuelIApplication);})
observe data
Definition: FeedWriter.js:1329
function NSGetModule(aCompMgr, aFileSpec)
const BOOKMARKS_ARCHIVE_INTERVAL
_getSelectedPageStyle s i
var brandBundle
Definition: xpInstallHat.js:37
function getMostRecentBrowserWindow()
sbDeviceFirmwareAutoCheckForUpdate prototype observe