summaryrefslogtreecommitdiffstats
path: root/dom/base/nsFrameLoader.h
diff options
context:
space:
mode:
Diffstat (limited to 'dom/base/nsFrameLoader.h')
-rw-r--r--dom/base/nsFrameLoader.h400
1 files changed, 400 insertions, 0 deletions
diff --git a/dom/base/nsFrameLoader.h b/dom/base/nsFrameLoader.h
new file mode 100644
index 000000000..bbbd52f58
--- /dev/null
+++ b/dom/base/nsFrameLoader.h
@@ -0,0 +1,400 @@
+/* -*- 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).
+ */
+
+#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<JSObject *> 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
+ * <browser> 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 <browser> 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<nsFrameMessageManager> mMessageManager;
+ nsCOMPtr<nsIInProcessContentFrameMessageManager> 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 <iframe mozbrowser> or
+ * <iframe mozapp>? (I.e., does the frame return true for
+ * nsIMozBrowserFrame::GetReallyIsBrowserOrApp()?)
+ * <xul:browser> is not a mozbrowser or app, so this is false for that case.
+ */
+ bool OwnerIsMozBrowserOrAppFrame();
+
+ /**
+ * Is this a frameloader for a bona fide <iframe mozapp>? (I.e., does the
+ * frame return true for nsIMozBrowserFrame::GetReallyIsApp()?)
+ */
+ bool OwnerIsAppFrame();
+
+ /**
+ * Is this a frame loader for a bona fide <iframe mozbrowser>?
+ * <xul:browser> is not a mozbrowser, so this is false for that case.
+ */
+ bool OwnerIsMozBrowserFrame();
+
+ /**
+ * Is this a frame loader for an isolated <iframe mozbrowser>?
+ *
+ * By default, mozbrowser frames are isolated. Isolation can be disabled by
+ * setting the frame's noisolation attribute. Disabling isolation is
+ * only allowed if the containing document is chrome.
+ */
+ bool OwnerIsIsolatedMozBrowserFrame();
+
+ /**
+ * Get our owning element's app manifest URL, or return the empty string if
+ * our owning element doesn't have an app manifest URL.
+ */
+ void GetOwnerAppManifestURL(nsAString& aOut);
+
+ /**
+ * Get the app for our frame. This is the app whose manifest is returned by
+ * GetOwnerAppManifestURL.
+ */
+ already_AddRefed<mozIApplication> GetOwnApp();
+
+ /**
+ * Get the app which contains this frame. This is the app associated with
+ * the frame element's principal.
+ */
+ already_AddRefed<mozIApplication> GetContainingApp();
+
+ /**
+ * If we are an IPC frame, set mRemoteFrame. Otherwise, create and
+ * initialize mDocShell.
+ */
+ nsresult MaybeCreateDocShell();
+ nsresult EnsureMessageManager();
+ nsresult ReallyLoadFrameScripts();
+
+ // Updates the subdocument position and size. This gets called only
+ // when we have our own in-process DocShell.
+ void UpdateBaseWindowPositionAndSize(nsSubDocumentFrame *aIFrame);
+ nsresult CheckURILoad(nsIURI* aURI);
+ void FireErrorEvent();
+ nsresult ReallyStartLoadingInternal();
+
+ // Return true if remote browser created; nothing else to do
+ bool TryRemoteBrowser();
+
+ // Tell the remote browser that it's now "virtually visible"
+ bool ShowRemoteFrame(const mozilla::ScreenIntSize& size,
+ nsSubDocumentFrame *aFrame = nullptr);
+
+ bool AddTreeItemToTreeOwner(nsIDocShellTreeItem* aItem,
+ nsIDocShellTreeOwner* aOwner,
+ int32_t aParentType,
+ nsIDocShell* aParentNode);
+
+ nsIAtom* TypeAttrName() const {
+ return mOwnerContent->IsXULElement()
+ ? nsGkAtoms::type : nsGkAtoms::mozframetype;
+ }
+
+ void InitializeBrowserAPI();
+ void DestroyBrowserFrameScripts();
+
+ nsresult GetNewTabContext(mozilla::dom::MutableTabContext* aTabContext,
+ nsIURI* aURI = nullptr);
+
+ enum TabParentChange {
+ eTabParentRemoved,
+ eTabParentChanged
+ };
+ void MaybeUpdatePrimaryTabParent(TabParentChange aChange);
+
+ nsresult
+ PopulateUserContextIdFromAttribute(mozilla::DocShellOriginAttributes& aAttr);
+
+ nsCOMPtr<nsIDocShell> mDocShell;
+ nsCOMPtr<nsIURI> mURIToLoad;
+ mozilla::dom::Element* mOwnerContent; // WEAK
+
+ // After the frameloader has been removed from the DOM but before all of the
+ // messages from the frame have been received, we keep a strong reference to
+ // our <browser> element.
+ RefPtr<mozilla::dom::Element> mOwnerContentStrong;
+
+ // Stores the root frame of the subdocument while the subdocument is being
+ // reframed. Used to restore the presentation after reframing.
+ nsWeakFrame mDetachedSubdocFrame;
+ // Stores the containing document of the frame corresponding to this
+ // frame loader. This is reference is kept valid while the subframe's
+ // presentation is detached and stored in mDetachedSubdocFrame. This
+ // enables us to detect whether the frame has moved documents during
+ // a reframe, so that we know not to restore the presentation.
+ nsCOMPtr<nsIDocument> mContainerDocWhileDetached;
+
+ // An opener window which should be used when the docshell is created.
+ nsCOMPtr<nsPIDOMWindowOuter> mOpener;
+
+ TabParent* mRemoteBrowser;
+ uint64_t mChildID;
+
+ // See nsIFrameLoader.idl. EVENT_MODE_NORMAL_DISPATCH automatically
+ // forwards some input events to out-of-process content.
+ uint32_t mEventMode;
+
+ // Holds the last known size of the frame.
+ mozilla::ScreenIntSize mLazySize;
+
+ nsCOMPtr<nsIPartialSHistory> mPartialSessionHistory;
+ nsCOMPtr<nsIGroupedSHistory> mGroupedSessionHistory;
+
+ bool mIsPrerendered : 1;
+ bool mDepthTooGreat : 1;
+ bool mIsTopLevelContent : 1;
+ bool mDestroyCalled : 1;
+ bool mNeedsAsyncDestroy : 1;
+ bool mInSwap : 1;
+ bool mInShow : 1;
+ bool mHideCalled : 1;
+ // True when the object is created for an element which the parser has
+ // created using NS_FROM_PARSER_NETWORK flag. If the element is modified,
+ // it may lose the flag.
+ bool mNetworkCreated : 1;
+
+ bool mRemoteBrowserShown : 1;
+ bool mRemoteFrame : 1;
+ bool mClipSubdocument : 1;
+ bool mClampScrollPosition : 1;
+ bool mObservingOwnerContent : 1;
+
+ // Backs nsIFrameLoader::{Get,Set}Visible. Visibility state here relates to
+ // whether this frameloader's <iframe mozbrowser> is setVisible(true)'ed, and
+ // doesn't necessarily correlate with docshell/document visibility.
+ bool mVisible : 1;
+ bool mFreshProcess : 1;
+};
+
+#endif