content/base/src/nsFrameLoader.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/content/base/src/nsFrameLoader.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,466 @@
     1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +/*
    1.10 + * Class for managing loading of a subframe (creation of the docshell,
    1.11 + * handling of loads in it, recursion-checking).
    1.12 + */
    1.13 +
    1.14 +#ifndef nsFrameLoader_h_
    1.15 +#define nsFrameLoader_h_
    1.16 +
    1.17 +#include "nsIDocShell.h"
    1.18 +#include "nsStringFwd.h"
    1.19 +#include "nsIFrameLoader.h"
    1.20 +#include "nsPoint.h"
    1.21 +#include "nsSize.h"
    1.22 +#include "nsIURI.h"
    1.23 +#include "nsAutoPtr.h"
    1.24 +#include "nsFrameMessageManager.h"
    1.25 +#include "mozilla/dom/Element.h"
    1.26 +#include "mozilla/Attributes.h"
    1.27 +#include "FrameMetrics.h"
    1.28 +#include "nsStubMutationObserver.h"
    1.29 +
    1.30 +class nsIURI;
    1.31 +class nsSubDocumentFrame;
    1.32 +class nsView;
    1.33 +class nsIInProcessContentFrameMessageManager;
    1.34 +class AutoResetInShow;
    1.35 +class nsITabParent;
    1.36 +class nsIDocShellTreeItem;
    1.37 +class nsIDocShellTreeOwner;
    1.38 +class mozIApplication;
    1.39 +
    1.40 +namespace mozilla {
    1.41 +namespace dom {
    1.42 +class ContentParent;
    1.43 +class PBrowserParent;
    1.44 +class TabParent;
    1.45 +struct StructuredCloneData;
    1.46 +}
    1.47 +
    1.48 +namespace layout {
    1.49 +class RenderFrameParent;
    1.50 +}
    1.51 +}
    1.52 +
    1.53 +#if defined(MOZ_WIDGET_GTK)
    1.54 +typedef struct _GtkWidget GtkWidget;
    1.55 +#endif
    1.56 +#ifdef MOZ_WIDGET_QT
    1.57 +class QX11EmbedContainer;
    1.58 +#endif
    1.59 +
    1.60 +/**
    1.61 + * Defines a target configuration for this <browser>'s content
    1.62 + * document's view.  If the content document's actual view
    1.63 + * doesn't match this nsIContentView, then on paints its pixels
    1.64 + * are transformed to compensate for the difference.
    1.65 + *
    1.66 + * Used to support asynchronous re-paints of content pixels; see
    1.67 + * nsIContentView.
    1.68 + */
    1.69 +class nsContentView MOZ_FINAL : public nsIContentView
    1.70 +{
    1.71 +public:
    1.72 +  typedef mozilla::layers::FrameMetrics::ViewID ViewID;
    1.73 +  NS_DECL_ISUPPORTS
    1.74 +  NS_DECL_NSICONTENTVIEW
    1.75 + 
    1.76 +  struct ViewConfig {
    1.77 +    ViewConfig()
    1.78 +      : mScrollOffset(0, 0)
    1.79 +      , mXScale(1.0)
    1.80 +      , mYScale(1.0)
    1.81 +    {}
    1.82 +
    1.83 +    // Default copy ctor and operator= are fine
    1.84 +
    1.85 +    bool operator==(const ViewConfig& aOther) const
    1.86 +    {
    1.87 +      return (mScrollOffset == aOther.mScrollOffset &&
    1.88 +              mXScale == aOther.mXScale &&
    1.89 +              mYScale == aOther.mYScale);
    1.90 +    }
    1.91 +
    1.92 +    // This is the scroll offset the <browser> user wishes or expects
    1.93 +    // its enclosed content document to have.  "Scroll offset" here
    1.94 +    // means the document pixel at pixel (0,0) within the CSS
    1.95 +    // viewport.  If the content document's actual scroll offset
    1.96 +    // doesn't match |mScrollOffset|, the difference is used to define
    1.97 +    // a translation transform when painting the content document.
    1.98 +    nsPoint mScrollOffset;
    1.99 +    // The scale at which the <browser> user wishes to paint its
   1.100 +    // enclosed content document.  If content-document layers have a
   1.101 +    // lower or higher resolution than the desired scale, then the
   1.102 +    // ratio is used to define a scale transform when painting the
   1.103 +    // content document.
   1.104 +    float mXScale;
   1.105 +    float mYScale;
   1.106 +  };
   1.107 +
   1.108 +  nsContentView(nsFrameLoader* aFrameLoader, ViewID aScrollId, bool aIsRoot,
   1.109 +                ViewConfig aConfig = ViewConfig())
   1.110 +    : mViewportSize(0, 0)
   1.111 +    , mContentSize(0, 0)
   1.112 +    , mParentScaleX(1.0)
   1.113 +    , mParentScaleY(1.0)
   1.114 +    , mFrameLoader(aFrameLoader)
   1.115 +    , mScrollId(aScrollId)
   1.116 +    , mIsRoot(aIsRoot)
   1.117 +    , mConfig(aConfig)
   1.118 +  {}
   1.119 +
   1.120 +  bool IsRoot() const
   1.121 +  {
   1.122 +    return mIsRoot;
   1.123 +  }
   1.124 +
   1.125 +  ViewID GetId() const
   1.126 +  {
   1.127 +    return mScrollId;
   1.128 +  }
   1.129 +
   1.130 +  ViewConfig GetViewConfig() const
   1.131 +  {
   1.132 +    return mConfig;
   1.133 +  }
   1.134 +
   1.135 +  nsSize mViewportSize;
   1.136 +  nsSize mContentSize;
   1.137 +  float mParentScaleX;
   1.138 +  float mParentScaleY;
   1.139 +
   1.140 +  nsFrameLoader* mFrameLoader;  // WEAK
   1.141 +
   1.142 +private:
   1.143 +  nsresult Update(const ViewConfig& aConfig);
   1.144 +
   1.145 +  ViewID mScrollId;
   1.146 +  bool mIsRoot;
   1.147 +  ViewConfig mConfig;
   1.148 +};
   1.149 +
   1.150 +
   1.151 +class nsFrameLoader MOZ_FINAL : public nsIFrameLoader,
   1.152 +                                public nsIContentViewManager,
   1.153 +                                public nsStubMutationObserver,
   1.154 +                                public mozilla::dom::ipc::MessageManagerCallback
   1.155 +{
   1.156 +  friend class AutoResetInShow;
   1.157 +  typedef mozilla::dom::PBrowserParent PBrowserParent;
   1.158 +  typedef mozilla::dom::TabParent TabParent;
   1.159 +  typedef mozilla::layout::RenderFrameParent RenderFrameParent;
   1.160 +
   1.161 +protected:
   1.162 +  nsFrameLoader(mozilla::dom::Element* aOwner, bool aNetworkCreated);
   1.163 +
   1.164 +public:
   1.165 +  ~nsFrameLoader();
   1.166 +
   1.167 +  bool AsyncScrollEnabled() const
   1.168 +  {
   1.169 +    return !!(mRenderMode & RENDER_MODE_ASYNC_SCROLL);
   1.170 +  }
   1.171 +
   1.172 +  static nsFrameLoader* Create(mozilla::dom::Element* aOwner,
   1.173 +                               bool aNetworkCreated);
   1.174 +
   1.175 +  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   1.176 +  NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsFrameLoader, nsIFrameLoader)
   1.177 +  NS_DECL_NSIFRAMELOADER
   1.178 +  NS_DECL_NSICONTENTVIEWMANAGER
   1.179 +  NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
   1.180 +  NS_HIDDEN_(nsresult) CheckForRecursiveLoad(nsIURI* aURI);
   1.181 +  nsresult ReallyStartLoading();
   1.182 +  void Finalize();
   1.183 +  nsIDocShell* GetExistingDocShell() { return mDocShell; }
   1.184 +  mozilla::dom::EventTarget* GetTabChildGlobalAsEventTarget();
   1.185 +  nsresult CreateStaticClone(nsIFrameLoader* aDest);
   1.186 +
   1.187 +  /**
   1.188 +   * MessageManagerCallback methods that we override.
   1.189 +   */
   1.190 +  virtual bool DoLoadFrameScript(const nsAString& aURL,
   1.191 +                                 bool aRunInGlobalScope) MOZ_OVERRIDE;
   1.192 +  virtual bool DoSendAsyncMessage(JSContext* aCx,
   1.193 +                                  const nsAString& aMessage,
   1.194 +                                  const mozilla::dom::StructuredCloneData& aData,
   1.195 +                                  JS::Handle<JSObject *> aCpows,
   1.196 +                                  nsIPrincipal* aPrincipal) MOZ_OVERRIDE;
   1.197 +  virtual bool CheckPermission(const nsAString& aPermission) MOZ_OVERRIDE;
   1.198 +  virtual bool CheckManifestURL(const nsAString& aManifestURL) MOZ_OVERRIDE;
   1.199 +  virtual bool CheckAppHasPermission(const nsAString& aPermission) MOZ_OVERRIDE;
   1.200 +
   1.201 +  /**
   1.202 +   * Called from the layout frame associated with this frame loader;
   1.203 +   * this notifies us to hook up with the widget and view.
   1.204 +   */
   1.205 +  bool Show(int32_t marginWidth, int32_t marginHeight,
   1.206 +              int32_t scrollbarPrefX, int32_t scrollbarPrefY,
   1.207 +              nsSubDocumentFrame* frame);
   1.208 +
   1.209 +  /**
   1.210 +   * Called when the margin properties of the containing frame are changed.
   1.211 +   */
   1.212 +  void MarginsChanged(uint32_t aMarginWidth, uint32_t aMarginHeight);
   1.213 +
   1.214 +  /**
   1.215 +   * Called from the layout frame associated with this frame loader, when
   1.216 +   * the frame is being torn down; this notifies us that out widget and view
   1.217 +   * are going away and we should unhook from them.
   1.218 +   */
   1.219 +  void Hide();
   1.220 +
   1.221 +  nsresult CloneForStatic(nsIFrameLoader* aOriginal);
   1.222 +
   1.223 +  // The guts of an nsIFrameLoaderOwner::SwapFrameLoader implementation.  A
   1.224 +  // frame loader owner needs to call this, and pass in the two references to
   1.225 +  // nsRefPtrs for frame loaders that need to be swapped.
   1.226 +  nsresult SwapWithOtherLoader(nsFrameLoader* aOther,
   1.227 +                               nsRefPtr<nsFrameLoader>& aFirstToSwap,
   1.228 +                               nsRefPtr<nsFrameLoader>& aSecondToSwap);
   1.229 +
   1.230 +  // When IPC is enabled, destroy any associated child process.
   1.231 +  void DestroyChild();
   1.232 +
   1.233 +  /**
   1.234 +   * Return the primary frame for our owning content, or null if it
   1.235 +   * can't be found.
   1.236 +   */
   1.237 +  nsIFrame* GetPrimaryFrameOfOwningContent() const
   1.238 +  {
   1.239 +    return mOwnerContent ? mOwnerContent->GetPrimaryFrame() : nullptr;
   1.240 +  }
   1.241 +
   1.242 +  /** 
   1.243 +   * Return the document that owns this, or null if we don't have
   1.244 +   * an owner.
   1.245 +   */
   1.246 +  nsIDocument* GetOwnerDoc() const
   1.247 +  { return mOwnerContent ? mOwnerContent->OwnerDoc() : nullptr; }
   1.248 +
   1.249 +  PBrowserParent* GetRemoteBrowser();
   1.250 +
   1.251 +  /**
   1.252 +   * The "current" render frame is the one on which the most recent
   1.253 +   * remote layer-tree transaction was executed.  If no content has
   1.254 +   * been drawn yet, or the remote browser doesn't have any drawn
   1.255 +   * content for whatever reason, return nullptr.  The returned render
   1.256 +   * frame has an associated shadow layer tree.
   1.257 +   *
   1.258 +   * Note that the returned render frame might not be a frame
   1.259 +   * constructed for this->GetURL().  This can happen, e.g., if the
   1.260 +   * <browser> was just navigated to a new URL, but hasn't painted the
   1.261 +   * new page yet.  A render frame for the previous page may be
   1.262 +   * returned.  (In-process <browser> behaves similarly, and this
   1.263 +   * behavior seems desirable.)
   1.264 +   */
   1.265 +  RenderFrameParent* GetCurrentRemoteFrame() const
   1.266 +  {
   1.267 +    return mCurrentRemoteFrame;
   1.268 +  }
   1.269 +
   1.270 +  /**
   1.271 +   * |aFrame| can be null.  If non-null, it must be the remote frame
   1.272 +   * on which the most recent layer transaction completed for this's
   1.273 +   * <browser>.
   1.274 +   */
   1.275 +  void SetCurrentRemoteFrame(RenderFrameParent* aFrame)
   1.276 +  {
   1.277 +    mCurrentRemoteFrame = aFrame;
   1.278 +  }
   1.279 +  nsFrameMessageManager* GetFrameMessageManager() { return mMessageManager; }
   1.280 +
   1.281 +  mozilla::dom::Element* GetOwnerContent() { return mOwnerContent; }
   1.282 +  bool ShouldClipSubdocument() { return mClipSubdocument; }
   1.283 +
   1.284 +  bool ShouldClampScrollPosition() { return mClampScrollPosition; }
   1.285 +
   1.286 +  /**
   1.287 +   * Tell this FrameLoader to use a particular remote browser.
   1.288 +   *
   1.289 +   * This will assert if mRemoteBrowser or mCurrentRemoteFrame is non-null.  In
   1.290 +   * practice, this means you can't have successfully run TryRemoteBrowser() on
   1.291 +   * this object, which means you can't have called ShowRemoteFrame() or
   1.292 +   * ReallyStartLoading().
   1.293 +   */
   1.294 +  void SetRemoteBrowser(nsITabParent* aTabParent);
   1.295 +
   1.296 +  /**
   1.297 +   * Stashes a detached view on the frame loader. We do this when we're
   1.298 +   * destroying the nsSubDocumentFrame. If the nsSubdocumentFrame is
   1.299 +   * being reframed we'll restore the detached view when it's recreated,
   1.300 +   * otherwise we'll discard the old presentation and set the detached
   1.301 +   * subdoc view to null. aContainerDoc is the document containing the
   1.302 +   * the subdoc frame. This enables us to detect when the containing
   1.303 +   * document has changed during reframe, so we can discard the presentation 
   1.304 +   * in that case.
   1.305 +   */
   1.306 +  void SetDetachedSubdocView(nsView* aDetachedView,
   1.307 +                             nsIDocument* aContainerDoc);
   1.308 +
   1.309 +  /**
   1.310 +   * Retrieves the detached view and the document containing the view,
   1.311 +   * as set by SetDetachedSubdocView().
   1.312 +   */
   1.313 +  nsView* GetDetachedSubdocView(nsIDocument** aContainerDoc) const;
   1.314 +
   1.315 +  /**
   1.316 +   * Applies a new set of sandbox flags. These are merged with the sandbox
   1.317 +   * flags from our owning content's owning document with a logical OR, this
   1.318 +   * ensures that we can only add restrictions and never remove them.
   1.319 +   */
   1.320 +  void ApplySandboxFlags(uint32_t sandboxFlags);
   1.321 +
   1.322 +  void GetURL(nsString& aURL);
   1.323 +
   1.324 +private:
   1.325 +
   1.326 +  void SetOwnerContent(mozilla::dom::Element* aContent);
   1.327 +
   1.328 +  bool ShouldUseRemoteProcess();
   1.329 +
   1.330 +  /**
   1.331 +   * Is this a frameloader for a bona fide <iframe mozbrowser> or
   1.332 +   * <iframe mozapp>?  (I.e., does the frame return true for
   1.333 +   * nsIMozBrowserFrame::GetReallyIsBrowserOrApp()?)
   1.334 +   */
   1.335 +  bool OwnerIsBrowserOrAppFrame();
   1.336 +
   1.337 +  /**
   1.338 +   * Is this a frameloader for a bona fide <iframe mozapp>?  (I.e., does the
   1.339 +   * frame return true for nsIMozBrowserFrame::GetReallyIsApp()?)
   1.340 +   */
   1.341 +  bool OwnerIsAppFrame();
   1.342 +
   1.343 +  /**
   1.344 +   * Is this a frame loader for a bona fide <iframe mozbrowser>?
   1.345 +   */
   1.346 +  bool OwnerIsBrowserFrame();
   1.347 +
   1.348 +  /**
   1.349 +   * Get our owning element's app manifest URL, or return the empty string if
   1.350 +   * our owning element doesn't have an app manifest URL.
   1.351 +   */
   1.352 +  void GetOwnerAppManifestURL(nsAString& aOut);
   1.353 +
   1.354 +  /**
   1.355 +   * Get the app for our frame.  This is the app whose manifest is returned by
   1.356 +   * GetOwnerAppManifestURL.
   1.357 +   */
   1.358 +  already_AddRefed<mozIApplication> GetOwnApp();
   1.359 +
   1.360 +  /**
   1.361 +   * Get the app which contains this frame.  This is the app associated with
   1.362 +   * the frame element's principal.
   1.363 +   */
   1.364 +  already_AddRefed<mozIApplication> GetContainingApp();
   1.365 +
   1.366 +  /**
   1.367 +   * If we are an IPC frame, set mRemoteFrame. Otherwise, create and
   1.368 +   * initialize mDocShell.
   1.369 +   */
   1.370 +  nsresult MaybeCreateDocShell();
   1.371 +  nsresult EnsureMessageManager();
   1.372 +
   1.373 +  // Properly retrieves documentSize of any subdocument type.
   1.374 +  nsresult GetWindowDimensions(nsRect& aRect);
   1.375 +
   1.376 +  // Updates the subdocument position and size. This gets called only
   1.377 +  // when we have our own in-process DocShell.
   1.378 +  NS_HIDDEN_(nsresult) UpdateBaseWindowPositionAndSize(nsSubDocumentFrame *aIFrame);
   1.379 +  nsresult CheckURILoad(nsIURI* aURI);
   1.380 +  void FireErrorEvent();
   1.381 +  nsresult ReallyStartLoadingInternal();
   1.382 +
   1.383 +  // Return true if remote browser created; nothing else to do
   1.384 +  bool TryRemoteBrowser();
   1.385 +
   1.386 +  // Tell the remote browser that it's now "virtually visible"
   1.387 +  bool ShowRemoteFrame(const nsIntSize& size,
   1.388 +                       nsSubDocumentFrame *aFrame = nullptr);
   1.389 +
   1.390 +  bool AddTreeItemToTreeOwner(nsIDocShellTreeItem* aItem,
   1.391 +                              nsIDocShellTreeOwner* aOwner,
   1.392 +                              int32_t aParentType,
   1.393 +                              nsIDocShell* aParentNode);
   1.394 +
   1.395 +  nsIAtom* TypeAttrName() const {
   1.396 +    return mOwnerContent->IsXUL() ? nsGkAtoms::type : nsGkAtoms::mozframetype;
   1.397 +  }
   1.398 +
   1.399 +  // Update the permission manager's app-id refcount based on mOwnerContent's
   1.400 +  // own-or-containing-app.
   1.401 +  void ResetPermissionManagerStatus();
   1.402 +
   1.403 +  nsCOMPtr<nsIDocShell> mDocShell;
   1.404 +  nsCOMPtr<nsIURI> mURIToLoad;
   1.405 +  mozilla::dom::Element* mOwnerContent; // WEAK
   1.406 +
   1.407 +  // Note: this variable must be modified only by ResetPermissionManagerStatus()
   1.408 +  uint32_t mAppIdSentToPermissionManager;
   1.409 +
   1.410 +public:
   1.411 +  // public because a callback needs these.
   1.412 +  nsRefPtr<nsFrameMessageManager> mMessageManager;
   1.413 +  nsCOMPtr<nsIInProcessContentFrameMessageManager> mChildMessageManager;
   1.414 +private:
   1.415 +  // Stores the root view of the subdocument while the subdocument is being
   1.416 +  // reframed. Used to restore the presentation after reframing.
   1.417 +  nsView* mDetachedSubdocViews;
   1.418 +  // Stores the containing document of the frame corresponding to this
   1.419 +  // frame loader. This is reference is kept valid while the subframe's
   1.420 +  // presentation is detached and stored in mDetachedSubdocViews. This
   1.421 +  // enables us to detect whether the frame has moved documents during
   1.422 +  // a reframe, so that we know not to restore the presentation.
   1.423 +  nsCOMPtr<nsIDocument> mContainerDocWhileDetached;
   1.424 +
   1.425 +  bool mDepthTooGreat : 1;
   1.426 +  bool mIsTopLevelContent : 1;
   1.427 +  bool mDestroyCalled : 1;
   1.428 +  bool mNeedsAsyncDestroy : 1;
   1.429 +  bool mInSwap : 1;
   1.430 +  bool mInShow : 1;
   1.431 +  bool mHideCalled : 1;
   1.432 +  // True when the object is created for an element which the parser has
   1.433 +  // created using NS_FROM_PARSER_NETWORK flag. If the element is modified,
   1.434 +  // it may lose the flag.
   1.435 +  bool mNetworkCreated : 1;
   1.436 +
   1.437 +  bool mRemoteBrowserShown : 1;
   1.438 +  bool mRemoteFrame : 1;
   1.439 +  bool mClipSubdocument : 1;
   1.440 +  bool mClampScrollPosition : 1;
   1.441 +  bool mRemoteBrowserInitialized : 1;
   1.442 +  bool mObservingOwnerContent : 1;
   1.443 +
   1.444 +  // Backs nsIFrameLoader::{Get,Set}Visible.  Visibility state here relates to
   1.445 +  // whether this frameloader's <iframe mozbrowser> is setVisible(true)'ed, and
   1.446 +  // doesn't necessarily correlate with docshell/document visibility.
   1.447 +  bool mVisible : 1;
   1.448 +
   1.449 +  // The ContentParent associated with mRemoteBrowser.  This was added as a
   1.450 +  // strong ref in bug 545237, and we're not sure if we can get rid of it.
   1.451 +  nsRefPtr<mozilla::dom::ContentParent> mContentParent;
   1.452 +  RenderFrameParent* mCurrentRemoteFrame;
   1.453 +  TabParent* mRemoteBrowser;
   1.454 +  uint64_t mChildID;
   1.455 +
   1.456 +  // See nsIFrameLoader.idl.  Short story, if !(mRenderMode &
   1.457 +  // RENDER_MODE_ASYNC_SCROLL), all the fields below are ignored in
   1.458 +  // favor of what content tells.
   1.459 +  uint32_t mRenderMode;
   1.460 +
   1.461 +  // See nsIFrameLoader.idl. EVENT_MODE_NORMAL_DISPATCH automatically
   1.462 +  // forwards some input events to out-of-process content.
   1.463 +  uint32_t mEventMode;
   1.464 +
   1.465 +  // Indicate if we have sent 'remote-browser-pending'.
   1.466 +  bool mPendingFrameSent;
   1.467 +};
   1.468 +
   1.469 +#endif

mercurial