This interface is deprecated since Firefox 20, and will probably be completely removed in Firefox 21.
See Supporting per-window private browsing for details.
Firefox 3.5 introduced private browsing mode, in which potentially private information is not recorded. This includes cookies, history information, download information, and so forth.
When private browsing mode is enabled, temporary, databases are created to be used for cookies and local storage; these databases are thrown away when private browsing mode is turned off, and the regular databases are re-activated. The temporary cookie and local storage databases start out empty.
Extensions that may record potentially private information may wish to hook into the private browsing service so that they can avoid saving personal information when private browsing mode is enabled. Doing this is quite easy, using the nsIPrivateBrowsingService
interface.
Determining whether or not the user is currently in private browsing mode is simple. Just check the value of the privateBrowsingEnabled
attribute on the nsIPrivateBrowsingService
service.
var pbs = Components.classes["@mozilla.org/privatebrowsing;1"] .getService(Components.interfaces.nsIPrivateBrowsingService); var inPrivateBrowsingMode = pbs.privateBrowsingEnabled; if (!inPrivateBrowsingMode) { /* save private information */ }
In the above example, we only save the user's private information if not in private browsing mode.
Firefox 4 added support for having private browsing mode permanently enabled. The theme looks different in this scenario. To determine whether or not the browser is permanently in private browsing mode, you can look at the privatebrowsingmode
attribute on the document root. Its value is "permanent" if private browsing is permanently enabled for the session, "temporary" if private browsing is temporarily enabled, or not defined at all if private browsing mode isn't active.
let docRoot = document.documentElement; if (docRoot.hasAttribute("privatebrowsingmode")) { // Private browsing mode is enabled } if (docRoot.getAttribute("privatebrowsingmode") == "temporary") { // private browsing mode is temporary } if (docRoot.getAttribute("privatebrowsingmode") == "permanent") { // private browsing mode is permanent for this session }
Extensions can turn private browsing mode on and off by manipulating the value of the privateBrowsingEnabled
attribute.
var pbs = Components.classes["@mozilla.org/privatebrowsing;1"] .getService(Components.interfaces.nsIPrivateBrowsingService); var oldPrivateMode = pbs.privateBrowsingMode; pbs.privateBrowsingEnabled = true; /* this is all private */ pbs.privateBrowsingEnabled = oldPrivateMode;
In this example, we save the current state of the private browsing mode setting in the oldPrivateMode
variable, then turn on private browsing by setting its value to true
. From that point until we restore the original value of the private browsing mode setting, things are done privately. This allows us to, for example, work with the Places database without affecting its contents.
There are notifications available that allow you to easily watch for changes to the status of the private browsing mode, including detecting when it turns on and off. In addition, there is a browser:purge-session-history
notification that is sent when the browser purges private data that extensions can watch in order to know when it's time to do the same.
This helper object registers listeners for private browsing mode changes. This handles interacting with the private browsing service so you don't have to.
function PrivateBrowsingListener() { this.init(); } PrivateBrowsingListener.prototype = { _os: null, _inPrivateBrowsing: false, // whether we are in private browsing mode _watcher: null, // the watcher object init : function () { this._inited = true; this._os = Components.classes["@mozilla.org/observer-service;1"] .getService(Components.interfaces.nsIObserverService); this._os.addObserver(this, "private-browsing", false); this._os.addObserver(this, "quit-application", false); try { var pbs = Components.classes["@mozilla.org/privatebrowsing;1"] .getService(Components.interfaces.nsIPrivateBrowsingService); this._inPrivateBrowsing = pbs.privateBrowsingEnabled; } catch(ex) { // ignore exceptions in older versions of Firefox } }, observe : function (aSubject, aTopic, aData) { if (aTopic == "private-browsing") { if (aData == "enter") { this._inPrivateBrowsing = true; if (this.watcher && "onEnterPrivateBrowsing" in this._watcher) { this.watcher.onEnterPrivateBrowsing(); } } else if (aData == "exit") { this._inPrivateBrowsing = false; if (this.watcher && "onExitPrivateBrowsing" in this._watcher) { this.watcher.onExitPrivateBrowsing(); } } } else if (aTopic == "quit-application") { this._os.removeObserver(this, "quit-application"); this._os.removeObserver(this, "private-browsing"); } }, get inPrivateBrowsing() { return this._inPrivateBrowsing; }, get watcher() { return this._watcher; }, set watcher(val) { this._watcher = val; } };
Of special note is the fact that this helper object is designed to not break on versions of Firefox without private browsing support (those prior to Firefox 3.5). It will simply always report that private browsing is off, and will never call any registered watcher functions.
The helper described above is very easy to use. Simply instantiate the helper, then you can use its inPrivateBrowsing
flag to detect whether or not private browsing is currently enabled, as shown here:
var listener = new PrivateBrowsingListener(); if (listener.inPrivateBrowsing) { // we are in private browsing mode! } else { // we are not in private browsing mode! }
In addition, you can install watcher functions to be called when private browsing turns on and off, as shown in the following example. This lets you passively monitor for changes in private browsing status.
var listener = new PrivateBrowsingListener(); listener.watcher = { onEnterPrivateBrowsing : function() { // we have just entered private browsing mode! }, onExitPrivateBrowsing : function() { // we have just left private browsing mode! } };
Extensions can prevent private browsing mode from being shut off. An extension might wish to do this if it's currently in the middle of an operation that prevents safely turning off private browsing (such as a database update operation, for example). To do this, simply watch for the private browsing private-browsing-cancel-vote
notification with the subject "exit", and set its data
field to true
to cancel the operation, like this:
var os = Components.classes["@mozilla.org/observer-service;1"] .getService(Components.interfaces.nsIObserverService); os.addObserver(function (aSubject, aTopic, aData) { aSubject.QueryInterface(Components.interfaces.nsISupportsPRBool); // if another extension has not already canceled entering the private mode if (!aSubject.data) { if (aData == "exit") { // if we are leaving the private mode /* you should display some user interface here */ aSubject.data = true; // cancel the operation } } }, "private-browsing-cancel-vote", false);
In some extensions, it's hard to decide whether the data retained by the extension should be written to disk in private browsing mode or not. In such a case, it is considered good practice for the extension to enable respecting the private browsing mode based on a preference specific to that extension, and set that preference to true
by default. For example, the Fire.fm extension has a preference called "Disable station history and Scrobble when Firefox is in Private Mode", and disabling publishing of that information inside the private browsing mode by default. It provides a means of disabling this behavior for users who do not want the extension to stop publishing the information in private browsing mode.
If you want to make your theme look different when used in private browsing mode, you can do so quite easily by using the browsingmode
attribute in the window
element in browser.xul
. This attribute has the value "normal" when the user isn't in private browsing mode, and is "private" when in private browsing mode.
For example, if you want to use a different background color for the URL bar when in private browsing mode, you could do the following:
[browsingmode=private] #urlbar { -moz-appearance: none; background: #eee }
Similarly, if you want to theme the Firefox button in Firefox 4 differently when private browsing mode is permanent:
#main-window[privatebrowsingmode=temporary] #appmenu-button:not(:-moz-window-inactive) { -moz-border-left-colors: rgba(255,255,255,.5) rgba(43,8,65,.9); -moz-border-bottom-colors: rgba(255,255,255,.5) rgba(43,8,65,.9); -moz-border-right-colors: rgba(255,255,255,.5) rgba(43,8,65,.9); }
This snippet is pulled directly from the standard skin; you can customize as you see fit.
Plug-ins can detect whether or not private browsing mode is in effect by using the NPN_GetValue()
function to check the current value of the NPNVprivateModeBool
variable. See Supporting private browsing in plugins for details.
In order to publicly list an add-on on addons.mozilla.org, the add-on must properly respect private browsing mode by not recording sensitive data while private browsing mode is active. This is a new policy that is just being implemented (as of February, 2010).
The following categories define what's considered "sensitive" data:
Add-ons that don't properly respect private browsing mode will be rejected.