mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 753978 - Be able to know if a window is part of an application. r=jlebar
This commit is contained in:
parent
ac7264c069
commit
18041509b8
@ -937,7 +937,10 @@ nsFrameLoader::ShowRemoteFrame(const nsIntSize& size)
|
||||
nsCOMPtr<nsIObserverService> os = services::GetObserverService();
|
||||
if (OwnerIsBrowserFrame() && os) {
|
||||
os->NotifyObservers(NS_ISUPPORTS_CAST(nsIFrameLoader*, this),
|
||||
"remote-browser-frame-shown", NULL);
|
||||
"remote-browser-frame-shown",
|
||||
mOwnerContent->HasAttr(kNameSpaceID_None, nsGkAtoms::mozapp)
|
||||
? NS_LITERAL_STRING("is-moz-app:true").get()
|
||||
: NS_LITERAL_STRING("is-moz-app:false").get());
|
||||
}
|
||||
} else {
|
||||
nsRect dimensions;
|
||||
@ -1522,7 +1525,10 @@ nsFrameLoader::MaybeCreateDocShell()
|
||||
if (OwnerIsBrowserFrame() && os) {
|
||||
mDocShell->SetIsBrowserFrame(true);
|
||||
os->NotifyObservers(NS_ISUPPORTS_CAST(nsIFrameLoader*, this),
|
||||
"in-process-browser-frame-shown", NULL);
|
||||
"in-process-browser-frame-shown",
|
||||
mOwnerContent->HasAttr(kNameSpaceID_None, nsGkAtoms::mozapp)
|
||||
? NS_LITERAL_STRING("is-moz-app:true").get()
|
||||
: NS_LITERAL_STRING("is-moz-app:false").get());
|
||||
}
|
||||
|
||||
// This is nasty, this code (the do_GetInterface(mDocShell) below)
|
||||
|
@ -108,6 +108,7 @@ GK_ATOM(ancestor, "ancestor")
|
||||
GK_ATOM(ancestorOrSelf, "ancestor-or-self")
|
||||
GK_ATOM(_and, "and")
|
||||
GK_ATOM(any, "any")
|
||||
GK_ATOM(mozapp, "mozapp")
|
||||
GK_ATOM(applet, "applet")
|
||||
GK_ATOM(applyImports, "apply-imports")
|
||||
GK_ATOM(applyTemplates, "apply-templates")
|
||||
|
@ -284,6 +284,7 @@ nsGenericHTMLFrameElement::GetReallyIsBrowser(bool *aOut)
|
||||
}
|
||||
|
||||
// Fail if the node principal isn't trusted.
|
||||
// TODO: check properly for mozApps rights when mozApps will be less hacky.
|
||||
nsIPrincipal *principal = NodePrincipal();
|
||||
nsCOMPtr<nsIURI> principalURI;
|
||||
principal->GetURI(getter_AddRefs(principalURI));
|
||||
|
@ -41,6 +41,17 @@ BrowserElementChild.prototype = {
|
||||
Ci.nsIWebProgress.NOTIFY_LOCATION |
|
||||
Ci.nsIWebProgress.NOTIFY_STATE_WINDOW);
|
||||
|
||||
// A mozbrowser iframe contained inside a mozapp iframe should return false
|
||||
// for nsWindowUtils::IsPartOfApp (unless the mozbrowser iframe is itself
|
||||
// also mozapp). That is, mozapp is transitive down to its children, but
|
||||
// mozbrowser serves as a barrier.
|
||||
//
|
||||
// This is because mozapp iframes have some privileges which we don't want
|
||||
// to extend to untrusted mozbrowser content.
|
||||
content.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Components.interfaces.nsIDOMWindowUtils)
|
||||
.setIsApp(false);
|
||||
|
||||
addEventListener('DOMTitleChanged',
|
||||
this._titleChangedHandler.bind(this),
|
||||
/* useCapture = */ true,
|
||||
|
@ -67,17 +67,17 @@ BrowserElementParent.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
_observeInProcessBrowserFrameShown: function(frameLoader) {
|
||||
_observeInProcessBrowserFrameShown: function(frameLoader, isMozApp) {
|
||||
debug("In-process browser frame shown " + frameLoader);
|
||||
this._setUpMessageManagerListeners(frameLoader);
|
||||
this._setUpMessageManagerListeners(frameLoader, isMozApp);
|
||||
},
|
||||
|
||||
_observeRemoteBrowserFrameShown: function(frameLoader) {
|
||||
_observeRemoteBrowserFrameShown: function(frameLoader, isMozApp) {
|
||||
debug("Remote browser frame shown " + frameLoader);
|
||||
this._setUpMessageManagerListeners(frameLoader);
|
||||
this._setUpMessageManagerListeners(frameLoader, isMozApp);
|
||||
},
|
||||
|
||||
_setUpMessageManagerListeners: function(frameLoader) {
|
||||
_setUpMessageManagerListeners: function(frameLoader, isMozApp) {
|
||||
let frameElement = frameLoader.QueryInterface(Ci.nsIFrameLoader).ownerElement;
|
||||
if (!frameElement) {
|
||||
debug("No frame element?");
|
||||
@ -102,6 +102,12 @@ BrowserElementParent.prototype = {
|
||||
|
||||
mm.loadFrameScript("chrome://global/content/BrowserElementChild.js",
|
||||
/* allowDelayedLoad = */ true);
|
||||
if (isMozApp) {
|
||||
mm.loadFrameScript("data:,content.QueryInterface(Ci.nsIInterfaceRequestor)" +
|
||||
" .getInterface(Components.interfaces.nsIDOMWindowUtils)" +
|
||||
" .setIsApp(true);",
|
||||
/* allowDelayedLoad = */ true);
|
||||
}
|
||||
},
|
||||
|
||||
_recvHello: function(frameElement, data) {
|
||||
@ -144,10 +150,10 @@ BrowserElementParent.prototype = {
|
||||
}
|
||||
break;
|
||||
case 'remote-browser-frame-shown':
|
||||
this._observeRemoteBrowserFrameShown(subject);
|
||||
this._observeRemoteBrowserFrameShown(subject, data == "is-moz-app:true");
|
||||
break;
|
||||
case 'in-process-browser-frame-shown':
|
||||
this._observeInProcessBrowserFrameShown(subject);
|
||||
this._observeInProcessBrowserFrameShown(subject, data == "is-moz-app:true");
|
||||
break;
|
||||
case 'content-document-global-created':
|
||||
this._observeContentGlobalCreated(subject);
|
||||
|
@ -2453,3 +2453,14 @@ nsDOMWindowUtils::SetScrollPositionClampingScrollPortSize(float aWidth, float aH
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMWindowUtils::SetIsApp(bool aValue)
|
||||
{
|
||||
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
|
||||
NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
|
||||
|
||||
static_cast<nsGlobalWindow*>(window.get())->SetIsApp(aValue);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -692,6 +692,7 @@ nsGlobalWindow::nsGlobalWindow(nsGlobalWindow *aOuterWindow)
|
||||
mShowFocusRingForContent(false),
|
||||
mFocusByKeyOccurred(false),
|
||||
mNotifiedIDDestroyed(false),
|
||||
mIsApp(TriState_Unknown),
|
||||
mTimeoutInsertionPoint(nsnull),
|
||||
mTimeoutPublicIdCounter(1),
|
||||
mTimeoutFiringDepth(0),
|
||||
@ -10015,6 +10016,33 @@ nsGlobalWindow::SizeOfIncludingThis(nsWindowSizes* aWindowSizes) const
|
||||
mNavigator->SizeOfIncludingThis(aWindowSizes->mMallocSizeOf) : 0;
|
||||
}
|
||||
|
||||
void
|
||||
nsGlobalWindow::SetIsApp(bool aValue)
|
||||
{
|
||||
FORWARD_TO_OUTER_VOID(SetIsApp, (aValue));
|
||||
|
||||
mIsApp = aValue ? TriState_True : TriState_False;
|
||||
}
|
||||
|
||||
bool
|
||||
nsGlobalWindow::IsPartOfApp()
|
||||
{
|
||||
FORWARD_TO_OUTER(IsPartOfApp, (), TriState_False);
|
||||
|
||||
// We go trough all window parents until we find one with |mIsApp| set to
|
||||
// something. If none is found, we are not part of an application.
|
||||
for (nsGlobalWindow* w = this; w;
|
||||
w = static_cast<nsGlobalWindow*>(w->GetParentInternal())) {
|
||||
if (w->mIsApp == TriState_True) {
|
||||
return true;
|
||||
} else if (w->mIsApp == TriState_False) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// nsGlobalChromeWindow implementation
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsGlobalChromeWindow)
|
||||
|
@ -558,10 +558,23 @@ public:
|
||||
void AddEventTargetObject(nsDOMEventTargetHelper* aObject);
|
||||
void RemoveEventTargetObject(nsDOMEventTargetHelper* aObject);
|
||||
|
||||
/**
|
||||
* Returns if the window is part of an application.
|
||||
* It will check for the window app state and its parents until a window has
|
||||
* an app state different from |TriState_Unknown|.
|
||||
*/
|
||||
bool IsPartOfApp();
|
||||
|
||||
protected:
|
||||
friend class HashchangeCallback;
|
||||
friend class nsBarProp;
|
||||
|
||||
enum TriState {
|
||||
TriState_Unknown = -1,
|
||||
TriState_False,
|
||||
TriState_True
|
||||
};
|
||||
|
||||
// Object Management
|
||||
virtual ~nsGlobalWindow();
|
||||
void CleanUp(bool aIgnoreModalDialog);
|
||||
@ -811,6 +824,8 @@ protected:
|
||||
nsresult CloneStorageEvent(const nsAString& aType,
|
||||
nsCOMPtr<nsIDOMStorageEvent>& aEvent);
|
||||
|
||||
void SetIsApp(bool aValue);
|
||||
|
||||
// When adding new member variables, be careful not to create cycles
|
||||
// through JavaScript. If there is any chance that a member variable
|
||||
// could own objects that are implemented in JavaScript, then those
|
||||
@ -878,6 +893,11 @@ protected:
|
||||
// whether we've sent the destroy notification for our window id
|
||||
bool mNotifiedIDDestroyed : 1;
|
||||
|
||||
// Whether the window is the window of an application frame.
|
||||
// This is TriState_Unknown if the object is the content window of an
|
||||
// iframe which is neither mozBrowser nor mozApp.
|
||||
TriState mIsApp : 2;
|
||||
|
||||
nsCOMPtr<nsIScriptContext> mContext;
|
||||
nsWeakPtr mOpener;
|
||||
nsCOMPtr<nsIControllers> mControllers;
|
||||
|
@ -70,7 +70,7 @@ interface nsIDOMFile;
|
||||
interface nsIFile;
|
||||
interface nsIDOMTouch;
|
||||
|
||||
[scriptable, uuid(f75d0a14-e278-4716-a151-637862451a2f)]
|
||||
[scriptable, uuid(2e5a1f37-786b-4a52-b0e3-f711ee2268a8)]
|
||||
interface nsIDOMWindowUtils : nsISupports {
|
||||
|
||||
/**
|
||||
@ -1149,4 +1149,13 @@ interface nsIDOMWindowUtils : nsISupports {
|
||||
* The caller of this method must have UniversalXPConnect privileges.
|
||||
*/
|
||||
void setScrollPositionClampingScrollPortSize(in float aWidth, in float aHeight);
|
||||
|
||||
/**
|
||||
* Mark if the window is an application window or not.
|
||||
* This should only be set for top-level mozApp or mozBrowser frames.
|
||||
* It should not be set for other frames unless you want a frame (and its
|
||||
* children) to have a different value for IsPartOfApp than the frame's
|
||||
* parent.
|
||||
*/
|
||||
void setIsApp(in boolean value);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user