/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* 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). */ #ifndef nsFrameLoader_h_ #define nsFrameLoader_h_ #include "nsIDocShell.h" #include "nsStringFwd.h" #include "nsIFrameLoader.h" #include "nsPoint.h" #include "nsSize.h" #include "nsIURI.h" #include "nsFrameMessageManager.h" #include "mozilla/dom/Element.h" #include "mozilla/Attributes.h" #include "nsStubMutationObserver.h" #include "Units.h" #include "nsIWebBrowserPersistable.h" #include "nsIFrame.h" #include "nsIGroupedSHistory.h" class nsIURI; class nsSubDocumentFrame; class nsView; class nsIInProcessContentFrameMessageManager; class AutoResetInShow; class AutoResetInFrameSwap; class nsITabParent; class nsIDocShellTreeItem; class nsIDocShellTreeOwner; class mozIApplication; namespace mozilla { class DocShellOriginAttributes; namespace dom { class ContentParent; class PBrowserParent; class TabParent; class MutableTabContext; } // namespace dom namespace ipc { class StructuredCloneData; } // namespace ipc namespace layout { class RenderFrameParent; } // namespace layout } // namespace mozilla #if defined(MOZ_WIDGET_GTK) typedef struct _GtkWidget GtkWidget; #endif class nsFrameLoader final : public nsIFrameLoader, public nsIWebBrowserPersistable, public nsStubMutationObserver, public mozilla::dom::ipc::MessageManagerCallback { friend class AutoResetInShow; friend class AutoResetInFrameSwap; typedef mozilla::dom::PBrowserParent PBrowserParent; typedef mozilla::dom::TabParent TabParent; typedef mozilla::layout::RenderFrameParent RenderFrameParent; public: static nsFrameLoader* Create(mozilla::dom::Element* aOwner, nsPIDOMWindowOuter* aOpener, bool aNetworkCreated); NS_DECL_CYCLE_COLLECTING_ISUPPORTS NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsFrameLoader, nsIFrameLoader) NS_DECL_NSIFRAMELOADER NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED NS_DECL_NSIWEBBROWSERPERSISTABLE nsresult CheckForRecursiveLoad(nsIURI* aURI); nsresult ReallyStartLoading(); void StartDestroy(); void DestroyDocShell(); void DestroyComplete(); nsIDocShell* GetExistingDocShell() { return mDocShell; } mozilla::dom::EventTarget* GetTabChildGlobalAsEventTarget(); nsresult CreateStaticClone(nsIFrameLoader* aDest); /** * MessageManagerCallback methods that we override. */ virtual bool DoLoadMessageManagerScript(const nsAString& aURL, bool aRunInGlobalScope) override; virtual nsresult DoSendAsyncMessage(JSContext* aCx, const nsAString& aMessage, mozilla::dom::ipc::StructuredCloneData& aData, JS::Handle aCpows, nsIPrincipal* aPrincipal) override; virtual bool CheckPermission(const nsAString& aPermission) override; virtual bool CheckManifestURL(const nsAString& aManifestURL) override; virtual bool CheckAppHasPermission(const nsAString& aPermission) override; /** * Called from the layout frame associated with this frame loader; * this notifies us to hook up with the widget and view. */ bool Show(int32_t marginWidth, int32_t marginHeight, int32_t scrollbarPrefX, int32_t scrollbarPrefY, nsSubDocumentFrame* frame); /** * Called when the margin properties of the containing frame are changed. */ void MarginsChanged(uint32_t aMarginWidth, uint32_t aMarginHeight); /** * Called from the layout frame associated with this frame loader, when * the frame is being torn down; this notifies us that out widget and view * are going away and we should unhook from them. */ void Hide(); nsresult CloneForStatic(nsIFrameLoader* aOriginal); // The guts of an nsIFrameLoaderOwner::SwapFrameLoader implementation. A // frame loader owner needs to call this, and pass in the two references to // nsRefPtrs for frame loaders that need to be swapped. nsresult SwapWithOtherLoader(nsFrameLoader* aOther, nsIFrameLoaderOwner* aThisOwner, nsIFrameLoaderOwner* aOtherOwner); nsresult SwapWithOtherRemoteLoader(nsFrameLoader* aOther, nsIFrameLoaderOwner* aThisOwner, nsIFrameLoaderOwner* aOtherOwner); /** * Return the primary frame for our owning content, or null if it * can't be found. */ nsIFrame* GetPrimaryFrameOfOwningContent() const { return mOwnerContent ? mOwnerContent->GetPrimaryFrame() : nullptr; } /** * Return the document that owns this, or null if we don't have * an owner. */ nsIDocument* GetOwnerDoc() const { return mOwnerContent ? mOwnerContent->OwnerDoc() : nullptr; } PBrowserParent* GetRemoteBrowser() const; /** * The "current" render frame is the one on which the most recent * remote layer-tree transaction was executed. If no content has * been drawn yet, or the remote browser doesn't have any drawn * content for whatever reason, return nullptr. The returned render * frame has an associated shadow layer tree. * * Note that the returned render frame might not be a frame * constructed for this->GetURL(). This can happen, e.g., if the * was just navigated to a new URL, but hasn't painted the * new page yet. A render frame for the previous page may be * returned. (In-process behaves similarly, and this * behavior seems desirable.) */ RenderFrameParent* GetCurrentRenderFrame() const; nsFrameMessageManager* GetFrameMessageManager() { return mMessageManager; } mozilla::dom::Element* GetOwnerContent() { return mOwnerContent; } bool ShouldClipSubdocument() { return mClipSubdocument; } bool ShouldClampScrollPosition() { return mClampScrollPosition; } /** * Tell this FrameLoader to use a particular remote browser. * * This will assert if mRemoteBrowser is non-null. In practice, * this means you can't have successfully run TryRemoteBrowser() on * this object, which means you can't have called ShowRemoteFrame() * or ReallyStartLoading(). */ void SetRemoteBrowser(nsITabParent* aTabParent); /** * Stashes a detached nsIFrame on the frame loader. We do this when we're * destroying the nsSubDocumentFrame. If the nsSubdocumentFrame is * being reframed we'll restore the detached nsIFrame when it's recreated, * otherwise we'll discard the old presentation and set the detached * subdoc nsIFrame to null. aContainerDoc is the document containing the * the subdoc frame. This enables us to detect when the containing * document has changed during reframe, so we can discard the presentation * in that case. */ void SetDetachedSubdocFrame(nsIFrame* aDetachedFrame, nsIDocument* aContainerDoc); /** * Retrieves the detached nsIFrame and the document containing the nsIFrame, * as set by SetDetachedSubdocFrame(). */ nsIFrame* GetDetachedSubdocFrame(nsIDocument** aContainerDoc) const; /** * Applies a new set of sandbox flags. These are merged with the sandbox * flags from our owning content's owning document with a logical OR, this * ensures that we can only add restrictions and never remove them. */ void ApplySandboxFlags(uint32_t sandboxFlags); void GetURL(nsString& aURL); // Properly retrieves documentSize of any subdocument type. nsresult GetWindowDimensions(nsIntRect& aRect); virtual nsIMessageSender* GetProcessMessageManager() const override; // public because a callback needs these. RefPtr mMessageManager; nsCOMPtr mChildMessageManager; private: nsFrameLoader(mozilla::dom::Element* aOwner, nsPIDOMWindowOuter* aOpener, bool aNetworkCreated); ~nsFrameLoader(); void SetOwnerContent(mozilla::dom::Element* aContent); bool ShouldUseRemoteProcess(); /** * Return true if the frame is a remote frame. Return false otherwise */ bool IsRemoteFrame(); /** * Is this a frameloader for a bona fide