1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is Mozilla Communicator client code.
16 : *
17 : * The Initial Developer of the Original Code is
18 : * Netscape Communications Corporation.
19 : * Portions created by the Initial Developer are Copyright (C) 1998
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : * Johnny Stenback <jst@netscape.com> (original author)
24 : *
25 : * Alternatively, the contents of this file may be used under the terms of
26 : * either of the GNU General Public License Version 2 or later (the "GPL"),
27 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 : * in which case the provisions of the GPL or the LGPL are applicable instead
29 : * of those above. If you wish to allow use of your version of this file only
30 : * under the terms of either the GPL or the LGPL, and not to allow others to
31 : * use your version of this file under the terms of the MPL, indicate your
32 : * decision by deleting the provisions above and replace them with the notice
33 : * and other provisions required by the GPL or the LGPL. If you do not delete
34 : * the provisions above, a recipient may use your version of this file under
35 : * the terms of any one of the MPL, the GPL or the LGPL.
36 : *
37 : * ***** END LICENSE BLOCK ***** */
38 :
39 : /*
40 : * Class for managing loading of a subframe (creation of the docshell,
41 : * handling of loads in it, recursion-checking).
42 : */
43 :
44 : #ifndef nsFrameLoader_h_
45 : #define nsFrameLoader_h_
46 :
47 : #include "nsIDocShell.h"
48 : #include "nsStringFwd.h"
49 : #include "nsIFrameLoader.h"
50 : #include "nsPoint.h"
51 : #include "nsSize.h"
52 : #include "nsIURI.h"
53 : #include "nsAutoPtr.h"
54 : #include "nsFrameMessageManager.h"
55 : #include "Layers.h"
56 : #include "mozilla/dom/Element.h"
57 :
58 : class nsIURI;
59 : class nsSubDocumentFrame;
60 : class nsIView;
61 : class nsIInProcessContentFrameMessageManager;
62 : class AutoResetInShow;
63 :
64 : namespace mozilla {
65 : namespace dom {
66 : class PBrowserParent;
67 : class TabParent;
68 : }
69 :
70 : namespace layout {
71 : class RenderFrameParent;
72 : }
73 : }
74 :
75 : #ifdef MOZ_WIDGET_GTK2
76 : typedef struct _GtkWidget GtkWidget;
77 : #endif
78 : #ifdef MOZ_WIDGET_QT
79 : class QX11EmbedContainer;
80 : #endif
81 :
82 : /**
83 : * Defines a target configuration for this <browser>'s content
84 : * document's view. If the content document's actual view
85 : * doesn't match this nsIContentView, then on paints its pixels
86 : * are transformed to compensate for the difference.
87 : *
88 : * Used to support asynchronous re-paints of content pixels; see
89 : * nsIContentView.
90 : */
91 : class nsContentView : public nsIContentView
92 : {
93 : public:
94 : typedef mozilla::layers::FrameMetrics::ViewID ViewID;
95 : NS_DECL_ISUPPORTS
96 : NS_DECL_NSICONTENTVIEW
97 :
98 0 : struct ViewConfig {
99 0 : ViewConfig()
100 : : mScrollOffset(0, 0)
101 : , mXScale(1.0)
102 0 : , mYScale(1.0)
103 0 : {}
104 :
105 : // Default copy ctor and operator= are fine
106 :
107 0 : bool operator==(const ViewConfig& aOther) const
108 : {
109 0 : return (mScrollOffset == aOther.mScrollOffset &&
110 : mXScale == aOther.mXScale &&
111 0 : mYScale == aOther.mYScale);
112 : }
113 :
114 : // This is the scroll offset the <browser> user wishes or expects
115 : // its enclosed content document to have. "Scroll offset" here
116 : // means the document pixel at pixel (0,0) within the CSS
117 : // viewport. If the content document's actual scroll offset
118 : // doesn't match |mScrollOffset|, the difference is used to define
119 : // a translation transform when painting the content document.
120 : nsPoint mScrollOffset;
121 : // The scale at which the <browser> user wishes to paint its
122 : // enclosed content document. If content-document layers have a
123 : // lower or higher resolution than the desired scale, then the
124 : // ratio is used to define a scale transform when painting the
125 : // content document.
126 : float mXScale;
127 : float mYScale;
128 : };
129 :
130 0 : nsContentView(nsFrameLoader* aFrameLoader, ViewID aScrollId,
131 : ViewConfig aConfig = ViewConfig())
132 : : mViewportSize(0, 0)
133 : , mContentSize(0, 0)
134 : , mParentScaleX(1.0)
135 : , mParentScaleY(1.0)
136 : , mFrameLoader(aFrameLoader)
137 : , mScrollId(aScrollId)
138 0 : , mConfig(aConfig)
139 0 : {}
140 :
141 : bool IsRoot() const;
142 :
143 : ViewID GetId() const
144 : {
145 : return mScrollId;
146 : }
147 :
148 0 : ViewConfig GetViewConfig() const
149 : {
150 0 : return mConfig;
151 : }
152 :
153 : nsSize mViewportSize;
154 : nsSize mContentSize;
155 : float mParentScaleX;
156 : float mParentScaleY;
157 :
158 : nsFrameLoader* mFrameLoader; // WEAK
159 :
160 : private:
161 : nsresult Update(const ViewConfig& aConfig);
162 :
163 : ViewID mScrollId;
164 : ViewConfig mConfig;
165 : };
166 :
167 :
168 : class nsFrameLoader : public nsIFrameLoader,
169 : public nsIContentViewManager
170 : {
171 : friend class AutoResetInShow;
172 : typedef mozilla::dom::PBrowserParent PBrowserParent;
173 : typedef mozilla::dom::TabParent TabParent;
174 : typedef mozilla::layout::RenderFrameParent RenderFrameParent;
175 :
176 : protected:
177 : nsFrameLoader(mozilla::dom::Element* aOwner, bool aNetworkCreated);
178 :
179 : public:
180 0 : ~nsFrameLoader() {
181 0 : mNeedsAsyncDestroy = true;
182 0 : if (mMessageManager) {
183 0 : mMessageManager->Disconnect();
184 : }
185 0 : nsFrameLoader::Destroy();
186 0 : }
187 :
188 0 : bool AsyncScrollEnabled() const
189 : {
190 0 : return !!(mRenderMode & RENDER_MODE_ASYNC_SCROLL);
191 : }
192 :
193 : static nsFrameLoader* Create(mozilla::dom::Element* aOwner,
194 : bool aNetworkCreated);
195 :
196 0 : NS_DECL_CYCLE_COLLECTING_ISUPPORTS
197 1464 : NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsFrameLoader, nsIFrameLoader)
198 : NS_DECL_NSIFRAMELOADER
199 : NS_DECL_NSICONTENTVIEWMANAGER
200 : NS_HIDDEN_(nsresult) CheckForRecursiveLoad(nsIURI* aURI);
201 : nsresult ReallyStartLoading();
202 : void Finalize();
203 0 : nsIDocShell* GetExistingDocShell() { return mDocShell; }
204 : nsIDOMEventTarget* GetTabChildGlobalAsEventTarget();
205 : nsresult CreateStaticClone(nsIFrameLoader* aDest);
206 :
207 : /**
208 : * Called from the layout frame associated with this frame loader;
209 : * this notifies us to hook up with the widget and view.
210 : */
211 : bool Show(PRInt32 marginWidth, PRInt32 marginHeight,
212 : PRInt32 scrollbarPrefX, PRInt32 scrollbarPrefY,
213 : nsSubDocumentFrame* frame);
214 :
215 : /**
216 : * Called when the margin properties of the containing frame are changed.
217 : */
218 : void MarginsChanged(PRUint32 aMarginWidth, PRUint32 aMarginHeight);
219 :
220 : /**
221 : * Called from the layout frame associated with this frame loader, when
222 : * the frame is being torn down; this notifies us that out widget and view
223 : * are going away and we should unhook from them.
224 : */
225 : void Hide();
226 :
227 : nsresult CloneForStatic(nsIFrameLoader* aOriginal);
228 :
229 : // The guts of an nsIFrameLoaderOwner::SwapFrameLoader implementation. A
230 : // frame loader owner needs to call this, and pass in the two references to
231 : // nsRefPtrs for frame loaders that need to be swapped.
232 : nsresult SwapWithOtherLoader(nsFrameLoader* aOther,
233 : nsRefPtr<nsFrameLoader>& aFirstToSwap,
234 : nsRefPtr<nsFrameLoader>& aSecondToSwap);
235 :
236 : // When IPC is enabled, destroy any associated child process.
237 : void DestroyChild();
238 :
239 : /**
240 : * Return the primary frame for our owning content, or null if it
241 : * can't be found.
242 : */
243 0 : nsIFrame* GetPrimaryFrameOfOwningContent() const
244 : {
245 0 : return mOwnerContent ? mOwnerContent->GetPrimaryFrame() : nsnull;
246 : }
247 :
248 : /**
249 : * Return the document that owns this, or null if we don't have
250 : * an owner.
251 : */
252 0 : nsIDocument* OwnerDoc() const
253 0 : { return mOwnerContent ? mOwnerContent->OwnerDoc() : nsnull; }
254 :
255 : PBrowserParent* GetRemoteBrowser();
256 :
257 : /**
258 : * The "current" render frame is the one on which the most recent
259 : * remote layer-tree transaction was executed. If no content has
260 : * been drawn yet, or the remote browser doesn't have any drawn
261 : * content for whatever reason, return NULL. The returned render
262 : * frame has an associated shadow layer tree.
263 : *
264 : * Note that the returned render frame might not be a frame
265 : * constructed for this->GetURL(). This can happen, e.g., if the
266 : * <browser> was just navigated to a new URL, but hasn't painted the
267 : * new page yet. A render frame for the previous page may be
268 : * returned. (In-process <browser> behaves similarly, and this
269 : * behavior seems desirable.)
270 : */
271 0 : RenderFrameParent* GetCurrentRemoteFrame() const
272 : {
273 0 : return mCurrentRemoteFrame;
274 : }
275 :
276 : /**
277 : * |aFrame| can be null. If non-null, it must be the remote frame
278 : * on which the most recent layer transaction completed for this's
279 : * <browser>.
280 : */
281 0 : void SetCurrentRemoteFrame(RenderFrameParent* aFrame)
282 : {
283 0 : mCurrentRemoteFrame = aFrame;
284 0 : }
285 0 : nsFrameMessageManager* GetFrameMessageManager() { return mMessageManager; }
286 :
287 0 : mozilla::dom::Element* GetOwnerContent() { return mOwnerContent; }
288 : void SetOwnerContent(mozilla::dom::Element* aContent);
289 :
290 0 : bool ShouldClipSubdocument() { return mClipSubdocument; }
291 :
292 0 : bool ShouldClampScrollPosition() { return mClampScrollPosition; }
293 :
294 : private:
295 :
296 : bool ShouldUseRemoteProcess();
297 :
298 : /**
299 : * If we are an IPC frame, set mRemoteFrame. Otherwise, create and
300 : * initialize mDocShell.
301 : */
302 : nsresult MaybeCreateDocShell();
303 : nsresult EnsureMessageManager();
304 : NS_HIDDEN_(void) GetURL(nsString& aURL);
305 :
306 : // Properly retrieves documentSize of any subdocument type.
307 : NS_HIDDEN_(nsIntSize) GetSubDocumentSize(const nsIFrame *aIFrame);
308 : nsresult GetWindowDimensions(nsRect& aRect);
309 :
310 : // Updates the subdocument position and size. This gets called only
311 : // when we have our own in-process DocShell.
312 : NS_HIDDEN_(nsresult) UpdateBaseWindowPositionAndSize(nsIFrame *aIFrame);
313 : nsresult CheckURILoad(nsIURI* aURI);
314 : void FireErrorEvent();
315 : nsresult ReallyStartLoadingInternal();
316 :
317 : // Return true if remote browser created; nothing else to do
318 : bool TryRemoteBrowser();
319 :
320 : // Tell the remote browser that it's now "virtually visible"
321 : bool ShowRemoteFrame(const nsIntSize& size);
322 :
323 : nsCOMPtr<nsIDocShell> mDocShell;
324 : nsCOMPtr<nsIURI> mURIToLoad;
325 : mozilla::dom::Element* mOwnerContent; // WEAK
326 : public:
327 : // public because a callback needs these.
328 : nsRefPtr<nsFrameMessageManager> mMessageManager;
329 : nsCOMPtr<nsIInProcessContentFrameMessageManager> mChildMessageManager;
330 : private:
331 : bool mDepthTooGreat : 1;
332 : bool mIsTopLevelContent : 1;
333 : bool mDestroyCalled : 1;
334 : bool mNeedsAsyncDestroy : 1;
335 : bool mInSwap : 1;
336 : bool mInShow : 1;
337 : bool mHideCalled : 1;
338 : // True when the object is created for an element which the parser has
339 : // created using NS_FROM_PARSER_NETWORK flag. If the element is modified,
340 : // it may lose the flag.
341 : bool mNetworkCreated : 1;
342 :
343 : bool mDelayRemoteDialogs : 1;
344 : bool mRemoteBrowserShown : 1;
345 : bool mRemoteFrame : 1;
346 : bool mClipSubdocument : 1;
347 : bool mClampScrollPosition : 1;
348 :
349 : // XXX leaking
350 : nsCOMPtr<nsIObserver> mChildHost;
351 : RenderFrameParent* mCurrentRemoteFrame;
352 : TabParent* mRemoteBrowser;
353 :
354 : // See nsIFrameLoader.idl. Short story, if !(mRenderMode &
355 : // RENDER_MODE_ASYNC_SCROLL), all the fields below are ignored in
356 : // favor of what content tells.
357 : PRUint32 mRenderMode;
358 :
359 : // See nsIFrameLoader.idl. EVENT_MODE_NORMAL_DISPATCH automatically
360 : // forwards some input events to out-of-process content.
361 : PRUint32 mEventMode;
362 : };
363 :
364 : #endif
|