/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* 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/. */ /* * Class for managing loading of a subframe (creation of the docshell, * handling of loads in it, recursion-checking). */ #include "base/basictypes.h" #include "prenv.h" #include "nsDocShell.h" #include "nsIDOMMozBrowserFrame.h" #include "nsIDOMWindow.h" #include "nsIContentInlines.h" #include "nsIContentViewer.h" #include "mozilla/dom/Document.h" #include "nsPIDOMWindow.h" #include "nsIWebNavigation.h" #include "nsIWebProgress.h" #include "nsIDocShell.h" #include "nsIDocShellTreeOwner.h" #include "nsDocShellLoadState.h" #include "nsIBaseWindow.h" #include "nsIBrowser.h" #include "nsContentUtils.h" #include "nsIXPConnect.h" #include "nsUnicharUtils.h" #include "nsIScriptGlobalObject.h" #include "nsIScriptSecurityManager.h" #include "nsIScrollable.h" #include "nsFrameLoader.h" #include "nsFrameLoaderOwner.h" #include "nsIFrame.h" #include "nsIScrollableFrame.h" #include "nsSubDocumentFrame.h" #include "nsError.h" #include "nsISHistory.h" #include "nsIXULWindow.h" #include "nsIMozBrowserFrame.h" #include "nsISHistory.h" #include "nsIScriptError.h" #include "nsGlobalWindow.h" #include "nsHTMLDocument.h" #include "nsPIWindowRoot.h" #include "nsLayoutUtils.h" #include "nsMappedAttributes.h" #include "nsView.h" #include "nsBaseWidget.h" #include "nsQueryObject.h" #include "ReferrerInfo.h" #include "nsIURI.h" #include "nsIURL.h" #include "nsNetUtil.h" #include "nsGkAtoms.h" #include "nsNameSpaceManager.h" #include "nsThreadUtils.h" #include "nsIDOMChromeWindow.h" #include "InProcessBrowserChildMessageManager.h" #include "Layers.h" #include "ClientLayerManager.h" #include "ContentParent.h" #include "BrowserParent.h" #include "mozilla/AsyncEventDispatcher.h" #include "mozilla/BasePrincipal.h" #include "mozilla/ExpandedPrincipal.h" #include "mozilla/GuardObjects.h" #include "mozilla/HTMLEditor.h" #include "mozilla/NullPrincipal.h" #include "mozilla/Preferences.h" #include "mozilla/PresShell.h" #include "mozilla/PresShellInlines.h" #include "mozilla/Unused.h" #include "mozilla/dom/ChromeMessageSender.h" #include "mozilla/dom/Element.h" #include "mozilla/dom/FrameCrashedEvent.h" #include "mozilla/dom/FrameLoaderBinding.h" #include "mozilla/dom/MozFrameLoaderOwnerBinding.h" #include "mozilla/dom/SessionStoreListener.h" #include "mozilla/gfx/CrossProcessPaint.h" #include "mozilla/jsipc/CrossProcessObjectWrappers.h" #include "nsGenericHTMLFrameElement.h" #include "GeckoProfiler.h" #include "jsapi.h" #include "mozilla/dom/HTMLIFrameElement.h" #include "nsSandboxFlags.h" #include "mozilla/layers/CompositorBridgeChild.h" #include "mozilla/dom/CustomEvent.h" #include "mozilla/dom/ipc/StructuredCloneData.h" #include "mozilla/WebBrowserPersistLocalDocument.h" #include "mozilla/dom/Promise.h" #include "mozilla/dom/PromiseNativeHandler.h" #include "mozilla/dom/ParentSHistory.h" #include "mozilla/dom/ChildSHistory.h" #include "mozilla/dom/CanonicalBrowsingContext.h" #include "mozilla/dom/ContentChild.h" #include "mozilla/dom/BrowserBridgeChild.h" #include "mozilla/dom/BrowserHost.h" #include "mozilla/dom/BrowserBridgeHost.h" #include "mozilla/dom/HTMLBodyElement.h" #include "mozilla/ContentPrincipal.h" #ifdef XP_WIN # include "mozilla/plugins/PPluginWidgetParent.h" # include "../plugins/ipc/PluginWidgetParent.h" #endif #ifdef MOZ_XUL # include "nsXULPopupManager.h" #endif #ifdef NS_PRINTING # include "mozilla/embedding/printingui/PrintingParent.h" # include "nsIWebBrowserPrint.h" #endif using namespace mozilla; using namespace mozilla::hal; using namespace mozilla::dom; using namespace mozilla::dom::ipc; using namespace mozilla::layers; using namespace mozilla::layout; typedef ScrollableLayerGuid::ViewID ViewID; // 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. // Limit this to 2, like chromium does. #define MAX_SAME_URL_CONTENT_FRAMES 2 // 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 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(nsFrameLoader, mBrowsingContext, mMessageManager, mChildMessageManager, mParentSHistory, mRemoteBrowser) NS_IMPL_CYCLE_COLLECTING_ADDREF(nsFrameLoader) NS_IMPL_CYCLE_COLLECTING_RELEASE(nsFrameLoader) NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsFrameLoader) NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY NS_INTERFACE_MAP_ENTRY_CONCRETE(nsFrameLoader) NS_INTERFACE_MAP_ENTRY(nsIMutationObserver) NS_INTERFACE_MAP_ENTRY(nsISupports) NS_INTERFACE_MAP_END nsFrameLoader::nsFrameLoader(Element* aOwner, BrowsingContext* aBrowsingContext, bool aNetworkCreated) : mBrowsingContext(aBrowsingContext), mOwnerContent(aOwner), mDetachedSubdocFrame(nullptr), mPendingSwitchID(0), mChildID(0), mRemoteType(VoidString()), mDepthTooGreat(false), mIsTopLevelContent(false), mDestroyCalled(false), mNeedsAsyncDestroy(false), mInSwap(false), mInShow(false), mHideCalled(false), mNetworkCreated(aNetworkCreated), mLoadingOriginalSrc(false), mRemoteBrowserShown(false), mIsRemoteFrame(false), mObservingOwnerContent(false), mTabProcessCrashFired(false) { mIsRemoteFrame = ShouldUseRemoteProcess(); MOZ_ASSERT(!mIsRemoteFrame || !mBrowsingContext->HasOpener(), "Cannot pass aOpener for a remote frame!"); if (mIsRemoteFrame && !aOwner->GetAttr(kNameSpaceID_None, nsGkAtoms::RemoteType, mRemoteType)) { mRemoteType.AssignLiteral(DEFAULT_REMOTE_TYPE); } } nsFrameLoader::nsFrameLoader(Element* aOwner, BrowsingContext* aBrowsingContext, const mozilla::dom::RemotenessOptions& aOptions) : mBrowsingContext(aBrowsingContext), mOwnerContent(aOwner), mDetachedSubdocFrame(nullptr), mPendingSwitchID(0), mChildID(0), mRemoteType(VoidString()), mDepthTooGreat(false), mIsTopLevelContent(false), mDestroyCalled(false), mNeedsAsyncDestroy(false), mInSwap(false), mInShow(false), mHideCalled(false), mNetworkCreated(false), mLoadingOriginalSrc(false), mRemoteBrowserShown(false), mIsRemoteFrame(false), mObservingOwnerContent(false), mTabProcessCrashFired(false) { if (aOptions.mRemoteType.WasPassed() && (!aOptions.mRemoteType.Value().IsVoid())) { mIsRemoteFrame = true; mRemoteType = aOptions.mRemoteType.Value(); } } nsFrameLoader::~nsFrameLoader() { if (mMessageManager) { mMessageManager->Disconnect(); } MOZ_RELEASE_ASSERT(mDestroyCalled); } static nsAtom* TypeAttrName(Element* aOwnerContent) { return aOwnerContent->IsXULElement() ? nsGkAtoms::type : nsGkAtoms::mozframetype; } static void GetFrameName(Element* aOwnerContent, nsAString& aFrameName) { int32_t namespaceID = aOwnerContent->GetNameSpaceID(); if (namespaceID == kNameSpaceID_XHTML && !aOwnerContent->IsInHTMLDocument()) { aOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::id, aFrameName); } else { aOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::name, aFrameName); // XXX if no NAME then use ID, after a transition period this will be // changed so that XUL only uses ID too (bug 254284). if (aFrameName.IsEmpty() && namespaceID == kNameSpaceID_XUL) { aOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::id, aFrameName); } } } // If this method returns true, the nsFrameLoader will act as a boundary, as is // the case for