2015-05-03 22:32:37 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
2012-05-21 15:12:37 +04:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
2002-01-29 09:27:27 +03:00
|
|
|
|
2006-03-30 12:03:04 +04:00
|
|
|
/*
|
|
|
|
* Class for managing loading of a subframe (creation of the docshell,
|
|
|
|
* handling of loads in it, recursion-checking).
|
|
|
|
*/
|
|
|
|
|
2011-04-03 06:14:00 +04:00
|
|
|
#include "base/basictypes.h"
|
2009-10-30 15:58:07 +03:00
|
|
|
|
2009-07-02 20:54:22 +04:00
|
|
|
#include "prenv.h"
|
|
|
|
|
2015-09-29 07:31:56 +03:00
|
|
|
#include "nsDocShell.h"
|
2012-06-20 23:25:22 +04:00
|
|
|
#include "nsIDOMMozBrowserFrame.h"
|
2002-01-29 09:27:27 +03:00
|
|
|
#include "nsIDOMWindow.h"
|
|
|
|
#include "nsIPresShell.h"
|
2013-10-02 15:40:07 +04:00
|
|
|
#include "nsIContentInlines.h"
|
2009-10-16 23:42:29 +04:00
|
|
|
#include "nsIContentViewer.h"
|
2002-01-29 09:27:27 +03:00
|
|
|
#include "nsIDocument.h"
|
2002-04-17 08:17:16 +04:00
|
|
|
#include "nsPIDOMWindow.h"
|
2002-01-29 09:27:27 +03:00
|
|
|
#include "nsIWebNavigation.h"
|
2010-03-26 21:39:39 +03:00
|
|
|
#include "nsIWebProgress.h"
|
2002-01-29 09:27:27 +03:00
|
|
|
#include "nsIDocShell.h"
|
|
|
|
#include "nsIDocShellTreeOwner.h"
|
2018-10-30 03:13:29 +03:00
|
|
|
#include "nsDocShellLoadState.h"
|
2002-01-29 09:27:27 +03:00
|
|
|
#include "nsIBaseWindow.h"
|
2016-08-16 04:04:04 +03:00
|
|
|
#include "nsIBrowser.h"
|
2003-10-30 06:01:25 +03:00
|
|
|
#include "nsContentUtils.h"
|
2009-11-06 23:43:39 +03:00
|
|
|
#include "nsIXPConnect.h"
|
2004-02-19 05:44:03 +03:00
|
|
|
#include "nsUnicharUtils.h"
|
2004-05-31 20:31:15 +04:00
|
|
|
#include "nsIScriptGlobalObject.h"
|
2002-01-29 09:27:27 +03:00
|
|
|
#include "nsIScriptSecurityManager.h"
|
2009-10-16 23:42:29 +04:00
|
|
|
#include "nsIScrollable.h"
|
2005-02-08 02:53:47 +03:00
|
|
|
#include "nsFrameLoader.h"
|
2008-08-08 03:15:40 +04:00
|
|
|
#include "nsIFrame.h"
|
2012-02-18 03:41:13 +04:00
|
|
|
#include "nsIScrollableFrame.h"
|
2010-08-31 04:49:07 +04:00
|
|
|
#include "nsSubDocumentFrame.h"
|
2012-07-27 18:03:27 +04:00
|
|
|
#include "nsError.h"
|
2008-10-08 17:04:32 +04:00
|
|
|
#include "nsISHistory.h"
|
2010-07-19 22:33:33 +04:00
|
|
|
#include "nsIXULWindow.h"
|
2012-03-04 20:02:00 +04:00
|
|
|
#include "nsIMozBrowserFrame.h"
|
2014-02-12 23:07:19 +04:00
|
|
|
#include "nsISHistory.h"
|
2014-11-24 22:05:35 +03:00
|
|
|
#include "nsIScriptError.h"
|
2015-02-06 19:26:29 +03:00
|
|
|
#include "nsGlobalWindow.h"
|
2018-01-26 09:00:49 +03:00
|
|
|
#include "nsHTMLDocument.h"
|
2015-02-06 19:26:29 +03:00
|
|
|
#include "nsPIWindowRoot.h"
|
2009-10-28 23:41:46 +03:00
|
|
|
#include "nsLayoutUtils.h"
|
2017-03-29 22:10:00 +03:00
|
|
|
#include "nsMappedAttributes.h"
|
2013-01-03 17:23:11 +04:00
|
|
|
#include "nsView.h"
|
2017-04-17 23:45:08 +03:00
|
|
|
#include "nsBaseWidget.h"
|
2017-10-05 08:59:44 +03:00
|
|
|
#include "nsQueryObject.h"
|
2002-01-29 09:27:27 +03:00
|
|
|
|
2003-08-08 17:14:06 +04:00
|
|
|
#include "nsIURI.h"
|
2003-08-09 00:32:22 +04:00
|
|
|
#include "nsIURL.h"
|
2002-01-29 09:27:27 +03:00
|
|
|
#include "nsNetUtil.h"
|
|
|
|
|
2006-12-26 20:47:52 +03:00
|
|
|
#include "nsGkAtoms.h"
|
2014-02-28 03:04:46 +04:00
|
|
|
#include "nsNameSpaceManager.h"
|
2002-04-17 08:17:16 +04:00
|
|
|
|
2008-02-26 17:47:51 +03:00
|
|
|
#include "nsThreadUtils.h"
|
2009-07-01 00:39:22 +04:00
|
|
|
|
2010-01-01 04:35:55 +03:00
|
|
|
#include "nsIDOMChromeWindow.h"
|
2018-08-11 00:08:07 +03:00
|
|
|
#include "InProcessTabChildMessageManager.h"
|
2010-01-01 04:35:55 +03:00
|
|
|
|
2011-01-13 20:45:14 +03:00
|
|
|
#include "Layers.h"
|
2014-10-07 06:30:42 +04:00
|
|
|
#include "ClientLayerManager.h"
|
2011-01-13 20:45:14 +03:00
|
|
|
|
2010-07-19 22:33:33 +04:00
|
|
|
#include "ContentParent.h"
|
2009-11-05 08:11:33 +03:00
|
|
|
#include "TabParent.h"
|
2014-03-17 10:56:54 +04:00
|
|
|
#include "mozilla/AsyncEventDispatcher.h"
|
2015-10-07 06:47:46 +03:00
|
|
|
#include "mozilla/BasePrincipal.h"
|
2011-11-16 11:50:19 +04:00
|
|
|
#include "mozilla/GuardObjects.h"
|
2017-08-07 09:02:16 +03:00
|
|
|
#include "mozilla/HTMLEditor.h"
|
2018-07-17 22:37:48 +03:00
|
|
|
#include "mozilla/NullPrincipal.h"
|
2011-05-25 10:31:59 +04:00
|
|
|
#include "mozilla/Preferences.h"
|
2016-08-23 07:09:32 +03:00
|
|
|
#include "mozilla/Unused.h"
|
2017-06-14 17:44:17 +03:00
|
|
|
#include "mozilla/dom/ChromeMessageSender.h"
|
2011-11-16 11:50:19 +04:00
|
|
|
#include "mozilla/dom/Element.h"
|
2017-08-19 10:55:00 +03:00
|
|
|
#include "mozilla/dom/FrameLoaderBinding.h"
|
2018-09-25 05:48:30 +03:00
|
|
|
#include "mozilla/gfx/CrossProcessPaint.h"
|
2015-01-27 00:32:18 +03:00
|
|
|
#include "mozilla/jsipc/CrossProcessObjectWrappers.h"
|
2018-11-07 00:35:37 +03:00
|
|
|
#include "mozilla/layout/RenderFrame.h"
|
2018-09-25 05:48:30 +03:00
|
|
|
#include "mozilla/ServoCSSParser.h"
|
|
|
|
#include "mozilla/ServoStyleSet.h"
|
2017-10-05 08:59:44 +03:00
|
|
|
#include "nsGenericHTMLFrameElement.h"
|
2013-03-18 18:25:50 +04:00
|
|
|
#include "GeckoProfiler.h"
|
2011-05-25 10:31:59 +04:00
|
|
|
|
2011-10-01 21:14:35 +04:00
|
|
|
#include "jsapi.h"
|
2013-02-23 04:59:26 +04:00
|
|
|
#include "mozilla/dom/HTMLIFrameElement.h"
|
2012-08-20 22:34:32 +04:00
|
|
|
#include "nsSandboxFlags.h"
|
2016-03-22 21:08:38 +03:00
|
|
|
#include "mozilla/layers/CompositorBridgeChild.h"
|
2016-11-09 22:51:02 +03:00
|
|
|
#include "mozilla/dom/CustomEvent.h"
|
2012-08-20 22:34:32 +04:00
|
|
|
|
2015-09-10 23:50:58 +03:00
|
|
|
#include "mozilla/dom/ipc/StructuredCloneData.h"
|
2015-08-06 00:25:39 +03:00
|
|
|
#include "mozilla/WebBrowserPersistLocalDocument.h"
|
2016-11-09 22:51:02 +03:00
|
|
|
#include "mozilla/dom/Promise.h"
|
|
|
|
#include "mozilla/dom/PromiseNativeHandler.h"
|
2018-02-02 01:35:47 +03:00
|
|
|
#include "mozilla/dom/ParentSHistory.h"
|
|
|
|
#include "mozilla/dom/ChildSHistory.h"
|
2018-10-20 03:02:37 +03:00
|
|
|
#include "mozilla/dom/ChromeBrowsingContext.h"
|
2011-10-01 21:14:35 +04:00
|
|
|
|
2017-06-21 13:14:01 +03:00
|
|
|
#include "mozilla/dom/HTMLBodyElement.h"
|
|
|
|
|
2018-07-17 22:38:48 +03:00
|
|
|
#include "mozilla/ContentPrincipal.h"
|
2015-10-22 06:44:00 +03:00
|
|
|
|
2017-02-09 19:53:50 +03:00
|
|
|
#ifdef XP_WIN
|
|
|
|
#include "mozilla/plugins/PPluginWidgetParent.h"
|
|
|
|
#include "../plugins/ipc/PluginWidgetParent.h"
|
|
|
|
#endif
|
|
|
|
|
2012-09-05 07:00:26 +04:00
|
|
|
#ifdef MOZ_XUL
|
|
|
|
#include "nsXULPopupManager.h"
|
|
|
|
#endif
|
|
|
|
|
2016-05-16 12:40:54 +03:00
|
|
|
#ifdef NS_PRINTING
|
|
|
|
#include "mozilla/embedding/printingui/PrintingParent.h"
|
|
|
|
#include "nsIWebBrowserPrint.h"
|
|
|
|
#endif
|
|
|
|
|
2009-11-05 08:11:33 +03:00
|
|
|
using namespace mozilla;
|
2013-02-15 00:41:30 +04:00
|
|
|
using namespace mozilla::hal;
|
2009-11-05 08:11:33 +03:00
|
|
|
using namespace mozilla::dom;
|
2012-09-28 09:43:12 +04:00
|
|
|
using namespace mozilla::dom::ipc;
|
2011-01-13 20:45:14 +03:00
|
|
|
using namespace mozilla::layers;
|
2011-07-18 22:04:47 +04:00
|
|
|
using namespace mozilla::layout;
|
2018-11-01 23:15:46 +03:00
|
|
|
typedef ScrollableLayerGuid::ViewID ViewID;
|
2011-01-13 20:45:14 +03:00
|
|
|
|
2003-08-09 00:32:22 +04:00
|
|
|
// Bug 136580: Limit to the number of nested content frames that can have the
|
|
|
|
// same URL. This is to stop content that is recursively loading
|
|
|
|
// itself. Note that "#foo" on the end of URL doesn't affect
|
|
|
|
// whether it's considered identical, but "?foo" or ";foo" are
|
|
|
|
// considered and compared.
|
2018-10-08 17:04:56 +03:00
|
|
|
// Limit this to 2, like chromium does.
|
|
|
|
#define MAX_SAME_URL_CONTENT_FRAMES 2
|
2003-08-09 00:32:22 +04:00
|
|
|
|
|
|
|
// Bug 8065: Limit content frame depth to some reasonable level. This
|
|
|
|
// does not count chrome frames when determining depth, nor does it
|
|
|
|
// prevent chrome recursion. Number is fairly arbitrary, but meant to
|
|
|
|
// keep number of shells to a reasonable number on accidental recursion with a
|
|
|
|
// small (but not 1) branching factor. With large branching factors the number
|
|
|
|
// of shells can rapidly become huge and run us out of memory. To solve that,
|
|
|
|
// we'd need to re-institute a fixed version of bug 98158.
|
|
|
|
#define MAX_DEPTH_CONTENT_FRAMES 10
|
|
|
|
|
2017-08-19 10:55:00 +03:00
|
|
|
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(nsFrameLoader, mDocShell, mMessageManager,
|
|
|
|
mChildMessageManager, mOpener,
|
2018-02-02 01:56:54 +03:00
|
|
|
mParentSHistory)
|
2011-03-06 14:11:31 +03:00
|
|
|
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsFrameLoader)
|
|
|
|
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsFrameLoader)
|
2007-03-08 14:17:16 +03:00
|
|
|
|
2007-04-25 20:35:27 +04:00
|
|
|
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsFrameLoader)
|
2017-08-19 10:55:00 +03:00
|
|
|
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
2018-05-22 02:33:18 +03:00
|
|
|
NS_INTERFACE_MAP_ENTRY_CONCRETE(nsFrameLoader)
|
2018-04-09 23:30:33 +03:00
|
|
|
NS_INTERFACE_MAP_ENTRY(nsIMutationObserver)
|
|
|
|
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
2007-03-08 14:17:16 +03:00
|
|
|
NS_INTERFACE_MAP_END
|
2002-01-29 09:27:27 +03:00
|
|
|
|
2018-04-13 16:01:28 +03:00
|
|
|
nsFrameLoader::nsFrameLoader(Element* aOwner, nsPIDOMWindowOuter* aOpener,
|
|
|
|
bool aNetworkCreated, int32_t aJSPluginID)
|
2011-01-13 20:45:14 +03:00
|
|
|
: mOwnerContent(aOwner),
|
2016-05-05 00:12:48 +03:00
|
|
|
mDetachedSubdocFrame(nullptr),
|
2016-10-17 17:37:50 +03:00
|
|
|
mOpener(aOpener),
|
2015-06-09 13:49:17 +03:00
|
|
|
mRemoteBrowser(nullptr),
|
|
|
|
mChildID(0),
|
2017-05-29 13:38:46 +03:00
|
|
|
mJSPluginID(aJSPluginID),
|
2011-10-17 18:59:28 +04:00
|
|
|
mDepthTooGreat(false),
|
|
|
|
mIsTopLevelContent(false),
|
|
|
|
mDestroyCalled(false),
|
|
|
|
mNeedsAsyncDestroy(false),
|
|
|
|
mInSwap(false),
|
|
|
|
mInShow(false),
|
|
|
|
mHideCalled(false),
|
2011-01-13 20:45:14 +03:00
|
|
|
mNetworkCreated(aNetworkCreated),
|
2017-11-05 07:06:20 +03:00
|
|
|
mLoadingOriginalSrc(false),
|
2011-10-17 18:59:28 +04:00
|
|
|
mRemoteBrowserShown(false),
|
2011-01-13 20:45:14 +03:00
|
|
|
mRemoteFrame(false),
|
2012-02-18 03:41:13 +04:00
|
|
|
mClampScrollPosition(true),
|
2012-09-05 07:00:26 +04:00
|
|
|
mObservingOwnerContent(false) {
|
2015-07-31 12:28:36 +03:00
|
|
|
mRemoteFrame = ShouldUseRemoteProcess();
|
2016-10-17 17:37:50 +03:00
|
|
|
MOZ_ASSERT(!mRemoteFrame || !aOpener,
|
|
|
|
"Cannot pass aOpener for a remote frame!");
|
2011-01-13 20:45:14 +03:00
|
|
|
}
|
|
|
|
|
2013-07-18 03:34:57 +04:00
|
|
|
nsFrameLoader::~nsFrameLoader() {
|
|
|
|
if (mMessageManager) {
|
|
|
|
mMessageManager->Disconnect();
|
|
|
|
}
|
2015-03-06 06:21:51 +03:00
|
|
|
MOZ_RELEASE_ASSERT(mDestroyCalled);
|
2013-07-18 03:34:57 +04:00
|
|
|
}
|
|
|
|
|
2017-05-29 13:38:46 +03:00
|
|
|
nsFrameLoader* nsFrameLoader::Create(Element* aOwner,
|
|
|
|
nsPIDOMWindowOuter* aOpener,
|
|
|
|
bool aNetworkCreated,
|
|
|
|
int32_t aJSPluginId) {
|
2012-07-30 18:20:58 +04:00
|
|
|
NS_ENSURE_TRUE(aOwner, nullptr);
|
2011-10-18 14:53:36 +04:00
|
|
|
nsIDocument* doc = aOwner->OwnerDoc();
|
2016-05-17 16:18:22 +03:00
|
|
|
|
|
|
|
// We never create nsFrameLoaders for elements in resource documents.
|
|
|
|
//
|
|
|
|
// We never create nsFrameLoaders for elements in data documents, unless the
|
|
|
|
// document is a static document.
|
|
|
|
// Static documents are an exception because any sub-documents need an
|
|
|
|
// nsFrameLoader to keep the relevant docShell alive, even though the
|
|
|
|
// nsFrameLoader isn't used to load anything (the sub-document is created by
|
|
|
|
// the static clone process).
|
|
|
|
//
|
|
|
|
// We never create nsFrameLoaders for elements that are not
|
|
|
|
// in-composed-document, unless the element belongs to a static document.
|
|
|
|
// Static documents are an exception because this method is called at a point
|
|
|
|
// in the static clone process before aOwner has been inserted into its
|
|
|
|
// document. For other types of documents this wouldn't be a problem since
|
|
|
|
// we'd create the nsFrameLoader as necessary after aOwner is inserted into a
|
|
|
|
// document, but the mechanisms that take care of that don't apply for static
|
|
|
|
// documents so we need to create the nsFrameLoader now. (This isn't wasteful
|
|
|
|
// since for a static document we know aOwner will end up in a document and
|
|
|
|
// the nsFrameLoader will be used for its docShell.)
|
|
|
|
//
|
2013-06-19 01:25:50 +04:00
|
|
|
NS_ENSURE_TRUE(!doc->IsResourceDoc() &&
|
2016-05-17 16:18:22 +03:00
|
|
|
((!doc->IsLoadedAsData() && aOwner->IsInComposedDoc()) ||
|
|
|
|
doc->IsStaticDocument()),
|
2012-07-30 18:20:58 +04:00
|
|
|
nullptr);
|
2009-08-19 13:09:26 +04:00
|
|
|
|
2017-05-29 13:38:46 +03:00
|
|
|
return new nsFrameLoader(aOwner, aOpener, aNetworkCreated, aJSPluginId);
|
2009-08-19 13:09:26 +04:00
|
|
|
}
|
|
|
|
|
2017-11-05 07:06:20 +03:00
|
|
|
void nsFrameLoader::LoadFrame(bool aOriginalSrc) {
|
2018-03-22 05:43:16 +03:00
|
|
|
if (NS_WARN_IF(!mOwnerContent)) {
|
|
|
|
return;
|
|
|
|
}
|
2002-01-29 09:27:27 +03:00
|
|
|
|
2002-04-17 08:17:16 +04:00
|
|
|
nsAutoString src;
|
2017-10-05 08:59:44 +03:00
|
|
|
nsCOMPtr<nsIPrincipal> principal;
|
2002-01-29 09:27:27 +03:00
|
|
|
|
2015-03-03 14:08:59 +03:00
|
|
|
bool isSrcdoc = mOwnerContent->IsHTMLElement(nsGkAtoms::iframe) &&
|
2013-06-29 07:13:23 +04:00
|
|
|
mOwnerContent->HasAttr(kNameSpaceID_None, nsGkAtoms::srcdoc);
|
|
|
|
if (isSrcdoc) {
|
|
|
|
src.AssignLiteral("about:srcdoc");
|
2018-09-28 17:00:13 +03:00
|
|
|
principal = mOwnerContent->NodePrincipal();
|
2013-06-29 07:13:23 +04:00
|
|
|
} else {
|
2017-10-05 08:59:44 +03:00
|
|
|
GetURL(src, getter_AddRefs(principal));
|
2013-06-29 07:13:23 +04:00
|
|
|
|
|
|
|
src.Trim(" \t\n\r");
|
|
|
|
|
|
|
|
if (src.IsEmpty()) {
|
|
|
|
// If the frame is a XUL element and has the attribute 'nodefaultsrc=true'
|
|
|
|
// then we will not use 'about:blank' as fallback but return early without
|
|
|
|
// starting a load if no 'src' attribute is given (or it's empty).
|
2015-03-03 14:08:59 +03:00
|
|
|
if (mOwnerContent->IsXULElement() &&
|
2013-06-29 07:13:23 +04:00
|
|
|
mOwnerContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::nodefaultsrc,
|
|
|
|
nsGkAtoms::_true, eCaseMatters)) {
|
2018-03-22 05:43:16 +03:00
|
|
|
return;
|
2013-06-29 07:13:23 +04:00
|
|
|
}
|
|
|
|
src.AssignLiteral("about:blank");
|
2018-09-28 17:00:13 +03:00
|
|
|
principal = mOwnerContent->NodePrincipal();
|
2013-06-06 23:05:21 +04:00
|
|
|
}
|
2002-04-17 08:17:16 +04:00
|
|
|
}
|
2002-01-29 09:27:27 +03:00
|
|
|
|
2011-10-18 14:53:36 +04:00
|
|
|
nsIDocument* doc = mOwnerContent->OwnerDoc();
|
2011-10-18 15:19:44 +04:00
|
|
|
if (doc->IsStaticDocument()) {
|
2018-03-22 05:43:16 +03:00
|
|
|
return;
|
2005-09-21 23:14:30 +04:00
|
|
|
}
|
|
|
|
|
2016-05-12 19:22:25 +03:00
|
|
|
if (doc->IsLoadedAsInteractiveData()) {
|
|
|
|
// XBL bindings doc shouldn't load sub-documents.
|
2018-03-22 05:43:16 +03:00
|
|
|
return;
|
2016-05-12 19:22:25 +03:00
|
|
|
}
|
|
|
|
|
2005-05-01 17:06:48 +04:00
|
|
|
nsCOMPtr<nsIURI> base_uri = mOwnerContent->GetBaseURI();
|
2017-06-18 14:37:50 +03:00
|
|
|
auto encoding = doc->GetDocumentCharacterSet();
|
2002-04-17 08:17:16 +04:00
|
|
|
|
|
|
|
nsCOMPtr<nsIURI> uri;
|
2017-06-18 14:37:50 +03:00
|
|
|
nsresult rv = NS_NewURI(getter_AddRefs(uri), src, encoding, base_uri);
|
2006-01-17 21:13:31 +03:00
|
|
|
|
|
|
|
// If the URI was malformed, try to recover by loading about:blank.
|
|
|
|
if (rv == NS_ERROR_MALFORMED_URI) {
|
|
|
|
rv = NS_NewURI(getter_AddRefs(uri), NS_LITERAL_STRING("about:blank"),
|
2017-06-18 14:37:50 +03:00
|
|
|
encoding, base_uri);
|
2006-01-17 21:13:31 +03:00
|
|
|
}
|
|
|
|
|
2010-02-25 05:45:43 +03:00
|
|
|
if (NS_SUCCEEDED(rv)) {
|
2017-11-05 07:06:20 +03:00
|
|
|
rv = LoadURI(uri, principal, aOriginalSrc);
|
2010-02-25 05:45:43 +03:00
|
|
|
}
|
2015-11-24 04:40:02 +03:00
|
|
|
|
2010-02-25 05:45:43 +03:00
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
FireErrorEvent();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void nsFrameLoader::FireErrorEvent() {
|
2014-03-17 10:56:54 +04:00
|
|
|
if (!mOwnerContent) {
|
|
|
|
return;
|
2010-02-25 05:45:43 +03:00
|
|
|
}
|
2018-06-25 19:23:50 +03:00
|
|
|
RefPtr<AsyncEventDispatcher> loadBlockingAsyncDispatcher =
|
2014-03-17 10:56:54 +04:00
|
|
|
new LoadBlockingAsyncEventDispatcher(
|
|
|
|
mOwnerContent, NS_LITERAL_STRING("error"), CanBubble::eNo,
|
2018-06-25 19:23:50 +03:00
|
|
|
ChromeOnlyDispatch::eNo);
|
2014-03-17 10:56:54 +04:00
|
|
|
loadBlockingAsyncDispatcher->PostDOMEvent();
|
2005-09-21 23:14:30 +04:00
|
|
|
}
|
|
|
|
|
2017-11-05 07:06:20 +03:00
|
|
|
nsresult nsFrameLoader::LoadURI(nsIURI* aURI,
|
|
|
|
nsIPrincipal* aTriggeringPrincipal,
|
|
|
|
bool aOriginalSrc) {
|
2005-09-21 23:14:30 +04:00
|
|
|
if (!aURI) return NS_ERROR_INVALID_POINTER;
|
2008-03-21 14:44:09 +03:00
|
|
|
NS_ENSURE_STATE(!mDestroyCalled && mOwnerContent);
|
2018-09-28 17:00:13 +03:00
|
|
|
MOZ_ASSERT(
|
|
|
|
aTriggeringPrincipal,
|
|
|
|
"Must have an explicit triggeringPrincipal to nsFrameLoader::LoadURI.");
|
2005-09-21 23:14:30 +04:00
|
|
|
|
2017-11-05 07:06:20 +03:00
|
|
|
mLoadingOriginalSrc = aOriginalSrc;
|
|
|
|
|
2011-10-18 14:53:36 +04:00
|
|
|
nsCOMPtr<nsIDocument> doc = mOwnerContent->OwnerDoc();
|
2005-09-21 23:14:30 +04:00
|
|
|
|
2017-05-29 13:38:46 +03:00
|
|
|
nsresult rv;
|
|
|
|
// If IsForJSPlugin() returns true then we want to allow the load. We're just
|
|
|
|
// loading the source for the implementation of the JS plugin from a URI
|
|
|
|
// that's under our control. We will already have done the security checks for
|
|
|
|
// loading the plugin content itself in the object/embed loading code.
|
|
|
|
if (!IsForJSPlugin()) {
|
2017-10-05 08:59:44 +03:00
|
|
|
rv = CheckURILoad(aURI, aTriggeringPrincipal);
|
2017-05-29 13:38:46 +03:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
}
|
2008-03-21 14:44:09 +03:00
|
|
|
|
|
|
|
mURIToLoad = aURI;
|
2017-10-05 08:59:44 +03:00
|
|
|
mTriggeringPrincipal = aTriggeringPrincipal;
|
2008-03-21 14:44:09 +03:00
|
|
|
rv = doc->InitializeFrameLoader(this);
|
|
|
|
if (NS_FAILED(rv)) {
|
2012-07-30 18:20:58 +04:00
|
|
|
mURIToLoad = nullptr;
|
2017-10-05 08:59:44 +03:00
|
|
|
mTriggeringPrincipal = nullptr;
|
2008-03-21 14:44:09 +03:00
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult nsFrameLoader::ReallyStartLoading() {
|
2010-02-25 05:45:43 +03:00
|
|
|
nsresult rv = ReallyStartLoadingInternal();
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
FireErrorEvent();
|
|
|
|
}
|
2015-11-24 04:40:02 +03:00
|
|
|
|
2010-02-25 05:45:43 +03:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult nsFrameLoader::ReallyStartLoadingInternal() {
|
2015-02-24 17:41:43 +03:00
|
|
|
NS_ENSURE_STATE(mURIToLoad && mOwnerContent &&
|
|
|
|
mOwnerContent->IsInComposedDoc());
|
2009-07-01 00:39:22 +04:00
|
|
|
|
Bug 1375392 - Tweak the PROFILER_LABEL* macros. r=mstange.
This patch makes the following changes to the macros.
- Removes PROFILER_LABEL_FUNC. It's only suitable for use in functions outside
classes, due to PROFILER_FUNCTION_NAME not getting class names, and it was
mostly misused.
- Removes PROFILER_FUNCTION_NAME. It's no longer used, and __func__ is
universally available now anyway.
- Combines the first two string literal arguments of PROFILER_LABEL and
PROFILER_LABEL_DYNAMIC into a single argument. There was no good reason for
them to be separate, and it forced a '::' in the label, which isn't always
appropriate. Also, the meaning of the "name_space" argument was interpreted
in an interesting variety of ways.
- Adds an "AUTO_" prefix to PROFILER_LABEL and PROFILER_LABEL_DYNAMIC, to make
it clearer they construct RAII objects rather than just being function calls.
(I myself have screwed up the scoping because of this in the past.)
- Fills in the 'js::ProfileEntry::Category::' qualifier within the macro, so
the caller doesn't need to. This makes a *lot* more of the uses fit onto a
single line.
The patch also makes the following changes to the macro uses (beyond those
required by the changes described above).
- Fixes a bunch of labels that had gotten out of sync with the name of the
class and/or function that encloses them.
- Removes a useless PROFILER_LABEL use within a trivial scope in
EventStateManager::DispatchMouseOrPointerEvent(). It clearly wasn't serving
any useful purpose. It also serves as extra evidence that the AUTO_ prefix is
a good idea.
- Tweaks DecodePool::SyncRunIf{Preferred,Possible} so that the labelling is
done within them, instead of at their callsites, because that's a more
standard way of doing things.
--HG--
extra : rebase_source : 318d1bc6fc1425a94aacbf489dd46e4f83211de4
2017-06-22 10:08:53 +03:00
|
|
|
AUTO_PROFILER_LABEL("nsFrameLoader::ReallyStartLoadingInternal", OTHER);
|
2013-01-31 10:40:43 +04:00
|
|
|
|
2015-07-31 12:28:36 +03:00
|
|
|
if (IsRemoteFrame()) {
|
2015-04-07 05:56:10 +03:00
|
|
|
if (!mRemoteBrowser && !TryRemoteBrowser()) {
|
2010-10-20 15:44:50 +04:00
|
|
|
NS_WARNING("Couldn't create child process for iframe.");
|
|
|
|
return NS_ERROR_FAILURE;
|
2009-10-16 23:42:27 +04:00
|
|
|
}
|
|
|
|
|
2015-04-07 05:56:10 +03:00
|
|
|
// FIXME get error codes from child
|
|
|
|
mRemoteBrowser->LoadURL(mURIToLoad);
|
2015-11-24 04:40:02 +03:00
|
|
|
|
2017-12-20 01:49:25 +03:00
|
|
|
if (!mRemoteBrowserShown) {
|
|
|
|
// This can fail if it's too early to show the frame, we will retry later.
|
|
|
|
Unused << ShowRemoteFrame(ScreenIntSize(0, 0));
|
2012-04-25 20:35:58 +04:00
|
|
|
}
|
|
|
|
|
2009-07-01 00:39:22 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
2008-03-21 14:44:09 +03:00
|
|
|
|
2015-07-31 12:28:36 +03:00
|
|
|
nsresult rv = MaybeCreateDocShell();
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
2009-10-16 23:42:27 +04:00
|
|
|
NS_ASSERTION(mDocShell,
|
|
|
|
"MaybeCreateDocShell succeeded with a null mDocShell");
|
|
|
|
|
|
|
|
// Just to be safe, recheck uri.
|
2017-10-05 08:59:44 +03:00
|
|
|
rv = CheckURILoad(mURIToLoad, mTriggeringPrincipal);
|
2002-04-17 08:17:16 +04:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2002-01-29 09:27:27 +03:00
|
|
|
|
2018-12-21 23:17:43 +03:00
|
|
|
RefPtr<nsDocShellLoadState> loadState = new nsDocShellLoadState(mURIToLoad);
|
2002-01-29 09:27:27 +03:00
|
|
|
|
2018-10-30 03:13:29 +03:00
|
|
|
loadState->SetOriginalFrameSrc(mLoadingOriginalSrc);
|
2017-11-05 07:06:20 +03:00
|
|
|
mLoadingOriginalSrc = false;
|
|
|
|
|
2013-03-15 21:25:31 +04:00
|
|
|
// If this frame is sandboxed with respect to origin we will set it up with
|
|
|
|
// a null principal later in nsDocShell::DoURILoad.
|
2012-08-20 22:34:32 +04:00
|
|
|
// We do it there to correctly sandbox content that was loaded into
|
2013-03-15 21:25:31 +04:00
|
|
|
// the frame via other methods than the src attribute.
|
2012-06-22 14:04:47 +04:00
|
|
|
// We'll use our principal, not that of the document loaded inside us. This
|
|
|
|
// is very important; needed to prevent XSS attacks on documents loaded in
|
|
|
|
// subframes!
|
2017-10-05 08:59:44 +03:00
|
|
|
if (mTriggeringPrincipal) {
|
2018-10-30 03:13:29 +03:00
|
|
|
loadState->SetTriggeringPrincipal(mTriggeringPrincipal);
|
2017-10-05 08:59:44 +03:00
|
|
|
} else {
|
2018-10-30 03:13:29 +03:00
|
|
|
loadState->SetTriggeringPrincipal(mOwnerContent->NodePrincipal());
|
2017-10-05 08:59:44 +03:00
|
|
|
}
|
2008-03-21 14:44:09 +03:00
|
|
|
|
|
|
|
nsCOMPtr<nsIURI> referrer;
|
2015-11-24 04:40:02 +03:00
|
|
|
|
2013-06-29 07:13:23 +04:00
|
|
|
nsAutoString srcdoc;
|
2015-03-03 14:08:59 +03:00
|
|
|
bool isSrcdoc =
|
|
|
|
mOwnerContent->IsHTMLElement(nsGkAtoms::iframe) &&
|
2013-06-29 07:13:23 +04:00
|
|
|
mOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::srcdoc, srcdoc);
|
|
|
|
|
|
|
|
if (isSrcdoc) {
|
|
|
|
nsAutoString referrerStr;
|
|
|
|
mOwnerContent->OwnerDoc()->GetReferrer(referrerStr);
|
|
|
|
rv = NS_NewURI(getter_AddRefs(referrer), referrerStr);
|
|
|
|
|
2018-10-30 03:13:29 +03:00
|
|
|
loadState->SetSrcdocData(srcdoc);
|
2014-02-06 18:46:29 +04:00
|
|
|
nsCOMPtr<nsIURI> baseURI = mOwnerContent->GetBaseURI();
|
2018-10-30 03:13:29 +03:00
|
|
|
loadState->SetBaseURI(baseURI);
|
2013-06-29 07:13:23 +04:00
|
|
|
} else {
|
|
|
|
rv = mOwnerContent->NodePrincipal()->GetURI(getter_AddRefs(referrer));
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
}
|
2008-03-21 14:44:09 +03:00
|
|
|
|
2017-03-22 13:38:40 +03:00
|
|
|
// Use referrer as long as it is not an NullPrincipalURI.
|
2014-03-29 23:10:27 +04:00
|
|
|
// We could add a method such as GetReferrerURI to principals to make this
|
|
|
|
// cleaner, but given that we need to start using Source Browsing Context for
|
|
|
|
// referrer (see Bug 960639) this may be wasted effort at this stage.
|
|
|
|
if (referrer) {
|
|
|
|
bool isNullPrincipalScheme;
|
|
|
|
rv = referrer->SchemeIs(NS_NULLPRINCIPAL_SCHEME, &isNullPrincipalScheme);
|
|
|
|
if (NS_SUCCEEDED(rv) && !isNullPrincipalScheme) {
|
2018-10-30 03:13:29 +03:00
|
|
|
loadState->SetReferrer(referrer);
|
2014-03-29 23:10:27 +04:00
|
|
|
}
|
|
|
|
}
|
2008-03-21 14:44:09 +03:00
|
|
|
|
2015-07-17 20:46:19 +03:00
|
|
|
// get referrer policy for this iframe:
|
|
|
|
// first load document wide policy, then
|
|
|
|
// load iframe referrer attribute if enabled in preferences
|
|
|
|
// per element referrer overrules document wide referrer if enabled
|
|
|
|
net::ReferrerPolicy referrerPolicy =
|
|
|
|
mOwnerContent->OwnerDoc()->GetReferrerPolicy();
|
2018-03-22 00:39:04 +03:00
|
|
|
HTMLIFrameElement* iframe = HTMLIFrameElement::FromNode(mOwnerContent);
|
2015-07-17 20:46:19 +03:00
|
|
|
if (iframe) {
|
2015-12-01 03:13:03 +03:00
|
|
|
net::ReferrerPolicy iframeReferrerPolicy =
|
|
|
|
iframe->GetReferrerPolicyAsEnum();
|
2015-07-17 20:46:19 +03:00
|
|
|
if (iframeReferrerPolicy != net::RP_Unset) {
|
|
|
|
referrerPolicy = iframeReferrerPolicy;
|
|
|
|
}
|
|
|
|
}
|
2018-10-30 03:13:29 +03:00
|
|
|
loadState->SetReferrerPolicy(referrerPolicy);
|
2014-11-18 16:46:29 +03:00
|
|
|
|
2012-10-26 12:46:27 +04:00
|
|
|
// Default flags:
|
|
|
|
int32_t flags = nsIWebNavigation::LOAD_FLAGS_NONE;
|
|
|
|
|
|
|
|
// Flags for browser frame:
|
2016-02-18 06:31:29 +03:00
|
|
|
if (OwnerIsMozBrowserFrame()) {
|
2012-10-26 12:46:27 +04:00
|
|
|
flags = nsIWebNavigation::LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP |
|
2016-07-28 10:20:41 +03:00
|
|
|
nsIWebNavigation::LOAD_FLAGS_DISALLOW_INHERIT_PRINCIPAL;
|
2012-10-26 12:46:27 +04:00
|
|
|
}
|
|
|
|
|
2018-11-21 19:28:20 +03:00
|
|
|
loadState->SetIsFromProcessingFrameAttributes();
|
|
|
|
|
2008-03-21 14:44:09 +03:00
|
|
|
// Kick off the load...
|
2011-09-29 10:19:26 +04:00
|
|
|
bool tmpState = mNeedsAsyncDestroy;
|
2011-10-17 18:59:28 +04:00
|
|
|
mNeedsAsyncDestroy = true;
|
2018-10-30 03:13:29 +03:00
|
|
|
loadState->SetLoadFlags(flags);
|
|
|
|
loadState->SetFirstParty(false);
|
|
|
|
rv = mDocShell->LoadURI(loadState);
|
2009-01-14 14:01:46 +03:00
|
|
|
mNeedsAsyncDestroy = tmpState;
|
2012-07-30 18:20:58 +04:00
|
|
|
mURIToLoad = nullptr;
|
2010-02-25 05:45:43 +03:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
2008-03-21 14:44:09 +03:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2017-10-05 08:59:44 +03:00
|
|
|
nsresult nsFrameLoader::CheckURILoad(nsIURI* aURI,
|
|
|
|
nsIPrincipal* aTriggeringPrincipal) {
|
2006-02-27 22:14:51 +03:00
|
|
|
// Check for security. The fun part is trying to figure out what principals
|
|
|
|
// to use. The way I figure it, if we're doing a LoadFrame() accidentally
|
|
|
|
// (eg someone created a frame/iframe node, we're being parsed, XUL iframes
|
|
|
|
// are being reframed, etc.) then we definitely want to use the node
|
|
|
|
// principal of mOwnerContent for security checks. If, on the other hand,
|
|
|
|
// someone's setting the src on our owner content, or created it via script,
|
|
|
|
// or whatever, then they can clearly access it... and we should still use
|
|
|
|
// the principal of mOwnerContent. I don't think that leads to privilege
|
|
|
|
// escalation, and it's reasonably guaranteed to not lead to XSS issues
|
2006-02-28 08:21:17 +03:00
|
|
|
// (since caller can already access mOwnerContent in this case). So just use
|
2006-02-27 22:14:51 +03:00
|
|
|
// the principal of mOwnerContent no matter what. If script wants to run
|
|
|
|
// things with its own permissions, which differ from those of mOwnerContent
|
|
|
|
// (which means the script is privileged in some way) it should set
|
|
|
|
// window.location instead.
|
2005-10-14 13:07:29 +04:00
|
|
|
nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager();
|
2003-10-30 06:01:25 +03:00
|
|
|
|
2006-02-27 22:14:51 +03:00
|
|
|
// Get our principal
|
2017-10-05 08:59:44 +03:00
|
|
|
nsIPrincipal* principal =
|
|
|
|
(aTriggeringPrincipal ? aTriggeringPrincipal
|
|
|
|
: mOwnerContent->NodePrincipal());
|
2002-01-29 09:27:27 +03:00
|
|
|
|
|
|
|
// Check if we are allowed to load absURL
|
2008-03-21 14:44:09 +03:00
|
|
|
nsresult rv = secMan->CheckLoadURIWithPrincipal(
|
|
|
|
principal, aURI, nsIScriptSecurityManager::STANDARD);
|
2002-01-29 09:27:27 +03:00
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv; // We're not
|
|
|
|
}
|
|
|
|
|
2005-03-08 03:02:55 +03:00
|
|
|
// Bail out if this is an infinite recursion scenario
|
2015-07-31 12:28:36 +03:00
|
|
|
if (IsRemoteFrame()) {
|
2009-10-16 23:42:27 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
2008-03-21 14:44:09 +03:00
|
|
|
return CheckForRecursiveLoad(aURI);
|
2002-01-29 09:27:27 +03:00
|
|
|
}
|
|
|
|
|
2019-01-02 16:27:05 +03:00
|
|
|
nsDocShell* nsFrameLoader::GetDocShell(ErrorResult& aRv) {
|
2015-07-31 12:28:36 +03:00
|
|
|
if (IsRemoteFrame()) {
|
2018-03-22 05:43:15 +03:00
|
|
|
return nullptr;
|
2015-07-31 12:28:36 +03:00
|
|
|
}
|
|
|
|
|
2003-05-09 05:42:13 +04:00
|
|
|
// If we have an owner, make sure we have a docshell and return
|
|
|
|
// that. If not, we're most likely in the middle of being torn down,
|
|
|
|
// then we just return null.
|
|
|
|
if (mOwnerContent) {
|
2009-10-16 23:42:27 +04:00
|
|
|
nsresult rv = MaybeCreateDocShell();
|
2015-07-31 12:28:36 +03:00
|
|
|
if (NS_FAILED(rv)) {
|
2018-03-22 05:43:15 +03:00
|
|
|
aRv.Throw(rv);
|
|
|
|
return nullptr;
|
2009-10-16 23:42:27 +04:00
|
|
|
}
|
|
|
|
NS_ASSERTION(mDocShell,
|
|
|
|
"MaybeCreateDocShell succeeded, but null mDocShell");
|
2003-05-09 05:42:13 +04:00
|
|
|
}
|
2002-01-29 09:27:27 +03:00
|
|
|
|
2018-03-22 05:43:15 +03:00
|
|
|
return mDocShell;
|
2002-01-29 09:27:27 +03:00
|
|
|
}
|
|
|
|
|
2008-08-08 03:15:40 +04:00
|
|
|
static void SetTreeOwnerAndChromeEventHandlerOnDocshellTree(
|
|
|
|
nsIDocShellTreeItem* aItem, nsIDocShellTreeOwner* aOwner,
|
2013-04-06 04:44:15 +04:00
|
|
|
EventTarget* aHandler) {
|
2018-04-28 22:50:58 +03:00
|
|
|
MOZ_ASSERT(aItem, "Must have item");
|
2008-08-08 03:15:40 +04:00
|
|
|
|
|
|
|
aItem->SetTreeOwner(aOwner);
|
|
|
|
|
2012-08-22 19:56:38 +04:00
|
|
|
int32_t childCount = 0;
|
2008-08-08 03:15:40 +04:00
|
|
|
aItem->GetChildCount(&childCount);
|
2012-08-22 19:56:38 +04:00
|
|
|
for (int32_t i = 0; i < childCount; ++i) {
|
2008-08-08 03:15:40 +04:00
|
|
|
nsCOMPtr<nsIDocShellTreeItem> item;
|
|
|
|
aItem->GetChildAt(i, getter_AddRefs(item));
|
2012-12-21 15:58:23 +04:00
|
|
|
if (aHandler) {
|
|
|
|
nsCOMPtr<nsIDocShell> shell(do_QueryInterface(item));
|
|
|
|
shell->SetChromeEventHandler(aHandler);
|
|
|
|
}
|
2008-08-08 03:15:40 +04:00
|
|
|
SetTreeOwnerAndChromeEventHandlerOnDocshellTree(item, aOwner, aHandler);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-06 22:35:25 +03:00
|
|
|
#if defined(MOZ_DIAGNOSTIC_ASSERT_ENABLED)
|
2018-11-05 15:43:10 +03:00
|
|
|
static bool CheckDocShellType(mozilla::dom::Element* aOwnerContent,
|
|
|
|
nsIDocShellTreeItem* aDocShell, nsAtom* aAtom) {
|
|
|
|
bool isContent = aOwnerContent->AttrValueIs(kNameSpaceID_None, aAtom,
|
|
|
|
nsGkAtoms::content, eIgnoreCase);
|
2008-08-08 03:15:40 +04:00
|
|
|
|
2018-11-05 15:43:10 +03:00
|
|
|
if (!isContent) {
|
|
|
|
nsCOMPtr<nsIMozBrowserFrame> mozbrowser =
|
|
|
|
aOwnerContent->GetAsMozBrowserFrame();
|
|
|
|
if (mozbrowser) {
|
|
|
|
mozbrowser->GetMozbrowser(&isContent);
|
|
|
|
}
|
2012-06-20 23:25:22 +04:00
|
|
|
}
|
|
|
|
|
2008-08-08 03:15:40 +04:00
|
|
|
if (isContent) {
|
2018-11-05 15:43:10 +03:00
|
|
|
return aDocShell->ItemType() == nsIDocShellTreeItem::typeContent;
|
|
|
|
}
|
2008-08-08 03:15:40 +04:00
|
|
|
|
2018-11-05 15:43:10 +03:00
|
|
|
nsCOMPtr<nsIDocShellTreeItem> parent;
|
|
|
|
aDocShell->GetParent(getter_AddRefs(parent));
|
2008-08-08 03:15:40 +04:00
|
|
|
|
2018-11-05 15:43:10 +03:00
|
|
|
return parent && parent->ItemType() == aDocShell->ItemType();
|
|
|
|
}
|
2018-11-06 22:35:25 +03:00
|
|
|
#endif // defined(MOZ_DIAGNOSTIC_ASSERT_ENABLED)
|
2008-08-08 03:15:40 +04:00
|
|
|
|
2018-11-05 15:43:10 +03:00
|
|
|
/**
|
|
|
|
* Hook up a given TreeItem to its tree owner. aItem's type must have already
|
|
|
|
* been set, and it should already be part of the DocShellTree.
|
|
|
|
* @param aItem the treeitem we're working with
|
|
|
|
* @param aTreeOwner the relevant treeowner; might be null
|
|
|
|
*/
|
|
|
|
void nsFrameLoader::AddTreeItemToTreeOwner(nsIDocShellTreeItem* aItem,
|
|
|
|
nsIDocShellTreeOwner* aOwner) {
|
|
|
|
MOZ_ASSERT(aItem, "Must have docshell treeitem");
|
|
|
|
MOZ_ASSERT(mOwnerContent, "Must have owning content");
|
2008-08-08 03:15:40 +04:00
|
|
|
|
2018-11-05 15:43:10 +03:00
|
|
|
MOZ_DIAGNOSTIC_ASSERT(
|
|
|
|
CheckDocShellType(mOwnerContent, aItem, TypeAttrName()),
|
|
|
|
"Correct ItemType should be set when creating BrowsingContext");
|
2008-08-08 03:15:40 +04:00
|
|
|
|
2018-11-05 15:43:10 +03:00
|
|
|
if (mIsTopLevelContent) {
|
2016-12-09 22:23:24 +03:00
|
|
|
bool is_primary = mOwnerContent->AttrValueIs(
|
|
|
|
kNameSpaceID_None, nsGkAtoms::primary, nsGkAtoms::_true, eIgnoreCase);
|
2008-08-08 03:15:40 +04:00
|
|
|
if (aOwner) {
|
2012-09-05 07:00:26 +04:00
|
|
|
mOwnerContent->AddMutationObserver(this);
|
|
|
|
mObservingOwnerContent = true;
|
2016-12-09 00:12:36 +03:00
|
|
|
aOwner->ContentShellAdded(aItem, is_primary);
|
2008-08-08 03:15:40 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-08-22 19:56:38 +04:00
|
|
|
static bool AllDescendantsOfType(nsIDocShellTreeItem* aParentItem,
|
|
|
|
int32_t aType) {
|
|
|
|
int32_t childCount = 0;
|
2008-10-08 17:04:32 +04:00
|
|
|
aParentItem->GetChildCount(&childCount);
|
|
|
|
|
2012-08-22 19:56:38 +04:00
|
|
|
for (int32_t i = 0; i < childCount; ++i) {
|
2008-10-08 17:04:32 +04:00
|
|
|
nsCOMPtr<nsIDocShellTreeItem> kid;
|
|
|
|
aParentItem->GetChildAt(i, getter_AddRefs(kid));
|
|
|
|
|
2014-01-20 11:58:26 +04:00
|
|
|
if (kid->ItemType() != aType || !AllDescendantsOfType(kid, aType)) {
|
2011-10-17 18:59:28 +04:00
|
|
|
return false;
|
2008-10-08 17:04:32 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-10-17 18:59:28 +04:00
|
|
|
return true;
|
2008-10-08 17:04:32 +04:00
|
|
|
}
|
|
|
|
|
2010-05-28 23:34:50 +04:00
|
|
|
/**
|
|
|
|
* A class that automatically sets mInShow to false when it goes
|
|
|
|
* out of scope.
|
|
|
|
*/
|
2015-09-03 19:15:23 +03:00
|
|
|
class MOZ_RAII AutoResetInShow {
|
2010-05-28 23:34:50 +04:00
|
|
|
private:
|
|
|
|
nsFrameLoader* mFrameLoader;
|
2012-01-10 09:29:30 +04:00
|
|
|
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
2010-05-28 23:34:50 +04:00
|
|
|
public:
|
2014-09-02 04:49:25 +04:00
|
|
|
explicit AutoResetInShow(
|
|
|
|
nsFrameLoader* aFrameLoader MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
2010-05-28 23:34:50 +04:00
|
|
|
: mFrameLoader(aFrameLoader) {
|
2012-01-10 09:29:30 +04:00
|
|
|
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
2010-05-28 23:34:50 +04:00
|
|
|
}
|
2011-10-17 18:59:28 +04:00
|
|
|
~AutoResetInShow() { mFrameLoader->mInShow = false; }
|
2010-05-28 23:34:50 +04:00
|
|
|
};
|
|
|
|
|
2017-04-06 10:58:02 +03:00
|
|
|
static bool ParentWindowIsActive(nsIDocument* aDoc) {
|
|
|
|
nsCOMPtr<nsPIWindowRoot> root = nsContentUtils::GetWindowRoot(aDoc);
|
|
|
|
if (root) {
|
|
|
|
nsPIDOMWindowOuter* rootWin = root->GetWindow();
|
|
|
|
return rootWin && rootWin->IsActive();
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2010-05-28 23:34:50 +04:00
|
|
|
|
2017-07-21 00:24:40 +03:00
|
|
|
void nsFrameLoader::MaybeShowFrame() {
|
|
|
|
nsIFrame* frame = GetPrimaryFrameOfOwningContent();
|
|
|
|
if (frame) {
|
|
|
|
nsSubDocumentFrame* subDocFrame = do_QueryFrame(frame);
|
|
|
|
if (subDocFrame) {
|
|
|
|
subDocFrame->MaybeShowViewer();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-08-22 19:56:38 +04:00
|
|
|
bool nsFrameLoader::Show(int32_t marginWidth, int32_t marginHeight,
|
|
|
|
int32_t scrollbarPrefX, int32_t scrollbarPrefY,
|
2010-08-31 04:49:07 +04:00
|
|
|
nsSubDocumentFrame* frame) {
|
2010-05-28 23:34:50 +04:00
|
|
|
if (mInShow) {
|
2011-10-17 18:59:28 +04:00
|
|
|
return false;
|
2010-05-28 23:34:50 +04:00
|
|
|
}
|
|
|
|
// Reset mInShow if we exit early.
|
|
|
|
AutoResetInShow resetInShow(this);
|
2011-10-17 18:59:28 +04:00
|
|
|
mInShow = true;
|
2010-05-28 23:34:50 +04:00
|
|
|
|
2015-07-31 12:28:36 +03:00
|
|
|
ScreenIntSize size = frame->GetSubdocumentSize();
|
|
|
|
if (IsRemoteFrame()) {
|
|
|
|
return ShowRemoteFrame(size, frame);
|
|
|
|
}
|
|
|
|
|
2009-10-16 23:42:29 +04:00
|
|
|
nsresult rv = MaybeCreateDocShell();
|
|
|
|
if (NS_FAILED(rv)) {
|
2011-10-17 18:59:28 +04:00
|
|
|
return false;
|
2009-10-16 23:42:29 +04:00
|
|
|
}
|
2015-07-31 12:28:36 +03:00
|
|
|
NS_ASSERTION(mDocShell, "MaybeCreateDocShell succeeded, but null mDocShell");
|
|
|
|
if (!mDocShell) {
|
|
|
|
return false;
|
|
|
|
}
|
2009-10-16 23:42:29 +04:00
|
|
|
|
2015-07-31 12:28:36 +03:00
|
|
|
mDocShell->SetMarginWidth(marginWidth);
|
|
|
|
mDocShell->SetMarginHeight(marginHeight);
|
2012-12-07 03:58:15 +04:00
|
|
|
|
2019-01-02 16:27:05 +03:00
|
|
|
mDocShell->SetDefaultScrollbarPreferences(nsIScrollable::ScrollOrientation_X,
|
|
|
|
scrollbarPrefX);
|
|
|
|
mDocShell->SetDefaultScrollbarPreferences(nsIScrollable::ScrollOrientation_Y,
|
|
|
|
scrollbarPrefY);
|
2009-10-16 23:42:29 +04:00
|
|
|
|
2015-07-31 12:28:36 +03:00
|
|
|
nsCOMPtr<nsIPresShell> presShell = mDocShell->GetPresShell();
|
|
|
|
if (presShell) {
|
|
|
|
// Ensure root scroll frame is reflowed in case scroll preferences or
|
|
|
|
// margins have changed
|
|
|
|
nsIFrame* rootScrollFrame = presShell->GetRootScrollFrame();
|
|
|
|
if (rootScrollFrame) {
|
|
|
|
presShell->FrameNeedsReflow(rootScrollFrame, nsIPresShell::eResize,
|
|
|
|
NS_FRAME_IS_DIRTY);
|
|
|
|
}
|
|
|
|
return true;
|
2013-01-10 11:23:55 +04:00
|
|
|
}
|
|
|
|
|
2013-01-03 17:23:11 +04:00
|
|
|
nsView* view = frame->EnsureInnerView();
|
2011-10-17 18:59:28 +04:00
|
|
|
if (!view) return false;
|
2009-10-16 23:42:29 +04:00
|
|
|
|
2019-01-02 16:27:05 +03:00
|
|
|
RefPtr<nsDocShell> baseWindow = mDocShell;
|
2012-07-30 18:20:58 +04:00
|
|
|
baseWindow->InitWindow(nullptr, view->GetWidget(), 0, 0, size.width,
|
2010-11-04 23:06:05 +03:00
|
|
|
size.height);
|
2009-10-28 23:41:46 +03:00
|
|
|
// This is kinda whacky, this "Create()" call doesn't really
|
|
|
|
// create anything, one starts to wonder why this was named
|
|
|
|
// "Create"...
|
|
|
|
baseWindow->Create();
|
2011-10-17 18:59:28 +04:00
|
|
|
baseWindow->SetVisibility(true);
|
2013-04-13 16:30:38 +04:00
|
|
|
NS_ENSURE_TRUE(mDocShell, false);
|
2009-10-28 23:41:46 +03:00
|
|
|
|
|
|
|
// Trigger editor re-initialization if midas is turned on in the
|
|
|
|
// sub-document. This shouldn't be necessary, but given the way our
|
|
|
|
// editor works, it is. See
|
|
|
|
// https://bugzilla.mozilla.org/show_bug.cgi?id=284245
|
2015-07-31 12:28:36 +03:00
|
|
|
presShell = mDocShell->GetPresShell();
|
2009-10-28 23:41:46 +03:00
|
|
|
if (presShell) {
|
2018-01-26 09:00:49 +03:00
|
|
|
nsIDocument* doc = presShell->GetDocument();
|
2018-04-21 19:42:31 +03:00
|
|
|
nsHTMLDocument* htmlDoc =
|
|
|
|
doc && doc->IsHTMLOrXHTML() ? doc->AsHTMLDocument() : nullptr;
|
2009-10-16 23:42:29 +04:00
|
|
|
|
2018-01-26 09:00:49 +03:00
|
|
|
if (htmlDoc) {
|
2009-10-28 23:41:46 +03:00
|
|
|
nsAutoString designMode;
|
2018-01-26 09:00:49 +03:00
|
|
|
htmlDoc->GetDesignMode(designMode);
|
2009-10-28 23:41:46 +03:00
|
|
|
|
|
|
|
if (designMode.EqualsLiteral("on")) {
|
2010-11-19 00:01:12 +03:00
|
|
|
// Hold on to the editor object to let the document reattach to the
|
|
|
|
// same editor object, instead of creating a new one.
|
2017-08-07 09:02:16 +03:00
|
|
|
RefPtr<HTMLEditor> htmlEditor = mDocShell->GetHTMLEditor();
|
|
|
|
Unused << htmlEditor;
|
2018-02-01 22:21:14 +03:00
|
|
|
htmlDoc->SetDesignMode(NS_LITERAL_STRING("off"), Nothing(),
|
|
|
|
IgnoreErrors());
|
2018-01-26 09:00:49 +03:00
|
|
|
|
2018-02-01 22:21:14 +03:00
|
|
|
htmlDoc->SetDesignMode(NS_LITERAL_STRING("on"), Nothing(),
|
|
|
|
IgnoreErrors());
|
2011-03-12 02:45:20 +03:00
|
|
|
} else {
|
2011-05-28 11:43:57 +04:00
|
|
|
// Re-initialize the presentation for contenteditable documents
|
2013-02-14 02:39:30 +04:00
|
|
|
bool editable = false, hasEditingSession = false;
|
|
|
|
mDocShell->GetEditable(&editable);
|
|
|
|
mDocShell->GetHasEditingSession(&hasEditingSession);
|
2017-08-07 09:02:16 +03:00
|
|
|
RefPtr<HTMLEditor> htmlEditor = mDocShell->GetHTMLEditor();
|
|
|
|
if (editable && hasEditingSession && htmlEditor) {
|
|
|
|
htmlEditor->PostCreate();
|
2011-03-12 02:45:20 +03:00
|
|
|
}
|
2009-10-16 23:42:29 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-10-17 18:59:28 +04:00
|
|
|
mInShow = false;
|
2010-05-28 23:34:50 +04:00
|
|
|
if (mHideCalled) {
|
2011-10-17 18:59:28 +04:00
|
|
|
mHideCalled = false;
|
2010-05-28 23:34:50 +04:00
|
|
|
Hide();
|
2011-10-17 18:59:28 +04:00
|
|
|
return false;
|
2010-05-28 23:34:50 +04:00
|
|
|
}
|
2011-10-17 18:59:28 +04:00
|
|
|
return true;
|
2009-10-16 23:42:29 +04:00
|
|
|
}
|
|
|
|
|
2012-08-22 19:56:38 +04:00
|
|
|
void nsFrameLoader::MarginsChanged(uint32_t aMarginWidth,
|
|
|
|
uint32_t aMarginHeight) {
|
2011-05-13 21:41:00 +04:00
|
|
|
// We assume that the margins are always zero for remote frames.
|
2015-07-31 12:28:36 +03:00
|
|
|
if (IsRemoteFrame()) return;
|
2011-05-13 21:41:00 +04:00
|
|
|
|
|
|
|
// If there's no docshell, we're probably not up and running yet.
|
|
|
|
// nsFrameLoader::Show() will take care of setting the right
|
|
|
|
// margins.
|
|
|
|
if (!mDocShell) return;
|
|
|
|
|
|
|
|
// Set the margins
|
|
|
|
mDocShell->SetMarginWidth(aMarginWidth);
|
|
|
|
mDocShell->SetMarginHeight(aMarginHeight);
|
|
|
|
|
2017-03-29 22:10:00 +03:00
|
|
|
// There's a cached property declaration block
|
|
|
|
// that needs to be updated
|
|
|
|
if (nsIDocument* doc = mDocShell->GetDocument()) {
|
2018-03-28 18:34:34 +03:00
|
|
|
for (nsINode* cur = doc; cur; cur = cur->GetNextNode()) {
|
|
|
|
if (cur->IsHTMLElement(nsGkAtoms::body)) {
|
|
|
|
static_cast<HTMLBodyElement*>(cur)->ClearMappedServoStyle();
|
2017-03-29 22:10:00 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-05-13 21:41:00 +04:00
|
|
|
// Trigger a restyle if there's a prescontext
|
2014-10-09 01:26:57 +04:00
|
|
|
// FIXME: This could do something much less expensive.
|
2018-11-20 04:17:53 +03:00
|
|
|
RefPtr<nsPresContext> presContext = mDocShell->GetPresContext();
|
2011-05-13 21:41:00 +04:00
|
|
|
if (presContext)
|
2017-03-29 22:10:00 +03:00
|
|
|
// rebuild, because now the same nsMappedAttributes* will produce
|
|
|
|
// a different style
|
2014-10-09 01:26:57 +04:00
|
|
|
presContext->RebuildAllStyleData(nsChangeHint(0), eRestyle_Subtree);
|
2011-05-13 21:41:00 +04:00
|
|
|
}
|
|
|
|
|
2015-03-05 12:13:05 +03:00
|
|
|
bool nsFrameLoader::ShowRemoteFrame(const ScreenIntSize& size,
|
2013-01-10 11:23:55 +04:00
|
|
|
nsSubDocumentFrame* aFrame) {
|
2018-05-19 00:58:43 +03:00
|
|
|
AUTO_PROFILER_LABEL("nsFrameLoader::ShowRemoteFrame", OTHER);
|
2015-07-31 12:28:36 +03:00
|
|
|
NS_ASSERTION(IsRemoteFrame(),
|
|
|
|
"ShowRemote only makes sense on remote frames.");
|
2009-10-28 23:41:46 +03:00
|
|
|
|
2015-04-07 05:56:10 +03:00
|
|
|
if (!mRemoteBrowser && !TryRemoteBrowser()) {
|
|
|
|
NS_ERROR("Couldn't create child process.");
|
|
|
|
return false;
|
2009-10-28 23:41:46 +03:00
|
|
|
}
|
|
|
|
|
2010-08-21 07:06:53 +04:00
|
|
|
// FIXME/bug 589337: Show()/Hide() is pretty expensive for
|
|
|
|
// cross-process layers; need to figure out what behavior we really
|
|
|
|
// want here. For now, hack.
|
2010-08-21 03:35:11 +04:00
|
|
|
if (!mRemoteBrowserShown) {
|
2015-02-24 17:41:43 +03:00
|
|
|
if (!mOwnerContent || !mOwnerContent->GetComposedDoc()) {
|
2012-04-25 20:35:58 +04:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2017-04-17 23:45:08 +03:00
|
|
|
// We never want to host remote frameloaders in simple popups, like menus.
|
|
|
|
nsIWidget* widget = nsContentUtils::WidgetForContent(mOwnerContent);
|
|
|
|
if (!widget || static_cast<nsBaseWidget*>(widget)->IsSmallPopup()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2018-11-07 00:35:37 +03:00
|
|
|
RenderFrame* rf = GetCurrentRenderFrame();
|
|
|
|
if (!rf) {
|
2017-04-18 07:41:18 +03:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2018-11-07 00:35:37 +03:00
|
|
|
if (!rf->AttachLayerManager()) {
|
2012-04-25 20:35:58 +04:00
|
|
|
// This is just not going to work.
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2017-04-06 10:58:02 +03:00
|
|
|
mRemoteBrowser->Show(size, ParentWindowIsActive(mOwnerContent->OwnerDoc()));
|
2011-10-17 18:59:28 +04:00
|
|
|
mRemoteBrowserShown = true;
|
2010-08-21 03:35:11 +04:00
|
|
|
|
2012-05-08 20:20:35 +04:00
|
|
|
nsCOMPtr<nsIObserverService> os = services::GetObserverService();
|
2015-02-09 10:04:18 +03:00
|
|
|
if (os) {
|
2018-03-22 05:43:17 +03:00
|
|
|
os->NotifyObservers(ToSupports(this), "remote-browser-shown", nullptr);
|
2012-05-08 20:20:35 +04:00
|
|
|
}
|
2010-08-21 03:35:11 +04:00
|
|
|
} else {
|
2014-08-08 21:23:50 +04:00
|
|
|
nsIntRect dimensions;
|
2011-07-16 01:46:56 +04:00
|
|
|
NS_ENSURE_SUCCESS(GetWindowDimensions(dimensions), false);
|
2013-01-10 11:23:55 +04:00
|
|
|
|
|
|
|
// Don't show remote iframe if we are waiting for the completion of reflow.
|
|
|
|
if (!aFrame || !(aFrame->GetStateBits() & NS_FRAME_FIRST_REFLOW)) {
|
2015-03-31 23:39:02 +03:00
|
|
|
mRemoteBrowser->UpdateDimensions(dimensions, size);
|
2013-01-10 11:23:55 +04:00
|
|
|
}
|
2010-08-21 03:35:11 +04:00
|
|
|
}
|
2009-10-28 23:41:46 +03:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2009-10-16 23:42:29 +04:00
|
|
|
void nsFrameLoader::Hide() {
|
2010-05-28 23:34:50 +04:00
|
|
|
if (mHideCalled) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (mInShow) {
|
2011-10-17 18:59:28 +04:00
|
|
|
mHideCalled = true;
|
2010-05-28 23:34:50 +04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2009-10-16 23:42:29 +04:00
|
|
|
if (!mDocShell) return;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIContentViewer> contentViewer;
|
|
|
|
mDocShell->GetContentViewer(getter_AddRefs(contentViewer));
|
2011-10-17 18:59:28 +04:00
|
|
|
if (contentViewer) contentViewer->SetSticky(false);
|
2009-10-16 23:42:29 +04:00
|
|
|
|
2019-01-02 16:27:05 +03:00
|
|
|
RefPtr<nsDocShell> baseWin = mDocShell;
|
2011-10-17 18:59:28 +04:00
|
|
|
baseWin->SetVisibility(false);
|
2012-07-30 18:20:58 +04:00
|
|
|
baseWin->SetParentWidget(nullptr);
|
2009-10-16 23:42:29 +04:00
|
|
|
}
|
|
|
|
|
2018-04-20 00:26:56 +03:00
|
|
|
void nsFrameLoader::ForceLayoutIfNecessary() {
|
|
|
|
nsIFrame* frame = GetPrimaryFrameOfOwningContent();
|
|
|
|
if (!frame) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsPresContext* presContext = frame->PresContext();
|
|
|
|
if (!presContext) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Only force the layout flush if the frameloader hasn't ever been
|
|
|
|
// run through layout.
|
|
|
|
if (frame->GetStateBits() & NS_FRAME_FIRST_REFLOW) {
|
|
|
|
if (nsCOMPtr<nsIPresShell> shell = presContext->GetPresShell()) {
|
|
|
|
shell->FlushPendingNotifications(FlushType::Layout);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-10-07 06:30:42 +04:00
|
|
|
nsresult nsFrameLoader::SwapWithOtherRemoteLoader(
|
2016-10-17 17:37:50 +03:00
|
|
|
nsFrameLoader* aOther, nsIFrameLoaderOwner* aThisOwner,
|
|
|
|
nsIFrameLoaderOwner* aOtherOwner) {
|
2015-02-09 02:50:01 +03:00
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
|
2016-10-17 17:37:50 +03:00
|
|
|
#ifdef DEBUG
|
|
|
|
RefPtr<nsFrameLoader> first = aThisOwner->GetFrameLoader();
|
|
|
|
RefPtr<nsFrameLoader> second = aOtherOwner->GetFrameLoader();
|
|
|
|
MOZ_ASSERT(first == this, "aThisOwner must own this");
|
|
|
|
MOZ_ASSERT(second == aOther, "aOtherOwner must own aOther");
|
|
|
|
#endif
|
|
|
|
|
2014-10-07 06:30:42 +04:00
|
|
|
Element* ourContent = mOwnerContent;
|
|
|
|
Element* otherContent = aOther->mOwnerContent;
|
|
|
|
|
|
|
|
if (!ourContent || !otherContent) {
|
|
|
|
// Can't handle this
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Make sure there are no same-origin issues
|
|
|
|
bool equal;
|
|
|
|
nsresult rv = ourContent->NodePrincipal()->Equals(
|
|
|
|
otherContent->NodePrincipal(), &equal);
|
|
|
|
if (NS_FAILED(rv) || !equal) {
|
|
|
|
// Security problems loom. Just bail on it all
|
|
|
|
return NS_ERROR_DOM_SECURITY_ERR;
|
|
|
|
}
|
|
|
|
|
2015-02-24 17:41:43 +03:00
|
|
|
nsIDocument* ourDoc = ourContent->GetComposedDoc();
|
|
|
|
nsIDocument* otherDoc = otherContent->GetComposedDoc();
|
2014-10-07 06:30:42 +04:00
|
|
|
if (!ourDoc || !otherDoc) {
|
|
|
|
// Again, how odd, given that we had docshells
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsIPresShell* ourShell = ourDoc->GetShell();
|
|
|
|
nsIPresShell* otherShell = otherDoc->GetShell();
|
|
|
|
if (!ourShell || !otherShell) {
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
2016-11-29 22:49:17 +03:00
|
|
|
if (!mRemoteBrowser || !aOther->mRemoteBrowser) {
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
2016-01-09 03:11:58 +03:00
|
|
|
if (mRemoteBrowser->IsIsolatedMozBrowserElement() !=
|
2016-10-15 04:46:26 +03:00
|
|
|
aOther->mRemoteBrowser->IsIsolatedMozBrowserElement()) {
|
2016-01-09 03:11:58 +03:00
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
2016-05-30 02:48:00 +03:00
|
|
|
// When we swap docShells, maybe we have to deal with a new page created just
|
|
|
|
// for this operation. In this case, the browser code should already have set
|
2018-02-24 02:32:18 +03:00
|
|
|
// the correct userContextId attribute value in the owning element, but our
|
2016-05-30 02:48:00 +03:00
|
|
|
// docShell, that has been created way before) doesn't know that that
|
|
|
|
// happened.
|
|
|
|
// This is the reason why now we must retrieve the correct value from the
|
|
|
|
// usercontextid attribute before comparing our originAttributes with the
|
|
|
|
// other one.
|
|
|
|
OriginAttributes ourOriginAttributes = mRemoteBrowser->OriginAttributesRef();
|
|
|
|
rv = PopulateUserContextIdFromAttribute(ourOriginAttributes);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
2017-01-12 19:38:48 +03:00
|
|
|
OriginAttributes otherOriginAttributes =
|
2016-05-30 02:48:00 +03:00
|
|
|
aOther->mRemoteBrowser->OriginAttributesRef();
|
|
|
|
rv = aOther->PopulateUserContextIdFromAttribute(otherOriginAttributes);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
if (ourOriginAttributes != otherOriginAttributes) {
|
2016-01-09 03:11:58 +03:00
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ourHasHistory =
|
|
|
|
mIsTopLevelContent && ourContent->IsXULElement(nsGkAtoms::browser) &&
|
|
|
|
!ourContent->HasAttr(kNameSpaceID_None, nsGkAtoms::disablehistory);
|
|
|
|
bool otherHasHistory =
|
|
|
|
aOther->mIsTopLevelContent &&
|
|
|
|
otherContent->IsXULElement(nsGkAtoms::browser) &&
|
|
|
|
!otherContent->HasAttr(kNameSpaceID_None, nsGkAtoms::disablehistory);
|
|
|
|
if (ourHasHistory != otherHasHistory) {
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
2014-10-07 06:30:42 +04:00
|
|
|
if (mInSwap || aOther->mInSwap) {
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
mInSwap = aOther->mInSwap = true;
|
|
|
|
|
|
|
|
nsIFrame* ourFrame = ourContent->GetPrimaryFrame();
|
|
|
|
nsIFrame* otherFrame = otherContent->GetPrimaryFrame();
|
|
|
|
if (!ourFrame || !otherFrame) {
|
|
|
|
mInSwap = aOther->mInSwap = false;
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsSubDocumentFrame* ourFrameFrame = do_QueryFrame(ourFrame);
|
|
|
|
if (!ourFrameFrame) {
|
|
|
|
mInSwap = aOther->mInSwap = false;
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = ourFrameFrame->BeginSwapDocShells(otherFrame);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
mInSwap = aOther->mInSwap = false;
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2015-04-10 00:55:07 +03:00
|
|
|
nsCOMPtr<nsIBrowserDOMWindow> otherBrowserDOMWindow =
|
|
|
|
aOther->mRemoteBrowser->GetBrowserDOMWindow();
|
|
|
|
nsCOMPtr<nsIBrowserDOMWindow> browserDOMWindow =
|
|
|
|
mRemoteBrowser->GetBrowserDOMWindow();
|
|
|
|
|
2016-02-04 14:50:03 +03:00
|
|
|
if (!!otherBrowserDOMWindow != !!browserDOMWindow) {
|
2015-04-10 00:55:07 +03:00
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
2016-09-09 00:00:12 +03:00
|
|
|
// Destroy browser frame scripts for content leaving a frame with browser API
|
2016-10-15 04:46:26 +03:00
|
|
|
if (OwnerIsMozBrowserFrame() && !aOther->OwnerIsMozBrowserFrame()) {
|
2016-09-09 00:00:12 +03:00
|
|
|
DestroyBrowserFrameScripts();
|
|
|
|
}
|
2016-10-15 04:46:26 +03:00
|
|
|
if (!OwnerIsMozBrowserFrame() && aOther->OwnerIsMozBrowserFrame()) {
|
2016-09-09 00:00:12 +03:00
|
|
|
aOther->DestroyBrowserFrameScripts();
|
|
|
|
}
|
|
|
|
|
2015-04-10 00:55:07 +03:00
|
|
|
aOther->mRemoteBrowser->SetBrowserDOMWindow(browserDOMWindow);
|
|
|
|
mRemoteBrowser->SetBrowserDOMWindow(otherBrowserDOMWindow);
|
|
|
|
|
2017-02-09 19:53:50 +03:00
|
|
|
#ifdef XP_WIN
|
2015-02-09 02:50:01 +03:00
|
|
|
// Native plugin windows used by this remote content need to be reparented.
|
2016-01-30 20:05:36 +03:00
|
|
|
if (nsPIDOMWindowOuter* newWin = ourDoc->GetWindow()) {
|
2017-11-04 01:25:38 +03:00
|
|
|
RefPtr<nsIWidget> newParent =
|
|
|
|
nsGlobalWindowOuter::Cast(newWin)->GetMainWidget();
|
2015-10-07 21:30:33 +03:00
|
|
|
const ManagedContainer<mozilla::plugins::PPluginWidgetParent>& plugins =
|
|
|
|
aOther->mRemoteBrowser->ManagedPPluginWidgetParent();
|
|
|
|
for (auto iter = plugins.ConstIter(); !iter.Done(); iter.Next()) {
|
|
|
|
static_cast<mozilla::plugins::PluginWidgetParent*>(iter.Get()->GetKey())
|
|
|
|
->SetParent(newParent);
|
2015-02-09 02:50:01 +03:00
|
|
|
}
|
|
|
|
}
|
2017-02-09 19:53:50 +03:00
|
|
|
#endif // XP_WIN
|
2015-02-09 02:50:01 +03:00
|
|
|
|
2015-10-01 20:06:51 +03:00
|
|
|
MaybeUpdatePrimaryTabParent(eTabParentRemoved);
|
|
|
|
aOther->MaybeUpdatePrimaryTabParent(eTabParentRemoved);
|
|
|
|
|
2014-10-07 06:30:42 +04:00
|
|
|
SetOwnerContent(otherContent);
|
|
|
|
aOther->SetOwnerContent(ourContent);
|
|
|
|
|
|
|
|
mRemoteBrowser->SetOwnerElement(otherContent);
|
|
|
|
aOther->mRemoteBrowser->SetOwnerElement(ourContent);
|
|
|
|
|
2017-04-06 10:58:02 +03:00
|
|
|
// Update window activation state for the swapped owner content.
|
2017-08-23 12:02:57 +03:00
|
|
|
Unused << mRemoteBrowser->SendParentActivated(
|
|
|
|
ParentWindowIsActive(otherContent->OwnerDoc()));
|
|
|
|
Unused << aOther->mRemoteBrowser->SendParentActivated(
|
|
|
|
ParentWindowIsActive(ourContent->OwnerDoc()));
|
2017-04-06 10:58:02 +03:00
|
|
|
|
2015-10-01 20:06:51 +03:00
|
|
|
MaybeUpdatePrimaryTabParent(eTabParentChanged);
|
|
|
|
aOther->MaybeUpdatePrimaryTabParent(eTabParentChanged);
|
|
|
|
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<nsFrameMessageManager> ourMessageManager = mMessageManager;
|
|
|
|
RefPtr<nsFrameMessageManager> otherMessageManager = aOther->mMessageManager;
|
2014-10-07 06:30:42 +04:00
|
|
|
// Swap and setup things in parent message managers.
|
2016-08-24 21:12:09 +03:00
|
|
|
if (ourMessageManager) {
|
|
|
|
ourMessageManager->SetCallback(aOther);
|
2014-10-07 06:30:42 +04:00
|
|
|
}
|
2016-08-24 21:12:09 +03:00
|
|
|
if (otherMessageManager) {
|
|
|
|
otherMessageManager->SetCallback(this);
|
2014-10-07 06:30:42 +04:00
|
|
|
}
|
|
|
|
mMessageManager.swap(aOther->mMessageManager);
|
|
|
|
|
2016-10-17 17:37:50 +03:00
|
|
|
// Perform the actual swap of the internal refptrs. We keep a strong reference
|
|
|
|
// to ourselves to make sure we don't die while we overwrite our reference to
|
|
|
|
// ourself.
|
2018-03-22 05:43:17 +03:00
|
|
|
RefPtr<nsFrameLoader> kungFuDeathGrip(this);
|
2016-10-17 17:37:50 +03:00
|
|
|
aThisOwner->InternalSetFrameLoader(aOther);
|
|
|
|
aOtherOwner->InternalSetFrameLoader(kungFuDeathGrip);
|
2014-10-07 06:30:42 +04:00
|
|
|
|
|
|
|
ourFrameFrame->EndSwapDocShells(otherFrame);
|
|
|
|
|
2015-06-16 20:40:55 +03:00
|
|
|
ourShell->BackingScaleFactorChanged();
|
|
|
|
otherShell->BackingScaleFactorChanged();
|
|
|
|
|
2016-04-29 01:04:52 +03:00
|
|
|
// Initialize browser API if needed now that owner content has changed.
|
|
|
|
InitializeBrowserAPI();
|
|
|
|
aOther->InitializeBrowserAPI();
|
|
|
|
|
2014-10-07 06:30:42 +04:00
|
|
|
mInSwap = aOther->mInSwap = false;
|
2015-05-07 18:43:40 +03:00
|
|
|
|
2016-04-29 01:04:52 +03:00
|
|
|
// Send an updated tab context since owner content type may have changed.
|
|
|
|
MutableTabContext ourContext;
|
|
|
|
rv = GetNewTabContext(&ourContext);
|
|
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
MutableTabContext otherContext;
|
|
|
|
rv = aOther->GetNewTabContext(&otherContext);
|
|
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
Bug 1338241 - Part 3: Relax the SwapWithOtherRemoteLoader swap check, r=bz
In bug 1147911, the concept of a remoteType was added to a xul:browser.
This was an attribute which would control the type of remote process was
intended to be used to load the page.
In order to swap two frameLoaders, it has always been necessary for them
to either both contain remote content, or both contain non-remote
content. This check is made in nsFrameLoader::SwapWithOtherLoader, by
checking `IsRemoteFrame() != aOther->IsRemoteFrame()`, and then
returning `NS_ERROR_NOT_IMPLEMENTED` if that was not the case.
In the follow-up bug 1317293, the check which is being removed here was
added to ensure that the remoteType of two frameLoaders which are being
swapped also matched. This was not a technical limitation, but rather
something which "seemed to make sense to do".
This bug removes that check as it is not a technical limitation and
causes problems in edge cases around Large-Allocation processes now that
the remoteType is being used to denote a Large-Allocation process.
Namely, it means that attempting to drag a Large-Allocation window into
a new window when at the Large-Allocation process cap will fail, due to
being unable to create a new Large-Allocation process in the new window
to swap with.
The new swapping of the attributes which is added below is done with the
intent that the `remoteType` attribute of the xul:browser element should
match the `remoteType` attribute of the frameLoader inside of it at all
times. As the swap can now occur between two different `remoteType`s,
this is necessary to keep that constraint.
MozReview-Commit-ID: BHFgjwRGrge
2017-02-10 21:13:43 +03:00
|
|
|
// Swap the remoteType property as the frameloaders are being swapped
|
|
|
|
nsAutoString ourRemoteType;
|
|
|
|
if (!ourContent->GetAttr(kNameSpaceID_None, nsGkAtoms::RemoteType,
|
|
|
|
ourRemoteType)) {
|
|
|
|
ourRemoteType.AssignLiteral(DEFAULT_REMOTE_TYPE);
|
|
|
|
}
|
|
|
|
nsAutoString otherRemoteType;
|
|
|
|
if (!otherContent->GetAttr(kNameSpaceID_None, nsGkAtoms::RemoteType,
|
|
|
|
otherRemoteType)) {
|
|
|
|
otherRemoteType.AssignLiteral(DEFAULT_REMOTE_TYPE);
|
|
|
|
}
|
|
|
|
ourContent->SetAttr(kNameSpaceID_None, nsGkAtoms::RemoteType, otherRemoteType,
|
|
|
|
false);
|
|
|
|
otherContent->SetAttr(kNameSpaceID_None, nsGkAtoms::RemoteType, ourRemoteType,
|
|
|
|
false);
|
|
|
|
|
2016-04-29 01:04:52 +03:00
|
|
|
Unused << mRemoteBrowser->SendSwappedWithOtherRemoteLoader(
|
|
|
|
ourContext.AsIPCTabContext());
|
|
|
|
Unused << aOther->mRemoteBrowser->SendSwappedWithOtherRemoteLoader(
|
|
|
|
otherContext.AsIPCTabContext());
|
2014-10-07 06:30:42 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2015-09-03 19:15:23 +03:00
|
|
|
class MOZ_RAII AutoResetInFrameSwap final {
|
2015-08-07 17:17:50 +03:00
|
|
|
public:
|
|
|
|
AutoResetInFrameSwap(
|
|
|
|
nsFrameLoader* aThisFrameLoader, nsFrameLoader* aOtherFrameLoader,
|
|
|
|
nsDocShell* aThisDocShell, nsDocShell* aOtherDocShell,
|
|
|
|
EventTarget* aThisEventTarget,
|
|
|
|
EventTarget* aOtherEventTarget MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
|
|
|
: mThisFrameLoader(aThisFrameLoader),
|
|
|
|
mOtherFrameLoader(aOtherFrameLoader),
|
|
|
|
mThisDocShell(aThisDocShell),
|
|
|
|
mOtherDocShell(aOtherDocShell),
|
|
|
|
mThisEventTarget(aThisEventTarget),
|
|
|
|
mOtherEventTarget(aOtherEventTarget) {
|
|
|
|
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
|
|
|
|
|
|
|
mThisFrameLoader->mInSwap = true;
|
|
|
|
mOtherFrameLoader->mInSwap = true;
|
|
|
|
mThisDocShell->SetInFrameSwap(true);
|
|
|
|
mOtherDocShell->SetInFrameSwap(true);
|
|
|
|
|
|
|
|
// Fire pageshow events on still-loading pages, and then fire pagehide
|
|
|
|
// events. Note that we do NOT fire these in the normal way, but just fire
|
|
|
|
// them on the chrome event handlers.
|
|
|
|
nsContentUtils::FirePageShowEvent(mThisDocShell, mThisEventTarget, false);
|
|
|
|
nsContentUtils::FirePageShowEvent(mOtherDocShell, mOtherEventTarget, false);
|
|
|
|
nsContentUtils::FirePageHideEvent(mThisDocShell, mThisEventTarget);
|
|
|
|
nsContentUtils::FirePageHideEvent(mOtherDocShell, mOtherEventTarget);
|
|
|
|
}
|
|
|
|
|
|
|
|
~AutoResetInFrameSwap() {
|
|
|
|
nsContentUtils::FirePageShowEvent(mThisDocShell, mThisEventTarget, true);
|
|
|
|
nsContentUtils::FirePageShowEvent(mOtherDocShell, mOtherEventTarget, true);
|
|
|
|
|
|
|
|
mThisFrameLoader->mInSwap = false;
|
|
|
|
mOtherFrameLoader->mInSwap = false;
|
|
|
|
mThisDocShell->SetInFrameSwap(false);
|
|
|
|
mOtherDocShell->SetInFrameSwap(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<nsFrameLoader> mThisFrameLoader;
|
|
|
|
RefPtr<nsFrameLoader> mOtherFrameLoader;
|
|
|
|
RefPtr<nsDocShell> mThisDocShell;
|
|
|
|
RefPtr<nsDocShell> mOtherDocShell;
|
2015-08-07 17:17:50 +03:00
|
|
|
nsCOMPtr<EventTarget> mThisEventTarget;
|
|
|
|
nsCOMPtr<EventTarget> mOtherEventTarget;
|
|
|
|
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
|
|
|
};
|
|
|
|
|
2008-08-08 03:15:40 +04:00
|
|
|
nsresult nsFrameLoader::SwapWithOtherLoader(nsFrameLoader* aOther,
|
2016-10-17 17:37:50 +03:00
|
|
|
nsIFrameLoaderOwner* aThisOwner,
|
|
|
|
nsIFrameLoaderOwner* aOtherOwner) {
|
|
|
|
#ifdef DEBUG
|
|
|
|
RefPtr<nsFrameLoader> first = aThisOwner->GetFrameLoader();
|
|
|
|
RefPtr<nsFrameLoader> second = aOtherOwner->GetFrameLoader();
|
|
|
|
MOZ_ASSERT(first == this, "aThisOwner must own this");
|
|
|
|
MOZ_ASSERT(second == aOther, "aOtherOwner must own aOther");
|
|
|
|
#endif
|
|
|
|
|
2010-05-28 23:34:50 +04:00
|
|
|
NS_ENSURE_STATE(!mInShow && !aOther->mInShow);
|
2008-08-08 03:15:40 +04:00
|
|
|
|
2016-01-09 03:11:58 +03:00
|
|
|
if (IsRemoteFrame() != aOther->IsRemoteFrame()) {
|
2014-10-07 06:30:42 +04:00
|
|
|
NS_WARNING(
|
|
|
|
"Swapping remote and non-remote frames is not currently supported");
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
2011-10-01 21:14:35 +04:00
|
|
|
Element* ourContent = mOwnerContent;
|
|
|
|
Element* otherContent = aOther->mOwnerContent;
|
2008-08-08 03:15:40 +04:00
|
|
|
|
|
|
|
if (!ourContent || !otherContent) {
|
|
|
|
// Can't handle this
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
2016-01-09 03:11:58 +03:00
|
|
|
bool ourHasSrcdoc = ourContent->IsHTMLElement(nsGkAtoms::iframe) &&
|
|
|
|
ourContent->HasAttr(kNameSpaceID_None, nsGkAtoms::srcdoc);
|
|
|
|
bool otherHasSrcdoc =
|
|
|
|
otherContent->IsHTMLElement(nsGkAtoms::iframe) &&
|
|
|
|
otherContent->HasAttr(kNameSpaceID_None, nsGkAtoms::srcdoc);
|
|
|
|
if (ourHasSrcdoc || otherHasSrcdoc) {
|
|
|
|
// Ignore this case entirely for now, since we support XUL <-> HTML swapping
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ourFullscreenAllowed =
|
|
|
|
ourContent->IsXULElement() ||
|
2016-10-15 04:46:26 +03:00
|
|
|
(OwnerIsMozBrowserFrame() &&
|
2016-01-09 03:11:58 +03:00
|
|
|
(ourContent->HasAttr(kNameSpaceID_None, nsGkAtoms::allowfullscreen) ||
|
|
|
|
ourContent->HasAttr(kNameSpaceID_None, nsGkAtoms::mozallowfullscreen)));
|
|
|
|
bool otherFullscreenAllowed =
|
|
|
|
otherContent->IsXULElement() ||
|
2016-10-15 04:46:26 +03:00
|
|
|
(aOther->OwnerIsMozBrowserFrame() &&
|
2016-01-09 03:11:58 +03:00
|
|
|
(otherContent->HasAttr(kNameSpaceID_None, nsGkAtoms::allowfullscreen) ||
|
|
|
|
otherContent->HasAttr(kNameSpaceID_None,
|
|
|
|
nsGkAtoms::mozallowfullscreen)));
|
|
|
|
if (ourFullscreenAllowed != otherFullscreenAllowed) {
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
2017-07-18 05:16:28 +03:00
|
|
|
bool ourPaymentRequestAllowed =
|
|
|
|
ourContent->HasAttr(kNameSpaceID_None, nsGkAtoms::allowpaymentrequest);
|
|
|
|
bool otherPaymentRequestAllowed =
|
|
|
|
otherContent->HasAttr(kNameSpaceID_None, nsGkAtoms::allowpaymentrequest);
|
|
|
|
if (ourPaymentRequestAllowed != otherPaymentRequestAllowed) {
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
2016-01-09 03:11:58 +03:00
|
|
|
// Divert to a separate path for the remaining steps in the remote case
|
|
|
|
if (IsRemoteFrame()) {
|
|
|
|
MOZ_ASSERT(aOther->IsRemoteFrame());
|
2016-10-17 17:37:50 +03:00
|
|
|
return SwapWithOtherRemoteLoader(aOther, aThisOwner, aOtherOwner);
|
2016-01-09 03:11:58 +03:00
|
|
|
}
|
|
|
|
|
2008-08-08 03:15:40 +04:00
|
|
|
// Make sure there are no same-origin issues
|
2011-09-29 10:19:26 +04:00
|
|
|
bool equal;
|
2008-08-08 03:15:40 +04:00
|
|
|
nsresult rv = ourContent->NodePrincipal()->Equals(
|
|
|
|
otherContent->NodePrincipal(), &equal);
|
|
|
|
if (NS_FAILED(rv) || !equal) {
|
|
|
|
// Security problems loom. Just bail on it all
|
|
|
|
return NS_ERROR_DOM_SECURITY_ERR;
|
|
|
|
}
|
|
|
|
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<nsDocShell> ourDocshell =
|
|
|
|
static_cast<nsDocShell*>(GetExistingDocShell());
|
|
|
|
RefPtr<nsDocShell> otherDocshell =
|
|
|
|
static_cast<nsDocShell*>(aOther->GetExistingDocShell());
|
2012-03-04 20:02:00 +04:00
|
|
|
if (!ourDocshell || !otherDocshell) {
|
2008-08-08 03:15:40 +04:00
|
|
|
// How odd
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
// To avoid having to mess with session history, avoid swapping
|
2008-10-08 17:04:32 +04:00
|
|
|
// frameloaders that don't correspond to root same-type docshells,
|
|
|
|
// unless both roots have session history disabled.
|
2008-08-08 03:15:40 +04:00
|
|
|
nsCOMPtr<nsIDocShellTreeItem> ourRootTreeItem, otherRootTreeItem;
|
2013-02-13 02:02:51 +04:00
|
|
|
ourDocshell->GetSameTypeRootTreeItem(getter_AddRefs(ourRootTreeItem));
|
|
|
|
otherDocshell->GetSameTypeRootTreeItem(getter_AddRefs(otherRootTreeItem));
|
2009-01-13 22:32:30 +03:00
|
|
|
nsCOMPtr<nsIWebNavigation> ourRootWebnav = do_QueryInterface(ourRootTreeItem);
|
|
|
|
nsCOMPtr<nsIWebNavigation> otherRootWebnav =
|
|
|
|
do_QueryInterface(otherRootTreeItem);
|
2008-10-08 17:04:32 +04:00
|
|
|
|
2009-01-13 22:32:30 +03:00
|
|
|
if (!ourRootWebnav || !otherRootWebnav) {
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
2008-10-08 17:04:32 +04:00
|
|
|
|
2018-02-02 01:35:47 +03:00
|
|
|
RefPtr<ChildSHistory> ourHistory = ourRootWebnav->GetSessionHistory();
|
|
|
|
RefPtr<ChildSHistory> otherHistory = otherRootWebnav->GetSessionHistory();
|
2009-01-13 22:32:30 +03:00
|
|
|
|
2013-02-13 02:02:51 +04:00
|
|
|
if ((ourRootTreeItem != ourDocshell || otherRootTreeItem != otherDocshell) &&
|
2009-01-13 22:32:30 +03:00
|
|
|
(ourHistory || otherHistory)) {
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
2008-08-08 03:15:40 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// Also make sure that the two docshells are the same type. Otherwise
|
2012-12-21 15:58:23 +04:00
|
|
|
// swapping is certainly not safe. If this needs to be changed then
|
|
|
|
// the code below needs to be audited as it assumes identical types.
|
2014-01-20 11:58:26 +04:00
|
|
|
int32_t ourType = ourDocshell->ItemType();
|
|
|
|
int32_t otherType = otherDocshell->ItemType();
|
2008-10-08 17:04:32 +04:00
|
|
|
if (ourType != otherType) {
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
2009-01-13 22:32:30 +03:00
|
|
|
// One more twist here. Setting up the right treeowners in a heterogeneous
|
2008-10-08 17:04:32 +04:00
|
|
|
// tree is a bit of a pain. So make sure that if ourType is not
|
|
|
|
// nsIDocShellTreeItem::typeContent then all of our descendants are the same
|
|
|
|
// type as us.
|
|
|
|
if (ourType != nsIDocShellTreeItem::typeContent &&
|
2013-02-13 02:02:51 +04:00
|
|
|
(!AllDescendantsOfType(ourDocshell, ourType) ||
|
|
|
|
!AllDescendantsOfType(otherDocshell, otherType))) {
|
2008-08-08 03:15:40 +04:00
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
2015-11-24 04:40:02 +03:00
|
|
|
|
2008-08-08 03:15:40 +04:00
|
|
|
// Save off the tree owners, frame elements, chrome event handlers, and
|
|
|
|
// docshell and document parents before doing anything else.
|
|
|
|
nsCOMPtr<nsIDocShellTreeOwner> ourOwner, otherOwner;
|
2013-02-13 02:02:51 +04:00
|
|
|
ourDocshell->GetTreeOwner(getter_AddRefs(ourOwner));
|
|
|
|
otherDocshell->GetTreeOwner(getter_AddRefs(otherOwner));
|
2008-08-08 03:15:40 +04:00
|
|
|
// Note: it's OK to have null treeowners.
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDocShellTreeItem> ourParentItem, otherParentItem;
|
2013-02-13 02:02:51 +04:00
|
|
|
ourDocshell->GetParent(getter_AddRefs(ourParentItem));
|
|
|
|
otherDocshell->GetParent(getter_AddRefs(otherParentItem));
|
2008-08-08 03:15:40 +04:00
|
|
|
if (!ourParentItem || !otherParentItem) {
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
2008-10-08 17:04:32 +04:00
|
|
|
// Make sure our parents are the same type too
|
2014-01-20 11:58:26 +04:00
|
|
|
int32_t ourParentType = ourParentItem->ItemType();
|
|
|
|
int32_t otherParentType = otherParentItem->ItemType();
|
2008-10-08 17:04:32 +04:00
|
|
|
if (ourParentType != otherParentType) {
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
2016-01-30 20:05:36 +03:00
|
|
|
nsCOMPtr<nsPIDOMWindowOuter> ourWindow = ourDocshell->GetWindow();
|
|
|
|
nsCOMPtr<nsPIDOMWindowOuter> otherWindow = otherDocshell->GetWindow();
|
2008-08-08 03:15:40 +04:00
|
|
|
|
|
|
|
nsCOMPtr<Element> ourFrameElement = ourWindow->GetFrameElementInternal();
|
|
|
|
nsCOMPtr<Element> otherFrameElement = otherWindow->GetFrameElementInternal();
|
|
|
|
|
2018-08-13 12:05:19 +03:00
|
|
|
nsCOMPtr<EventTarget> ourChromeEventHandler =
|
|
|
|
ourWindow->GetChromeEventHandler();
|
|
|
|
nsCOMPtr<EventTarget> otherChromeEventHandler =
|
|
|
|
otherWindow->GetChromeEventHandler();
|
2008-08-08 03:15:40 +04:00
|
|
|
|
2014-09-03 07:09:24 +04:00
|
|
|
nsCOMPtr<EventTarget> ourEventTarget = ourWindow->GetParentTarget();
|
|
|
|
nsCOMPtr<EventTarget> otherEventTarget = otherWindow->GetParentTarget();
|
|
|
|
|
2008-08-08 03:15:40 +04:00
|
|
|
NS_ASSERTION(SameCOMIdentity(ourFrameElement, ourContent) &&
|
|
|
|
SameCOMIdentity(otherFrameElement, otherContent) &&
|
|
|
|
SameCOMIdentity(ourChromeEventHandler, ourContent) &&
|
|
|
|
SameCOMIdentity(otherChromeEventHandler, otherContent),
|
|
|
|
"How did that happen, exactly?");
|
|
|
|
|
2013-04-24 08:22:37 +04:00
|
|
|
nsCOMPtr<nsIDocument> ourChildDocument = ourWindow->GetExtantDoc();
|
|
|
|
nsCOMPtr<nsIDocument> otherChildDocument = otherWindow->GetExtantDoc();
|
2008-08-08 03:15:40 +04:00
|
|
|
if (!ourChildDocument || !otherChildDocument) {
|
|
|
|
// This shouldn't be happening
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDocument> ourParentDocument =
|
|
|
|
ourChildDocument->GetParentDocument();
|
|
|
|
nsCOMPtr<nsIDocument> otherParentDocument =
|
|
|
|
otherChildDocument->GetParentDocument();
|
|
|
|
|
|
|
|
// Make sure to swap docshells between the two frames.
|
2015-02-24 17:41:43 +03:00
|
|
|
nsIDocument* ourDoc = ourContent->GetComposedDoc();
|
|
|
|
nsIDocument* otherDoc = otherContent->GetComposedDoc();
|
2008-08-08 03:15:40 +04:00
|
|
|
if (!ourDoc || !otherDoc) {
|
|
|
|
// Again, how odd, given that we had docshells
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_ASSERTION(ourDoc == ourParentDocument, "Unexpected parent document");
|
|
|
|
NS_ASSERTION(otherDoc == otherParentDocument, "Unexpected parent document");
|
|
|
|
|
2010-06-25 17:59:57 +04:00
|
|
|
nsIPresShell* ourShell = ourDoc->GetShell();
|
|
|
|
nsIPresShell* otherShell = otherDoc->GetShell();
|
2008-08-08 03:15:40 +04:00
|
|
|
if (!ourShell || !otherShell) {
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
2016-02-18 06:53:32 +03:00
|
|
|
if (ourDocshell->GetIsIsolatedMozBrowserElement() !=
|
2016-10-15 04:46:26 +03:00
|
|
|
otherDocshell->GetIsIsolatedMozBrowserElement()) {
|
2016-01-09 03:11:58 +03:00
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
2016-05-30 02:48:00 +03:00
|
|
|
// When we swap docShells, maybe we have to deal with a new page created just
|
|
|
|
// for this operation. In this case, the browser code should already have set
|
2018-02-24 02:32:18 +03:00
|
|
|
// the correct userContextId attribute value in the owning element, but our
|
2016-05-30 02:48:00 +03:00
|
|
|
// docShell, that has been created way before) doesn't know that that
|
|
|
|
// happened.
|
|
|
|
// This is the reason why now we must retrieve the correct value from the
|
|
|
|
// usercontextid attribute before comparing our originAttributes with the
|
|
|
|
// other one.
|
2017-01-12 19:38:48 +03:00
|
|
|
OriginAttributes ourOriginAttributes = ourDocshell->GetOriginAttributes();
|
2016-05-30 02:48:00 +03:00
|
|
|
rv = PopulateUserContextIdFromAttribute(ourOriginAttributes);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
2017-01-12 19:38:48 +03:00
|
|
|
OriginAttributes otherOriginAttributes = otherDocshell->GetOriginAttributes();
|
2016-05-30 02:48:00 +03:00
|
|
|
rv = aOther->PopulateUserContextIdFromAttribute(otherOriginAttributes);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
if (ourOriginAttributes != otherOriginAttributes) {
|
2016-01-09 03:11:58 +03:00
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
2012-07-19 09:26:21 +04:00
|
|
|
}
|
|
|
|
|
2008-08-08 03:15:40 +04:00
|
|
|
if (mInSwap || aOther->mInSwap) {
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
2015-08-07 17:17:50 +03:00
|
|
|
AutoResetInFrameSwap autoFrameSwap(this, aOther, ourDocshell, otherDocshell,
|
|
|
|
ourEventTarget, otherEventTarget);
|
|
|
|
|
2009-12-25 00:20:05 +03:00
|
|
|
nsIFrame* ourFrame = ourContent->GetPrimaryFrame();
|
|
|
|
nsIFrame* otherFrame = otherContent->GetPrimaryFrame();
|
2008-08-08 03:15:40 +04:00
|
|
|
if (!ourFrame || !otherFrame) {
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
2010-08-31 04:49:07 +04:00
|
|
|
nsSubDocumentFrame* ourFrameFrame = do_QueryFrame(ourFrame);
|
2008-08-08 03:15:40 +04:00
|
|
|
if (!ourFrameFrame) {
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
// OK. First begin to swap the docshells in the two nsIFrames
|
|
|
|
rv = ourFrameFrame->BeginSwapDocShells(otherFrame);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2016-09-09 00:00:12 +03:00
|
|
|
// Destroy browser frame scripts for content leaving a frame with browser API
|
2016-10-15 04:46:26 +03:00
|
|
|
if (OwnerIsMozBrowserFrame() && !aOther->OwnerIsMozBrowserFrame()) {
|
2016-09-09 00:00:12 +03:00
|
|
|
DestroyBrowserFrameScripts();
|
|
|
|
}
|
2016-10-15 04:46:26 +03:00
|
|
|
if (!OwnerIsMozBrowserFrame() && aOther->OwnerIsMozBrowserFrame()) {
|
2016-09-09 00:00:12 +03:00
|
|
|
aOther->DestroyBrowserFrameScripts();
|
|
|
|
}
|
|
|
|
|
2008-08-08 03:15:40 +04:00
|
|
|
// Now move the docshells to the right docshell trees. Note that this
|
|
|
|
// resets their treeowners to null.
|
2013-02-13 02:02:51 +04:00
|
|
|
ourParentItem->RemoveChild(ourDocshell);
|
|
|
|
otherParentItem->RemoveChild(otherDocshell);
|
2008-08-08 03:15:40 +04:00
|
|
|
if (ourType == nsIDocShellTreeItem::typeContent) {
|
2013-02-13 02:02:51 +04:00
|
|
|
ourOwner->ContentShellRemoved(ourDocshell);
|
|
|
|
otherOwner->ContentShellRemoved(otherDocshell);
|
2008-08-08 03:15:40 +04:00
|
|
|
}
|
2015-11-24 04:40:02 +03:00
|
|
|
|
2013-02-13 02:02:51 +04:00
|
|
|
ourParentItem->AddChild(otherDocshell);
|
|
|
|
otherParentItem->AddChild(ourDocshell);
|
2008-08-08 03:15:40 +04:00
|
|
|
|
2012-12-21 15:58:23 +04:00
|
|
|
// Restore the correct chrome event handlers.
|
|
|
|
ourDocshell->SetChromeEventHandler(otherChromeEventHandler);
|
|
|
|
otherDocshell->SetChromeEventHandler(ourChromeEventHandler);
|
2008-08-08 03:15:40 +04:00
|
|
|
// Restore the correct treeowners
|
2012-12-21 15:58:23 +04:00
|
|
|
// (and also chrome event handlers for content frames only).
|
2013-02-13 02:02:51 +04:00
|
|
|
SetTreeOwnerAndChromeEventHandlerOnDocshellTree(
|
|
|
|
ourDocshell, otherOwner,
|
2016-05-01 21:29:23 +03:00
|
|
|
ourType == nsIDocShellTreeItem::typeContent
|
|
|
|
? otherChromeEventHandler.get()
|
|
|
|
: nullptr);
|
2013-02-13 02:02:51 +04:00
|
|
|
SetTreeOwnerAndChromeEventHandlerOnDocshellTree(
|
|
|
|
otherDocshell, ourOwner,
|
2016-05-01 21:29:23 +03:00
|
|
|
ourType == nsIDocShellTreeItem::typeContent ? ourChromeEventHandler.get()
|
|
|
|
: nullptr);
|
2008-08-08 03:15:40 +04:00
|
|
|
|
2012-09-05 07:00:26 +04:00
|
|
|
// Switch the owner content before we start calling AddTreeItemToTreeOwner.
|
|
|
|
// Note that we rely on this to deal with setting mObservingOwnerContent to
|
|
|
|
// false and calling RemoveMutationObserver as needed.
|
|
|
|
SetOwnerContent(otherContent);
|
|
|
|
aOther->SetOwnerContent(ourContent);
|
|
|
|
|
2018-11-05 15:43:10 +03:00
|
|
|
AddTreeItemToTreeOwner(ourDocshell, otherOwner);
|
|
|
|
aOther->AddTreeItemToTreeOwner(otherDocshell, ourOwner);
|
2008-08-08 03:15:40 +04:00
|
|
|
|
|
|
|
// SetSubDocumentFor nulls out parent documents on the old child doc if a
|
|
|
|
// new non-null document is passed in, so just go ahead and remove both
|
|
|
|
// kids before reinserting in the parent subdoc maps, to avoid
|
|
|
|
// complications.
|
2012-07-30 18:20:58 +04:00
|
|
|
ourParentDocument->SetSubDocumentFor(ourContent, nullptr);
|
|
|
|
otherParentDocument->SetSubDocumentFor(otherContent, nullptr);
|
2008-08-08 03:15:40 +04:00
|
|
|
ourParentDocument->SetSubDocumentFor(ourContent, otherChildDocument);
|
|
|
|
otherParentDocument->SetSubDocumentFor(otherContent, ourChildDocument);
|
|
|
|
|
|
|
|
ourWindow->SetFrameElementInternal(otherFrameElement);
|
|
|
|
otherWindow->SetFrameElementInternal(ourFrameElement);
|
|
|
|
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<nsFrameMessageManager> ourMessageManager = mMessageManager;
|
|
|
|
RefPtr<nsFrameMessageManager> otherMessageManager = aOther->mMessageManager;
|
2010-05-18 16:28:37 +04:00
|
|
|
// Swap pointers in child message managers.
|
|
|
|
if (mChildMessageManager) {
|
2018-08-11 00:08:07 +03:00
|
|
|
InProcessTabChildMessageManager* tabChild = mChildMessageManager;
|
2010-05-18 16:28:37 +04:00
|
|
|
tabChild->SetOwner(otherContent);
|
|
|
|
tabChild->SetChromeMessageManager(otherMessageManager);
|
|
|
|
}
|
|
|
|
if (aOther->mChildMessageManager) {
|
2018-08-11 00:08:07 +03:00
|
|
|
InProcessTabChildMessageManager* otherTabChild =
|
|
|
|
aOther->mChildMessageManager;
|
2010-05-18 16:28:37 +04:00
|
|
|
otherTabChild->SetOwner(ourContent);
|
|
|
|
otherTabChild->SetChromeMessageManager(ourMessageManager);
|
|
|
|
}
|
|
|
|
// Swap and setup things in parent message managers.
|
|
|
|
if (mMessageManager) {
|
2014-01-31 22:45:54 +04:00
|
|
|
mMessageManager->SetCallback(aOther);
|
2010-05-18 16:28:37 +04:00
|
|
|
}
|
|
|
|
if (aOther->mMessageManager) {
|
2014-01-31 22:45:54 +04:00
|
|
|
aOther->mMessageManager->SetCallback(this);
|
2010-05-18 16:28:37 +04:00
|
|
|
}
|
|
|
|
mMessageManager.swap(aOther->mMessageManager);
|
|
|
|
|
2016-10-17 17:37:50 +03:00
|
|
|
// Perform the actual swap of the internal refptrs. We keep a strong reference
|
|
|
|
// to ourselves to make sure we don't die while we overwrite our reference to
|
|
|
|
// ourself.
|
2018-03-22 05:43:17 +03:00
|
|
|
RefPtr<nsFrameLoader> kungFuDeathGrip(this);
|
2016-10-17 17:37:50 +03:00
|
|
|
aThisOwner->InternalSetFrameLoader(aOther);
|
|
|
|
aOtherOwner->InternalSetFrameLoader(kungFuDeathGrip);
|
2008-08-08 03:15:40 +04:00
|
|
|
|
2009-01-13 22:32:30 +03:00
|
|
|
// Drop any cached content viewers in the two session histories.
|
2018-02-02 01:35:47 +03:00
|
|
|
if (ourHistory) {
|
2018-02-12 23:47:06 +03:00
|
|
|
ourHistory->EvictLocalContentViewers();
|
2009-01-13 22:32:30 +03:00
|
|
|
}
|
2018-02-02 01:35:47 +03:00
|
|
|
if (otherHistory) {
|
2018-02-12 23:47:06 +03:00
|
|
|
otherHistory->EvictLocalContentViewers();
|
2009-01-13 22:32:30 +03:00
|
|
|
}
|
|
|
|
|
2010-09-18 15:28:49 +04:00
|
|
|
NS_ASSERTION(ourFrame == ourContent->GetPrimaryFrame() &&
|
|
|
|
otherFrame == otherContent->GetPrimaryFrame(),
|
|
|
|
"changed primary frame");
|
|
|
|
|
|
|
|
ourFrameFrame->EndSwapDocShells(otherFrame);
|
2008-08-08 03:15:40 +04:00
|
|
|
|
2013-02-03 16:21:52 +04:00
|
|
|
// If the content being swapped came from windows on two screens with
|
|
|
|
// incompatible backing resolution (e.g. dragging a tab between windows on
|
|
|
|
// hi-dpi and low-dpi screens), it will have style data that is based on
|
|
|
|
// the wrong appUnitsPerDevPixel value. So we tell the PresShells that their
|
|
|
|
// backing scale factor may have changed. (Bug 822266)
|
|
|
|
ourShell->BackingScaleFactorChanged();
|
|
|
|
otherShell->BackingScaleFactorChanged();
|
|
|
|
|
2016-04-29 01:04:52 +03:00
|
|
|
// Initialize browser API if needed now that owner content has changed
|
|
|
|
InitializeBrowserAPI();
|
|
|
|
aOther->InitializeBrowserAPI();
|
|
|
|
|
2008-08-08 03:15:40 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2015-02-27 08:35:26 +03:00
|
|
|
void nsFrameLoader::Destroy() { StartDestroy(); }
|
2010-04-12 04:34:02 +04:00
|
|
|
|
2016-04-26 03:23:21 +03:00
|
|
|
class nsFrameLoaderDestroyRunnable : public Runnable {
|
2015-02-27 08:35:26 +03:00
|
|
|
enum DestroyPhase {
|
|
|
|
// See the implementation of Run for an explanation of these phases.
|
|
|
|
eDestroyDocShell,
|
|
|
|
eWaitForUnloadMessage,
|
|
|
|
eDestroyComplete
|
|
|
|
};
|
|
|
|
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<nsFrameLoader> mFrameLoader;
|
2015-02-27 08:35:26 +03:00
|
|
|
DestroyPhase mPhase;
|
|
|
|
|
|
|
|
public:
|
|
|
|
explicit nsFrameLoaderDestroyRunnable(nsFrameLoader* aFrameLoader)
|
2017-06-12 22:34:10 +03:00
|
|
|
: mozilla::Runnable("nsFrameLoaderDestroyRunnable"),
|
|
|
|
mFrameLoader(aFrameLoader),
|
|
|
|
mPhase(eDestroyDocShell) {}
|
2015-02-27 08:35:26 +03:00
|
|
|
|
2016-08-08 03:54:47 +03:00
|
|
|
NS_IMETHOD Run() override;
|
2015-02-27 08:35:26 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
void nsFrameLoader::StartDestroy() {
|
|
|
|
// nsFrameLoader::StartDestroy is called just before the frameloader is
|
|
|
|
// detached from the <browser> element. Destruction continues in phases via
|
|
|
|
// the nsFrameLoaderDestroyRunnable.
|
|
|
|
|
2008-02-26 17:47:51 +03:00
|
|
|
if (mDestroyCalled) {
|
2015-02-27 08:35:26 +03:00
|
|
|
return;
|
2008-02-26 17:47:51 +03:00
|
|
|
}
|
2011-10-17 18:59:28 +04:00
|
|
|
mDestroyCalled = true;
|
2008-02-26 17:47:51 +03:00
|
|
|
|
2015-02-27 08:35:26 +03:00
|
|
|
// After this point, we return an error when trying to send a message using
|
|
|
|
// the message manager on the frame.
|
2010-05-18 16:28:37 +04:00
|
|
|
if (mMessageManager) {
|
2015-02-27 08:35:26 +03:00
|
|
|
mMessageManager->Close();
|
2010-05-18 16:28:37 +04:00
|
|
|
}
|
2015-02-27 08:35:26 +03:00
|
|
|
|
|
|
|
// Retain references to the <browser> element and the frameloader in case we
|
|
|
|
// receive any messages from the message manager on the frame. These
|
|
|
|
// references are dropped in DestroyComplete.
|
|
|
|
if (mChildMessageManager || mRemoteBrowser) {
|
|
|
|
mOwnerContentStrong = mOwnerContent;
|
|
|
|
if (mRemoteBrowser) {
|
|
|
|
mRemoteBrowser->CacheFrameLoader(this);
|
|
|
|
}
|
2015-04-16 18:17:54 +03:00
|
|
|
if (mChildMessageManager) {
|
|
|
|
mChildMessageManager->CacheFrameLoader(this);
|
|
|
|
}
|
2010-05-18 16:28:37 +04:00
|
|
|
}
|
|
|
|
|
2015-03-31 23:39:02 +03:00
|
|
|
// If the TabParent has installed any event listeners on the window, this is
|
|
|
|
// its last chance to remove them while we're still in the document.
|
|
|
|
if (mRemoteBrowser) {
|
|
|
|
mRemoteBrowser->RemoveWindowListeners();
|
|
|
|
}
|
|
|
|
|
2008-02-26 17:47:51 +03:00
|
|
|
nsCOMPtr<nsIDocument> doc;
|
2011-09-29 10:19:26 +04:00
|
|
|
bool dynamicSubframeRemoval = false;
|
2002-04-17 08:17:16 +04:00
|
|
|
if (mOwnerContent) {
|
2011-10-18 14:53:36 +04:00
|
|
|
doc = mOwnerContent->OwnerDoc();
|
2011-10-18 15:19:44 +04:00
|
|
|
dynamicSubframeRemoval = !mIsTopLevelContent && !doc->InUnlinkOrDeletion();
|
2012-07-30 18:20:58 +04:00
|
|
|
doc->SetSubDocumentFor(mOwnerContent, nullptr);
|
2015-10-01 20:06:51 +03:00
|
|
|
MaybeUpdatePrimaryTabParent(eTabParentRemoved);
|
2012-07-30 18:20:58 +04:00
|
|
|
SetOwnerContent(nullptr);
|
2002-04-17 08:17:16 +04:00
|
|
|
}
|
2010-08-17 18:13:55 +04:00
|
|
|
|
|
|
|
// Seems like this is a dynamic frame removal.
|
|
|
|
if (dynamicSubframeRemoval) {
|
2013-02-15 20:07:29 +04:00
|
|
|
if (mDocShell) {
|
|
|
|
mDocShell->RemoveFromSessionHistory();
|
2010-08-17 18:13:55 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-02-22 06:58:48 +03:00
|
|
|
// Let the tree owner know we're gone.
|
|
|
|
if (mIsTopLevelContent) {
|
2013-02-13 02:02:51 +04:00
|
|
|
if (mDocShell) {
|
2006-02-22 06:58:48 +03:00
|
|
|
nsCOMPtr<nsIDocShellTreeItem> parentItem;
|
2013-02-13 02:02:51 +04:00
|
|
|
mDocShell->GetParent(getter_AddRefs(parentItem));
|
2006-02-22 06:58:48 +03:00
|
|
|
nsCOMPtr<nsIDocShellTreeOwner> owner = do_GetInterface(parentItem);
|
2007-10-06 03:37:25 +04:00
|
|
|
if (owner) {
|
2013-02-13 02:02:51 +04:00
|
|
|
owner->ContentShellRemoved(mDocShell);
|
2006-02-22 06:58:48 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-02-27 08:35:26 +03:00
|
|
|
|
2003-11-04 05:01:23 +03:00
|
|
|
// Let our window know that we are gone
|
2014-01-10 06:03:47 +04:00
|
|
|
if (mDocShell) {
|
2016-01-30 20:05:36 +03:00
|
|
|
nsCOMPtr<nsPIDOMWindowOuter> win_private(mDocShell->GetWindow());
|
2014-01-10 06:03:47 +04:00
|
|
|
if (win_private) {
|
|
|
|
win_private->SetFrameElementInternal(nullptr);
|
|
|
|
}
|
2003-11-04 05:01:23 +03:00
|
|
|
}
|
2002-04-17 08:17:16 +04:00
|
|
|
|
2015-02-27 08:35:26 +03:00
|
|
|
nsCOMPtr<nsIRunnable> destroyRunnable =
|
|
|
|
new nsFrameLoaderDestroyRunnable(this);
|
|
|
|
if (mNeedsAsyncDestroy || !doc ||
|
|
|
|
NS_FAILED(doc->FinalizeFrameLoader(this, destroyRunnable))) {
|
|
|
|
NS_DispatchToCurrentThread(destroyRunnable);
|
|
|
|
}
|
|
|
|
}
|
2008-02-26 17:47:51 +03:00
|
|
|
|
2015-02-27 08:35:26 +03:00
|
|
|
nsresult nsFrameLoaderDestroyRunnable::Run() {
|
|
|
|
switch (mPhase) {
|
|
|
|
case eDestroyDocShell:
|
|
|
|
mFrameLoader->DestroyDocShell();
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2015-02-27 08:35:26 +03:00
|
|
|
// In the out-of-process case, TabParent will eventually call
|
|
|
|
// DestroyComplete once it receives a __delete__ message from the child.
|
|
|
|
// In the in-process case, we dispatch a series of runnables to ensure
|
|
|
|
// that DestroyComplete gets called at the right time. The frame loader is
|
|
|
|
// kept alive by mFrameLoader during this time.
|
|
|
|
if (mFrameLoader->mChildMessageManager) {
|
|
|
|
// When the docshell is destroyed, NotifyWindowIDDestroyed is called to
|
|
|
|
// asynchronously notify {outer,inner}-window-destroyed via a runnable.
|
|
|
|
// We don't want DestroyComplete to run until after those runnables have
|
|
|
|
// run. Since we're enqueueing ourselves after the window-destroyed
|
|
|
|
// runnables are enqueued, we're guaranteed to run after.
|
|
|
|
mPhase = eWaitForUnloadMessage;
|
|
|
|
NS_DispatchToCurrentThread(this);
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2015-02-27 08:35:26 +03:00
|
|
|
case eWaitForUnloadMessage:
|
|
|
|
// The *-window-destroyed observers have finished running at this
|
|
|
|
// point. However, it's possible that a *-window-destroyed observer might
|
|
|
|
// have sent a message using the message manager. These messages might not
|
|
|
|
// have been processed yet. So we enqueue ourselves again to ensure that
|
|
|
|
// DestroyComplete runs after all messages sent by *-window-destroyed
|
|
|
|
// observers have been processed.
|
|
|
|
mPhase = eDestroyComplete;
|
|
|
|
NS_DispatchToCurrentThread(this);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case eDestroyComplete:
|
|
|
|
// Now that all messages sent by unload listeners and window destroyed
|
|
|
|
// observers have been processed, we disconnect the message manager and
|
|
|
|
// finish destruction.
|
|
|
|
mFrameLoader->DestroyComplete();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2008-02-26 17:47:51 +03:00
|
|
|
|
2015-02-27 08:35:26 +03:00
|
|
|
void nsFrameLoader::DestroyDocShell() {
|
|
|
|
// This code runs after the frameloader has been detached from the <browser>
|
|
|
|
// element. We postpone this work because we may not be allowed to run
|
|
|
|
// script at that time.
|
|
|
|
|
|
|
|
// Ask the TabChild to fire the frame script "unload" event, destroy its
|
|
|
|
// docshell, and finally destroy the PBrowser actor. This eventually leads to
|
|
|
|
// nsFrameLoader::DestroyComplete being called.
|
|
|
|
if (mRemoteBrowser) {
|
|
|
|
mRemoteBrowser->Destroy();
|
2002-04-17 08:17:16 +04:00
|
|
|
}
|
|
|
|
|
2015-02-27 08:35:26 +03:00
|
|
|
// Fire the "unload" event if we're in-process.
|
|
|
|
if (mChildMessageManager) {
|
2017-07-19 15:59:02 +03:00
|
|
|
mChildMessageManager->FireUnloadEvent();
|
2015-02-27 08:35:26 +03:00
|
|
|
}
|
2008-02-26 17:47:51 +03:00
|
|
|
|
2015-02-27 08:35:26 +03:00
|
|
|
// Destroy the docshell.
|
2019-01-02 16:27:05 +03:00
|
|
|
if (mDocShell) {
|
|
|
|
mDocShell->Destroy();
|
2015-02-27 08:35:26 +03:00
|
|
|
}
|
|
|
|
mDocShell = nullptr;
|
|
|
|
|
|
|
|
if (mChildMessageManager) {
|
|
|
|
// Stop handling events in the in-process frame script.
|
2017-07-19 15:59:02 +03:00
|
|
|
mChildMessageManager->DisconnectEventListeners();
|
2015-02-27 08:35:26 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void nsFrameLoader::DestroyComplete() {
|
|
|
|
// We get here, as part of StartDestroy, after the docshell has been destroyed
|
|
|
|
// and all message manager messages sent during docshell destruction have been
|
|
|
|
// dispatched. We also get here if the child process crashes. In the latter
|
|
|
|
// case, StartDestroy might not have been called.
|
|
|
|
|
|
|
|
// Drop the strong references created in StartDestroy.
|
|
|
|
if (mChildMessageManager || mRemoteBrowser) {
|
|
|
|
mOwnerContentStrong = nullptr;
|
|
|
|
if (mRemoteBrowser) {
|
|
|
|
mRemoteBrowser->CacheFrameLoader(nullptr);
|
|
|
|
}
|
2015-04-16 18:17:54 +03:00
|
|
|
if (mChildMessageManager) {
|
|
|
|
mChildMessageManager->CacheFrameLoader(nullptr);
|
|
|
|
}
|
2015-02-27 08:35:26 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// Call TabParent::Destroy if we haven't already (in case of a crash).
|
|
|
|
if (mRemoteBrowser) {
|
|
|
|
mRemoteBrowser->SetOwnerElement(nullptr);
|
|
|
|
mRemoteBrowser->Destroy();
|
|
|
|
mRemoteBrowser = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mMessageManager) {
|
|
|
|
mMessageManager->Disconnect();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mChildMessageManager) {
|
2017-07-19 15:59:02 +03:00
|
|
|
mChildMessageManager->Disconnect();
|
2015-02-27 08:35:26 +03:00
|
|
|
}
|
2016-02-20 13:33:30 +03:00
|
|
|
|
|
|
|
mMessageManager = nullptr;
|
|
|
|
mChildMessageManager = nullptr;
|
2002-01-29 09:27:27 +03:00
|
|
|
}
|
|
|
|
|
2011-10-01 21:14:35 +04:00
|
|
|
void nsFrameLoader::SetOwnerContent(Element* aContent) {
|
2012-09-05 07:00:26 +04:00
|
|
|
if (mObservingOwnerContent) {
|
|
|
|
mObservingOwnerContent = false;
|
|
|
|
mOwnerContent->RemoveMutationObserver(this);
|
|
|
|
}
|
2011-01-13 20:45:14 +03:00
|
|
|
mOwnerContent = aContent;
|
2017-08-19 23:03:59 +03:00
|
|
|
|
|
|
|
AutoJSAPI jsapi;
|
|
|
|
jsapi.Init();
|
|
|
|
|
|
|
|
JS::RootedObject wrapper(jsapi.cx(), GetWrapper());
|
|
|
|
if (wrapper) {
|
2018-08-02 09:48:40 +03:00
|
|
|
JSAutoRealm ar(jsapi.cx(), wrapper);
|
2017-09-13 20:34:55 +03:00
|
|
|
IgnoredErrorResult rv;
|
2018-12-19 22:52:31 +03:00
|
|
|
UpdateReflectorGlobal(jsapi.cx(), wrapper, rv);
|
2017-09-13 20:34:55 +03:00
|
|
|
Unused << NS_WARN_IF(rv.Failed());
|
2017-08-19 23:03:59 +03:00
|
|
|
}
|
|
|
|
|
2018-11-07 00:35:37 +03:00
|
|
|
if (RenderFrame* rfp = GetCurrentRenderFrame()) {
|
2011-01-13 20:45:14 +03:00
|
|
|
rfp->OwnerContentChanged(aContent);
|
|
|
|
}
|
2011-01-13 20:45:14 +03:00
|
|
|
}
|
|
|
|
|
2016-10-15 04:46:26 +03:00
|
|
|
bool nsFrameLoader::OwnerIsMozBrowserFrame() {
|
2012-04-25 20:35:58 +04:00
|
|
|
nsCOMPtr<nsIMozBrowserFrame> browserFrame = do_QueryInterface(mOwnerContent);
|
2016-10-15 04:46:26 +03:00
|
|
|
return browserFrame ? browserFrame->GetReallyIsBrowser() : false;
|
2012-04-25 20:35:58 +04:00
|
|
|
}
|
2012-04-25 19:51:31 +04:00
|
|
|
|
2016-02-18 06:31:29 +03:00
|
|
|
bool nsFrameLoader::OwnerIsIsolatedMozBrowserFrame() {
|
|
|
|
nsCOMPtr<nsIMozBrowserFrame> browserFrame = do_QueryInterface(mOwnerContent);
|
|
|
|
if (!browserFrame) {
|
|
|
|
return false;
|
|
|
|
}
|
2016-02-18 07:57:41 +03:00
|
|
|
|
|
|
|
if (!OwnerIsMozBrowserFrame()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool isolated = browserFrame->GetIsolated();
|
|
|
|
if (isolated) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
2012-07-14 01:10:20 +04:00
|
|
|
}
|
|
|
|
|
2012-04-25 20:35:58 +04:00
|
|
|
bool nsFrameLoader::ShouldUseRemoteProcess() {
|
2017-05-29 13:38:46 +03:00
|
|
|
if (IsForJSPlugin()) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2011-06-07 23:23:15 +04:00
|
|
|
if (PR_GetEnv("MOZ_DISABLE_OOP_TABS") ||
|
2011-09-29 10:19:26 +04:00
|
|
|
Preferences::GetBool("dom.ipc.tabs.disabled", false)) {
|
2009-10-16 23:42:27 +04:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-06-11 09:44:13 +04:00
|
|
|
// Don't try to launch nested children if we don't have OMTC.
|
|
|
|
// They won't render!
|
2015-07-04 04:29:00 +03:00
|
|
|
if (XRE_IsContentProcess() &&
|
2015-11-24 04:50:51 +03:00
|
|
|
!CompositorBridgeChild::ChildProcessHasCompositorBridge()) {
|
2014-06-11 09:44:13 +04:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-07-04 04:29:00 +03:00
|
|
|
if (XRE_IsContentProcess() &&
|
2014-06-11 09:44:13 +04:00
|
|
|
!(PR_GetEnv("MOZ_NESTED_OOP_TABS") ||
|
|
|
|
Preferences::GetBool("dom.ipc.tabs.nested.enabled", false))) {
|
2012-07-10 07:32:47 +04:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2012-05-16 09:28:56 +04:00
|
|
|
// If we're an <iframe mozbrowser> and we don't have a "remote" attribute,
|
|
|
|
// fall back to the default.
|
2016-10-15 04:46:26 +03:00
|
|
|
if (OwnerIsMozBrowserFrame() &&
|
2018-03-14 02:27:25 +03:00
|
|
|
!mOwnerContent->HasAttr(kNameSpaceID_None, nsGkAtoms::remote)) {
|
2012-05-16 09:28:56 +04:00
|
|
|
return Preferences::GetBool("dom.ipc.browser_frames.oop_by_default", false);
|
|
|
|
}
|
|
|
|
|
2012-05-16 09:28:57 +04:00
|
|
|
// Otherwise, we're remote if we have "remote=true" and we're either a
|
|
|
|
// browser frame or a XUL element.
|
2016-10-15 04:46:26 +03:00
|
|
|
return (OwnerIsMozBrowserFrame() ||
|
2012-05-16 09:28:57 +04:00
|
|
|
mOwnerContent->GetNameSpaceID() == kNameSpaceID_XUL) &&
|
|
|
|
mOwnerContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::remote,
|
2012-05-16 09:28:56 +04:00
|
|
|
nsGkAtoms::_true, eCaseMatters);
|
2009-10-16 23:42:27 +04:00
|
|
|
}
|
|
|
|
|
2015-07-31 12:28:36 +03:00
|
|
|
bool nsFrameLoader::IsRemoteFrame() {
|
|
|
|
if (mRemoteFrame) {
|
|
|
|
MOZ_ASSERT(!mDocShell, "Found a remote frame with a DocShell");
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2018-11-05 15:43:10 +03:00
|
|
|
static already_AddRefed<BrowsingContext> CreateBrowsingContext(
|
|
|
|
BrowsingContext* aParentContext, BrowsingContext* aOpenerContext,
|
|
|
|
const nsAString& aName, bool aIsContent) {
|
|
|
|
// If we're content but our parent isn't, we're going to want to start a new
|
|
|
|
// browsing context tree.
|
|
|
|
if (aIsContent && !aParentContext->IsContent()) {
|
|
|
|
aParentContext = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
BrowsingContext::Type type = aIsContent ? BrowsingContext::Type::Content
|
|
|
|
: BrowsingContext::Type::Chrome;
|
|
|
|
|
2018-11-27 12:59:44 +03:00
|
|
|
return BrowsingContext::Create(aParentContext, aOpenerContext, aName, type);
|
2018-11-05 15:43:10 +03:00
|
|
|
}
|
|
|
|
|
2009-10-16 23:42:27 +04:00
|
|
|
nsresult nsFrameLoader::MaybeCreateDocShell() {
|
2009-10-27 23:38:26 +03:00
|
|
|
if (mDocShell) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2015-07-31 12:28:36 +03:00
|
|
|
if (IsRemoteFrame()) {
|
2002-01-29 09:27:27 +03:00
|
|
|
return NS_OK;
|
|
|
|
}
|
2008-02-26 17:47:51 +03:00
|
|
|
NS_ENSURE_STATE(!mDestroyCalled);
|
2002-01-29 09:27:27 +03:00
|
|
|
|
2004-05-31 20:31:15 +04:00
|
|
|
// Get our parent docshell off the document of mOwnerContent
|
|
|
|
// XXXbz this is such a total hack.... We really need to have a
|
|
|
|
// better setup for doing this.
|
2011-10-18 14:53:36 +04:00
|
|
|
nsIDocument* doc = mOwnerContent->OwnerDoc();
|
2016-05-12 19:22:25 +03:00
|
|
|
|
|
|
|
MOZ_RELEASE_ASSERT(!doc->IsResourceDoc(), "We shouldn't even exist");
|
|
|
|
|
2017-10-10 19:54:00 +03:00
|
|
|
// Check if the document still has a window since it is possible for an
|
|
|
|
// iframe to be inserted and cause the creation of the docshell in a
|
|
|
|
// partially unloaded document (see Bug 1305237 comment 127).
|
|
|
|
if (!doc->IsStaticDocument() &&
|
|
|
|
(!doc->GetWindow() || !mOwnerContent->IsInComposedDoc())) {
|
2004-05-31 20:31:15 +04:00
|
|
|
return NS_ERROR_UNEXPECTED;
|
|
|
|
}
|
|
|
|
|
2016-05-12 19:22:25 +03:00
|
|
|
if (!doc->IsActive()) {
|
|
|
|
// Don't allow subframe loads in non-active documents.
|
|
|
|
// (See bug 610571 comment 5.)
|
2008-10-05 00:00:09 +04:00
|
|
|
return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
}
|
|
|
|
|
2018-11-05 15:43:10 +03:00
|
|
|
// Determine our parent nsDocShell
|
|
|
|
RefPtr<nsDocShell> parentDocShell = nsDocShell::Cast(doc->GetDocShell());
|
|
|
|
if (NS_WARN_IF(!parentDocShell)) {
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
2010-08-17 18:13:55 +04:00
|
|
|
}
|
|
|
|
|
2018-11-05 15:43:10 +03:00
|
|
|
RefPtr<BrowsingContext> parentBC = parentDocShell->GetBrowsingContext();
|
|
|
|
MOZ_ASSERT(parentBC, "docShell must have BrowsingContext");
|
|
|
|
|
|
|
|
// Determine the frame name for the new browsing context.
|
2002-01-29 09:27:27 +03:00
|
|
|
nsAutoString frameName;
|
2004-09-13 03:34:00 +04:00
|
|
|
|
2012-08-22 19:56:38 +04:00
|
|
|
int32_t namespaceID = mOwnerContent->GetNameSpaceID();
|
2015-02-10 12:14:19 +03:00
|
|
|
if (namespaceID == kNameSpaceID_XHTML && !mOwnerContent->IsInHTMLDocument()) {
|
2006-12-26 20:47:52 +03:00
|
|
|
mOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::id, frameName);
|
2004-09-13 03:34:00 +04:00
|
|
|
} else {
|
2006-12-26 20:47:52 +03:00
|
|
|
mOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::name, frameName);
|
2004-10-01 22:32:18 +04:00
|
|
|
// XXX if no NAME then use ID, after a transition period this will be
|
|
|
|
// changed so that XUL only uses ID too (bug 254284).
|
2005-09-24 22:43:15 +04:00
|
|
|
if (frameName.IsEmpty() && namespaceID == kNameSpaceID_XUL) {
|
2006-12-26 20:47:52 +03:00
|
|
|
mOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::id, frameName);
|
2004-10-01 22:32:18 +04:00
|
|
|
}
|
2004-09-13 03:34:00 +04:00
|
|
|
}
|
2002-01-29 09:27:27 +03:00
|
|
|
|
2018-11-05 15:43:10 +03:00
|
|
|
// Check if our new context is chrome or content
|
|
|
|
bool isContent = parentBC->IsContent() ||
|
|
|
|
mOwnerContent->AttrValueIs(kNameSpaceID_None, TypeAttrName(),
|
|
|
|
nsGkAtoms::content, eIgnoreCase);
|
|
|
|
|
|
|
|
// Force mozbrowser frames to always be content, even if the mozbrowser
|
|
|
|
// interfaces are disabled.
|
|
|
|
nsCOMPtr<nsIMozBrowserFrame> mozbrowser =
|
|
|
|
mOwnerContent->GetAsMozBrowserFrame();
|
|
|
|
if (!isContent && mozbrowser) {
|
|
|
|
mozbrowser->GetMozbrowser(&isContent);
|
2002-01-29 09:27:27 +03:00
|
|
|
}
|
|
|
|
|
2018-11-27 12:59:44 +03:00
|
|
|
RefPtr<BrowsingContext> openerBC =
|
|
|
|
mOpener ? mOpener->GetBrowsingContext() : nullptr;
|
|
|
|
RefPtr<BrowsingContext> browsingContext =
|
|
|
|
CreateBrowsingContext(parentBC, openerBC, frameName, isContent);
|
2002-01-29 09:27:27 +03:00
|
|
|
|
2018-11-05 15:43:10 +03:00
|
|
|
mDocShell = nsDocShell::Create(browsingContext);
|
|
|
|
NS_ENSURE_TRUE(mDocShell, NS_ERROR_FAILURE);
|
2006-02-22 06:58:48 +03:00
|
|
|
|
2018-11-05 15:43:10 +03:00
|
|
|
mIsTopLevelContent = isContent && !parentBC->IsContent();
|
|
|
|
if (!mNetworkCreated && !mIsTopLevelContent) {
|
|
|
|
mDocShell->SetCreatedDynamically(true);
|
|
|
|
}
|
2002-04-05 09:42:10 +04:00
|
|
|
|
2017-08-02 20:08:04 +03:00
|
|
|
if (mIsTopLevelContent) {
|
2018-11-05 15:43:10 +03:00
|
|
|
// Manually add ourselves to our parent's docshell, as BrowsingContext won't
|
|
|
|
// have done this for us.
|
|
|
|
//
|
|
|
|
// XXX(nika): Consider removing the DocShellTree in the future, for
|
|
|
|
// consistency between local and remote frames..
|
|
|
|
parentDocShell->AddChild(mDocShell);
|
2017-08-02 20:08:04 +03:00
|
|
|
}
|
|
|
|
|
2018-11-05 15:43:10 +03:00
|
|
|
// Now that we are part of the DocShellTree, attach our DocShell to our
|
|
|
|
// parent's TreeOwner.
|
|
|
|
nsCOMPtr<nsIDocShellTreeOwner> parentTreeOwner;
|
|
|
|
parentDocShell->GetTreeOwner(getter_AddRefs(parentTreeOwner));
|
|
|
|
AddTreeItemToTreeOwner(mDocShell, parentTreeOwner);
|
2002-01-29 09:27:27 +03:00
|
|
|
|
2018-11-05 15:43:10 +03:00
|
|
|
// Make sure all nsDocShells have links back to the content element in the
|
|
|
|
// nearest enclosing chrome shell.
|
|
|
|
RefPtr<EventTarget> chromeEventHandler;
|
|
|
|
if (parentBC->IsContent()) {
|
|
|
|
// Our parent shell is a content shell. Get the chrome event handler from it
|
|
|
|
// and use that for our shell as well.
|
2018-03-22 05:43:15 +03:00
|
|
|
parentDocShell->GetChromeEventHandler(getter_AddRefs(chromeEventHandler));
|
2018-11-05 15:43:10 +03:00
|
|
|
} else {
|
|
|
|
// Our parent shell is a chrome shell. It is therefore our nearest enclosing
|
|
|
|
// chrome shell.
|
|
|
|
chromeEventHandler = mOwnerContent;
|
2002-04-17 08:17:16 +04:00
|
|
|
}
|
2002-01-29 09:27:27 +03:00
|
|
|
|
2014-01-07 02:34:15 +04:00
|
|
|
mDocShell->SetChromeEventHandler(chromeEventHandler);
|
|
|
|
|
2014-01-10 06:03:47 +04:00
|
|
|
// This is nasty, this code (the mDocShell->GetWindow() below)
|
2002-04-17 08:17:16 +04:00
|
|
|
// *must* come *after* the above call to
|
|
|
|
// mDocShell->SetChromeEventHandler() for the global window to get
|
|
|
|
// the right chrome event handler.
|
2002-01-29 09:27:27 +03:00
|
|
|
|
2002-04-17 08:17:16 +04:00
|
|
|
// Tell the window about the frame that hosts it.
|
2018-11-05 15:43:10 +03:00
|
|
|
nsCOMPtr<nsPIDOMWindowOuter> newWindow = mDocShell->GetWindow();
|
|
|
|
if (NS_WARN_IF(!newWindow)) {
|
|
|
|
// Do not call Destroy() here. See bug 472312.
|
|
|
|
NS_WARNING("Something wrong when creating the docshell for a frameloader!");
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
2002-01-29 09:27:27 +03:00
|
|
|
|
2018-11-05 15:43:10 +03:00
|
|
|
newWindow->SetFrameElementInternal(mOwnerContent);
|
2016-10-17 17:37:50 +03:00
|
|
|
|
2018-11-27 12:59:44 +03:00
|
|
|
// Set the opener window if we have one provided here XXX(nika): We
|
|
|
|
// should tell our BrowsingContext this as we create it.
|
|
|
|
// TODO(farre): Remove this when nsGlobalWindowOuter::GetOpenerWindowOuter
|
|
|
|
// starts using BrowsingContext::GetOpener.
|
2018-11-05 15:43:10 +03:00
|
|
|
if (mOpener) {
|
|
|
|
newWindow->SetOpenerWindow(mOpener, true);
|
|
|
|
mOpener = nullptr;
|
2008-12-13 23:30:02 +03:00
|
|
|
}
|
2002-04-05 02:42:19 +04:00
|
|
|
|
2018-09-15 11:26:33 +03:00
|
|
|
// Allow scripts to close the docshell if specified.
|
2018-11-05 15:43:10 +03:00
|
|
|
if (mOwnerContent->IsXULElement(nsGkAtoms::browser) &&
|
2018-09-15 11:26:33 +03:00
|
|
|
mOwnerContent->AttrValueIs(kNameSpaceID_None,
|
|
|
|
nsGkAtoms::allowscriptstoclose,
|
|
|
|
nsGkAtoms::_true, eCaseMatters)) {
|
2018-11-05 15:43:10 +03:00
|
|
|
nsGlobalWindowOuter::Cast(newWindow)->AllowScriptsToClose();
|
2018-09-15 11:26:33 +03:00
|
|
|
}
|
|
|
|
|
2002-04-17 08:17:16 +04:00
|
|
|
// This is kinda whacky, this call doesn't really create anything,
|
|
|
|
// but it must be called to make sure things are properly
|
2009-01-08 23:16:33 +03:00
|
|
|
// initialized.
|
2019-01-02 16:27:05 +03:00
|
|
|
RefPtr<nsDocShell> docShell = mDocShell;
|
|
|
|
if (NS_FAILED(docShell->Create())) {
|
2009-01-08 23:16:33 +03:00
|
|
|
// Do not call Destroy() here. See bug 472312.
|
2009-01-09 00:36:22 +03:00
|
|
|
NS_WARNING("Something wrong when creating the docshell for a frameloader!");
|
2008-12-13 23:30:02 +03:00
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
2002-04-04 06:09:19 +04:00
|
|
|
|
2018-02-02 01:56:54 +03:00
|
|
|
// If we are an in-process browser, we want to set up our session history. We
|
|
|
|
// do this by creating both the child SHistory (which is in the nsDocShell),
|
|
|
|
// and creating the corresponding in-process ParentSHistory.
|
2015-03-03 14:08:59 +03:00
|
|
|
if (mIsTopLevelContent && mOwnerContent->IsXULElement(nsGkAtoms::browser) &&
|
2014-02-12 23:07:19 +04:00
|
|
|
!mOwnerContent->HasAttr(kNameSpaceID_None, nsGkAtoms::disablehistory)) {
|
2018-02-02 01:35:47 +03:00
|
|
|
// XXX(nika): Set this up more explicitly?
|
|
|
|
nsresult rv = mDocShell->InitSessionHistory();
|
2014-02-12 23:07:19 +04:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2018-02-02 01:56:54 +03:00
|
|
|
mParentSHistory = new ParentSHistory(this);
|
2014-02-12 23:07:19 +04:00
|
|
|
}
|
|
|
|
|
2017-01-12 19:38:48 +03:00
|
|
|
OriginAttributes attrs;
|
2018-03-22 05:43:15 +03:00
|
|
|
if (parentDocShell->ItemType() == mDocShell->ItemType()) {
|
2018-11-05 15:43:10 +03:00
|
|
|
attrs = parentDocShell->GetOriginAttributes();
|
2016-02-16 10:04:14 +03:00
|
|
|
}
|
|
|
|
|
2016-08-26 07:41:37 +03:00
|
|
|
// Inherit origin attributes from parent document if
|
|
|
|
// 1. It's in a content docshell.
|
|
|
|
// 2. its nodePrincipal is not a SystemPrincipal.
|
2016-10-15 04:46:26 +03:00
|
|
|
// 3. It's not a mozbrowser frame.
|
2016-08-26 07:41:37 +03:00
|
|
|
//
|
|
|
|
// For example, firstPartyDomain is computed from top-level document, it
|
|
|
|
// doesn't exist in the top-level docshell.
|
2018-11-05 15:43:10 +03:00
|
|
|
if (parentBC->IsContent() &&
|
2016-08-26 07:41:37 +03:00
|
|
|
!nsContentUtils::IsSystemPrincipal(doc->NodePrincipal()) &&
|
2016-10-15 04:46:26 +03:00
|
|
|
!OwnerIsMozBrowserFrame()) {
|
2017-01-12 19:38:48 +03:00
|
|
|
OriginAttributes oa = doc->NodePrincipal()->OriginAttributesRef();
|
2016-08-26 07:41:37 +03:00
|
|
|
|
|
|
|
// Assert on the firstPartyDomain from top-level docshell should be empty
|
2017-03-02 06:01:33 +03:00
|
|
|
MOZ_ASSERT_IF(mIsTopLevelContent, attrs.mFirstPartyDomain.IsEmpty());
|
2016-08-26 07:41:37 +03:00
|
|
|
|
2017-01-12 19:38:48 +03:00
|
|
|
// So far we want to make sure Inherit doesn't override any other origin
|
|
|
|
// attribute than firstPartyDomain.
|
|
|
|
MOZ_ASSERT(attrs.mAppId == oa.mAppId,
|
2016-08-26 07:41:37 +03:00
|
|
|
"docshell and document should have the same appId attribute.");
|
2017-01-12 19:38:48 +03:00
|
|
|
MOZ_ASSERT(
|
|
|
|
attrs.mUserContextId == oa.mUserContextId,
|
2016-08-26 07:41:37 +03:00
|
|
|
"docshell and document should have the same userContextId attribute.");
|
2017-01-12 19:38:48 +03:00
|
|
|
MOZ_ASSERT(attrs.mInIsolatedMozBrowser == oa.mInIsolatedMozBrowser,
|
2016-08-26 07:41:37 +03:00
|
|
|
"docshell and document should have the same "
|
|
|
|
"inIsolatedMozBrowser attribute.");
|
2017-01-12 19:38:48 +03:00
|
|
|
MOZ_ASSERT(attrs.mPrivateBrowsingId == oa.mPrivateBrowsingId,
|
2016-08-26 07:41:37 +03:00
|
|
|
"docshell and document should have the same privateBrowsingId "
|
|
|
|
"attribute.");
|
|
|
|
|
2017-03-08 09:41:51 +03:00
|
|
|
attrs = oa;
|
2016-08-26 07:41:37 +03:00
|
|
|
}
|
|
|
|
|
2016-02-18 06:31:29 +03:00
|
|
|
if (OwnerIsMozBrowserFrame()) {
|
2016-10-15 04:46:26 +03:00
|
|
|
attrs.mAppId = nsIScriptSecurityManager::NO_APP_ID;
|
2016-02-16 10:04:14 +03:00
|
|
|
attrs.mInIsolatedMozBrowser = OwnerIsIsolatedMozBrowserFrame();
|
|
|
|
mDocShell->SetFrameType(nsIDocShell::FRAME_TYPE_BROWSER);
|
Bug 802366 - The main event: Let a browser process inherit its app's id. r=bz,cjones
The main bug fixed here is that in half of our interfaces, we use "is browser frame/element" to mean "browser or app", and in the other half, we use it to mean "is browser not app".
There's a related, functional bug also fixed here, which is that a browser process doesn't inherit its parent's app-id. This causes problems e.g. for IndexedDB: If a browser inside an app uses IndexedDB, the DB should have the app's app-id.
I also modified Tab{Parent,Child} and nsFrameLoader to call "app" "ownOrContainingApp", to emphasize that we might have inherited the app from a parent process. I left nsIDocShell::appId alone, because changing that would have necessitated changing nsILoadGroup and therefore a /lot/ of users in Necko; it's also not clear it would have clarified anything in those cases.
2012-11-10 22:32:37 +04:00
|
|
|
}
|
2012-06-22 05:17:52 +04:00
|
|
|
|
2016-06-21 21:31:00 +03:00
|
|
|
// Apply sandbox flags even if our owner is not an iframe, as this copies
|
|
|
|
// flags from our owning content's owning document.
|
|
|
|
// Note: ApplySandboxFlags should be called after mDocShell->SetFrameType
|
|
|
|
// because we need to get the correct presentation URL in ApplySandboxFlags.
|
|
|
|
uint32_t sandboxFlags = 0;
|
2018-03-22 00:39:04 +03:00
|
|
|
HTMLIFrameElement* iframe = HTMLIFrameElement::FromNode(mOwnerContent);
|
2016-06-21 21:31:00 +03:00
|
|
|
if (iframe) {
|
|
|
|
sandboxFlags = iframe->GetSandboxFlags();
|
|
|
|
}
|
|
|
|
ApplySandboxFlags(sandboxFlags);
|
|
|
|
|
2018-02-24 02:32:18 +03:00
|
|
|
// Grab the userContextId from owner
|
2016-05-30 02:48:00 +03:00
|
|
|
nsresult rv = PopulateUserContextIdFromAttribute(attrs);
|
|
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
|
|
return rv;
|
2016-02-16 10:04:14 +03:00
|
|
|
}
|
|
|
|
|
2016-06-03 00:02:29 +03:00
|
|
|
bool isPrivate = false;
|
2018-11-05 15:43:10 +03:00
|
|
|
rv = parentDocShell->GetUsePrivateBrowsing(&isPrivate);
|
2016-06-03 00:02:29 +03:00
|
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
attrs.SyncAttributesWithPrivateBrowsing(isPrivate);
|
|
|
|
|
2016-10-15 04:46:26 +03:00
|
|
|
if (OwnerIsMozBrowserFrame()) {
|
2014-11-24 22:05:35 +03:00
|
|
|
// For inproc frames, set the docshell properties.
|
|
|
|
nsAutoString name;
|
|
|
|
if (mOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::name, name)) {
|
2018-03-22 05:43:15 +03:00
|
|
|
mDocShell->SetName(name);
|
2014-11-24 22:05:35 +03:00
|
|
|
}
|
|
|
|
mDocShell->SetFullscreenAllowed(
|
|
|
|
mOwnerContent->HasAttr(kNameSpaceID_None, nsGkAtoms::allowfullscreen) ||
|
|
|
|
mOwnerContent->HasAttr(kNameSpaceID_None,
|
|
|
|
nsGkAtoms::mozallowfullscreen));
|
|
|
|
bool isPrivate = mOwnerContent->HasAttr(kNameSpaceID_None,
|
|
|
|
nsGkAtoms::mozprivatebrowsing);
|
|
|
|
if (isPrivate) {
|
2016-08-12 08:19:29 +03:00
|
|
|
if (mDocShell->GetHasLoadedNonBlankURI()) {
|
2014-11-24 22:05:35 +03:00
|
|
|
nsContentUtils::ReportToConsoleNonLocalized(
|
|
|
|
NS_LITERAL_STRING("We should not switch to Private Browsing after "
|
|
|
|
"loading a document."),
|
|
|
|
nsIScriptError::warningFlag,
|
|
|
|
NS_LITERAL_CSTRING("mozprivatebrowsing"), nullptr);
|
|
|
|
} else {
|
2016-06-06 08:42:00 +03:00
|
|
|
// This handles the case where a frames private browsing is set by
|
|
|
|
// chrome flags and not inherited by its parent.
|
|
|
|
attrs.SyncAttributesWithPrivateBrowsing(isPrivate);
|
2014-11-24 22:05:35 +03:00
|
|
|
}
|
|
|
|
}
|
2012-06-22 05:17:52 +04:00
|
|
|
}
|
|
|
|
|
2016-06-06 08:42:00 +03:00
|
|
|
nsDocShell::Cast(mDocShell)->SetOriginAttributes(attrs);
|
|
|
|
|
2017-10-10 19:54:00 +03:00
|
|
|
// Typically there will be a window, however for some cases such as printing
|
|
|
|
// the document is cloned with a docshell that has no window. We check
|
|
|
|
// that the window exists to ensure we don't try to gather ancestors for
|
|
|
|
// those cases.
|
|
|
|
nsCOMPtr<nsPIDOMWindowOuter> win = doc->GetWindow();
|
2017-09-19 04:24:38 +03:00
|
|
|
if (!mDocShell->GetIsMozBrowser() &&
|
2018-11-05 15:43:10 +03:00
|
|
|
parentDocShell->ItemType() == mDocShell->ItemType() &&
|
2017-10-10 19:54:00 +03:00
|
|
|
!doc->IsStaticDocument() && win) {
|
2017-09-19 04:24:38 +03:00
|
|
|
// Propagate through the ancestor principals.
|
|
|
|
nsTArray<nsCOMPtr<nsIPrincipal>> ancestorPrincipals;
|
|
|
|
// Make a copy, so we can modify it.
|
|
|
|
ancestorPrincipals = doc->AncestorPrincipals();
|
|
|
|
ancestorPrincipals.InsertElementAt(0, doc->NodePrincipal());
|
2018-05-30 22:15:35 +03:00
|
|
|
nsDocShell::Cast(mDocShell)->SetAncestorPrincipals(
|
|
|
|
std::move(ancestorPrincipals));
|
2017-10-10 19:54:00 +03:00
|
|
|
|
|
|
|
// Repeat for outer window IDs.
|
|
|
|
nsTArray<uint64_t> ancestorOuterWindowIDs;
|
|
|
|
ancestorOuterWindowIDs = doc->AncestorOuterWindowIDs();
|
|
|
|
ancestorOuterWindowIDs.InsertElementAt(0, win->WindowID());
|
2018-05-30 22:15:35 +03:00
|
|
|
nsDocShell::Cast(mDocShell)->SetAncestorOuterWindowIDs(
|
|
|
|
std::move(ancestorOuterWindowIDs));
|
2017-09-19 04:24:38 +03:00
|
|
|
}
|
|
|
|
|
2015-07-31 13:08:36 +03:00
|
|
|
ReallyLoadFrameScripts();
|
|
|
|
InitializeBrowserAPI();
|
|
|
|
|
|
|
|
nsCOMPtr<nsIObserverService> os = services::GetObserverService();
|
|
|
|
if (os) {
|
2018-03-22 05:43:17 +03:00
|
|
|
os->NotifyObservers(ToSupports(this), "inprocess-browser-shown", nullptr);
|
2015-07-31 13:08:36 +03:00
|
|
|
}
|
|
|
|
|
2002-04-04 11:31:16 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
2002-04-04 06:09:19 +04:00
|
|
|
|
2017-10-05 08:59:44 +03:00
|
|
|
void nsFrameLoader::GetURL(nsString& aURI,
|
|
|
|
nsIPrincipal** aTriggeringPrincipal) {
|
2002-04-17 08:17:16 +04:00
|
|
|
aURI.Truncate();
|
2002-04-05 02:42:19 +04:00
|
|
|
|
2015-03-03 14:09:00 +03:00
|
|
|
if (mOwnerContent->IsHTMLElement(nsGkAtoms::object)) {
|
2006-12-26 20:47:52 +03:00
|
|
|
mOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::data, aURI);
|
2018-09-28 17:00:13 +03:00
|
|
|
nsCOMPtr<nsIPrincipal> prin = mOwnerContent->NodePrincipal();
|
|
|
|
prin.forget(aTriggeringPrincipal);
|
2002-04-17 08:17:16 +04:00
|
|
|
} else {
|
2006-12-26 20:47:52 +03:00
|
|
|
mOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::src, aURI);
|
2017-10-05 08:59:44 +03:00
|
|
|
if (RefPtr<nsGenericHTMLFrameElement> frame =
|
|
|
|
do_QueryObject(mOwnerContent)) {
|
|
|
|
nsCOMPtr<nsIPrincipal> prin = frame->GetSrcTriggeringPrincipal();
|
|
|
|
prin.forget(aTriggeringPrincipal);
|
2018-09-28 17:00:13 +03:00
|
|
|
} else {
|
|
|
|
nsCOMPtr<nsIPrincipal> prin = mOwnerContent->NodePrincipal();
|
|
|
|
prin.forget(aTriggeringPrincipal);
|
2017-10-05 08:59:44 +03:00
|
|
|
}
|
2002-04-17 08:17:16 +04:00
|
|
|
}
|
2002-01-29 09:27:27 +03:00
|
|
|
}
|
|
|
|
|
2005-03-08 03:02:55 +03:00
|
|
|
nsresult nsFrameLoader::CheckForRecursiveLoad(nsIURI* aURI) {
|
2009-10-16 23:42:27 +04:00
|
|
|
nsresult rv;
|
|
|
|
|
2015-07-31 12:28:36 +03:00
|
|
|
MOZ_ASSERT(!IsRemoteFrame(),
|
|
|
|
"Shouldn't call CheckForRecursiveLoad on remote frames.");
|
|
|
|
|
2011-10-17 18:59:28 +04:00
|
|
|
mDepthTooGreat = false;
|
2009-10-16 23:42:27 +04:00
|
|
|
rv = MaybeCreateDocShell();
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
2015-07-31 12:28:36 +03:00
|
|
|
NS_ASSERTION(mDocShell, "MaybeCreateDocShell succeeded, but null mDocShell");
|
2009-10-16 23:42:27 +04:00
|
|
|
if (!mDocShell) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
2007-07-17 11:43:36 +04:00
|
|
|
|
2010-09-15 20:10:16 +04:00
|
|
|
// Check that we're still in the docshell tree.
|
|
|
|
nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
|
2013-02-13 02:02:51 +04:00
|
|
|
mDocShell->GetTreeOwner(getter_AddRefs(treeOwner));
|
2016-09-01 08:01:16 +03:00
|
|
|
NS_WARNING_ASSERTION(treeOwner,
|
|
|
|
"Trying to load a new url to a docshell without owner!");
|
2010-09-15 20:10:16 +04:00
|
|
|
NS_ENSURE_STATE(treeOwner);
|
2015-11-24 04:40:02 +03:00
|
|
|
|
2014-01-20 11:58:26 +04:00
|
|
|
if (mDocShell->ItemType() != nsIDocShellTreeItem::typeContent) {
|
2005-03-08 03:02:55 +03:00
|
|
|
// No need to do recursion-protection here XXXbz why not?? Do we really
|
|
|
|
// trust people not to screw up with non-content docshells?
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Bug 8065: Don't exceed some maximum depth in content frames
|
|
|
|
// (MAX_DEPTH_CONTENT_FRAMES)
|
|
|
|
nsCOMPtr<nsIDocShellTreeItem> parentAsItem;
|
2013-02-13 02:02:51 +04:00
|
|
|
mDocShell->GetSameTypeParent(getter_AddRefs(parentAsItem));
|
2012-08-22 19:56:38 +04:00
|
|
|
int32_t depth = 0;
|
2005-03-08 03:02:55 +03:00
|
|
|
while (parentAsItem) {
|
|
|
|
++depth;
|
2015-11-24 04:40:02 +03:00
|
|
|
|
2005-03-08 03:02:55 +03:00
|
|
|
if (depth >= MAX_DEPTH_CONTENT_FRAMES) {
|
2011-10-17 18:59:28 +04:00
|
|
|
mDepthTooGreat = true;
|
2005-03-08 03:02:55 +03:00
|
|
|
NS_WARNING("Too many nested content frames so giving up");
|
|
|
|
|
|
|
|
return NS_ERROR_UNEXPECTED; // Too deep, give up! (silently?)
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDocShellTreeItem> temp;
|
|
|
|
temp.swap(parentAsItem);
|
|
|
|
temp->GetSameTypeParent(getter_AddRefs(parentAsItem));
|
|
|
|
}
|
2014-02-09 06:05:48 +04:00
|
|
|
|
|
|
|
// Bug 136580: Check for recursive frame loading excluding about:srcdoc URIs.
|
|
|
|
// srcdoc URIs require their contents to be specified inline, so it isn't
|
|
|
|
// possible for undesirable recursion to occur without the aid of a
|
|
|
|
// non-srcdoc URI, which this method will block normally.
|
|
|
|
// Besides, URI is not enough to guarantee uniqueness of srcdoc documents.
|
|
|
|
nsAutoCString buffer;
|
|
|
|
rv = aURI->GetScheme(buffer);
|
|
|
|
if (NS_SUCCEEDED(rv) && buffer.EqualsLiteral("about")) {
|
2017-07-29 14:50:21 +03:00
|
|
|
rv = aURI->GetPathQueryRef(buffer);
|
2014-02-09 06:05:48 +04:00
|
|
|
if (NS_SUCCEEDED(rv) && buffer.EqualsLiteral("srcdoc")) {
|
|
|
|
// Duplicates allowed up to depth limits
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
}
|
2012-08-22 19:56:38 +04:00
|
|
|
int32_t matchCount = 0;
|
2013-02-13 02:02:51 +04:00
|
|
|
mDocShell->GetSameTypeParent(getter_AddRefs(parentAsItem));
|
2005-03-08 03:02:55 +03:00
|
|
|
while (parentAsItem) {
|
|
|
|
// Check the parent URI with the URI we're loading
|
|
|
|
nsCOMPtr<nsIWebNavigation> parentAsNav(do_QueryInterface(parentAsItem));
|
|
|
|
if (parentAsNav) {
|
|
|
|
// Does the URI match the one we're about to load?
|
|
|
|
nsCOMPtr<nsIURI> parentURI;
|
|
|
|
parentAsNav->GetCurrentURI(getter_AddRefs(parentURI));
|
|
|
|
if (parentURI) {
|
2011-05-22 05:12:46 +04:00
|
|
|
// Bug 98158/193011: We need to ignore data after the #
|
2011-09-29 10:19:26 +04:00
|
|
|
bool equal;
|
2011-05-22 05:12:46 +04:00
|
|
|
rv = aURI->EqualsExceptRef(parentURI, &equal);
|
2005-03-10 00:59:18 +03:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2015-11-24 04:40:02 +03:00
|
|
|
|
2005-03-10 00:59:18 +03:00
|
|
|
if (equal) {
|
2005-03-08 03:02:55 +03:00
|
|
|
matchCount++;
|
|
|
|
if (matchCount >= MAX_SAME_URL_CONTENT_FRAMES) {
|
|
|
|
NS_WARNING(
|
|
|
|
"Too many nested content frames have the same url (recursion?) "
|
|
|
|
"so giving up");
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
nsCOMPtr<nsIDocShellTreeItem> temp;
|
|
|
|
temp.swap(parentAsItem);
|
|
|
|
temp->GetSameTypeParent(getter_AddRefs(parentAsItem));
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2009-07-01 00:39:22 +04:00
|
|
|
|
2014-08-08 21:23:50 +04:00
|
|
|
nsresult nsFrameLoader::GetWindowDimensions(nsIntRect& aRect) {
|
2011-07-16 01:46:56 +04:00
|
|
|
// Need to get outer window position here
|
2014-08-23 00:11:27 +04:00
|
|
|
nsIDocument* doc = mOwnerContent->GetComposedDoc();
|
2011-07-16 01:46:56 +04:00
|
|
|
if (!doc) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
2016-05-12 19:22:25 +03:00
|
|
|
MOZ_RELEASE_ASSERT(!doc->IsResourceDoc(), "We shouldn't even exist");
|
2011-07-16 01:46:56 +04:00
|
|
|
|
2016-01-30 20:05:36 +03:00
|
|
|
nsCOMPtr<nsPIDOMWindowOuter> win = doc->GetWindow();
|
2014-01-10 06:03:47 +04:00
|
|
|
if (!win) {
|
2011-07-16 01:46:56 +04:00
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
2014-01-10 06:03:47 +04:00
|
|
|
nsCOMPtr<nsIDocShellTreeItem> parentAsItem(win->GetDocShell());
|
|
|
|
if (!parentAsItem) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
2011-07-16 01:46:56 +04:00
|
|
|
|
|
|
|
nsCOMPtr<nsIDocShellTreeOwner> parentOwner;
|
|
|
|
if (NS_FAILED(parentAsItem->GetTreeOwner(getter_AddRefs(parentOwner))) ||
|
|
|
|
!parentOwner) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIBaseWindow> treeOwnerAsWin(do_GetInterface(parentOwner));
|
2018-02-19 23:15:23 +03:00
|
|
|
treeOwnerAsWin->GetPosition(&aRect.x, &aRect.y);
|
|
|
|
treeOwnerAsWin->GetSize(&aRect.width, &aRect.height);
|
2011-07-16 01:46:56 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2013-01-10 11:23:55 +04:00
|
|
|
nsresult nsFrameLoader::UpdatePositionAndSize(nsSubDocumentFrame* aIFrame) {
|
2015-07-31 12:28:36 +03:00
|
|
|
if (IsRemoteFrame()) {
|
2010-07-19 22:33:33 +04:00
|
|
|
if (mRemoteBrowser) {
|
2015-03-05 12:13:05 +03:00
|
|
|
ScreenIntSize size = aIFrame->GetSubdocumentSize();
|
2017-05-19 13:20:18 +03:00
|
|
|
// If we were not able to show remote frame before, we should probably
|
|
|
|
// retry now to send correct showInfo.
|
|
|
|
if (!mRemoteBrowserShown) {
|
|
|
|
ShowRemoteFrame(size, aIFrame);
|
|
|
|
}
|
2014-08-08 21:23:50 +04:00
|
|
|
nsIntRect dimensions;
|
2011-07-16 01:46:56 +04:00
|
|
|
NS_ENSURE_SUCCESS(GetWindowDimensions(dimensions), NS_ERROR_FAILURE);
|
2016-04-08 03:04:57 +03:00
|
|
|
mLazySize = size;
|
2015-03-31 23:39:02 +03:00
|
|
|
mRemoteBrowser->UpdateDimensions(dimensions, size);
|
2009-10-16 23:42:29 +04:00
|
|
|
}
|
2009-10-05 15:52:19 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
2015-01-14 22:04:00 +03:00
|
|
|
UpdateBaseWindowPositionAndSize(aIFrame);
|
|
|
|
return NS_OK;
|
2009-10-05 15:52:19 +04:00
|
|
|
}
|
|
|
|
|
2013-01-10 11:23:55 +04:00
|
|
|
void nsFrameLoader::UpdateBaseWindowPositionAndSize(
|
|
|
|
nsSubDocumentFrame* aIFrame) {
|
2019-01-02 16:27:05 +03:00
|
|
|
nsCOMPtr<nsIBaseWindow> baseWindow = GetDocShell(IgnoreErrors());
|
2009-10-05 15:52:19 +04:00
|
|
|
|
|
|
|
// resize the sub document
|
|
|
|
if (baseWindow) {
|
2012-08-22 19:56:38 +04:00
|
|
|
int32_t x = 0;
|
|
|
|
int32_t y = 0;
|
2009-10-05 15:52:19 +04:00
|
|
|
|
2017-03-01 20:03:14 +03:00
|
|
|
AutoWeakFrame weakFrame(aIFrame);
|
2009-10-05 15:52:19 +04:00
|
|
|
|
2015-01-14 22:03:59 +03:00
|
|
|
baseWindow->GetPosition(&x, &y);
|
2009-10-05 15:52:19 +04:00
|
|
|
|
|
|
|
if (!weakFrame.IsAlive()) {
|
2015-01-14 22:03:59 +03:00
|
|
|
// GetPosition() killed us
|
2015-01-14 22:04:00 +03:00
|
|
|
return;
|
2009-10-05 15:52:19 +04:00
|
|
|
}
|
|
|
|
|
2015-03-05 12:13:05 +03:00
|
|
|
ScreenIntSize size = aIFrame->GetSubdocumentSize();
|
2016-04-08 03:04:57 +03:00
|
|
|
mLazySize = size;
|
2009-10-05 15:52:19 +04:00
|
|
|
|
2016-05-12 03:07:45 +03:00
|
|
|
baseWindow->SetPositionAndSize(x, y, size.width, size.height,
|
|
|
|
nsIBaseWindow::eDelayResize);
|
2009-10-05 15:52:19 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-08-19 10:55:00 +03:00
|
|
|
uint32_t nsFrameLoader::LazyWidth() const {
|
|
|
|
uint32_t lazyWidth = mLazySize.width;
|
2016-04-08 03:04:57 +03:00
|
|
|
|
|
|
|
nsIFrame* frame = GetPrimaryFrameOfOwningContent();
|
|
|
|
if (frame) {
|
2017-08-19 10:55:00 +03:00
|
|
|
lazyWidth = frame->PresContext()->DevPixelsToIntCSSPixels(lazyWidth);
|
2016-04-08 03:04:57 +03:00
|
|
|
}
|
|
|
|
|
2017-08-19 10:55:00 +03:00
|
|
|
return lazyWidth;
|
2016-04-08 03:04:57 +03:00
|
|
|
}
|
|
|
|
|
2017-08-19 10:55:00 +03:00
|
|
|
uint32_t nsFrameLoader::LazyHeight() const {
|
|
|
|
uint32_t lazyHeight = mLazySize.height;
|
2016-04-08 03:04:57 +03:00
|
|
|
|
|
|
|
nsIFrame* frame = GetPrimaryFrameOfOwningContent();
|
|
|
|
if (frame) {
|
2017-08-19 10:55:00 +03:00
|
|
|
lazyHeight = frame->PresContext()->DevPixelsToIntCSSPixels(lazyHeight);
|
2016-04-08 03:04:57 +03:00
|
|
|
}
|
|
|
|
|
2017-08-19 10:55:00 +03:00
|
|
|
return lazyHeight;
|
|
|
|
}
|
|
|
|
|
2012-02-18 03:41:13 +04:00
|
|
|
void nsFrameLoader::SetClampScrollPosition(bool aClamp) {
|
|
|
|
mClampScrollPosition = aClamp;
|
|
|
|
|
|
|
|
// When turning clamping on, make sure the current position is clamped.
|
|
|
|
if (aClamp) {
|
|
|
|
nsIFrame* frame = GetPrimaryFrameOfOwningContent();
|
2014-03-25 19:36:49 +04:00
|
|
|
nsSubDocumentFrame* subdocFrame = do_QueryFrame(frame);
|
|
|
|
if (subdocFrame) {
|
|
|
|
nsIFrame* subdocRootFrame = subdocFrame->GetSubdocumentRootFrame();
|
|
|
|
if (subdocRootFrame) {
|
2017-11-09 05:00:48 +03:00
|
|
|
nsIScrollableFrame* subdocRootScrollFrame =
|
|
|
|
subdocRootFrame->PresShell()->GetRootScrollFrameAsScrollable();
|
2014-03-25 19:36:49 +04:00
|
|
|
if (subdocRootScrollFrame) {
|
|
|
|
subdocRootScrollFrame->ScrollTo(
|
|
|
|
subdocRootScrollFrame->GetScrollPosition(),
|
|
|
|
nsIScrollableFrame::INSTANT);
|
2012-02-18 03:41:13 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-16 04:04:04 +03:00
|
|
|
static Tuple<ContentParent*, TabParent*> GetContentParent(Element* aBrowser) {
|
2017-04-07 02:46:18 +03:00
|
|
|
using ReturnTuple = Tuple<ContentParent*, TabParent*>;
|
|
|
|
|
2018-12-04 19:33:06 +03:00
|
|
|
nsCOMPtr<nsIBrowser> browser = aBrowser ? aBrowser->AsBrowser() : nullptr;
|
2016-08-16 04:04:04 +03:00
|
|
|
if (!browser) {
|
2017-04-07 02:46:18 +03:00
|
|
|
return ReturnTuple(nullptr, nullptr);
|
2016-08-16 04:04:04 +03:00
|
|
|
}
|
|
|
|
|
2018-04-07 01:32:25 +03:00
|
|
|
RefPtr<nsFrameLoader> otherLoader;
|
|
|
|
browser->GetSameProcessAsFrameLoader(getter_AddRefs(otherLoader));
|
2017-02-14 23:12:35 +03:00
|
|
|
if (!otherLoader) {
|
2017-04-07 02:46:18 +03:00
|
|
|
return ReturnTuple(nullptr, nullptr);
|
2016-08-16 04:04:04 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
TabParent* tabParent = TabParent::GetFrom(otherLoader);
|
|
|
|
if (tabParent && tabParent->Manager() &&
|
|
|
|
tabParent->Manager()->IsContentParent()) {
|
2017-04-07 02:46:18 +03:00
|
|
|
return MakeTuple(tabParent->Manager()->AsContentParent(), tabParent);
|
2016-08-16 04:04:04 +03:00
|
|
|
}
|
|
|
|
|
2017-04-07 02:46:18 +03:00
|
|
|
return ReturnTuple(nullptr, nullptr);
|
2016-08-16 04:04:04 +03:00
|
|
|
}
|
|
|
|
|
2010-08-21 03:24:40 +04:00
|
|
|
bool nsFrameLoader::TryRemoteBrowser() {
|
|
|
|
NS_ASSERTION(!mRemoteBrowser,
|
|
|
|
"TryRemoteBrowser called with a remote browser already?");
|
2009-07-02 20:54:22 +04:00
|
|
|
|
2018-08-07 19:02:01 +03:00
|
|
|
if (!mOwnerContent) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-08-23 00:11:27 +04:00
|
|
|
// XXXsmaug Per spec (2014/08/21) frameloader should not work in case the
|
|
|
|
// element isn't in document, only in shadow dom, but that will change
|
|
|
|
// https://www.w3.org/Bugs/Public/show_bug.cgi?id=26365#c0
|
|
|
|
nsIDocument* doc = mOwnerContent->GetComposedDoc();
|
2009-07-01 00:39:22 +04:00
|
|
|
if (!doc) {
|
2009-10-28 23:41:46 +03:00
|
|
|
return false;
|
2009-07-01 00:39:22 +04:00
|
|
|
}
|
|
|
|
|
2016-05-12 19:22:25 +03:00
|
|
|
MOZ_RELEASE_ASSERT(!doc->IsResourceDoc(), "We shouldn't even exist");
|
|
|
|
|
|
|
|
if (!doc->IsActive()) {
|
|
|
|
// Don't allow subframe loads in non-active documents.
|
|
|
|
// (See bug 610571 comment 5.)
|
2009-10-28 23:41:46 +03:00
|
|
|
return false;
|
2009-07-01 00:39:22 +04:00
|
|
|
}
|
|
|
|
|
2016-01-30 20:05:36 +03:00
|
|
|
nsCOMPtr<nsPIDOMWindowOuter> parentWin = doc->GetWindow();
|
2014-01-10 06:03:47 +04:00
|
|
|
if (!parentWin) {
|
2009-10-28 23:41:46 +03:00
|
|
|
return false;
|
2009-07-01 00:39:22 +04:00
|
|
|
}
|
|
|
|
|
2014-06-20 21:55:40 +04:00
|
|
|
nsCOMPtr<nsIDocShell> parentDocShell = parentWin->GetDocShell();
|
|
|
|
if (!parentDocShell) {
|
2014-01-10 06:03:47 +04:00
|
|
|
return false;
|
|
|
|
}
|
2009-07-01 00:39:22 +04:00
|
|
|
|
2015-02-06 00:47:32 +03:00
|
|
|
TabParent* openingTab = TabParent::GetFrom(parentDocShell->GetOpener());
|
2017-04-07 02:46:18 +03:00
|
|
|
RefPtr<ContentParent> openerContentParent;
|
|
|
|
RefPtr<TabParent> sameTabGroupAs;
|
2014-06-20 21:55:40 +04:00
|
|
|
|
|
|
|
if (openingTab && openingTab->Manager() &&
|
|
|
|
openingTab->Manager()->IsContentParent()) {
|
|
|
|
openerContentParent = openingTab->Manager()->AsContentParent();
|
|
|
|
}
|
|
|
|
|
2012-04-25 20:35:58 +04:00
|
|
|
// <iframe mozbrowser> gets to skip these checks.
|
2017-05-29 13:38:46 +03:00
|
|
|
// iframes for JS plugins also get to skip these checks. We control the URL
|
|
|
|
// that gets loaded, but the load is triggered from the document containing
|
|
|
|
// the plugin.
|
|
|
|
if (!OwnerIsMozBrowserFrame() && !IsForJSPlugin()) {
|
2014-06-20 21:55:40 +04:00
|
|
|
if (parentDocShell->ItemType() != nsIDocShellTreeItem::typeChrome) {
|
2016-11-16 02:01:50 +03:00
|
|
|
// Allow about:addon an exception to this rule so it can load remote
|
|
|
|
// extension options pages.
|
|
|
|
//
|
|
|
|
// Note that the new frame's message manager will not be a child of the
|
|
|
|
// chrome window message manager, and, the values of window.top and
|
|
|
|
// window.parent will be different than they would be for a non-remote
|
|
|
|
// frame.
|
|
|
|
nsCOMPtr<nsIWebNavigation> parentWebNav;
|
|
|
|
nsCOMPtr<nsIURI> aboutAddons;
|
|
|
|
nsCOMPtr<nsIURI> parentURI;
|
|
|
|
bool equals;
|
|
|
|
if (!((parentWebNav = do_GetInterface(parentDocShell)) &&
|
|
|
|
NS_SUCCEEDED(
|
|
|
|
NS_NewURI(getter_AddRefs(aboutAddons), "about:addons")) &&
|
|
|
|
NS_SUCCEEDED(
|
|
|
|
parentWebNav->GetCurrentURI(getter_AddRefs(parentURI))) &&
|
|
|
|
NS_SUCCEEDED(parentURI->EqualsExceptRef(aboutAddons, &equals)) &&
|
|
|
|
equals)) {
|
|
|
|
return false;
|
|
|
|
}
|
2012-04-25 20:35:58 +04:00
|
|
|
}
|
2009-07-01 00:39:22 +04:00
|
|
|
|
2015-03-03 14:08:59 +03:00
|
|
|
if (!mOwnerContent->IsXULElement()) {
|
2012-04-25 20:35:58 +04:00
|
|
|
return false;
|
|
|
|
}
|
2009-07-01 00:39:22 +04:00
|
|
|
|
2018-01-10 22:37:29 +03:00
|
|
|
if (!mOwnerContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type,
|
|
|
|
nsGkAtoms::content, eIgnoreCase)) {
|
2012-04-25 20:35:58 +04:00
|
|
|
return false;
|
|
|
|
}
|
2016-08-16 04:04:04 +03:00
|
|
|
|
|
|
|
// Try to get the related content parent from our browser element.
|
2017-04-07 02:46:18 +03:00
|
|
|
Tie(openerContentParent, sameTabGroupAs) = GetContentParent(mOwnerContent);
|
2009-07-01 00:39:22 +04:00
|
|
|
}
|
|
|
|
|
2012-08-22 19:56:38 +04:00
|
|
|
uint32_t chromeFlags = 0;
|
2010-07-19 22:33:33 +04:00
|
|
|
nsCOMPtr<nsIDocShellTreeOwner> parentOwner;
|
2014-06-20 21:55:40 +04:00
|
|
|
if (NS_FAILED(parentDocShell->GetTreeOwner(getter_AddRefs(parentOwner))) ||
|
2010-07-19 22:33:33 +04:00
|
|
|
!parentOwner) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
nsCOMPtr<nsIXULWindow> window(do_GetInterface(parentOwner));
|
2014-06-11 09:44:13 +04:00
|
|
|
if (window && NS_FAILED(window->GetChromeFlags(&chromeFlags))) {
|
2010-07-19 22:33:33 +04:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
Bug 1375392 - Tweak the PROFILER_LABEL* macros. r=mstange.
This patch makes the following changes to the macros.
- Removes PROFILER_LABEL_FUNC. It's only suitable for use in functions outside
classes, due to PROFILER_FUNCTION_NAME not getting class names, and it was
mostly misused.
- Removes PROFILER_FUNCTION_NAME. It's no longer used, and __func__ is
universally available now anyway.
- Combines the first two string literal arguments of PROFILER_LABEL and
PROFILER_LABEL_DYNAMIC into a single argument. There was no good reason for
them to be separate, and it forced a '::' in the label, which isn't always
appropriate. Also, the meaning of the "name_space" argument was interpreted
in an interesting variety of ways.
- Adds an "AUTO_" prefix to PROFILER_LABEL and PROFILER_LABEL_DYNAMIC, to make
it clearer they construct RAII objects rather than just being function calls.
(I myself have screwed up the scoping because of this in the past.)
- Fills in the 'js::ProfileEntry::Category::' qualifier within the macro, so
the caller doesn't need to. This makes a *lot* more of the uses fit onto a
single line.
The patch also makes the following changes to the macro uses (beyond those
required by the changes described above).
- Fixes a bunch of labels that had gotten out of sync with the name of the
class and/or function that encloses them.
- Removes a useless PROFILER_LABEL use within a trivial scope in
EventStateManager::DispatchMouseOrPointerEvent(). It clearly wasn't serving
any useful purpose. It also serves as extra evidence that the AUTO_ prefix is
a good idea.
- Tweaks DecodePool::SyncRunIf{Preferred,Possible} so that the labelling is
done within them, instead of at their callsites, because that's a more
standard way of doing things.
--HG--
extra : rebase_source : 318d1bc6fc1425a94aacbf489dd46e4f83211de4
2017-06-22 10:08:53 +03:00
|
|
|
AUTO_PROFILER_LABEL("nsFrameLoader::TryRemoteBrowser:Create", OTHER);
|
2013-01-31 10:40:43 +04:00
|
|
|
|
Bug 802366 - The main event: Let a browser process inherit its app's id. r=bz,cjones
The main bug fixed here is that in half of our interfaces, we use "is browser frame/element" to mean "browser or app", and in the other half, we use it to mean "is browser not app".
There's a related, functional bug also fixed here, which is that a browser process doesn't inherit its parent's app-id. This causes problems e.g. for IndexedDB: If a browser inside an app uses IndexedDB, the DB should have the app's app-id.
I also modified Tab{Parent,Child} and nsFrameLoader to call "app" "ownOrContainingApp", to emphasize that we might have inherited the app from a parent process. I left nsIDocShell::appId alone, because changing that would have necessitated changing nsILoadGroup and therefore a /lot/ of users in Necko; it's also not clear it would have clarified anything in those cases.
2012-11-10 22:32:37 +04:00
|
|
|
MutableTabContext context;
|
2015-10-08 09:44:36 +03:00
|
|
|
nsresult rv = GetNewTabContext(&context);
|
|
|
|
NS_ENSURE_SUCCESS(rv, false);
|
2012-07-22 04:16:11 +04:00
|
|
|
|
2017-04-17 01:52:02 +03:00
|
|
|
uint64_t nextTabParentId = 0;
|
|
|
|
if (mOwnerContent) {
|
|
|
|
nsAutoString nextTabParentIdAttr;
|
|
|
|
mOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::nextTabParentId,
|
|
|
|
nextTabParentIdAttr);
|
|
|
|
nextTabParentId =
|
|
|
|
strtoull(NS_ConvertUTF16toUTF8(nextTabParentIdAttr).get(), nullptr, 10);
|
|
|
|
|
|
|
|
// We may be in a window that was just opened, so try the
|
|
|
|
// nsIBrowserDOMWindow API as a backup.
|
|
|
|
if (!nextTabParentId && window) {
|
|
|
|
Unused << window->GetNextTabParentId(&nextTabParentId);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-07-24 03:39:17 +04:00
|
|
|
nsCOMPtr<Element> ownerElement = mOwnerContent;
|
2017-04-07 02:46:18 +03:00
|
|
|
mRemoteBrowser =
|
|
|
|
ContentParent::CreateBrowser(context, ownerElement, openerContentParent,
|
2017-04-17 01:52:02 +03:00
|
|
|
sameTabGroupAs, nextTabParentId);
|
2015-04-07 05:56:10 +03:00
|
|
|
if (!mRemoteBrowser) {
|
|
|
|
return false;
|
|
|
|
}
|
2018-11-07 00:35:37 +03:00
|
|
|
// Now that mRemoteBrowser is set, we can initialize the RenderFrame
|
2018-11-07 00:15:07 +03:00
|
|
|
mRemoteBrowser->InitRendering();
|
2012-08-09 06:58:06 +04:00
|
|
|
|
2015-10-01 20:06:51 +03:00
|
|
|
MaybeUpdatePrimaryTabParent(eTabParentChanged);
|
|
|
|
|
2015-04-07 05:56:10 +03:00
|
|
|
mChildID = mRemoteBrowser->Manager()->ChildID();
|
2013-08-13 11:56:57 +04:00
|
|
|
|
2015-04-07 05:56:10 +03:00
|
|
|
nsCOMPtr<nsIDocShellTreeItem> rootItem;
|
|
|
|
parentDocShell->GetRootTreeItem(getter_AddRefs(rootItem));
|
2016-01-30 20:05:36 +03:00
|
|
|
nsCOMPtr<nsPIDOMWindowOuter> rootWin = rootItem->GetWindow();
|
2015-04-07 05:56:10 +03:00
|
|
|
nsCOMPtr<nsIDOMChromeWindow> rootChromeWin = do_QueryInterface(rootWin);
|
|
|
|
|
|
|
|
if (rootChromeWin) {
|
|
|
|
nsCOMPtr<nsIBrowserDOMWindow> browserDOMWin;
|
|
|
|
rootChromeWin->GetBrowserDOMWindow(getter_AddRefs(browserDOMWin));
|
|
|
|
mRemoteBrowser->SetBrowserDOMWindow(browserDOMWin);
|
2009-11-05 21:14:22 +03:00
|
|
|
}
|
2015-04-07 05:56:10 +03:00
|
|
|
|
2018-02-02 01:56:54 +03:00
|
|
|
// Set up a parent SHistory
|
|
|
|
if (XRE_IsParentProcess()) {
|
|
|
|
// XXX(nika): Once we get out of process iframes we won't want to
|
|
|
|
// unconditionally set this up. What do we do for iframes in a chrome loaded
|
|
|
|
// document for example?
|
|
|
|
mParentSHistory = new ParentSHistory(this);
|
|
|
|
}
|
|
|
|
|
2018-09-15 11:26:33 +03:00
|
|
|
// For xul:browsers, update some settings based on attributes:
|
2017-06-05 20:33:11 +03:00
|
|
|
if (mOwnerContent->IsXULElement()) {
|
2018-09-15 11:26:33 +03:00
|
|
|
// Send down the name of the browser through mRemoteBrowser if it is set.
|
2017-06-05 20:33:11 +03:00
|
|
|
nsAutoString frameName;
|
|
|
|
mOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::name, frameName);
|
|
|
|
if (nsContentUtils::IsOverridingWindowName(frameName)) {
|
|
|
|
Unused << mRemoteBrowser->SendSetWindowName(frameName);
|
|
|
|
}
|
2018-09-15 11:26:33 +03:00
|
|
|
// Allow scripts to close the window if the browser specified so:
|
|
|
|
if (mOwnerContent->AttrValueIs(kNameSpaceID_None,
|
|
|
|
nsGkAtoms::allowscriptstoclose,
|
|
|
|
nsGkAtoms::_true, eCaseMatters)) {
|
|
|
|
Unused << mRemoteBrowser->SendAllowScriptsToClose();
|
|
|
|
}
|
2017-06-05 20:33:11 +03:00
|
|
|
}
|
|
|
|
|
2015-07-31 13:08:36 +03:00
|
|
|
ReallyLoadFrameScripts();
|
|
|
|
InitializeBrowserAPI();
|
|
|
|
|
|
|
|
return true;
|
2009-07-01 00:39:22 +04:00
|
|
|
}
|
2009-10-29 20:58:31 +03:00
|
|
|
|
2015-06-09 13:20:41 +03:00
|
|
|
mozilla::dom::PBrowserParent* nsFrameLoader::GetRemoteBrowser() const {
|
2010-07-19 22:33:33 +04:00
|
|
|
return mRemoteBrowser;
|
2009-10-29 20:58:31 +03:00
|
|
|
}
|
2009-11-05 21:14:22 +03:00
|
|
|
|
2015-06-09 13:30:08 +03:00
|
|
|
RenderFrame* nsFrameLoader::GetCurrentRenderFrame() const {
|
2015-06-09 13:20:41 +03:00
|
|
|
if (mRemoteBrowser) {
|
|
|
|
return mRemoteBrowser->GetRenderFrame();
|
|
|
|
}
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2017-08-19 10:55:00 +03:00
|
|
|
void nsFrameLoader::ActivateRemoteFrame(ErrorResult& aRv) {
|
2018-03-22 05:43:15 +03:00
|
|
|
if (!mRemoteBrowser) {
|
|
|
|
aRv.Throw(NS_ERROR_UNEXPECTED);
|
|
|
|
return;
|
2017-08-19 10:55:00 +03:00
|
|
|
}
|
|
|
|
|
2018-03-22 05:43:15 +03:00
|
|
|
mRemoteBrowser->Activate();
|
2009-11-05 21:14:22 +03:00
|
|
|
}
|
2009-11-05 21:21:09 +03:00
|
|
|
|
2017-08-19 10:55:00 +03:00
|
|
|
void nsFrameLoader::DeactivateRemoteFrame(ErrorResult& aRv) {
|
2018-03-22 05:43:15 +03:00
|
|
|
if (!mRemoteBrowser) {
|
|
|
|
aRv.Throw(NS_ERROR_UNEXPECTED);
|
|
|
|
return;
|
2017-08-19 10:55:00 +03:00
|
|
|
}
|
|
|
|
|
2018-03-22 05:43:15 +03:00
|
|
|
mRemoteBrowser->Deactivate();
|
2011-06-18 04:08:32 +04:00
|
|
|
}
|
|
|
|
|
2017-08-19 10:55:00 +03:00
|
|
|
void nsFrameLoader::SendCrossProcessMouseEvent(const nsAString& aType, float aX,
|
|
|
|
float aY, int32_t aButton,
|
|
|
|
int32_t aClickCount,
|
|
|
|
int32_t aModifiers,
|
|
|
|
bool aIgnoreRootScrollFrame,
|
|
|
|
ErrorResult& aRv) {
|
2018-03-22 05:43:15 +03:00
|
|
|
if (!mRemoteBrowser) {
|
|
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
|
|
return;
|
2017-08-19 10:55:00 +03:00
|
|
|
}
|
|
|
|
|
2018-03-22 05:43:15 +03:00
|
|
|
mRemoteBrowser->SendMouseEvent(aType, aX, aY, aButton, aClickCount,
|
|
|
|
aModifiers, aIgnoreRootScrollFrame);
|
2009-11-05 21:21:09 +03:00
|
|
|
}
|
|
|
|
|
2017-08-19 10:55:00 +03:00
|
|
|
void nsFrameLoader::ActivateFrameEvent(const nsAString& aType, bool aCapture,
|
|
|
|
ErrorResult& aRv) {
|
2018-03-22 05:43:15 +03:00
|
|
|
if (!mRemoteBrowser) {
|
|
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
|
|
return;
|
2017-08-19 10:55:00 +03:00
|
|
|
}
|
|
|
|
|
2018-03-22 05:43:15 +03:00
|
|
|
bool ok = mRemoteBrowser->SendActivateFrameEvent(nsString(aType), aCapture);
|
|
|
|
if (!ok) {
|
|
|
|
aRv.Throw(NS_ERROR_NOT_AVAILABLE);
|
2009-11-17 17:22:23 +03:00
|
|
|
}
|
2010-03-19 09:52:18 +03:00
|
|
|
}
|
|
|
|
|
2018-03-22 05:43:17 +03:00
|
|
|
nsresult nsFrameLoader::CreateStaticClone(nsFrameLoader* aDest) {
|
|
|
|
aDest->MaybeCreateDocShell();
|
|
|
|
NS_ENSURE_STATE(aDest->mDocShell);
|
2009-12-11 07:02:13 +03:00
|
|
|
|
2018-03-22 05:43:17 +03:00
|
|
|
nsCOMPtr<nsIDocument> kungFuDeathGrip = aDest->mDocShell->GetDocument();
|
2016-08-24 21:12:09 +03:00
|
|
|
Unused << kungFuDeathGrip;
|
|
|
|
|
2009-12-11 07:02:13 +03:00
|
|
|
nsCOMPtr<nsIContentViewer> viewer;
|
2018-03-22 05:43:17 +03:00
|
|
|
aDest->mDocShell->GetContentViewer(getter_AddRefs(viewer));
|
2009-12-11 07:02:13 +03:00
|
|
|
NS_ENSURE_STATE(viewer);
|
|
|
|
|
2018-03-22 05:43:15 +03:00
|
|
|
nsIDocShell* origDocShell = GetDocShell(IgnoreErrors());
|
2014-01-10 06:03:47 +04:00
|
|
|
NS_ENSURE_STATE(origDocShell);
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDocument> doc = origDocShell->GetDocument();
|
2009-12-11 07:02:13 +03:00
|
|
|
NS_ENSURE_STATE(doc);
|
2014-01-10 06:03:47 +04:00
|
|
|
|
2018-03-22 05:43:17 +03:00
|
|
|
nsCOMPtr<nsIDocument> clonedDoc = doc->CreateStaticClone(aDest->mDocShell);
|
2009-12-11 07:02:13 +03:00
|
|
|
|
2018-01-31 23:18:09 +03:00
|
|
|
viewer->SetDocument(clonedDoc);
|
2009-12-11 07:02:13 +03:00
|
|
|
return NS_OK;
|
|
|
|
}
|
2010-02-20 20:05:20 +03:00
|
|
|
|
2015-02-20 04:11:32 +03:00
|
|
|
bool nsFrameLoader::DoLoadMessageManagerScript(const nsAString& aURL,
|
|
|
|
bool aRunInGlobalScope) {
|
2015-02-06 00:47:32 +03:00
|
|
|
auto* tabParent = TabParent::GetFrom(GetRemoteBrowser());
|
2010-02-20 20:05:20 +03:00
|
|
|
if (tabParent) {
|
2013-11-24 09:32:45 +04:00
|
|
|
return tabParent->SendLoadRemoteScript(nsString(aURL), aRunInGlobalScope);
|
2010-02-20 20:05:20 +03:00
|
|
|
}
|
2018-08-11 00:08:07 +03:00
|
|
|
RefPtr<InProcessTabChildMessageManager> tabChild =
|
|
|
|
GetTabChildMessageManager();
|
2010-05-18 16:28:37 +04:00
|
|
|
if (tabChild) {
|
2013-11-24 09:32:45 +04:00
|
|
|
tabChild->LoadFrameScript(aURL, aRunInGlobalScope);
|
2010-05-18 16:28:37 +04:00
|
|
|
}
|
|
|
|
return true;
|
2010-02-20 20:05:20 +03:00
|
|
|
}
|
|
|
|
|
2014-03-12 18:22:00 +04:00
|
|
|
class nsAsyncMessageToChild : public nsSameProcessAsyncMessageBase,
|
2016-04-26 03:23:21 +03:00
|
|
|
public Runnable {
|
2010-05-18 16:28:37 +04:00
|
|
|
public:
|
2016-08-12 12:39:16 +03:00
|
|
|
nsAsyncMessageToChild(JS::RootingContext* aRootingCx,
|
|
|
|
JS::Handle<JSObject*> aCpows,
|
|
|
|
nsFrameLoader* aFrameLoader)
|
|
|
|
: nsSameProcessAsyncMessageBase(aRootingCx, aCpows),
|
2017-06-12 22:34:10 +03:00
|
|
|
mozilla::Runnable("nsAsyncMessageToChild"),
|
2014-03-12 18:22:00 +04:00
|
|
|
mFrameLoader(aFrameLoader) {}
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2016-08-08 05:18:10 +03:00
|
|
|
NS_IMETHOD Run() override {
|
2018-08-11 00:08:07 +03:00
|
|
|
InProcessTabChildMessageManager* tabChild =
|
|
|
|
mFrameLoader->mChildMessageManager;
|
2016-02-29 14:25:48 +03:00
|
|
|
// Since bug 1126089, messages can arrive even when the docShell is
|
|
|
|
// destroyed. Here we make sure that those messages are not delivered.
|
|
|
|
if (tabChild && tabChild->GetInnerManager() &&
|
|
|
|
mFrameLoader->GetExistingDocShell()) {
|
2017-07-19 15:59:02 +03:00
|
|
|
JS::Rooted<JSObject*> kungFuDeathGrip(dom::RootingCx(),
|
|
|
|
tabChild->GetWrapper());
|
2015-04-16 18:17:54 +03:00
|
|
|
ReceiveMessage(static_cast<EventTarget*>(tabChild), mFrameLoader,
|
2014-03-12 18:22:00 +04:00
|
|
|
tabChild->GetInnerManager());
|
2010-05-18 16:28:37 +04:00
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<nsFrameLoader> mFrameLoader;
|
2010-05-18 16:28:37 +04:00
|
|
|
};
|
|
|
|
|
2013-07-11 02:05:39 +04:00
|
|
|
nsresult nsFrameLoader::DoSendAsyncMessage(JSContext* aCx,
|
|
|
|
const nsAString& aMessage,
|
2015-09-10 23:50:58 +03:00
|
|
|
StructuredCloneData& aData,
|
2013-11-06 21:21:15 +04:00
|
|
|
JS::Handle<JSObject*> aCpows,
|
|
|
|
nsIPrincipal* aPrincipal) {
|
2013-07-10 21:07:51 +04:00
|
|
|
TabParent* tabParent = mRemoteBrowser;
|
2010-02-20 20:05:20 +03:00
|
|
|
if (tabParent) {
|
2012-08-02 10:02:29 +04:00
|
|
|
ClonedMessageData data;
|
2014-06-11 09:44:03 +04:00
|
|
|
nsIContentParent* cp = tabParent->Manager();
|
2015-09-10 23:50:58 +03:00
|
|
|
if (!BuildClonedMessageDataForParent(cp, aData, data)) {
|
2015-10-07 13:42:43 +03:00
|
|
|
MOZ_CRASH();
|
|
|
|
return NS_ERROR_DOM_DATA_CLONE_ERR;
|
2012-08-02 10:02:29 +04:00
|
|
|
}
|
2013-07-11 02:05:39 +04:00
|
|
|
InfallibleTArray<mozilla::jsipc::CpowEntry> cpows;
|
2015-04-28 03:05:05 +03:00
|
|
|
jsipc::CPOWManager* mgr = cp->GetCPOWManager();
|
|
|
|
if (aCpows && (!mgr || !mgr->Wrap(aCx, aCpows, &cpows))) {
|
2015-10-07 13:42:43 +03:00
|
|
|
return NS_ERROR_UNEXPECTED;
|
|
|
|
}
|
2016-04-09 16:50:59 +03:00
|
|
|
if (tabParent->SendAsyncMessage(nsString(aMessage), cpows,
|
|
|
|
IPC::Principal(aPrincipal), data)) {
|
2015-10-07 13:42:43 +03:00
|
|
|
return NS_OK;
|
|
|
|
} else {
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
2013-07-11 02:05:39 +04:00
|
|
|
}
|
2010-02-20 20:05:20 +03:00
|
|
|
}
|
2012-08-02 10:02:29 +04:00
|
|
|
|
2012-09-28 09:43:12 +04:00
|
|
|
if (mChildMessageManager) {
|
2016-08-12 12:39:16 +03:00
|
|
|
JS::RootingContext* rcx = JS::RootingContext::get(aCx);
|
|
|
|
RefPtr<nsAsyncMessageToChild> ev =
|
|
|
|
new nsAsyncMessageToChild(rcx, aCpows, this);
|
|
|
|
nsresult rv = ev->Init(aMessage, aData, aPrincipal);
|
2015-10-07 13:42:43 +03:00
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
rv = NS_DispatchToCurrentThread(ev);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
return rv;
|
2012-09-19 15:08:36 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// We don't have any targets to send our asynchronous message to.
|
2015-10-07 13:42:43 +03:00
|
|
|
return NS_ERROR_UNEXPECTED;
|
2010-05-18 16:28:37 +04:00
|
|
|
}
|
2010-02-20 20:05:20 +03:00
|
|
|
|
2017-08-19 10:55:00 +03:00
|
|
|
already_AddRefed<MessageSender> nsFrameLoader::GetMessageManager() {
|
2010-05-24 18:45:59 +04:00
|
|
|
EnsureMessageManager();
|
2018-03-22 05:43:15 +03:00
|
|
|
return do_AddRef(mMessageManager);
|
2010-05-18 16:28:37 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
nsresult nsFrameLoader::EnsureMessageManager() {
|
2010-02-20 20:05:20 +03:00
|
|
|
NS_ENSURE_STATE(mOwnerContent);
|
|
|
|
|
2015-07-30 06:07:14 +03:00
|
|
|
if (mMessageManager) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2016-10-15 04:46:26 +03:00
|
|
|
if (!mIsTopLevelContent && !OwnerIsMozBrowserFrame() && !IsRemoteFrame() &&
|
2015-03-03 14:08:59 +03:00
|
|
|
!(mOwnerContent->IsXULElement() &&
|
2015-01-08 19:44:00 +03:00
|
|
|
mOwnerContent->AttrValueIs(kNameSpaceID_None,
|
|
|
|
nsGkAtoms::forcemessagemanager,
|
|
|
|
nsGkAtoms::_true, eCaseMatters))) {
|
2010-08-10 19:10:22 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2018-02-14 19:35:39 +03:00
|
|
|
RefPtr<nsGlobalWindowOuter> window =
|
|
|
|
nsGlobalWindowOuter::Cast(GetOwnerDoc()->GetWindow());
|
|
|
|
RefPtr<ChromeMessageBroadcaster> parentManager;
|
2014-05-23 16:49:09 +04:00
|
|
|
|
2018-02-14 19:35:39 +03:00
|
|
|
if (window && window->IsChromeWindow()) {
|
2014-05-23 16:49:09 +04:00
|
|
|
nsAutoString messagemanagergroup;
|
2015-03-03 14:08:59 +03:00
|
|
|
if (mOwnerContent->IsXULElement() &&
|
2014-05-23 16:49:09 +04:00
|
|
|
mOwnerContent->GetAttr(kNameSpaceID_None,
|
|
|
|
nsGkAtoms::messagemanagergroup,
|
|
|
|
messagemanagergroup)) {
|
2018-02-14 19:35:39 +03:00
|
|
|
parentManager = window->GetGroupMessageManager(messagemanagergroup);
|
2014-05-23 16:49:09 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!parentManager) {
|
2018-02-14 19:35:39 +03:00
|
|
|
parentManager = window->GetMessageManager();
|
2014-05-23 16:49:09 +04:00
|
|
|
}
|
2015-11-24 03:25:15 +03:00
|
|
|
} else {
|
2018-02-14 19:35:39 +03:00
|
|
|
parentManager = nsFrameMessageManager::GetGlobalMessageManager();
|
2012-05-11 11:47:40 +04:00
|
|
|
}
|
2010-05-18 16:28:37 +04:00
|
|
|
|
2018-04-16 16:18:48 +03:00
|
|
|
mMessageManager = new ChromeMessageSender(parentManager);
|
2015-07-31 12:28:36 +03:00
|
|
|
if (!IsRemoteFrame()) {
|
|
|
|
nsresult rv = MaybeCreateDocShell();
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
NS_ASSERTION(mDocShell,
|
|
|
|
"MaybeCreateDocShell succeeded, but null mDocShell");
|
|
|
|
if (!mDocShell) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
2018-08-11 00:08:07 +03:00
|
|
|
mChildMessageManager = InProcessTabChildMessageManager::Create(
|
|
|
|
mDocShell, mOwnerContent, mMessageManager);
|
2018-04-17 14:59:44 +03:00
|
|
|
NS_ENSURE_TRUE(mChildMessageManager, NS_ERROR_UNEXPECTED);
|
2015-07-30 06:07:14 +03:00
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult nsFrameLoader::ReallyLoadFrameScripts() {
|
|
|
|
nsresult rv = EnsureMessageManager();
|
|
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
if (mMessageManager) {
|
2014-01-31 22:45:54 +04:00
|
|
|
mMessageManager->InitWithCallback(this);
|
2010-02-20 20:05:20 +03:00
|
|
|
}
|
|
|
|
return NS_OK;
|
2010-05-18 16:28:37 +04:00
|
|
|
}
|
|
|
|
|
2017-08-19 10:55:00 +03:00
|
|
|
already_AddRefed<Element> nsFrameLoader::GetOwnerElement() {
|
2018-03-22 05:43:15 +03:00
|
|
|
return do_AddRef(mOwnerContent);
|
2013-09-12 23:24:10 +04:00
|
|
|
}
|
|
|
|
|
2012-06-13 02:01:25 +04:00
|
|
|
void nsFrameLoader::SetRemoteBrowser(nsITabParent* aTabParent) {
|
|
|
|
MOZ_ASSERT(!mRemoteBrowser);
|
2012-08-18 01:07:54 +04:00
|
|
|
mRemoteFrame = true;
|
2015-02-06 00:47:32 +03:00
|
|
|
mRemoteBrowser = TabParent::GetFrom(aTabParent);
|
2013-09-12 23:24:10 +04:00
|
|
|
mChildID = mRemoteBrowser ? mRemoteBrowser->Manager()->ChildID() : 0;
|
2015-10-01 20:06:51 +03:00
|
|
|
MaybeUpdatePrimaryTabParent(eTabParentChanged);
|
2015-07-31 13:08:36 +03:00
|
|
|
ReallyLoadFrameScripts();
|
|
|
|
InitializeBrowserAPI();
|
2018-11-07 00:15:07 +03:00
|
|
|
mRemoteBrowser->InitRendering();
|
2015-09-01 10:39:25 +03:00
|
|
|
ShowRemoteFrame(ScreenIntSize(0, 0));
|
2012-06-13 02:01:25 +04:00
|
|
|
}
|
2012-07-31 06:09:31 +04:00
|
|
|
|
2016-05-05 00:12:48 +03:00
|
|
|
void nsFrameLoader::SetDetachedSubdocFrame(nsIFrame* aDetachedFrame,
|
|
|
|
nsIDocument* aContainerDoc) {
|
|
|
|
mDetachedSubdocFrame = aDetachedFrame;
|
2012-08-14 08:06:44 +04:00
|
|
|
mContainerDocWhileDetached = aContainerDoc;
|
|
|
|
}
|
|
|
|
|
2016-05-05 00:12:48 +03:00
|
|
|
nsIFrame* nsFrameLoader::GetDetachedSubdocFrame(
|
|
|
|
nsIDocument** aContainerDoc) const {
|
2012-08-14 08:06:44 +04:00
|
|
|
NS_IF_ADDREF(*aContainerDoc = mContainerDocWhileDetached);
|
2016-05-05 00:12:48 +03:00
|
|
|
return mDetachedSubdocFrame.GetFrame();
|
2012-08-14 08:06:44 +04:00
|
|
|
}
|
|
|
|
|
2013-08-06 14:01:23 +04:00
|
|
|
void nsFrameLoader::ApplySandboxFlags(uint32_t sandboxFlags) {
|
|
|
|
if (mDocShell) {
|
|
|
|
uint32_t parentSandboxFlags = mOwnerContent->OwnerDoc()->GetSandboxFlags();
|
|
|
|
|
|
|
|
// The child can only add restrictions, never remove them.
|
|
|
|
sandboxFlags |= parentSandboxFlags;
|
2016-06-21 21:31:00 +03:00
|
|
|
|
|
|
|
// If this frame is a receiving browsing context, we should add
|
|
|
|
// sandboxed auxiliary navigation flag to sandboxFlags. See
|
|
|
|
// https://w3c.github.io/presentation-api/#creating-a-receiving-browsing-context
|
|
|
|
nsAutoString presentationURL;
|
|
|
|
nsContentUtils::GetPresentationURL(mDocShell, presentationURL);
|
|
|
|
if (!presentationURL.IsEmpty()) {
|
|
|
|
sandboxFlags |= SANDBOXED_AUXILIARY_NAVIGATION;
|
|
|
|
}
|
2013-08-06 14:01:23 +04:00
|
|
|
mDocShell->SetSandboxFlags(sandboxFlags);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-01 14:36:58 +03:00
|
|
|
/* virtual */ void nsFrameLoader::AttributeChanged(
|
|
|
|
mozilla::dom::Element* aElement, int32_t aNameSpaceID, nsAtom* aAttribute,
|
2015-07-25 09:01:19 +03:00
|
|
|
int32_t aModType, const nsAttrValue* aOldValue) {
|
2012-09-05 07:00:26 +04:00
|
|
|
MOZ_ASSERT(mObservingOwnerContent);
|
|
|
|
|
2016-12-09 22:23:24 +03:00
|
|
|
if (aNameSpaceID != kNameSpaceID_None ||
|
|
|
|
(aAttribute != TypeAttrName() && aAttribute != nsGkAtoms::primary)) {
|
2012-09-05 07:00:26 +04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (aElement != mOwnerContent) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Note: This logic duplicates a lot of logic in
|
|
|
|
// MaybeCreateDocshell. We should fix that.
|
|
|
|
|
|
|
|
// Notify our enclosing chrome that our type has changed. We only do this
|
|
|
|
// if our parent is chrome, since in all other cases we're random content
|
|
|
|
// subframes and the treeowner shouldn't worry about us.
|
2013-02-13 02:02:51 +04:00
|
|
|
if (!mDocShell) {
|
2015-10-01 20:06:51 +03:00
|
|
|
MaybeUpdatePrimaryTabParent(eTabParentChanged);
|
2012-09-05 07:00:26 +04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDocShellTreeItem> parentItem;
|
2013-02-13 02:02:51 +04:00
|
|
|
mDocShell->GetParent(getter_AddRefs(parentItem));
|
2012-09-05 07:00:26 +04:00
|
|
|
if (!parentItem) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-01-20 11:58:26 +04:00
|
|
|
if (parentItem->ItemType() != nsIDocShellTreeItem::typeChrome) {
|
2012-09-05 07:00:26 +04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDocShellTreeOwner> parentTreeOwner;
|
|
|
|
parentItem->GetTreeOwner(getter_AddRefs(parentTreeOwner));
|
|
|
|
if (!parentTreeOwner) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-12-09 22:23:24 +03:00
|
|
|
bool is_primary = aElement->AttrValueIs(kNameSpaceID_None, nsGkAtoms::primary,
|
|
|
|
nsGkAtoms::_true, eIgnoreCase);
|
2012-09-05 07:00:26 +04:00
|
|
|
|
|
|
|
#ifdef MOZ_XUL
|
|
|
|
// when a content panel is no longer primary, hide any open popups it may have
|
|
|
|
if (!is_primary) {
|
|
|
|
nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
|
2013-02-13 02:02:51 +04:00
|
|
|
if (pm) pm->HidePopupsInDocShell(mDocShell);
|
2012-09-05 07:00:26 +04:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2013-02-13 02:02:51 +04:00
|
|
|
parentTreeOwner->ContentShellRemoved(mDocShell);
|
2018-01-10 22:37:29 +03:00
|
|
|
if (aElement->AttrValueIs(kNameSpaceID_None, TypeAttrName(),
|
|
|
|
nsGkAtoms::content, eIgnoreCase)) {
|
2016-12-09 00:12:36 +03:00
|
|
|
parentTreeOwner->ContentShellAdded(mDocShell, is_primary);
|
2012-09-05 07:00:26 +04:00
|
|
|
}
|
|
|
|
}
|
2013-01-06 02:02:29 +04:00
|
|
|
|
2014-05-23 22:19:00 +04:00
|
|
|
/**
|
|
|
|
* Send the RequestNotifyAfterRemotePaint message to the current Tab.
|
|
|
|
*/
|
|
|
|
void nsFrameLoader::RequestNotifyAfterRemotePaint() {
|
|
|
|
// If remote browsing (e10s), handle this with the TabParent.
|
|
|
|
if (mRemoteBrowser) {
|
2015-11-02 08:53:26 +03:00
|
|
|
Unused << mRemoteBrowser->SendRequestNotifyAfterRemotePaint();
|
2014-05-23 22:19:00 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-09-20 21:03:58 +03:00
|
|
|
void nsFrameLoader::RequestUpdatePosition(ErrorResult& aRv) {
|
|
|
|
if (auto* tabParent = TabParent::GetFrom(GetRemoteBrowser())) {
|
|
|
|
nsresult rv = tabParent->UpdatePosition();
|
|
|
|
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
aRv.Throw(rv);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-08-19 10:55:00 +03:00
|
|
|
void nsFrameLoader::Print(uint64_t aOuterWindowID,
|
|
|
|
nsIPrintSettings* aPrintSettings,
|
|
|
|
nsIWebProgressListener* aProgressListener,
|
|
|
|
ErrorResult& aRv) {
|
2016-05-16 12:40:54 +03:00
|
|
|
#if defined(NS_PRINTING)
|
|
|
|
if (mRemoteBrowser) {
|
|
|
|
RefPtr<embedding::PrintingParent> printingParent =
|
|
|
|
mRemoteBrowser->Manager()->AsContentParent()->GetPrintingParent();
|
|
|
|
|
|
|
|
embedding::PrintData printData;
|
|
|
|
nsresult rv = printingParent->SerializeAndEnsureRemotePrintJob(
|
|
|
|
aPrintSettings, aProgressListener, nullptr, &printData);
|
|
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
2018-03-22 05:43:15 +03:00
|
|
|
aRv.Throw(rv);
|
|
|
|
return;
|
2016-05-16 12:40:54 +03:00
|
|
|
}
|
|
|
|
|
2016-05-25 09:41:54 +03:00
|
|
|
bool success = mRemoteBrowser->SendPrint(aOuterWindowID, printData);
|
2018-03-22 05:43:15 +03:00
|
|
|
if (!success) {
|
|
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
|
|
}
|
|
|
|
return;
|
2016-05-16 12:40:54 +03:00
|
|
|
}
|
|
|
|
|
2017-11-04 01:25:38 +03:00
|
|
|
nsGlobalWindowOuter* outerWindow =
|
2017-11-06 21:09:35 +03:00
|
|
|
nsGlobalWindowOuter::GetOuterWindowWithId(aOuterWindowID);
|
2016-05-25 09:41:54 +03:00
|
|
|
if (NS_WARN_IF(!outerWindow)) {
|
2018-03-22 05:43:15 +03:00
|
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
|
|
return;
|
2016-05-25 09:41:54 +03:00
|
|
|
}
|
2016-05-16 12:40:54 +03:00
|
|
|
|
2016-05-25 09:41:54 +03:00
|
|
|
nsCOMPtr<nsIWebBrowserPrint> webBrowserPrint =
|
|
|
|
do_GetInterface(outerWindow->AsOuter());
|
|
|
|
if (NS_WARN_IF(!webBrowserPrint)) {
|
2018-03-22 05:43:15 +03:00
|
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
|
|
return;
|
2016-05-16 12:40:54 +03:00
|
|
|
}
|
|
|
|
|
2018-03-22 05:43:15 +03:00
|
|
|
nsresult rv = webBrowserPrint->Print(aPrintSettings, aProgressListener);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
aRv.Throw(rv);
|
|
|
|
return;
|
|
|
|
}
|
2016-05-16 12:40:54 +03:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2018-09-25 05:48:30 +03:00
|
|
|
already_AddRefed<mozilla::dom::Promise> nsFrameLoader::DrawSnapshot(
|
|
|
|
double aX, double aY, double aW, double aH, double aScale,
|
|
|
|
const nsAString& aBackgroundColor, mozilla::ErrorResult& aRv) {
|
|
|
|
RefPtr<nsIGlobalObject> global = GetOwnerContent()->GetOwnerGlobal();
|
|
|
|
RefPtr<Promise> promise = Promise::Create(global, aRv);
|
|
|
|
if (NS_WARN_IF(aRv.Failed())) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
RefPtr<nsIDocument> document = GetOwnerContent()->GetOwnerDocument();
|
|
|
|
if (NS_WARN_IF(!document)) {
|
|
|
|
aRv = NS_ERROR_FAILURE;
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
nsIPresShell* presShell = document->GetShell();
|
|
|
|
if (NS_WARN_IF(!presShell)) {
|
|
|
|
aRv = NS_ERROR_FAILURE;
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
nscolor color;
|
|
|
|
css::Loader* loader = document->CSSLoader();
|
|
|
|
ServoStyleSet* set = presShell->StyleSet();
|
|
|
|
if (NS_WARN_IF(!ServoCSSParser::ComputeColor(
|
|
|
|
set, NS_RGB(0, 0, 0), aBackgroundColor, &color, nullptr, loader))) {
|
|
|
|
aRv = NS_ERROR_FAILURE;
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
gfx::IntRect rect = gfx::IntRect::RoundOut(gfx::Rect(aX, aY, aW, aH));
|
|
|
|
|
|
|
|
if (IsRemoteFrame()) {
|
|
|
|
gfx::CrossProcessPaint::StartRemote(mRemoteBrowser->GetTabId(), rect,
|
|
|
|
aScale, color, promise);
|
|
|
|
} else {
|
|
|
|
gfx::CrossProcessPaint::StartLocal(mDocShell, rect, aScale, color, promise);
|
|
|
|
}
|
|
|
|
|
|
|
|
return promise.forget();
|
|
|
|
}
|
|
|
|
|
2017-08-19 10:55:00 +03:00
|
|
|
already_AddRefed<nsITabParent> nsFrameLoader::GetTabParent() {
|
|
|
|
return do_AddRef(mRemoteBrowser);
|
|
|
|
}
|
|
|
|
|
|
|
|
already_AddRefed<nsILoadContext> nsFrameLoader::LoadContext() {
|
2014-01-11 05:10:57 +04:00
|
|
|
nsCOMPtr<nsILoadContext> loadContext;
|
2017-02-25 00:59:53 +03:00
|
|
|
if (IsRemoteFrame() && (mRemoteBrowser || TryRemoteBrowser())) {
|
2014-01-11 05:10:57 +04:00
|
|
|
loadContext = mRemoteBrowser->GetLoadContext();
|
|
|
|
} else {
|
2019-01-02 16:27:05 +03:00
|
|
|
loadContext = do_GetInterface(ToSupports(GetDocShell(IgnoreErrors())));
|
2014-01-11 05:10:57 +04:00
|
|
|
}
|
2018-03-22 05:43:15 +03:00
|
|
|
return loadContext.forget();
|
2014-01-11 05:10:57 +04:00
|
|
|
}
|
2015-02-09 10:04:18 +03:00
|
|
|
|
2018-10-20 03:02:37 +03:00
|
|
|
already_AddRefed<BrowsingContext> nsFrameLoader::GetBrowsingContext() {
|
|
|
|
RefPtr<BrowsingContext> browsingContext;
|
|
|
|
if (IsRemoteFrame() && (mRemoteBrowser || TryRemoteBrowser())) {
|
|
|
|
browsingContext = mRemoteBrowser->GetBrowsingContext();
|
|
|
|
} else if (GetDocShell(IgnoreErrors())) {
|
|
|
|
browsingContext = nsDocShell::Cast(mDocShell)->GetBrowsingContext();
|
|
|
|
}
|
|
|
|
return browsingContext.forget();
|
|
|
|
}
|
|
|
|
|
2015-02-09 10:04:18 +03:00
|
|
|
void nsFrameLoader::InitializeBrowserAPI() {
|
2016-10-15 04:46:26 +03:00
|
|
|
if (!OwnerIsMozBrowserFrame()) {
|
2016-09-09 00:00:12 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (!IsRemoteFrame()) {
|
|
|
|
nsresult rv = EnsureMessageManager();
|
|
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
|
|
return;
|
2015-07-31 13:08:36 +03:00
|
|
|
}
|
2016-09-09 00:00:12 +03:00
|
|
|
if (mMessageManager) {
|
|
|
|
mMessageManager->LoadFrameScript(
|
|
|
|
NS_LITERAL_STRING("chrome://global/content/BrowserElementChild.js"),
|
|
|
|
/* allowDelayedLoad = */ true,
|
2018-02-10 01:31:39 +03:00
|
|
|
/* aRunInGlobalScope */ true, IgnoreErrors());
|
2015-07-31 13:08:36 +03:00
|
|
|
}
|
2015-02-09 10:04:18 +03:00
|
|
|
}
|
2016-09-09 00:00:12 +03:00
|
|
|
nsCOMPtr<nsIMozBrowserFrame> browserFrame = do_QueryInterface(mOwnerContent);
|
|
|
|
if (browserFrame) {
|
|
|
|
browserFrame->InitializeBrowserAPI();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void nsFrameLoader::DestroyBrowserFrameScripts() {
|
2016-10-15 04:46:26 +03:00
|
|
|
if (!OwnerIsMozBrowserFrame()) {
|
2016-09-09 00:00:12 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
nsCOMPtr<nsIMozBrowserFrame> browserFrame = do_QueryInterface(mOwnerContent);
|
|
|
|
if (browserFrame) {
|
|
|
|
browserFrame->DestroyBrowserFrameScripts();
|
|
|
|
}
|
2015-02-09 10:04:18 +03:00
|
|
|
}
|
2015-08-06 00:25:39 +03:00
|
|
|
|
2017-08-20 00:16:16 +03:00
|
|
|
void nsFrameLoader::StartPersistence(
|
|
|
|
uint64_t aOuterWindowID, nsIWebBrowserPersistDocumentReceiver* aRecv,
|
|
|
|
ErrorResult& aRv) {
|
2018-04-09 23:30:33 +03:00
|
|
|
MOZ_ASSERT(aRecv);
|
2015-08-06 17:44:16 +03:00
|
|
|
|
2015-08-06 00:25:39 +03:00
|
|
|
if (mRemoteBrowser) {
|
2018-04-09 23:30:33 +03:00
|
|
|
mRemoteBrowser->StartPersistence(aOuterWindowID, aRecv, aRv);
|
|
|
|
return;
|
2015-08-06 00:25:39 +03:00
|
|
|
}
|
2015-08-06 17:44:16 +03:00
|
|
|
|
2016-04-12 10:40:36 +03:00
|
|
|
nsCOMPtr<nsIDocument> rootDoc =
|
|
|
|
mDocShell ? mDocShell->GetDocument() : nullptr;
|
2015-08-06 17:44:16 +03:00
|
|
|
nsCOMPtr<nsIDocument> foundDoc;
|
|
|
|
if (aOuterWindowID) {
|
|
|
|
foundDoc = nsContentUtils::GetSubdocumentWithOuterWindowId(rootDoc,
|
|
|
|
aOuterWindowID);
|
|
|
|
} else {
|
|
|
|
foundDoc = rootDoc;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!foundDoc) {
|
|
|
|
aRecv->OnError(NS_ERROR_NO_CONTENT);
|
|
|
|
} else {
|
2015-08-06 00:25:39 +03:00
|
|
|
nsCOMPtr<nsIWebBrowserPersistDocument> pdoc =
|
2015-08-06 17:44:16 +03:00
|
|
|
new mozilla::WebBrowserPersistLocalDocument(foundDoc);
|
2015-08-06 00:25:39 +03:00
|
|
|
aRecv->OnDocumentReady(pdoc);
|
|
|
|
}
|
|
|
|
}
|
2015-10-01 20:06:51 +03:00
|
|
|
|
|
|
|
void nsFrameLoader::MaybeUpdatePrimaryTabParent(TabParentChange aChange) {
|
|
|
|
if (mRemoteBrowser && mOwnerContent) {
|
|
|
|
nsCOMPtr<nsIDocShell> docShell = mOwnerContent->OwnerDoc()->GetDocShell();
|
|
|
|
if (!docShell) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
int32_t parentType = docShell->ItemType();
|
|
|
|
if (parentType != nsIDocShellTreeItem::typeChrome) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDocShellTreeOwner> parentTreeOwner;
|
|
|
|
docShell->GetTreeOwner(getter_AddRefs(parentTreeOwner));
|
|
|
|
if (!parentTreeOwner) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!mObservingOwnerContent) {
|
|
|
|
mOwnerContent->AddMutationObserver(this);
|
|
|
|
mObservingOwnerContent = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
parentTreeOwner->TabParentRemoved(mRemoteBrowser);
|
|
|
|
if (aChange == eTabParentChanged) {
|
2016-12-09 22:23:24 +03:00
|
|
|
bool isPrimary = mOwnerContent->AttrValueIs(
|
|
|
|
kNameSpaceID_None, nsGkAtoms::primary, nsGkAtoms::_true, eIgnoreCase);
|
2015-10-01 20:06:51 +03:00
|
|
|
parentTreeOwner->TabParentAdded(mRemoteBrowser, isPrimary);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-10-08 09:44:36 +03:00
|
|
|
|
2015-10-22 06:44:00 +03:00
|
|
|
nsresult nsFrameLoader::GetNewTabContext(MutableTabContext* aTabContext,
|
2016-11-06 18:15:36 +03:00
|
|
|
nsIURI* aURI) {
|
2017-05-29 13:38:46 +03:00
|
|
|
if (IsForJSPlugin()) {
|
|
|
|
return aTabContext->SetTabContextForJSPluginFrame(mJSPluginID)
|
|
|
|
? NS_OK
|
|
|
|
: NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
2017-01-12 19:38:48 +03:00
|
|
|
OriginAttributes attrs;
|
2016-02-18 06:31:29 +03:00
|
|
|
attrs.mInIsolatedMozBrowser = OwnerIsIsolatedMozBrowserFrame();
|
2016-10-31 21:03:12 +03:00
|
|
|
nsresult rv;
|
2015-10-08 09:44:36 +03:00
|
|
|
|
2016-10-15 04:46:26 +03:00
|
|
|
attrs.mAppId = nsIScriptSecurityManager::NO_APP_ID;
|
2015-10-08 09:44:36 +03:00
|
|
|
|
2015-11-24 04:40:02 +03:00
|
|
|
// set the userContextId on the attrs before we pass them into
|
|
|
|
// the tab context
|
2016-10-31 21:03:12 +03:00
|
|
|
rv = PopulateUserContextIdFromAttribute(attrs);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2015-11-24 04:40:02 +03:00
|
|
|
|
2016-05-17 06:10:59 +03:00
|
|
|
nsAutoString presentationURLStr;
|
|
|
|
mOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::mozpresentation,
|
|
|
|
presentationURLStr);
|
|
|
|
|
2016-06-08 08:42:00 +03:00
|
|
|
nsCOMPtr<nsIDocShell> docShell = mOwnerContent->OwnerDoc()->GetDocShell();
|
|
|
|
nsCOMPtr<nsILoadContext> parentContext = do_QueryInterface(docShell);
|
|
|
|
NS_ENSURE_STATE(parentContext);
|
|
|
|
|
|
|
|
bool isPrivate = parentContext->UsePrivateBrowsing();
|
2016-06-03 00:02:29 +03:00
|
|
|
attrs.SyncAttributesWithPrivateBrowsing(isPrivate);
|
|
|
|
|
2016-06-09 14:59:31 +03:00
|
|
|
UIStateChangeType showAccelerators = UIStateChangeType_NoChange;
|
|
|
|
UIStateChangeType showFocusRings = UIStateChangeType_NoChange;
|
2018-07-11 05:31:55 +03:00
|
|
|
uint64_t chromeOuterWindowID = 0;
|
|
|
|
|
2016-06-09 14:59:31 +03:00
|
|
|
nsIDocument* doc = mOwnerContent->OwnerDoc();
|
|
|
|
if (doc) {
|
|
|
|
nsCOMPtr<nsPIWindowRoot> root = nsContentUtils::GetWindowRoot(doc);
|
|
|
|
if (root) {
|
|
|
|
showAccelerators = root->ShowAccelerators() ? UIStateChangeType_Set
|
|
|
|
: UIStateChangeType_Clear;
|
|
|
|
showFocusRings = root->ShowFocusRings() ? UIStateChangeType_Set
|
|
|
|
: UIStateChangeType_Clear;
|
2018-07-11 05:31:55 +03:00
|
|
|
|
|
|
|
nsPIDOMWindowOuter* outerWin = root->GetWindow();
|
|
|
|
if (outerWin) {
|
|
|
|
chromeOuterWindowID = outerWin->WindowID();
|
|
|
|
}
|
2016-06-09 14:59:31 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-02-18 07:35:45 +03:00
|
|
|
bool tabContextUpdated = aTabContext->SetTabContext(
|
|
|
|
OwnerIsMozBrowserFrame(), chromeOuterWindowID, showAccelerators,
|
2016-05-17 06:10:59 +03:00
|
|
|
showFocusRings, attrs, presentationURLStr);
|
2015-10-08 09:44:36 +03:00
|
|
|
NS_ENSURE_STATE(tabContextUpdated);
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2016-05-30 02:48:00 +03:00
|
|
|
|
2017-01-12 19:38:48 +03:00
|
|
|
nsresult nsFrameLoader::PopulateUserContextIdFromAttribute(
|
|
|
|
OriginAttributes& aAttr) {
|
2016-05-30 02:48:00 +03:00
|
|
|
if (aAttr.mUserContextId ==
|
|
|
|
nsIScriptSecurityManager::DEFAULT_USER_CONTEXT_ID) {
|
2018-02-24 02:32:18 +03:00
|
|
|
// Grab the userContextId from owner if XUL or mozbrowser frame
|
2016-05-30 02:48:00 +03:00
|
|
|
nsAutoString userContextIdStr;
|
|
|
|
int32_t namespaceID = mOwnerContent->GetNameSpaceID();
|
2018-02-24 02:32:18 +03:00
|
|
|
if ((namespaceID == kNameSpaceID_XUL || OwnerIsMozBrowserFrame()) &&
|
2016-05-30 02:48:00 +03:00
|
|
|
mOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::usercontextid,
|
|
|
|
userContextIdStr) &&
|
|
|
|
!userContextIdStr.IsEmpty()) {
|
|
|
|
nsresult rv;
|
|
|
|
aAttr.mUserContextId = userContextIdStr.ToInteger(&rv);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2016-08-22 11:28:04 +03:00
|
|
|
|
|
|
|
ProcessMessageManager* nsFrameLoader::GetProcessMessageManager() const {
|
|
|
|
return mRemoteBrowser ? mRemoteBrowser->Manager()->GetMessageManager()
|
|
|
|
: nullptr;
|
|
|
|
};
|
2017-08-19 10:55:00 +03:00
|
|
|
|
|
|
|
JSObject* nsFrameLoader::WrapObject(JSContext* cx,
|
|
|
|
JS::Handle<JSObject*> aGivenProto) {
|
|
|
|
JS::RootedObject result(cx);
|
2018-06-26 00:20:54 +03:00
|
|
|
FrameLoader_Binding::Wrap(cx, this, this, aGivenProto, &result);
|
2017-08-19 10:55:00 +03:00
|
|
|
return result;
|
|
|
|
}
|