Thu, 15 Jan 2015 21:03:48 +0100
Integrate friendly tips from Tor colleagues to make (or not) 4.5 alpha 3;
This includes removal of overloaded (but unused) methods, and addition of
a overlooked call to DataStruct::SetData(nsISupports, uint32_t, bool.)
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/. */
6 /*
7 * Class for managing loading of a subframe (creation of the docshell,
8 * handling of loads in it, recursion-checking).
9 */
11 #ifndef nsFrameLoader_h_
12 #define nsFrameLoader_h_
14 #include "nsIDocShell.h"
15 #include "nsStringFwd.h"
16 #include "nsIFrameLoader.h"
17 #include "nsPoint.h"
18 #include "nsSize.h"
19 #include "nsIURI.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"
27 class nsIURI;
28 class nsSubDocumentFrame;
29 class nsView;
30 class nsIInProcessContentFrameMessageManager;
31 class AutoResetInShow;
32 class nsITabParent;
33 class nsIDocShellTreeItem;
34 class nsIDocShellTreeOwner;
35 class mozIApplication;
37 namespace mozilla {
38 namespace dom {
39 class ContentParent;
40 class PBrowserParent;
41 class TabParent;
42 struct StructuredCloneData;
43 }
45 namespace layout {
46 class RenderFrameParent;
47 }
48 }
50 #if defined(MOZ_WIDGET_GTK)
51 typedef struct _GtkWidget GtkWidget;
52 #endif
53 #ifdef MOZ_WIDGET_QT
54 class QX11EmbedContainer;
55 #endif
57 /**
58 * Defines a target configuration for this <browser>'s content
59 * document's view. If the content document's actual view
60 * doesn't match this nsIContentView, then on paints its pixels
61 * are transformed to compensate for the difference.
62 *
63 * Used to support asynchronous re-paints of content pixels; see
64 * nsIContentView.
65 */
66 class nsContentView MOZ_FINAL : public nsIContentView
67 {
68 public:
69 typedef mozilla::layers::FrameMetrics::ViewID ViewID;
70 NS_DECL_ISUPPORTS
71 NS_DECL_NSICONTENTVIEW
73 struct ViewConfig {
74 ViewConfig()
75 : mScrollOffset(0, 0)
76 , mXScale(1.0)
77 , mYScale(1.0)
78 {}
80 // Default copy ctor and operator= are fine
82 bool operator==(const ViewConfig& aOther) const
83 {
84 return (mScrollOffset == aOther.mScrollOffset &&
85 mXScale == aOther.mXScale &&
86 mYScale == aOther.mYScale);
87 }
89 // This is the scroll offset the <browser> user wishes or expects
90 // its enclosed content document to have. "Scroll offset" here
91 // means the document pixel at pixel (0,0) within the CSS
92 // viewport. If the content document's actual scroll offset
93 // doesn't match |mScrollOffset|, the difference is used to define
94 // a translation transform when painting the content document.
95 nsPoint mScrollOffset;
96 // The scale at which the <browser> user wishes to paint its
97 // enclosed content document. If content-document layers have a
98 // lower or higher resolution than the desired scale, then the
99 // ratio is used to define a scale transform when painting the
100 // content document.
101 float mXScale;
102 float mYScale;
103 };
105 nsContentView(nsFrameLoader* aFrameLoader, ViewID aScrollId, bool aIsRoot,
106 ViewConfig aConfig = ViewConfig())
107 : mViewportSize(0, 0)
108 , mContentSize(0, 0)
109 , mParentScaleX(1.0)
110 , mParentScaleY(1.0)
111 , mFrameLoader(aFrameLoader)
112 , mScrollId(aScrollId)
113 , mIsRoot(aIsRoot)
114 , mConfig(aConfig)
115 {}
117 bool IsRoot() const
118 {
119 return mIsRoot;
120 }
122 ViewID GetId() const
123 {
124 return mScrollId;
125 }
127 ViewConfig GetViewConfig() const
128 {
129 return mConfig;
130 }
132 nsSize mViewportSize;
133 nsSize mContentSize;
134 float mParentScaleX;
135 float mParentScaleY;
137 nsFrameLoader* mFrameLoader; // WEAK
139 private:
140 nsresult Update(const ViewConfig& aConfig);
142 ViewID mScrollId;
143 bool mIsRoot;
144 ViewConfig mConfig;
145 };
148 class nsFrameLoader MOZ_FINAL : public nsIFrameLoader,
149 public nsIContentViewManager,
150 public nsStubMutationObserver,
151 public mozilla::dom::ipc::MessageManagerCallback
152 {
153 friend class AutoResetInShow;
154 typedef mozilla::dom::PBrowserParent PBrowserParent;
155 typedef mozilla::dom::TabParent TabParent;
156 typedef mozilla::layout::RenderFrameParent RenderFrameParent;
158 protected:
159 nsFrameLoader(mozilla::dom::Element* aOwner, bool aNetworkCreated);
161 public:
162 ~nsFrameLoader();
164 bool AsyncScrollEnabled() const
165 {
166 return !!(mRenderMode & RENDER_MODE_ASYNC_SCROLL);
167 }
169 static nsFrameLoader* Create(mozilla::dom::Element* aOwner,
170 bool aNetworkCreated);
172 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
173 NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsFrameLoader, nsIFrameLoader)
174 NS_DECL_NSIFRAMELOADER
175 NS_DECL_NSICONTENTVIEWMANAGER
176 NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
177 NS_HIDDEN_(nsresult) CheckForRecursiveLoad(nsIURI* aURI);
178 nsresult ReallyStartLoading();
179 void Finalize();
180 nsIDocShell* GetExistingDocShell() { return mDocShell; }
181 mozilla::dom::EventTarget* GetTabChildGlobalAsEventTarget();
182 nsresult CreateStaticClone(nsIFrameLoader* aDest);
184 /**
185 * MessageManagerCallback methods that we override.
186 */
187 virtual bool DoLoadFrameScript(const nsAString& aURL,
188 bool aRunInGlobalScope) MOZ_OVERRIDE;
189 virtual bool DoSendAsyncMessage(JSContext* aCx,
190 const nsAString& aMessage,
191 const mozilla::dom::StructuredCloneData& aData,
192 JS::Handle<JSObject *> aCpows,
193 nsIPrincipal* aPrincipal) MOZ_OVERRIDE;
194 virtual bool CheckPermission(const nsAString& aPermission) MOZ_OVERRIDE;
195 virtual bool CheckManifestURL(const nsAString& aManifestURL) MOZ_OVERRIDE;
196 virtual bool CheckAppHasPermission(const nsAString& aPermission) MOZ_OVERRIDE;
198 /**
199 * Called from the layout frame associated with this frame loader;
200 * this notifies us to hook up with the widget and view.
201 */
202 bool Show(int32_t marginWidth, int32_t marginHeight,
203 int32_t scrollbarPrefX, int32_t scrollbarPrefY,
204 nsSubDocumentFrame* frame);
206 /**
207 * Called when the margin properties of the containing frame are changed.
208 */
209 void MarginsChanged(uint32_t aMarginWidth, uint32_t aMarginHeight);
211 /**
212 * Called from the layout frame associated with this frame loader, when
213 * the frame is being torn down; this notifies us that out widget and view
214 * are going away and we should unhook from them.
215 */
216 void Hide();
218 nsresult CloneForStatic(nsIFrameLoader* aOriginal);
220 // The guts of an nsIFrameLoaderOwner::SwapFrameLoader implementation. A
221 // frame loader owner needs to call this, and pass in the two references to
222 // nsRefPtrs for frame loaders that need to be swapped.
223 nsresult SwapWithOtherLoader(nsFrameLoader* aOther,
224 nsRefPtr<nsFrameLoader>& aFirstToSwap,
225 nsRefPtr<nsFrameLoader>& aSecondToSwap);
227 // When IPC is enabled, destroy any associated child process.
228 void DestroyChild();
230 /**
231 * Return the primary frame for our owning content, or null if it
232 * can't be found.
233 */
234 nsIFrame* GetPrimaryFrameOfOwningContent() const
235 {
236 return mOwnerContent ? mOwnerContent->GetPrimaryFrame() : nullptr;
237 }
239 /**
240 * Return the document that owns this, or null if we don't have
241 * an owner.
242 */
243 nsIDocument* GetOwnerDoc() const
244 { return mOwnerContent ? mOwnerContent->OwnerDoc() : nullptr; }
246 PBrowserParent* GetRemoteBrowser();
248 /**
249 * The "current" render frame is the one on which the most recent
250 * remote layer-tree transaction was executed. If no content has
251 * been drawn yet, or the remote browser doesn't have any drawn
252 * content for whatever reason, return nullptr. The returned render
253 * frame has an associated shadow layer tree.
254 *
255 * Note that the returned render frame might not be a frame
256 * constructed for this->GetURL(). This can happen, e.g., if the
257 * <browser> was just navigated to a new URL, but hasn't painted the
258 * new page yet. A render frame for the previous page may be
259 * returned. (In-process <browser> behaves similarly, and this
260 * behavior seems desirable.)
261 */
262 RenderFrameParent* GetCurrentRemoteFrame() const
263 {
264 return mCurrentRemoteFrame;
265 }
267 /**
268 * |aFrame| can be null. If non-null, it must be the remote frame
269 * on which the most recent layer transaction completed for this's
270 * <browser>.
271 */
272 void SetCurrentRemoteFrame(RenderFrameParent* aFrame)
273 {
274 mCurrentRemoteFrame = aFrame;
275 }
276 nsFrameMessageManager* GetFrameMessageManager() { return mMessageManager; }
278 mozilla::dom::Element* GetOwnerContent() { return mOwnerContent; }
279 bool ShouldClipSubdocument() { return mClipSubdocument; }
281 bool ShouldClampScrollPosition() { return mClampScrollPosition; }
283 /**
284 * Tell this FrameLoader to use a particular remote browser.
285 *
286 * This will assert if mRemoteBrowser or mCurrentRemoteFrame is non-null. In
287 * practice, this means you can't have successfully run TryRemoteBrowser() on
288 * this object, which means you can't have called ShowRemoteFrame() or
289 * ReallyStartLoading().
290 */
291 void SetRemoteBrowser(nsITabParent* aTabParent);
293 /**
294 * Stashes a detached view on the frame loader. We do this when we're
295 * destroying the nsSubDocumentFrame. If the nsSubdocumentFrame is
296 * being reframed we'll restore the detached view when it's recreated,
297 * otherwise we'll discard the old presentation and set the detached
298 * subdoc view to null. aContainerDoc is the document containing the
299 * the subdoc frame. This enables us to detect when the containing
300 * document has changed during reframe, so we can discard the presentation
301 * in that case.
302 */
303 void SetDetachedSubdocView(nsView* aDetachedView,
304 nsIDocument* aContainerDoc);
306 /**
307 * Retrieves the detached view and the document containing the view,
308 * as set by SetDetachedSubdocView().
309 */
310 nsView* GetDetachedSubdocView(nsIDocument** aContainerDoc) const;
312 /**
313 * Applies a new set of sandbox flags. These are merged with the sandbox
314 * flags from our owning content's owning document with a logical OR, this
315 * ensures that we can only add restrictions and never remove them.
316 */
317 void ApplySandboxFlags(uint32_t sandboxFlags);
319 void GetURL(nsString& aURL);
321 private:
323 void SetOwnerContent(mozilla::dom::Element* aContent);
325 bool ShouldUseRemoteProcess();
327 /**
328 * Is this a frameloader for a bona fide <iframe mozbrowser> or
329 * <iframe mozapp>? (I.e., does the frame return true for
330 * nsIMozBrowserFrame::GetReallyIsBrowserOrApp()?)
331 */
332 bool OwnerIsBrowserOrAppFrame();
334 /**
335 * Is this a frameloader for a bona fide <iframe mozapp>? (I.e., does the
336 * frame return true for nsIMozBrowserFrame::GetReallyIsApp()?)
337 */
338 bool OwnerIsAppFrame();
340 /**
341 * Is this a frame loader for a bona fide <iframe mozbrowser>?
342 */
343 bool OwnerIsBrowserFrame();
345 /**
346 * Get our owning element's app manifest URL, or return the empty string if
347 * our owning element doesn't have an app manifest URL.
348 */
349 void GetOwnerAppManifestURL(nsAString& aOut);
351 /**
352 * Get the app for our frame. This is the app whose manifest is returned by
353 * GetOwnerAppManifestURL.
354 */
355 already_AddRefed<mozIApplication> GetOwnApp();
357 /**
358 * Get the app which contains this frame. This is the app associated with
359 * the frame element's principal.
360 */
361 already_AddRefed<mozIApplication> GetContainingApp();
363 /**
364 * If we are an IPC frame, set mRemoteFrame. Otherwise, create and
365 * initialize mDocShell.
366 */
367 nsresult MaybeCreateDocShell();
368 nsresult EnsureMessageManager();
370 // Properly retrieves documentSize of any subdocument type.
371 nsresult GetWindowDimensions(nsRect& aRect);
373 // Updates the subdocument position and size. This gets called only
374 // when we have our own in-process DocShell.
375 NS_HIDDEN_(nsresult) UpdateBaseWindowPositionAndSize(nsSubDocumentFrame *aIFrame);
376 nsresult CheckURILoad(nsIURI* aURI);
377 void FireErrorEvent();
378 nsresult ReallyStartLoadingInternal();
380 // Return true if remote browser created; nothing else to do
381 bool TryRemoteBrowser();
383 // Tell the remote browser that it's now "virtually visible"
384 bool ShowRemoteFrame(const nsIntSize& size,
385 nsSubDocumentFrame *aFrame = nullptr);
387 bool AddTreeItemToTreeOwner(nsIDocShellTreeItem* aItem,
388 nsIDocShellTreeOwner* aOwner,
389 int32_t aParentType,
390 nsIDocShell* aParentNode);
392 nsIAtom* TypeAttrName() const {
393 return mOwnerContent->IsXUL() ? nsGkAtoms::type : nsGkAtoms::mozframetype;
394 }
396 // Update the permission manager's app-id refcount based on mOwnerContent's
397 // own-or-containing-app.
398 void ResetPermissionManagerStatus();
400 nsCOMPtr<nsIDocShell> mDocShell;
401 nsCOMPtr<nsIURI> mURIToLoad;
402 mozilla::dom::Element* mOwnerContent; // WEAK
404 // Note: this variable must be modified only by ResetPermissionManagerStatus()
405 uint32_t mAppIdSentToPermissionManager;
407 public:
408 // public because a callback needs these.
409 nsRefPtr<nsFrameMessageManager> mMessageManager;
410 nsCOMPtr<nsIInProcessContentFrameMessageManager> mChildMessageManager;
411 private:
412 // Stores the root view of the subdocument while the subdocument is being
413 // reframed. Used to restore the presentation after reframing.
414 nsView* mDetachedSubdocViews;
415 // Stores the containing document of the frame corresponding to this
416 // frame loader. This is reference is kept valid while the subframe's
417 // presentation is detached and stored in mDetachedSubdocViews. This
418 // enables us to detect whether the frame has moved documents during
419 // a reframe, so that we know not to restore the presentation.
420 nsCOMPtr<nsIDocument> mContainerDocWhileDetached;
422 bool mDepthTooGreat : 1;
423 bool mIsTopLevelContent : 1;
424 bool mDestroyCalled : 1;
425 bool mNeedsAsyncDestroy : 1;
426 bool mInSwap : 1;
427 bool mInShow : 1;
428 bool mHideCalled : 1;
429 // True when the object is created for an element which the parser has
430 // created using NS_FROM_PARSER_NETWORK flag. If the element is modified,
431 // it may lose the flag.
432 bool mNetworkCreated : 1;
434 bool mRemoteBrowserShown : 1;
435 bool mRemoteFrame : 1;
436 bool mClipSubdocument : 1;
437 bool mClampScrollPosition : 1;
438 bool mRemoteBrowserInitialized : 1;
439 bool mObservingOwnerContent : 1;
441 // Backs nsIFrameLoader::{Get,Set}Visible. Visibility state here relates to
442 // whether this frameloader's <iframe mozbrowser> is setVisible(true)'ed, and
443 // doesn't necessarily correlate with docshell/document visibility.
444 bool mVisible : 1;
446 // The ContentParent associated with mRemoteBrowser. This was added as a
447 // strong ref in bug 545237, and we're not sure if we can get rid of it.
448 nsRefPtr<mozilla::dom::ContentParent> mContentParent;
449 RenderFrameParent* mCurrentRemoteFrame;
450 TabParent* mRemoteBrowser;
451 uint64_t mChildID;
453 // See nsIFrameLoader.idl. Short story, if !(mRenderMode &
454 // RENDER_MODE_ASYNC_SCROLL), all the fields below are ignored in
455 // favor of what content tells.
456 uint32_t mRenderMode;
458 // See nsIFrameLoader.idl. EVENT_MODE_NORMAL_DISPATCH automatically
459 // forwards some input events to out-of-process content.
460 uint32_t mEventMode;
462 // Indicate if we have sent 'remote-browser-pending'.
463 bool mPendingFrameSent;
464 };
466 #endif