1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 * Class for managing loading of a subframe (creation of the docshell,
8 * handling of loads in it, recursion-checking).
11 #ifndef nsFrameLoader_h_
12 #define nsFrameLoader_h_
14 #include "nsIDocShell.h"
15 #include "nsStringFwd.h"
16 #include "nsIFrameLoader.h"
20 #include "nsAutoPtr.h"
21 #include "nsFrameMessageManager.h"
22 #include "mozilla/dom/Element.h"
23 #include "mozilla/Attributes.h"
24 #include "FrameMetrics.h"
25 #include "nsStubMutationObserver.h"
28 class nsSubDocumentFrame
;
30 class nsIInProcessContentFrameMessageManager
;
31 class AutoResetInShow
;
33 class nsIDocShellTreeItem
;
34 class nsIDocShellTreeOwner
;
35 class mozIApplication
;
42 struct StructuredCloneData
;
46 class RenderFrameParent
;
50 #if defined(MOZ_WIDGET_GTK)
51 typedef struct _GtkWidget GtkWidget
;
54 class QX11EmbedContainer
;
57 class nsFrameLoader MOZ_FINAL
: public nsIFrameLoader
,
58 public nsStubMutationObserver
,
59 public mozilla::dom::ipc::MessageManagerCallback
61 friend class AutoResetInShow
;
62 typedef mozilla::dom::PBrowserParent PBrowserParent
;
63 typedef mozilla::dom::TabParent TabParent
;
64 typedef mozilla::layout::RenderFrameParent RenderFrameParent
;
67 nsFrameLoader(mozilla::dom::Element
* aOwner
, bool aNetworkCreated
);
72 bool AsyncScrollEnabled() const
74 return !!(mRenderMode
& RENDER_MODE_ASYNC_SCROLL
);
77 static nsFrameLoader
* Create(mozilla::dom::Element
* aOwner
,
78 bool aNetworkCreated
);
80 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
81 NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsFrameLoader
, nsIFrameLoader
)
82 NS_DECL_NSIFRAMELOADER
83 NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
84 nsresult
CheckForRecursiveLoad(nsIURI
* aURI
);
85 nsresult
ReallyStartLoading();
87 nsIDocShell
* GetExistingDocShell() { return mDocShell
; }
88 mozilla::dom::EventTarget
* GetTabChildGlobalAsEventTarget();
89 nsresult
CreateStaticClone(nsIFrameLoader
* aDest
);
92 * MessageManagerCallback methods that we override.
94 virtual bool DoLoadFrameScript(const nsAString
& aURL
,
95 bool aRunInGlobalScope
) MOZ_OVERRIDE
;
96 virtual bool DoSendAsyncMessage(JSContext
* aCx
,
97 const nsAString
& aMessage
,
98 const mozilla::dom::StructuredCloneData
& aData
,
99 JS::Handle
<JSObject
*> aCpows
,
100 nsIPrincipal
* aPrincipal
) MOZ_OVERRIDE
;
101 virtual bool CheckPermission(const nsAString
& aPermission
) MOZ_OVERRIDE
;
102 virtual bool CheckManifestURL(const nsAString
& aManifestURL
) MOZ_OVERRIDE
;
103 virtual bool CheckAppHasPermission(const nsAString
& aPermission
) MOZ_OVERRIDE
;
106 * Called from the layout frame associated with this frame loader;
107 * this notifies us to hook up with the widget and view.
109 bool Show(int32_t marginWidth
, int32_t marginHeight
,
110 int32_t scrollbarPrefX
, int32_t scrollbarPrefY
,
111 nsSubDocumentFrame
* frame
);
114 * Called when the margin properties of the containing frame are changed.
116 void MarginsChanged(uint32_t aMarginWidth
, uint32_t aMarginHeight
);
119 * Called from the layout frame associated with this frame loader, when
120 * the frame is being torn down; this notifies us that out widget and view
121 * are going away and we should unhook from them.
125 nsresult
CloneForStatic(nsIFrameLoader
* aOriginal
);
127 // The guts of an nsIFrameLoaderOwner::SwapFrameLoader implementation. A
128 // frame loader owner needs to call this, and pass in the two references to
129 // nsRefPtrs for frame loaders that need to be swapped.
130 nsresult
SwapWithOtherLoader(nsFrameLoader
* aOther
,
131 nsRefPtr
<nsFrameLoader
>& aFirstToSwap
,
132 nsRefPtr
<nsFrameLoader
>& aSecondToSwap
);
134 // When IPC is enabled, destroy any associated child process.
138 * Return the primary frame for our owning content, or null if it
141 nsIFrame
* GetPrimaryFrameOfOwningContent() const
143 return mOwnerContent
? mOwnerContent
->GetPrimaryFrame() : nullptr;
147 * Return the document that owns this, or null if we don't have
150 nsIDocument
* GetOwnerDoc() const
151 { return mOwnerContent
? mOwnerContent
->OwnerDoc() : nullptr; }
153 PBrowserParent
* GetRemoteBrowser();
156 * The "current" render frame is the one on which the most recent
157 * remote layer-tree transaction was executed. If no content has
158 * been drawn yet, or the remote browser doesn't have any drawn
159 * content for whatever reason, return nullptr. The returned render
160 * frame has an associated shadow layer tree.
162 * Note that the returned render frame might not be a frame
163 * constructed for this->GetURL(). This can happen, e.g., if the
164 * <browser> was just navigated to a new URL, but hasn't painted the
165 * new page yet. A render frame for the previous page may be
166 * returned. (In-process <browser> behaves similarly, and this
167 * behavior seems desirable.)
169 RenderFrameParent
* GetCurrentRemoteFrame() const
171 return mCurrentRemoteFrame
;
175 * |aFrame| can be null. If non-null, it must be the remote frame
176 * on which the most recent layer transaction completed for this's
179 void SetCurrentRemoteFrame(RenderFrameParent
* aFrame
)
181 mCurrentRemoteFrame
= aFrame
;
183 nsFrameMessageManager
* GetFrameMessageManager() { return mMessageManager
; }
185 mozilla::dom::Element
* GetOwnerContent() { return mOwnerContent
; }
186 bool ShouldClipSubdocument() { return mClipSubdocument
; }
188 bool ShouldClampScrollPosition() { return mClampScrollPosition
; }
191 * Tell this FrameLoader to use a particular remote browser.
193 * This will assert if mRemoteBrowser or mCurrentRemoteFrame is non-null. In
194 * practice, this means you can't have successfully run TryRemoteBrowser() on
195 * this object, which means you can't have called ShowRemoteFrame() or
196 * ReallyStartLoading().
198 void SetRemoteBrowser(nsITabParent
* aTabParent
);
201 * Stashes a detached view on the frame loader. We do this when we're
202 * destroying the nsSubDocumentFrame. If the nsSubdocumentFrame is
203 * being reframed we'll restore the detached view when it's recreated,
204 * otherwise we'll discard the old presentation and set the detached
205 * subdoc view to null. aContainerDoc is the document containing the
206 * the subdoc frame. This enables us to detect when the containing
207 * document has changed during reframe, so we can discard the presentation
210 void SetDetachedSubdocView(nsView
* aDetachedView
,
211 nsIDocument
* aContainerDoc
);
214 * Retrieves the detached view and the document containing the view,
215 * as set by SetDetachedSubdocView().
217 nsView
* GetDetachedSubdocView(nsIDocument
** aContainerDoc
) const;
220 * Applies a new set of sandbox flags. These are merged with the sandbox
221 * flags from our owning content's owning document with a logical OR, this
222 * ensures that we can only add restrictions and never remove them.
224 void ApplySandboxFlags(uint32_t sandboxFlags
);
226 void GetURL(nsString
& aURL
);
230 void SetOwnerContent(mozilla::dom::Element
* aContent
);
232 bool ShouldUseRemoteProcess();
235 * Is this a frameloader for a bona fide <iframe mozbrowser> or
236 * <iframe mozapp>? (I.e., does the frame return true for
237 * nsIMozBrowserFrame::GetReallyIsBrowserOrApp()?)
239 bool OwnerIsBrowserOrAppFrame();
242 * Is this a frameloader for a bona fide <iframe mozwidget>? (I.e., does the
243 * frame return true for nsIMozBrowserFrame::GetReallyIsWidget()?)
245 bool OwnerIsWidget();
248 * Is this a frameloader for a bona fide <iframe mozapp>? (I.e., does the
249 * frame return true for nsIMozBrowserFrame::GetReallyIsApp()?)
251 bool OwnerIsAppFrame();
254 * Is this a frame loader for a bona fide <iframe mozbrowser>?
256 bool OwnerIsBrowserFrame();
259 * Get our owning element's app manifest URL, or return the empty string if
260 * our owning element doesn't have an app manifest URL.
262 void GetOwnerAppManifestURL(nsAString
& aOut
);
265 * Get the app for our frame. This is the app whose manifest is returned by
266 * GetOwnerAppManifestURL.
268 already_AddRefed
<mozIApplication
> GetOwnApp();
271 * Get the app which contains this frame. This is the app associated with
272 * the frame element's principal.
274 already_AddRefed
<mozIApplication
> GetContainingApp();
277 * If we are an IPC frame, set mRemoteFrame. Otherwise, create and
278 * initialize mDocShell.
280 nsresult
MaybeCreateDocShell();
281 nsresult
EnsureMessageManager();
283 // Properly retrieves documentSize of any subdocument type.
284 nsresult
GetWindowDimensions(nsIntRect
& aRect
);
286 // Updates the subdocument position and size. This gets called only
287 // when we have our own in-process DocShell.
288 nsresult
UpdateBaseWindowPositionAndSize(nsSubDocumentFrame
*aIFrame
);
289 nsresult
CheckURILoad(nsIURI
* aURI
);
290 void FireErrorEvent();
291 nsresult
ReallyStartLoadingInternal();
293 // Return true if remote browser created; nothing else to do
294 bool TryRemoteBrowser();
296 // Tell the remote browser that it's now "virtually visible"
297 bool ShowRemoteFrame(const nsIntSize
& size
,
298 nsSubDocumentFrame
*aFrame
= nullptr);
300 bool AddTreeItemToTreeOwner(nsIDocShellTreeItem
* aItem
,
301 nsIDocShellTreeOwner
* aOwner
,
303 nsIDocShell
* aParentNode
);
305 nsIAtom
* TypeAttrName() const {
306 return mOwnerContent
->IsXUL() ? nsGkAtoms::type
: nsGkAtoms::mozframetype
;
309 // Update the permission manager's app-id refcount based on mOwnerContent's
310 // own-or-containing-app.
311 void ResetPermissionManagerStatus();
313 nsCOMPtr
<nsIDocShell
> mDocShell
;
314 nsCOMPtr
<nsIURI
> mURIToLoad
;
315 mozilla::dom::Element
* mOwnerContent
; // WEAK
317 // Note: this variable must be modified only by ResetPermissionManagerStatus()
318 uint32_t mAppIdSentToPermissionManager
;
321 // public because a callback needs these.
322 nsRefPtr
<nsFrameMessageManager
> mMessageManager
;
323 nsCOMPtr
<nsIInProcessContentFrameMessageManager
> mChildMessageManager
;
325 // Stores the root view of the subdocument while the subdocument is being
326 // reframed. Used to restore the presentation after reframing.
327 nsView
* mDetachedSubdocViews
;
328 // Stores the containing document of the frame corresponding to this
329 // frame loader. This is reference is kept valid while the subframe's
330 // presentation is detached and stored in mDetachedSubdocViews. This
331 // enables us to detect whether the frame has moved documents during
332 // a reframe, so that we know not to restore the presentation.
333 nsCOMPtr
<nsIDocument
> mContainerDocWhileDetached
;
335 bool mDepthTooGreat
: 1;
336 bool mIsTopLevelContent
: 1;
337 bool mDestroyCalled
: 1;
338 bool mNeedsAsyncDestroy
: 1;
341 bool mHideCalled
: 1;
342 // True when the object is created for an element which the parser has
343 // created using NS_FROM_PARSER_NETWORK flag. If the element is modified,
344 // it may lose the flag.
345 bool mNetworkCreated
: 1;
347 bool mRemoteBrowserShown
: 1;
348 bool mRemoteFrame
: 1;
349 bool mClipSubdocument
: 1;
350 bool mClampScrollPosition
: 1;
351 bool mRemoteBrowserInitialized
: 1;
352 bool mObservingOwnerContent
: 1;
354 // Backs nsIFrameLoader::{Get,Set}Visible. Visibility state here relates to
355 // whether this frameloader's <iframe mozbrowser> is setVisible(true)'ed, and
356 // doesn't necessarily correlate with docshell/document visibility.
359 // The ContentParent associated with mRemoteBrowser. This was added as a
360 // strong ref in bug 545237, and we're not sure if we can get rid of it.
361 nsRefPtr
<mozilla::dom::nsIContentParent
> mContentParent
;
362 RenderFrameParent
* mCurrentRemoteFrame
;
363 TabParent
* mRemoteBrowser
;
366 // See nsIFrameLoader.idl. Short story, if !(mRenderMode &
367 // RENDER_MODE_ASYNC_SCROLL), all the fields below are ignored in
368 // favor of what content tells.
369 uint32_t mRenderMode
;
371 // See nsIFrameLoader.idl. EVENT_MODE_NORMAL_DISPATCH automatically
372 // forwards some input events to out-of-process content.
375 // Indicate if we have sent 'remote-browser-pending'.
376 bool mPendingFrameSent
;