nsPrivateBrowsingService.js
Go to the documentation of this file.
1 # ***** BEGIN LICENSE BLOCK *****
2 # Version: MPL 1.1/GPL 2.0/LGPL 2.1
3 #
4 # The contents of this file are subject to the Mozilla Public License Version
5 # 1.1 (the "License"); you may not use this file except in compliance with
6 # the License. You may obtain a copy of the License at
7 # http://www.mozilla.org/MPL/
8 #
9 # Software distributed under the License is distributed on an "AS IS" basis,
10 # WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 # for the specific language governing rights and limitations under the
12 # License.
13 #
14 # The Original Code is Private Browsing.
15 #
16 # The Initial Developer of the Original Code is
17 # Ehsan Akhgari.
18 # Portions created by the Initial Developer are Copyright (C) 2008
19 # the Initial Developer. All Rights Reserved.
20 #
21 # Contributor(s):
22 # Ehsan Akhgari <ehsan.akhgari@gmail.com> (Original Author)
23 # Simon Bünzli <zeniko@gmail.com>
24 #
25 # Alternatively, the contents of this file may be used under the terms of
26 # either the GNU General Public License Version 2 or later (the "GPL"), or
27 # the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 # in which case the provisions of the GPL or the LGPL are applicable instead
29 # of those above. If you wish to allow use of your version of this file only
30 # under the terms of either the GPL or the LGPL, and not to allow others to
31 # use your version of this file under the terms of the MPL, indicate your
32 # decision by deleting the provisions above and replace them with the notice
33 # and other provisions required by the GPL or the LGPL. If you do not delete
34 # the provisions above, a recipient may use your version of this file under
35 # the terms of any one of the MPL, the GPL or the LGPL.
36 #
37 # ***** END LICENSE BLOCK *****
38 
39 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
40 
43 
50 String.prototype.hasRootDomain = function hasRootDomain(aDomain)
51 {
52  let index = this.indexOf(aDomain);
53  // If aDomain is not found, we know we do not have it as a root domain.
54  if (index == -1)
55  return false;
56 
57  // If the strings are the same, we obviously have a match.
58  if (this == aDomain)
59  return true;
60 
61  // Otherwise, we have aDomain as our root domain iff the index of aDomain is
62  // aDomain.length subtracted from our length and (since we do not have an
63  // exact match) the character before the index is a dot or slash.
64  let prevChar = this[index - 1];
65  return (index == (this.length - aDomain.length)) &&
66  (prevChar == "." || prevChar == "/");
67 }
68 
71 
72 const Cc = Components.classes;
73 const Ci = Components.interfaces;
74 const Cu = Components.utils;
75 const Cr = Components.results;
76 
77 const STATE_IDLE = 0;
81 
84 
86  this._obs.addObserver(this, "profile-after-change", true);
87  this._obs.addObserver(this, "quit-application-granted", true);
88  this._obs.addObserver(this, "private-browsing", true);
89  this._obs.addObserver(this, "command-line-startup", true);
90  this._obs.addObserver(this, "sessionstore-browser-state-restored", true);
91 }
92 
94  // Observer Service
95  __obs: null,
96  get _obs() {
97  if (!this.__obs)
98  this.__obs = Cc["@mozilla.org/observer-service;1"].
99  getService(Ci.nsIObserverService);
100  return this.__obs;
101  },
102 
103  // Preferences Service
104  __prefs: null,
105  get _prefs() {
106  if (!this.__prefs)
107  this.__prefs = Cc["@mozilla.org/preferences-service;1"].
108  getService(Ci.nsIPrefBranch);
109  return this.__prefs;
110  },
111 
112  // Whether the private browsing mode is currently active or not.
113  _inPrivateBrowsing: false,
114 
115  // Saved browser state before entering the private mode.
116  _savedBrowserState: null,
117 
118  // Whether we're in the process of shutting down
119  _quitting: false,
120 
121  // How to treat the non-private session
122  _saveSession: true,
123 
124  // The current status of the private browsing service
125  _currentStatus: STATE_IDLE,
126 
127  // Whether the private browsing mode has been started automatically (ie. always-on)
128  _autoStarted: false,
129 
130  // List of view source window URIs for restoring later
131  _viewSrcURLs: [],
132 
133  // List of nsIXULWindows we are going to be closing during the transition
134  _windowsToClose: [],
135 
136  // XPCOM registration
137  classDescription: "PrivateBrowsing Service",
138  contractID: "@mozilla.org/privatebrowsing;1",
139  classID: Components.ID("{c31f4883-839b-45f6-82ad-a6a9bc5ad599}"),
141  { category: "command-line-handler", entry: "m-privatebrowsing" },
142  { category: "app-startup", service: true }
143  ],
144 
145  QueryInterface: XPCOMUtils.generateQI([Ci.nsIPrivateBrowsingService,
146  Ci.nsIObserver,
147  Ci.nsISupportsWeakReference,
148  Ci.nsICommandLineHandler]),
149 
150  _unload: function PBS__destroy() {
151  // Force an exit from the private browsing mode on shutdown
152  this._quitting = true;
153  if (this._inPrivateBrowsing)
154  this.privateBrowsingEnabled = false;
155  },
156 
157  _onBeforePrivateBrowsingModeChange: function PBS__onBeforePrivateBrowsingModeChange() {
158  // nothing needs to be done here if we're enabling at startup
159  if (!this._autoStarted) {
160  let ss = Cc["@mozilla.org/browser/sessionstore;1"].
161  getService(Ci.nsISessionStore);
162  let blankState = JSON.stringify({
163  "windows": [{
164  "tabs": [{
165  "entries": [{
166  "url": "about:blank"
167  }]
168  }],
169  "_closedTabs": []
170  }]
171  });
172 
173  if (this._inPrivateBrowsing) {
174  // save the whole browser state in order to restore all windows/tabs later
175  if (this._saveSession && !this._savedBrowserState) {
176  if (this._getBrowserWindow())
177  this._savedBrowserState = ss.getBrowserState();
178  else // no open browser windows, just restore a blank state on exit
179  this._savedBrowserState = blankState;
180  }
181  }
182 
183  this._closePageInfoWindows();
184 
185  // save view-source windows URIs and close them
186  let viewSrcWindowsEnum = Cc["@mozilla.org/appshell/window-mediator;1"].
187  getService(Ci.nsIWindowMediator).
188  getEnumerator("navigator:view-source");
189  while (viewSrcWindowsEnum.hasMoreElements()) {
190  let win = viewSrcWindowsEnum.getNext();
191  if (this._inPrivateBrowsing) {
192  let plainURL = win.getBrowser().currentURI.spec;
193  if (plainURL.indexOf("view-source:") == 0) {
194  plainURL = plainURL.substr(12);
195  this._viewSrcURLs.push(plainURL);
196  }
197  }
198  win.close();
199  }
200 
201  if (!this._quitting && this._saveSession) {
202  let browserWindow = this._getBrowserWindow();
203 
204  // if there are open browser windows, load a dummy session to get a distinct
205  // separation between private and non-private sessions
206  if (browserWindow) {
207  // set an empty session to transition from/to pb mode, see bug 476463
208  ss.setBrowserState(blankState);
209 
210  // just in case the only remaining window after setBrowserState is different.
211  // it probably shouldn't be with the current sessionstore impl, but we shouldn't
212  // rely on behaviour the API doesn't guarantee
213  browserWindow = this._getBrowserWindow();
214  let browser = browserWindow.gBrowser;
215 
216  // this ensures a clean slate from which to transition into or out of
217  // private browsing
218  browser.addTab();
219  browser.getBrowserForTab(browser.tabContainer.firstChild).stop();
220  browser.removeTab(browser.tabContainer.firstChild);
221  browserWindow.getInterface(Ci.nsIWebNavigation)
222  .QueryInterface(Ci.nsIDocShellTreeItem)
223  .treeOwner
224  .QueryInterface(Ci.nsIInterfaceRequestor)
225  .getInterface(Ci.nsIXULWindow)
226  .docShell.contentViewer.resetCloseWindow();
227  }
228  }
229  }
230  else
231  this._saveSession = false;
232  },
233 
234  _onAfterPrivateBrowsingModeChange: function PBS__onAfterPrivateBrowsingModeChange() {
235  // nothing to do here if we're enabling at startup or the current session is being
236  // used
237  if (!this._autoStarted && this._saveSession) {
238  let ss = Cc["@mozilla.org/browser/sessionstore;1"].
239  getService(Ci.nsISessionStore);
240  // if we have transitioned out of private browsing mode and the session is
241  // to be restored, do it now
242  if (!this._inPrivateBrowsing) {
243  this._currentStatus = STATE_WAITING_FOR_RESTORE;
244  ss.setBrowserState(this._savedBrowserState);
245  this._savedBrowserState = null;
246 
247  this._closePageInfoWindows();
248 
249  // re-open all view-source windows
250  let windowWatcher = Cc["@mozilla.org/embedcomp/window-watcher;1"].
251  getService(Ci.nsIWindowWatcher);
252  this._viewSrcURLs.forEach(function(uri) {
253  let args = Cc["@mozilla.org/supports-array;1"].
254  createInstance(Ci.nsISupportsArray);
255  let str = Cc["@mozilla.org/supports-string;1"].
256  createInstance(Ci.nsISupportsString);
257  str.data = uri;
258  args.AppendElement(str);
259  args.AppendElement(null); // charset
260  args.AppendElement(null); // page descriptor
261  args.AppendElement(null); // line number
262  let forcedCharset = Cc["@mozilla.org/supports-PRBool;1"].
263  createInstance(Ci.nsISupportsPRBool);
264  forcedCharset.data = false;
265  args.AppendElement(forcedCharset);
266  windowWatcher.openWindow(null, "chrome://global/content/viewSource.xul",
267  "_blank", "all,dialog=no", args);
268  });
269  this._viewSrcURLs = [];
270  }
271  else {
272  // otherwise, if we have transitioned into private browsing mode, load
273  // about:privatebrowsing
274  let privateBrowsingState = {
275  "windows": [{
276  "tabs": [{
277  "entries": [{
278  "url": "about:privatebrowsing"
279  }]
280  }],
281  "_closedTabs": []
282  }]
283  };
284  // Transition into private browsing mode
285  this._currentStatus = STATE_WAITING_FOR_RESTORE;
286  ss.setBrowserState(JSON.stringify(privateBrowsingState));
287  }
288  }
289  },
290 
291  _notifyIfTransitionComplete: function PBS__notifyIfTransitionComplete() {
292  switch (this._currentStatus) {
294  // no session store operation was needed, so just notify of transition completion
296  // restore has been completed
297  this._currentStatus = STATE_IDLE;
298  this._obs.notifyObservers(null, "private-browsing-transition-complete", "");
299  break;
301  // too soon to notify...
302  break;
303  case STATE_IDLE:
304  // no need to notify
305  break;
306  default:
307  // unexpected state observed
308  Cu.reportError("Unexpected private browsing status reached: " +
309  this._currentStatus);
310  break;
311  }
312  },
313 
314  _canEnterPrivateBrowsingMode: function PBS__canEnterPrivateBrowsingMode() {
315  let cancelEnter = Cc["@mozilla.org/supports-PRBool;1"].
316  createInstance(Ci.nsISupportsPRBool);
317  cancelEnter.data = false;
318  this._obs.notifyObservers(cancelEnter, "private-browsing-cancel-vote", "enter");
319  return !cancelEnter.data;
320  },
321 
322  _canLeavePrivateBrowsingMode: function PBS__canLeavePrivateBrowsingMode() {
323  let cancelLeave = Cc["@mozilla.org/supports-PRBool;1"].
324  createInstance(Ci.nsISupportsPRBool);
325  cancelLeave.data = false;
326  this._obs.notifyObservers(cancelLeave, "private-browsing-cancel-vote", "exit");
327  return !cancelLeave.data;
328  },
329 
330  _getBrowserWindow: function PBS__getBrowserWindow() {
331  return Cc["@mozilla.org/appshell/window-mediator;1"].
332  getService(Ci.nsIWindowMediator).
333  getMostRecentWindow("navigator:browser");
334  },
335 
336  _ensureCanCloseWindows: function PBS__ensureCanCloseWindows() {
337  // whether we should save and close the current session
338  this._saveSession = true;
339  try {
340  if (this._prefs.getBoolPref("browser.privatebrowsing.keep_current_session")) {
341  this._saveSession = false;
342  return;
343  }
344  } catch (ex) {}
345 
346  let windowMediator = Cc["@mozilla.org/appshell/window-mediator;1"].
347  getService(Ci.nsIWindowMediator);
348  let windowsEnum = windowMediator.getXULWindowEnumerator("navigator:browser");
349 
350  while (windowsEnum.hasMoreElements()) {
351  let win = windowsEnum.getNext().QueryInterface(Ci.nsIXULWindow);
352  if (win.docShell.contentViewer.permitUnload(true))
353  this._windowsToClose.push(win);
354  else
355  throw Cr.NS_ERROR_ABORT;
356  }
357  },
358 
359  _closePageInfoWindows: function PBS__closePageInfoWindows() {
360  let pageInfoEnum = Cc["@mozilla.org/appshell/window-mediator;1"].
361  getService(Ci.nsIWindowMediator).
362  getEnumerator("Browser:page-info");
363  while (pageInfoEnum.hasMoreElements()) {
364  let win = pageInfoEnum.getNext();
365  win.close();
366  }
367  },
368 
369  // nsIObserver
370 
371  observe: function PBS_observe(aSubject, aTopic, aData) {
372  switch (aTopic) {
373  case "profile-after-change":
374  // If the autostart prefs has been set, simulate entering the
375  // private browsing mode upon startup.
376  // This won't interfere with the session store component, because
377  // that component will be initialized on final-ui-startup.
378  if (!this._autoStarted) {
379  this._autoStarted = this._prefs.getBoolPref("browser.privatebrowsing.autostart");
380  if (this._autoStarted)
381  this.privateBrowsingEnabled = true;
382  }
383  this._obs.removeObserver(this, "profile-after-change");
384  break;
385  case "quit-application-granted":
386  this._unload();
387  break;
388  case "private-browsing":
389  // clear all auth tokens
390  let sdr = Cc["@mozilla.org/security/sdr;1"].
391  getService(Ci.nsISecretDecoderRing);
392  sdr.logoutAndTeardown();
393 
394  // clear plain HTTP auth sessions
395  let authMgr = Cc['@mozilla.org/network/http-auth-manager;1'].
396  getService(Ci.nsIHttpAuthManager);
397  authMgr.clearAll();
398 
399  try {
400  this._prefs.deleteBranch("geo.wifi.access_token.");
401  } catch (ex) {}
402 
403  if (!this._inPrivateBrowsing) {
404  // Clear the error console
405  let consoleService = Cc["@mozilla.org/consoleservice;1"].
406  getService(Ci.nsIConsoleService);
407  consoleService.logStringMessage(null); // trigger the listeners
408  consoleService.reset();
409  }
410  break;
411  case "command-line-startup":
412  this._obs.removeObserver(this, "command-line-startup");
413  aSubject.QueryInterface(Ci.nsICommandLine);
414  this.handle(aSubject);
415  break;
416  case "sessionstore-browser-state-restored":
417  if (this._currentStatus == STATE_WAITING_FOR_RESTORE) {
418  this._currentStatus = STATE_RESTORE_FINISHED;
419  this._notifyIfTransitionComplete();
420  }
421  break;
422  }
423  },
424 
425  // nsICommandLineHandler
426 
427  handle: function PBS_handle(aCmdLine) {
428  if (aCmdLine.handleFlag("private", false)) {
429  this.privateBrowsingEnabled = true;
430  this._autoStarted = true;
431  }
432  },
433 
434  get helpInfo PBS_get_helpInfo() {
435  return " -private Enable private browsing mode.\n";
436  },
437 
438  // nsIPrivateBrowsingService
439 
443  get privateBrowsingEnabled PBS_get_privateBrowsingEnabled() {
444  return this._inPrivateBrowsing;
445  },
446 
450  set privateBrowsingEnabled PBS_set_privateBrowsingEnabled(val) {
451  // Allowing observers to set the private browsing status from their
452  // notification handlers is not desired, because it will change the
453  // status of the service while it's in the process of another transition.
454  // So, we detect a reentrant call here and throw an error.
455  // This is documented in nsIPrivateBrowsingService.idl.
456  if (this._currentStatus != STATE_IDLE)
457  throw Cr.NS_ERROR_FAILURE;
458 
459  try {
460  this._currentStatus = STATE_TRANSITION_STARTED;
461 
462  if (val != this._inPrivateBrowsing) {
463  if (val) {
464  if (!this._canEnterPrivateBrowsingMode())
465  return;
466  }
467  else {
468  if (!this._canLeavePrivateBrowsingMode())
469  return;
470  }
471 
472  this._ensureCanCloseWindows();
473 
474  this._autoStarted = this._prefs.getBoolPref("browser.privatebrowsing.autostart");
475  this._inPrivateBrowsing = val != false;
476 
477  let data = val ? "enter" : "exit";
478 
479  let quitting = Cc["@mozilla.org/supports-PRBool;1"].
480  createInstance(Ci.nsISupportsPRBool);
481  quitting.data = this._quitting;
482 
483  // notify observers of the pending private browsing mode change
484  this._obs.notifyObservers(quitting, "private-browsing-change-granted", data);
485 
486  // destroy the current session and start initial cleanup
487  this._onBeforePrivateBrowsingModeChange();
488 
489  this._obs.notifyObservers(quitting, "private-browsing", data);
490 
491  // load the appropriate session
492  this._onAfterPrivateBrowsingModeChange();
493  }
494  } catch (ex) {
495  // We aborted the transition to/from private browsing, we must restore the
496  // beforeunload handling on all the windows for which we switched it off.
497  for (let i = 0; i < this._windowsToClose.length; i++)
498  this._windowsToClose[i].docShell.contentViewer.resetCloseWindow();
499  // We don't log an error when the transition is canceled from beforeunload
500  if (ex != Cr.NS_ERROR_ABORT)
501  Cu.reportError("Exception thrown while processing the " +
502  "private browsing mode change request: " + ex.toString());
503  } finally {
504  this._windowsToClose = [];
505  this._notifyIfTransitionComplete();
506  }
507  },
508 
512  get autoStarted PBS_get_autoStarted() {
513  return this._inPrivateBrowsing && this._autoStarted;
514  },
515 
516  removeDataFromDomain: function PBS_removeDataFromDomain(aDomain)
517  {
518 
519  // clear any and all network geolocation provider sessions
520  try {
521  this._prefs.deleteBranch("geo.wifi.access_token.");
522  } catch (e) {}
523 
524  // History
525  let (bh = Cc["@mozilla.org/browser/global-history;2"].
526  getService(Ci.nsIBrowserHistory)) {
527  bh.removePagesFromHost(aDomain, true);
528  }
529 
530  // Cache
531  let (cs = Cc["@mozilla.org/network/cache-service;1"].
532  getService(Ci.nsICacheService)) {
533  // NOTE: there is no way to clear just that domain, so we clear out
534  // everything)
535  try {
536  cs.evictEntries(Ci.nsICache.STORE_ANYWHERE);
537  } catch (ex) {
538  Cu.reportError("Exception thrown while clearing the cache: " +
539  ex.toString());
540  }
541  }
542 
543  // Cookies
544  let (cm = Cc["@mozilla.org/cookiemanager;1"].
545  getService(Ci.nsICookieManager)) {
546  let enumerator = cm.enumerator;
547  while (enumerator.hasMoreElements()) {
548  let cookie = enumerator.getNext().QueryInterface(Ci.nsICookie);
549  if (cookie.host.hasRootDomain(aDomain))
550  cm.remove(cookie.host, cookie.name, cookie.path, false);
551  }
552  }
553 
554  // Downloads
555  let (dm = Cc["@mozilla.org/download-manager;1"].
556  getService(Ci.nsIDownloadManager)) {
557  // Active downloads
558  let enumerator = dm.activeDownloads;
559  while (enumerator.hasMoreElements()) {
560  let dl = enumerator.getNext().QueryInterface(Ci.nsIDownload);
561  if (dl.source.host.hasRootDomain(aDomain)) {
562  dm.cancelDownload(dl.id);
563  dm.removeDownload(dl.id);
564  }
565  }
566 
567  // Completed downloads
568  let db = dm.DBConnection;
569  // NOTE: This is lossy, but we feel that it is OK to be lossy here and not
570  // invoke the cost of creating a URI for each download entry and
571  // ensure that the hostname matches.
572  let stmt = db.createStatement(
573  "DELETE FROM moz_downloads " +
574  "WHERE source LIKE ?1 ESCAPE '/' " +
575  "AND state NOT IN (?2, ?3, ?4)"
576  );
577  let pattern = stmt.escapeStringForLIKE(aDomain, "/");
578  stmt.bindStringParameter(0, "%" + pattern + "%");
579  stmt.bindInt32Parameter(1, Ci.nsIDownloadManager.DOWNLOAD_DOWNLOADING);
580  stmt.bindInt32Parameter(2, Ci.nsIDownloadManager.DOWNLOAD_PAUSED);
581  stmt.bindInt32Parameter(3, Ci.nsIDownloadManager.DOWNLOAD_QUEUED);
582  try {
583  stmt.execute();
584  }
585  finally {
586  stmt.finalize();
587  }
588 
589  // We want to rebuild the list if the UI is showing, so dispatch the
590  // observer topic
591  let os = Cc["@mozilla.org/observer-service;1"].
592  getService(Ci.nsIObserverService);
593  os.notifyObservers(null, "download-manager-remove-download", null);
594  }
595 
596  // Passwords
597  let (lm = Cc["@mozilla.org/login-manager;1"].
598  getService(Ci.nsILoginManager)) {
599  // Clear all passwords for domain
600  try {
601  let logins = lm.getAllLogins({});
602  for (let i = 0; i < logins.length; i++)
603  if (logins[i].hostname.hasRootDomain(aDomain))
604  lm.removeLogin(logins[i]);
605  }
606  // XXXehsan: is there a better way to do this rather than this
607  // hacky comparison?
608  catch (ex if ex.message.indexOf("User canceled Master Password entry") != -1) { }
609 
610  // Clear any "do not save for this site" for this domain
611  let disabledHosts = lm.getAllDisabledHosts({});
612  for (let i = 0; i < disabledHosts.length; i++)
613  if (disabledHosts[i].hasRootDomain(aDomain))
614  lm.setLoginSavingEnabled(disabledHosts, true);
615  }
616 
617  // Permissions
618  let (pm = Cc["@mozilla.org/permissionmanager;1"].
619  getService(Ci.nsIPermissionManager)) {
620  // Enumerate all of the permissions, and if one matches, remove it
621  let enumerator = pm.enumerator;
622  while (enumerator.hasMoreElements()) {
623  let perm = enumerator.getNext().QueryInterface(Ci.nsIPermission);
624  if (perm.host.hasRootDomain(aDomain))
625  pm.remove(perm.host, perm.type);
626  }
627  }
628 
629  // Content Preferences
630  let (cp = Cc["@mozilla.org/content-pref/service;1"].
631  getService(Ci.nsIContentPrefService)) {
632  let db = cp.DBConnection;
633  // First we need to get the list of "groups" which are really just domains
634  let names = [];
635  let stmt = db.createStatement(
636  "SELECT name " +
637  "FROM groups " +
638  "WHERE name LIKE ?1 ESCAPE '/'"
639  );
640  let pattern = stmt.escapeStringForLIKE(aDomain, "/");
641  stmt.bindStringParameter(0, "%" + pattern);
642  try {
643  while (stmt.executeStep())
644  if (stmt.getString(0).hasRootDomain(aDomain))
645  names.push(stmt.getString(0));
646  }
647  finally {
648  stmt.finalize();
649  }
650 
651  // Now, for each name we got back, remove all of its prefs.
652  for (let i = 0; i < names.length; i++) {
653  // The service only cares about the host of the URI, so we don't need a
654  // full nsIURI object here.
655  let uri = { host: names[i]};
656  let enumerator = cp.getPrefs(uri).enumerator;
657  while (enumerator.hasMoreElements()) {
658  let pref = enumerator.getNext().QueryInterface(Ci.nsIProperty);
659  cp.removePref(uri, pref.name);
660  }
661  }
662  }
663 
664  // Everybody else (including extensions)
665  this._obs.notifyObservers(null, "browser:purge-domain-data", aDomain);
666  }
667 };
668 
669 function NSGetModule(compMgr, fileSpec)
670  XPCOMUtils.generateModule([PrivateBrowsingService]);
classDescription entry
Definition: FeedWriter.js:1427
const Cc
var args
Definition: alert.js:8
browser docShell
const STATE_TRANSITION_STARTED
id service()
function PrivateBrowsingService()
var pref
Definition: openLocation.js:44
sbDeviceFirmwareAutoCheckForUpdate prototype contractID
sidebarFactory createInstance
Definition: nsSidebar.js:351
sbOSDControlService prototype QueryInterface
sbDeviceFirmwareAutoCheckForUpdate prototype classDescription
function handle(request, response)
const STATE_IDLE
getService(Ci.sbIFaceplateManager)
return elem filter &&elem filter indexOf("opacity=")>=0?(parseFloat(elem.filter.match(/opacity
function NSGetModule(compMgr, fileSpec) XPCOMUtils.generateModule([PrivateBrowsingService])
const STATE_RESTORE_FINISHED
this _dialogInput val(dateText)
return null
Definition: FeedWriter.js:1143
var windowsEnum
var os
var uri
Definition: FeedWriter.js:1135
String prototype hasRootDomain
Sanitizer _prefs
Definition: sanitize.js:435
var JSON
sbDeviceFirmwareAutoCheckForUpdate prototype classID
sbWindowsAutoPlayServiceCfg _xpcom_categories
const STATE_WAITING_FOR_RESTORE
var browser
Definition: openLocation.js:42
observe data
Definition: FeedWriter.js:1329
function getMostRecentWindow(aType)
_getSelectedPageStyle s i
var cm
_updateTextAndScrollDataForFrame aData
sbDeviceFirmwareAutoCheckForUpdate prototype observe