diff -r 000000000000 -r 6474c204b198 content/base/src/nsFrameLoader.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/content/base/src/nsFrameLoader.h Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,466 @@ +/* -*- Mode: C++; tab-width: 2; 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 "nsAutoPtr.h" +#include "nsFrameMessageManager.h" +#include "mozilla/dom/Element.h" +#include "mozilla/Attributes.h" +#include "FrameMetrics.h" +#include "nsStubMutationObserver.h" + +class nsIURI; +class nsSubDocumentFrame; +class nsView; +class nsIInProcessContentFrameMessageManager; +class AutoResetInShow; +class nsITabParent; +class nsIDocShellTreeItem; +class nsIDocShellTreeOwner; +class mozIApplication; + +namespace mozilla { +namespace dom { +class ContentParent; +class PBrowserParent; +class TabParent; +struct StructuredCloneData; +} + +namespace layout { +class RenderFrameParent; +} +} + +#if defined(MOZ_WIDGET_GTK) +typedef struct _GtkWidget GtkWidget; +#endif +#ifdef MOZ_WIDGET_QT +class QX11EmbedContainer; +#endif + +/** + * Defines a target configuration for this 's content + * document's view. If the content document's actual view + * doesn't match this nsIContentView, then on paints its pixels + * are transformed to compensate for the difference. + * + * Used to support asynchronous re-paints of content pixels; see + * nsIContentView. + */ +class nsContentView MOZ_FINAL : public nsIContentView +{ +public: + typedef mozilla::layers::FrameMetrics::ViewID ViewID; + NS_DECL_ISUPPORTS + NS_DECL_NSICONTENTVIEW + + struct ViewConfig { + ViewConfig() + : mScrollOffset(0, 0) + , mXScale(1.0) + , mYScale(1.0) + {} + + // Default copy ctor and operator= are fine + + bool operator==(const ViewConfig& aOther) const + { + return (mScrollOffset == aOther.mScrollOffset && + mXScale == aOther.mXScale && + mYScale == aOther.mYScale); + } + + // This is the scroll offset the user wishes or expects + // its enclosed content document to have. "Scroll offset" here + // means the document pixel at pixel (0,0) within the CSS + // viewport. If the content document's actual scroll offset + // doesn't match |mScrollOffset|, the difference is used to define + // a translation transform when painting the content document. + nsPoint mScrollOffset; + // The scale at which the user wishes to paint its + // enclosed content document. If content-document layers have a + // lower or higher resolution than the desired scale, then the + // ratio is used to define a scale transform when painting the + // content document. + float mXScale; + float mYScale; + }; + + nsContentView(nsFrameLoader* aFrameLoader, ViewID aScrollId, bool aIsRoot, + ViewConfig aConfig = ViewConfig()) + : mViewportSize(0, 0) + , mContentSize(0, 0) + , mParentScaleX(1.0) + , mParentScaleY(1.0) + , mFrameLoader(aFrameLoader) + , mScrollId(aScrollId) + , mIsRoot(aIsRoot) + , mConfig(aConfig) + {} + + bool IsRoot() const + { + return mIsRoot; + } + + ViewID GetId() const + { + return mScrollId; + } + + ViewConfig GetViewConfig() const + { + return mConfig; + } + + nsSize mViewportSize; + nsSize mContentSize; + float mParentScaleX; + float mParentScaleY; + + nsFrameLoader* mFrameLoader; // WEAK + +private: + nsresult Update(const ViewConfig& aConfig); + + ViewID mScrollId; + bool mIsRoot; + ViewConfig mConfig; +}; + + +class nsFrameLoader MOZ_FINAL : public nsIFrameLoader, + public nsIContentViewManager, + public nsStubMutationObserver, + public mozilla::dom::ipc::MessageManagerCallback +{ + friend class AutoResetInShow; + typedef mozilla::dom::PBrowserParent PBrowserParent; + typedef mozilla::dom::TabParent TabParent; + typedef mozilla::layout::RenderFrameParent RenderFrameParent; + +protected: + nsFrameLoader(mozilla::dom::Element* aOwner, bool aNetworkCreated); + +public: + ~nsFrameLoader(); + + bool AsyncScrollEnabled() const + { + return !!(mRenderMode & RENDER_MODE_ASYNC_SCROLL); + } + + static nsFrameLoader* Create(mozilla::dom::Element* aOwner, + bool aNetworkCreated); + + NS_DECL_CYCLE_COLLECTING_ISUPPORTS + NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsFrameLoader, nsIFrameLoader) + NS_DECL_NSIFRAMELOADER + NS_DECL_NSICONTENTVIEWMANAGER + NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED + NS_HIDDEN_(nsresult) CheckForRecursiveLoad(nsIURI* aURI); + nsresult ReallyStartLoading(); + void Finalize(); + nsIDocShell* GetExistingDocShell() { return mDocShell; } + mozilla::dom::EventTarget* GetTabChildGlobalAsEventTarget(); + nsresult CreateStaticClone(nsIFrameLoader* aDest); + + /** + * MessageManagerCallback methods that we override. + */ + virtual bool DoLoadFrameScript(const nsAString& aURL, + bool aRunInGlobalScope) MOZ_OVERRIDE; + virtual bool DoSendAsyncMessage(JSContext* aCx, + const nsAString& aMessage, + const mozilla::dom::StructuredCloneData& aData, + JS::Handle aCpows, + nsIPrincipal* aPrincipal) MOZ_OVERRIDE; + virtual bool CheckPermission(const nsAString& aPermission) MOZ_OVERRIDE; + virtual bool CheckManifestURL(const nsAString& aManifestURL) MOZ_OVERRIDE; + virtual bool CheckAppHasPermission(const nsAString& aPermission) MOZ_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, + nsRefPtr& aFirstToSwap, + nsRefPtr& aSecondToSwap); + + // When IPC is enabled, destroy any associated child process. + void DestroyChild(); + + /** + * 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(); + + /** + * 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* GetCurrentRemoteFrame() const + { + return mCurrentRemoteFrame; + } + + /** + * |aFrame| can be null. If non-null, it must be the remote frame + * on which the most recent layer transaction completed for this's + * . + */ + void SetCurrentRemoteFrame(RenderFrameParent* aFrame) + { + mCurrentRemoteFrame = aFrame; + } + 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 or mCurrentRemoteFrame 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 view on the frame loader. We do this when we're + * destroying the nsSubDocumentFrame. If the nsSubdocumentFrame is + * being reframed we'll restore the detached view when it's recreated, + * otherwise we'll discard the old presentation and set the detached + * subdoc view 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 SetDetachedSubdocView(nsView* aDetachedView, + nsIDocument* aContainerDoc); + + /** + * Retrieves the detached view and the document containing the view, + * as set by SetDetachedSubdocView(). + */ + nsView* GetDetachedSubdocView(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); + +private: + + void SetOwnerContent(mozilla::dom::Element* aContent); + + bool ShouldUseRemoteProcess(); + + /** + * Is this a frameloader for a bona fide