Bug 832700 - Add private browsing to Firefox OS r=ehsan,smaug
--- a/content/base/src/nsGkAtomList.h
+++ b/content/base/src/nsGkAtomList.h
@@ -604,16 +604,17 @@ GK_ATOM(mousethrough, "mousethrough")
GK_ATOM(mouseup, "mouseup")
GK_ATOM(mozaudiochannel, "mozaudiochannel")
GK_ATOM(mozasyncpanzoom, "mozasyncpanzoom")
GK_ATOM(mozfullscreenchange, "mozfullscreenchange")
GK_ATOM(mozfullscreenerror, "mozfullscreenerror")
GK_ATOM(mozpasspointerevents, "mozpasspointerevents")
GK_ATOM(mozpointerlockchange, "mozpointerlockchange")
GK_ATOM(mozpointerlockerror, "mozpointerlockerror")
+GK_ATOM(mozprivatebrowsing, "mozprivatebrowsing")
GK_ATOM(moz_opaque, "moz-opaque")
GK_ATOM(moz_action_hint, "mozactionhint")
GK_ATOM(x_moz_errormessage, "x-moz-errormessage")
GK_ATOM(msthemecompatible, "msthemecompatible")
GK_ATOM(multicol, "multicol")
GK_ATOM(multiple, "multiple")
GK_ATOM(muted, "muted")
GK_ATOM(name, "name")
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -846,16 +846,17 @@ nsDocShell::nsDocShell():
mIsExecutingOnLoadHandler(false),
mIsPrintingOrPP(false),
mSavingOldViewer(false),
#ifdef DEBUG
mInEnsureScriptEnv(false),
#endif
mAffectPrivateSessionLifetime(true),
mInvisible(false),
+ mHasLoadedNonBlankURI(false),
mDefaultLoadFlags(nsIRequest::LOAD_NORMAL),
mFrameType(eFrameTypeRegular),
mOwnOrContainingAppId(nsIScriptSecurityManager::UNKNOWN_APP_ID),
mParentCharsetSource(0)
{
mHistoryID = ++gDocshellIDCounter;
if (gDocShellCount++ == 0) {
NS_ASSERTION(sURIFixup == nullptr,
@@ -1923,16 +1924,20 @@ nsDocShell::SetCurrentURI(nsIURI *aURI,
// We don't want to send a location change when we're displaying an error
// page, and we don't want to change our idea of "current URI" either
if (mLoadType == LOAD_ERROR_PAGE) {
return false;
}
mCurrentURI = NS_TryToMakeImmutable(aURI);
+ if (!NS_IsAboutBlank(mCurrentURI)) {
+ mHasLoadedNonBlankURI = true;
+ }
+
bool isRoot = false; // Is this the root docshell
bool isSubFrame = false; // Is this a subframe navigation?
nsCOMPtr<nsIDocShellTreeItem> root;
GetSameTypeRootTreeItem(getter_AddRefs(root));
if (root.get() == static_cast<nsIDocShellTreeItem *>(this))
{
@@ -2273,16 +2278,25 @@ nsDocShell::SetPrivateBrowsing(bool aUse
obs->PrivateModeChanged(aUsePrivateBrowsing);
}
}
}
return NS_OK;
}
NS_IMETHODIMP
+nsDocShell::GetHasLoadedNonBlankURI(bool* aResult)
+{
+ NS_ENSURE_ARG_POINTER(aResult);
+
+ *aResult = mHasLoadedNonBlankURI;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
nsDocShell::GetUseRemoteTabs(bool* aUseRemoteTabs)
{
NS_ENSURE_ARG_POINTER(aUseRemoteTabs);
*aUseRemoteTabs = mUseRemoteTabs;
return NS_OK;
}
--- a/docshell/base/nsDocShell.h
+++ b/docshell/base/nsDocShell.h
@@ -910,16 +910,17 @@ protected:
// @see nsIDocShellHistory::createdDynamically
bool mDynamicallyCreated;
#ifdef DEBUG
bool mInEnsureScriptEnv;
#endif
bool mAffectPrivateSessionLifetime;
bool mInvisible;
+ bool mHasLoadedNonBlankURI;
uint64_t mHistoryID;
uint32_t mDefaultLoadFlags;
static nsIURIFixup *sURIFixup;
nsRefPtr<nsDOMNavigationTiming> mTiming;
// Are we a regular frame, a browser frame, or an app frame?
--- a/docshell/base/nsIDocShell.idl
+++ b/docshell/base/nsIDocShell.idl
@@ -49,17 +49,17 @@ interface nsIWebBrowserPrint;
interface nsIVariant;
interface nsIPrivacyTransitionObserver;
interface nsIReflowObserver;
interface nsIScrollObserver;
interface nsITabParent;
typedef unsigned long nsLoadFlags;
-[scriptable, builtinclass, uuid(2b8e4a50-7744-454d-a05b-debead8070fe)]
+[scriptable, builtinclass, uuid(23157a63-26fd-44a0-a0f9-fdc64dcc004c)]
interface nsIDocShell : nsIDocShellTreeItem
{
/**
* Loads a given URI. This will give priority to loading the requested URI
* in the object implementing this interface. If it can't be loaded here
* however, the URL dispatcher will go through its normal process of content
* loading.
*
@@ -1012,9 +1012,16 @@ interface nsIDocShell : nsIDocShellTreeI
* See the documentation for setOpener and getOpener about why we
* don't use attribute here instead.
*/
[noscript,notxpcom,nostdcall] void setOpenedRemote(in nsITabParent aOpenedRemote);
[noscript,notxpcom,nostdcall] nsITabParent getOpenedRemote();
// URLSearchParams for the window.location is owned by the docShell.
[noscript,notxpcom] URLSearchParams getURLSearchParams();
+
+ /**
+ * This attribute determines whether a document which is not about:blank has
+ * already be loaded by this docShell.
+ */
+ [infallible] readonly attribute boolean hasLoadedNonBlankURI;
+
};
--- a/dom/browser-element/BrowserElementChild.js
+++ b/dom/browser-element/BrowserElementChild.js
@@ -51,8 +51,15 @@ if (!('BrowserElementIsPreloaded' in thi
}
var BrowserElementIsReady = true;
let infos = sendSyncMessage('browser-element-api:call',
{ 'msg_name': 'hello' })[0];
docShell.QueryInterface(Ci.nsIDocShellTreeItem).name = infos.name;
docShell.setFullscreenAllowed(infos.fullscreenAllowed);
+if (infos.isPrivate) {
+ if (!docShell.hasLoadedNonBlankURI) {
+ Cu.reportError("We should not switch to Private Browsing after loading a document.");
+ } else {
+ docShell.QueryInterface(Ci.nsILoadContext).usePrivateBrowsing = true;
+ }
+}
--- a/dom/browser-element/BrowserElementParent.cpp
+++ b/dom/browser-element/BrowserElementParent.cpp
@@ -71,16 +71,24 @@ CreateIframe(Element* aOpenerFrameElemen
aName, /* aNotify = */ false);
// Indicate whether the iframe is should be remote.
popupFrameElement->SetAttr(kNameSpaceID_None, nsGkAtoms::Remote,
aRemote ? NS_LITERAL_STRING("true") :
NS_LITERAL_STRING("false"),
/* aNotify = */ false);
+ // Copy the opener frame's mozprivatebrowsing attribute to the popup frame.
+ nsAutoString mozprivatebrowsing;
+ if (aOpenerFrameElement->GetAttr(kNameSpaceID_None, nsGkAtoms::mozprivatebrowsing,
+ mozprivatebrowsing)) {
+ popupFrameElement->SetAttr(kNameSpaceID_None, nsGkAtoms::mozprivatebrowsing,
+ mozprivatebrowsing, /* aNotify = */ false);
+ }
+
return popupFrameElement.forget();
}
bool
DispatchCustomDOMEvent(Element* aFrameElement, const nsAString& aEventName,
JSContext* cx, JS::Handle<JS::Value> aDetailValue,
nsEventStatus *aStatus)
{
--- a/dom/browser-element/BrowserElementParent.jsm
+++ b/dom/browser-element/BrowserElementParent.jsm
@@ -384,17 +384,18 @@ BrowserElementParent.prototype = {
this._domRequestReady = true;
this._runPendingAPICall();
}
return {
name: this._frameElement.getAttribute('name'),
fullscreenAllowed:
this._frameElement.hasAttribute('allowfullscreen') ||
- this._frameElement.hasAttribute('mozallowfullscreen')
+ this._frameElement.hasAttribute('mozallowfullscreen'),
+ isPrivate: this._frameElement.hasAttribute('mozprivatebrowsing')
};
},
_fireCtxMenuEvent: function(data) {
let detail = data.json;
let evtName = detail.msg_name;
debug('fireCtxMenuEventFromMsg: ' + evtName + ' ' + detail);