1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 : * vim: set ts=4 sw=4 et tw=80:
3 : *
4 : * ***** BEGIN LICENSE BLOCK *****
5 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 : *
7 : * The contents of this file are subject to the Mozilla Public License Version
8 : * 1.1 (the "License"); you may not use this file except in compliance with
9 : * the License. You may obtain a copy of the License at
10 : * http://www.mozilla.org/MPL/
11 : *
12 : * Software distributed under the License is distributed on an "AS IS" basis,
13 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 : * for the specific language governing rights and limitations under the
15 : * License.
16 : *
17 : * The Original Code is the Mozilla browser.
18 : *
19 : * The Initial Developer of the Original Code is
20 : * Netscape Communications, Inc.
21 : * Portions created by the Initial Developer are Copyright (C) 1999
22 : * the Initial Developer. All Rights Reserved.
23 : *
24 : * Contributor(s):
25 : * Travis Bogard <travis@netscape.com>
26 : *
27 : * Alternatively, the contents of this file may be used under the terms of
28 : * either of the GNU General Public License Version 2 or later (the "GPL"),
29 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
30 : * in which case the provisions of the GPL or the LGPL are applicable instead
31 : * of those above. If you wish to allow use of your version of this file only
32 : * under the terms of either the GPL or the LGPL, and not to allow others to
33 : * use your version of this file under the terms of the MPL, indicate your
34 : * decision by deleting the provisions above and replace them with the notice
35 : * and other provisions required by the GPL or the LGPL. If you do not delete
36 : * the provisions above, a recipient may use your version of this file under
37 : * the terms of any one of the MPL, the GPL or the LGPL.
38 : *
39 : * ***** END LICENSE BLOCK ***** */
40 :
41 : #ifndef nsDocShell_h__
42 : #define nsDocShell_h__
43 :
44 : #include "nsIDOMNode.h"
45 : #include "nsIDOMNodeList.h"
46 : #include "nsIContentViewer.h"
47 : #include "nsInterfaceHashtable.h"
48 : #include "nsIScriptContext.h"
49 : #include "nsITimer.h"
50 :
51 : #include "nsIDocShell.h"
52 : #include "nsIDocShellTreeItem.h"
53 : #include "nsIDocShellTreeNode.h"
54 : #include "nsIBaseWindow.h"
55 : #include "nsIScrollable.h"
56 : #include "nsITextScroll.h"
57 : #include "nsIDocShellTreeOwner.h"
58 : #include "nsIContentViewerContainer.h"
59 :
60 : #include "nsDocLoader.h"
61 : #include "nsIURILoader.h"
62 : #include "nsIEditorDocShell.h"
63 :
64 : #include "nsWeakReference.h"
65 :
66 : // Local Includes
67 : #include "nsDSURIContentListener.h"
68 : #include "nsDocShellEditorData.h"
69 :
70 : // Helper Classes
71 : #include "nsCOMPtr.h"
72 : #include "nsPoint.h" // mCurrent/mDefaultScrollbarPreferences
73 : #include "nsString.h"
74 : #include "nsAutoPtr.h"
75 : #include "nsThreadUtils.h"
76 :
77 : // Threshold value in ms for META refresh based redirects
78 : #define REFRESH_REDIRECT_TIMER 15000
79 :
80 : // Interfaces Needed
81 : #include "nsIDocCharset.h"
82 : #include "nsIGlobalHistory2.h"
83 : #include "nsIInterfaceRequestor.h"
84 : #include "nsIInterfaceRequestorUtils.h"
85 : #include "nsIPrompt.h"
86 : #include "nsIRefreshURI.h"
87 : #include "nsIScriptGlobalObject.h"
88 : #include "nsIScriptGlobalObjectOwner.h"
89 : #include "nsISHistory.h"
90 : #include "nsILayoutHistoryState.h"
91 : #include "nsIStringBundle.h"
92 : #include "nsISupportsArray.h"
93 : #include "nsIWebNavigation.h"
94 : #include "nsIWebPageDescriptor.h"
95 : #include "nsIWebProgressListener.h"
96 : #include "nsISHContainer.h"
97 : #include "nsIDocShellLoadInfo.h"
98 : #include "nsIDocShellHistory.h"
99 : #include "nsIURIFixup.h"
100 : #include "nsIWebBrowserFind.h"
101 : #include "nsIHttpChannel.h"
102 : #include "nsDocShellTransferableHooks.h"
103 : #include "nsIAuthPromptProvider.h"
104 : #include "nsISecureBrowserUI.h"
105 : #include "nsIObserver.h"
106 : #include "nsDocShellLoadTypes.h"
107 : #include "nsIDOMEventTarget.h"
108 : #include "nsILoadContext.h"
109 : #include "nsIWidget.h"
110 : #include "nsIWebShellServices.h"
111 : #include "nsILinkHandler.h"
112 : #include "nsIClipboardCommands.h"
113 : #include "nsICommandManager.h"
114 : #include "nsCRT.h"
115 :
116 : class nsDocShell;
117 : class nsIController;
118 : class OnLinkClickEvent;
119 : class nsIScrollableFrame;
120 : class nsDOMNavigationTiming;
121 :
122 : /* load commands were moved to nsIDocShell.h */
123 : /* load types were moved to nsDocShellLoadTypes.h */
124 :
125 : /* internally used ViewMode types */
126 : enum ViewMode {
127 : viewNormal = 0x0,
128 : viewSource = 0x1
129 : };
130 :
131 : //*****************************************************************************
132 : //*** nsRefreshTimer
133 : //*****************************************************************************
134 :
135 : class nsRefreshTimer : public nsITimerCallback
136 : {
137 : public:
138 : nsRefreshTimer();
139 :
140 : NS_DECL_ISUPPORTS
141 : NS_DECL_NSITIMERCALLBACK
142 :
143 0 : PRInt32 GetDelay() { return mDelay ;}
144 :
145 : nsRefPtr<nsDocShell> mDocShell;
146 : nsCOMPtr<nsIURI> mURI;
147 : PRInt32 mDelay;
148 : bool mRepeat;
149 : bool mMetaRefresh;
150 :
151 : protected:
152 : virtual ~nsRefreshTimer();
153 : };
154 :
155 : #define NS_ERROR_DOCSHELL_REQUEST_REJECTED NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_GENERAL,1001)
156 :
157 : typedef enum {
158 : eCharsetReloadInit,
159 : eCharsetReloadRequested,
160 : eCharsetReloadStopOrigional
161 : } eCharsetReloadState;
162 :
163 : //*****************************************************************************
164 : //*** nsDocShell
165 : //*****************************************************************************
166 :
167 : class nsDocShell : public nsDocLoader,
168 : public nsIDocShell,
169 : public nsIDocShellTreeItem,
170 : public nsIDocShellHistory,
171 : public nsIWebNavigation,
172 : public nsIBaseWindow,
173 : public nsIScrollable,
174 : public nsITextScroll,
175 : public nsIDocCharset,
176 : public nsIContentViewerContainer,
177 : public nsIScriptGlobalObjectOwner,
178 : public nsIRefreshURI,
179 : public nsIWebProgressListener,
180 : public nsIEditorDocShell,
181 : public nsIWebPageDescriptor,
182 : public nsIAuthPromptProvider,
183 : public nsIObserver,
184 : public nsILoadContext,
185 : public nsIWebShellServices,
186 : public nsILinkHandler,
187 : public nsIClipboardCommands
188 : {
189 : friend class nsDSURIContentListener;
190 :
191 : public:
192 : // Object Management
193 : nsDocShell();
194 :
195 0 : NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
196 :
197 : virtual nsresult Init();
198 :
199 : NS_DECL_ISUPPORTS_INHERITED
200 :
201 : NS_DECL_NSIDOCSHELL
202 : NS_DECL_NSIDOCSHELLTREEITEM
203 : NS_DECL_NSIDOCSHELLTREENODE
204 : NS_DECL_NSIDOCSHELLHISTORY
205 : NS_DECL_NSIWEBNAVIGATION
206 : NS_DECL_NSIBASEWINDOW
207 : NS_DECL_NSISCROLLABLE
208 : NS_DECL_NSITEXTSCROLL
209 : NS_DECL_NSIDOCCHARSET
210 : NS_DECL_NSIINTERFACEREQUESTOR
211 : NS_DECL_NSIWEBPROGRESSLISTENER
212 : NS_DECL_NSIREFRESHURI
213 : NS_DECL_NSICONTENTVIEWERCONTAINER
214 : NS_DECL_NSIEDITORDOCSHELL
215 : NS_DECL_NSIWEBPAGEDESCRIPTOR
216 : NS_DECL_NSIAUTHPROMPTPROVIDER
217 : NS_DECL_NSIOBSERVER
218 : NS_DECL_NSILOADCONTEXT
219 : NS_DECL_NSICLIPBOARDCOMMANDS
220 : NS_DECL_NSIWEBSHELLSERVICES
221 :
222 0 : NS_IMETHOD Stop() {
223 : // Need this here because otherwise nsIWebNavigation::Stop
224 : // overrides the docloader's Stop()
225 0 : return nsDocLoader::Stop();
226 : }
227 :
228 : // Need to implement (and forward) nsISecurityEventSink, because
229 : // nsIWebProgressListener has methods with identical names...
230 0 : NS_FORWARD_NSISECURITYEVENTSINK(nsDocLoader::)
231 :
232 : // nsILinkHandler
233 : NS_IMETHOD OnLinkClick(nsIContent* aContent,
234 : nsIURI* aURI,
235 : const PRUnichar* aTargetSpec,
236 : nsIInputStream* aPostDataStream,
237 : nsIInputStream* aHeadersDataStream,
238 : bool aIsTrusted);
239 : NS_IMETHOD OnLinkClickSync(nsIContent* aContent,
240 : nsIURI* aURI,
241 : const PRUnichar* aTargetSpec,
242 : nsIInputStream* aPostDataStream = 0,
243 : nsIInputStream* aHeadersDataStream = 0,
244 : nsIDocShell** aDocShell = 0,
245 : nsIRequest** aRequest = 0);
246 : NS_IMETHOD OnOverLink(nsIContent* aContent,
247 : nsIURI* aURI,
248 : const PRUnichar* aTargetSpec);
249 : NS_IMETHOD OnLeaveLink();
250 :
251 : nsDocShellInfoLoadType ConvertLoadTypeToDocShellLoadInfo(PRUint32 aLoadType);
252 : PRUint32 ConvertDocShellLoadInfoToLoadType(nsDocShellInfoLoadType aDocShellLoadType);
253 :
254 : // nsIScriptGlobalObjectOwner methods
255 : virtual nsIScriptGlobalObject* GetScriptGlobalObject();
256 :
257 : // Restores a cached presentation from history (mLSHE).
258 : // This method swaps out the content viewer and simulates loads for
259 : // subframes. It then simulates the completion of the toplevel load.
260 : nsresult RestoreFromHistory();
261 :
262 : // Perform a URI load from a refresh timer. This is just like the
263 : // ForceRefreshURI method on nsIRefreshURI, but makes sure to take
264 : // the timer involved out of mRefreshURIList if it's there.
265 : // aTimer must not be null.
266 : nsresult ForceRefreshURIFromTimer(nsIURI * aURI, PRInt32 aDelay,
267 : bool aMetaRefresh, nsITimer* aTimer);
268 :
269 : friend class OnLinkClickEvent;
270 :
271 : // We need dummy OnLocationChange in some cases to update the UI without
272 : // updating security info.
273 0 : void FireDummyOnLocationChange()
274 : {
275 : FireOnLocationChange(this, nsnull, mCurrentURI,
276 0 : LOCATION_CHANGE_SAME_DOCUMENT);
277 0 : }
278 :
279 : nsresult HistoryTransactionRemoved(PRInt32 aIndex);
280 : protected:
281 : // Object Management
282 : virtual ~nsDocShell();
283 : virtual void DestroyChildren();
284 :
285 : // Content Viewer Management
286 : NS_IMETHOD EnsureContentViewer();
287 : // aPrincipal can be passed in if the caller wants. If null is
288 : // passed in, the about:blank principal will end up being used.
289 : nsresult CreateAboutBlankContentViewer(nsIPrincipal* aPrincipal,
290 : nsIURI* aBaseURI,
291 : bool aTryToSaveOldPresentation = true);
292 : NS_IMETHOD CreateContentViewer(const char * aContentType,
293 : nsIRequest * request, nsIStreamListener ** aContentHandler);
294 : NS_IMETHOD NewContentViewerObj(const char * aContentType,
295 : nsIRequest * request, nsILoadGroup * aLoadGroup,
296 : nsIStreamListener ** aContentHandler, nsIContentViewer ** aViewer);
297 : NS_IMETHOD SetupNewViewer(nsIContentViewer * aNewViewer);
298 :
299 : void SetupReferrerFromChannel(nsIChannel * aChannel);
300 :
301 : NS_IMETHOD GetEldestPresContext(nsPresContext** aPresContext);
302 :
303 : // Get the principal that we'll set on the channel if we're inheriting. If
304 : // aConsiderCurrentDocument is true, we try to use the current document if
305 : // at all possible. If that fails, we fall back on the parent document.
306 : // If that fails too, we force creation of a content viewer and use the
307 : // resulting principal. If aConsiderCurrentDocument is false, we just look
308 : // at the parent.
309 : nsIPrincipal* GetInheritedPrincipal(bool aConsiderCurrentDocument);
310 :
311 : // True if when loading aURI into this docshell, the channel should look
312 : // for an appropriate application cache.
313 : bool ShouldCheckAppCache(nsIURI * aURI);
314 :
315 : // Actually open a channel and perform a URI load. Note: whatever owner is
316 : // passed to this function will be set on the channel. Callers who wish to
317 : // not have an owner on the channel should just pass null.
318 : virtual nsresult DoURILoad(nsIURI * aURI,
319 : nsIURI * aReferrer,
320 : bool aSendReferrer,
321 : nsISupports * aOwner,
322 : const char * aTypeHint,
323 : nsIInputStream * aPostData,
324 : nsIInputStream * aHeadersData,
325 : bool firstParty,
326 : nsIDocShell ** aDocShell,
327 : nsIRequest ** aRequest,
328 : bool aIsNewWindowTarget,
329 : bool aBypassClassifier,
330 : bool aForceAllowCookies);
331 : NS_IMETHOD AddHeadersToChannel(nsIInputStream * aHeadersData,
332 : nsIChannel * aChannel);
333 : virtual nsresult DoChannelLoad(nsIChannel * aChannel,
334 : nsIURILoader * aURILoader,
335 : bool aBypassClassifier);
336 :
337 : nsresult ScrollToAnchor(nsACString & curHash, nsACString & newHash,
338 : PRUint32 aLoadType);
339 :
340 : // Tries to serialize a given variant using structured clone. This only
341 : // works if the variant is backed by a JSVal.
342 : nsresult SerializeJSValVariant(JSContext *aCx, nsIVariant *aData,
343 : nsAString &aResult);
344 :
345 : // Returns true if would have called FireOnLocationChange,
346 : // but did not because aFireOnLocationChange was false on entry.
347 : // In this case it is the caller's responsibility to ensure
348 : // FireOnLocationChange is called.
349 : // In all other cases false is returned.
350 : bool OnLoadingSite(nsIChannel * aChannel,
351 : bool aFireOnLocationChange,
352 : bool aAddToGlobalHistory = true);
353 :
354 : // Returns true if would have called FireOnLocationChange,
355 : // but did not because aFireOnLocationChange was false on entry.
356 : // In this case it is the caller's responsibility to ensure
357 : // FireOnLocationChange is called.
358 : // In all other cases false is returned.
359 : // Either aChannel or aOwner must be null. If aChannel is
360 : // present, the owner should be gotten from it.
361 : // If OnNewURI calls AddToSessionHistory, it will pass its
362 : // aCloneSHChildren argument as aCloneChildren.
363 : bool OnNewURI(nsIURI * aURI, nsIChannel * aChannel, nsISupports* aOwner,
364 : PRUint32 aLoadType,
365 : bool aFireOnLocationChange,
366 : bool aAddToGlobalHistory,
367 : bool aCloneSHChildren);
368 :
369 : virtual void SetReferrerURI(nsIURI * aURI);
370 :
371 : // Session History
372 : virtual bool ShouldAddToSessionHistory(nsIURI * aURI);
373 : // Either aChannel or aOwner must be null. If aChannel is
374 : // present, the owner should be gotten from it.
375 : // If aCloneChildren is true, then our current session history's
376 : // children will be cloned onto the new entry. This should be
377 : // used when we aren't actually changing the document while adding
378 : // the new session history entry.
379 : virtual nsresult AddToSessionHistory(nsIURI * aURI, nsIChannel * aChannel,
380 : nsISupports* aOwner,
381 : bool aCloneChildren,
382 : nsISHEntry ** aNewEntry);
383 : nsresult DoAddChildSHEntry(nsISHEntry* aNewEntry, PRInt32 aChildOffset,
384 : bool aCloneChildren);
385 :
386 : NS_IMETHOD LoadHistoryEntry(nsISHEntry * aEntry, PRUint32 aLoadType);
387 : NS_IMETHOD PersistLayoutHistoryState();
388 :
389 : // Clone a session history tree for subframe navigation.
390 : // The tree rooted at |aSrcEntry| will be cloned into |aDestEntry|, except
391 : // for the entry with id |aCloneID|, which will be replaced with
392 : // |aReplaceEntry|. |aSrcShell| is a (possibly null) docshell which
393 : // corresponds to |aSrcEntry| via its mLSHE or mOHE pointers, and will
394 : // have that pointer updated to point to the cloned history entry.
395 : // If aCloneChildren is true then the children of the entry with id
396 : // |aCloneID| will be cloned into |aReplaceEntry|.
397 : static nsresult CloneAndReplace(nsISHEntry *aSrcEntry,
398 : nsDocShell *aSrcShell,
399 : PRUint32 aCloneID,
400 : nsISHEntry *aReplaceEntry,
401 : bool aCloneChildren,
402 : nsISHEntry **aDestEntry);
403 :
404 : // Child-walking callback for CloneAndReplace
405 : static nsresult CloneAndReplaceChild(nsISHEntry *aEntry,
406 : nsDocShell *aShell,
407 : PRInt32 aChildIndex, void *aData);
408 :
409 : nsresult GetRootSessionHistory(nsISHistory ** aReturn);
410 : nsresult GetHttpChannel(nsIChannel * aChannel, nsIHttpChannel ** aReturn);
411 : bool ShouldDiscardLayoutState(nsIHttpChannel * aChannel);
412 :
413 : // Determine whether this docshell corresponds to the given history entry,
414 : // via having a pointer to it in mOSHE or mLSHE.
415 0 : bool HasHistoryEntry(nsISHEntry *aEntry) const
416 : {
417 0 : return aEntry && (aEntry == mOSHE || aEntry == mLSHE);
418 : }
419 :
420 : // Update any pointers (mOSHE or mLSHE) to aOldEntry to point to aNewEntry
421 : void SwapHistoryEntries(nsISHEntry *aOldEntry, nsISHEntry *aNewEntry);
422 :
423 : // Call this method to swap in a new history entry to m[OL]SHE, rather than
424 : // setting it directly. This completes the navigation in all docshells
425 : // in the case of a subframe navigation.
426 : void SetHistoryEntry(nsCOMPtr<nsISHEntry> *aPtr, nsISHEntry *aEntry);
427 :
428 : // Child-walking callback for SetHistoryEntry
429 : static nsresult SetChildHistoryEntry(nsISHEntry *aEntry,
430 : nsDocShell *aShell,
431 : PRInt32 aEntryIndex, void *aData);
432 :
433 : // Callback prototype for WalkHistoryEntries.
434 : // aEntry is the child history entry, aShell is its corresponding docshell,
435 : // aChildIndex is the child's index in its parent entry, and aData is
436 : // the opaque pointer passed to WalkHistoryEntries.
437 : typedef nsresult (*WalkHistoryEntriesFunc)(nsISHEntry *aEntry,
438 : nsDocShell *aShell,
439 : PRInt32 aChildIndex,
440 : void *aData);
441 :
442 : // For each child of aRootEntry, find the corresponding docshell which is
443 : // a child of aRootShell, and call aCallback. The opaque pointer aData
444 : // is passed to the callback.
445 : static nsresult WalkHistoryEntries(nsISHEntry *aRootEntry,
446 : nsDocShell *aRootShell,
447 : WalkHistoryEntriesFunc aCallback,
448 : void *aData);
449 :
450 : // overridden from nsDocLoader, this provides more information than the
451 : // normal OnStateChange with flags STATE_REDIRECTING
452 : virtual void OnRedirectStateChange(nsIChannel* aOldChannel,
453 : nsIChannel* aNewChannel,
454 : PRUint32 aRedirectFlags,
455 : PRUint32 aStateFlags);
456 :
457 : /**
458 : * Helper function that determines if channel is an HTTP POST.
459 : *
460 : * @param aChannel
461 : * The channel to test
462 : *
463 : * @return True iff channel is an HTTP post.
464 : */
465 : bool ChannelIsPost(nsIChannel* aChannel);
466 :
467 : /**
468 : * Helper function that finds the last URI and its transition flags for a
469 : * channel.
470 : *
471 : * This method first checks the channel's property bag to see if previous
472 : * info has been saved. If not, it gives back the referrer of the channel.
473 : *
474 : * @param aChannel
475 : * The channel we are transitioning to
476 : * @param aURI
477 : * Output parameter with the previous URI, not addref'd
478 : * @param aChannelRedirectFlags
479 : * If a redirect, output parameter with the previous redirect flags
480 : * from nsIChannelEventSink
481 : */
482 : void ExtractLastVisit(nsIChannel* aChannel,
483 : nsIURI** aURI,
484 : PRUint32* aChannelRedirectFlags);
485 :
486 : /**
487 : * Helper function that caches a URI and a transition for saving later.
488 : *
489 : * @param aChannel
490 : * Channel that will have these properties saved
491 : * @param aURI
492 : * The URI to save for later
493 : * @param aChannelRedirectFlags
494 : * The nsIChannelEventSink redirect flags to save for later
495 : */
496 : void SaveLastVisit(nsIChannel* aChannel,
497 : nsIURI* aURI,
498 : PRUint32 aChannelRedirectFlags);
499 :
500 : /**
501 : * Helper function for adding a URI visit using IHistory. If IHistory is
502 : * not available, the method tries nsIGlobalHistory2.
503 : *
504 : * The IHistory API maintains chains of visits, tracking both HTTP referrers
505 : * and redirects for a user session. VisitURI requires the current URI and
506 : * the previous URI in the chain.
507 : *
508 : * Visits can be saved either during a redirect or when the request has
509 : * reached its final destination. The previous URI in the visit may be
510 : * from another redirect or it may be the referrer.
511 : *
512 : * @pre aURI is not null.
513 : *
514 : * @param aURI
515 : * The URI that was just visited
516 : * @param aReferrerURI
517 : * The referrer URI of this request
518 : * @param aPreviousURI
519 : * The previous URI of this visit (may be the same as aReferrerURI)
520 : * @param aChannelRedirectFlags
521 : * For redirects, the redirect flags from nsIChannelEventSink
522 : * (0 otherwise)
523 : */
524 : void AddURIVisit(nsIURI* aURI,
525 : nsIURI* aReferrerURI,
526 : nsIURI* aPreviousURI,
527 : PRUint32 aChannelRedirectFlags);
528 :
529 : // Helper Routines
530 : nsresult ConfirmRepost(bool * aRepost);
531 : NS_IMETHOD GetPromptAndStringBundle(nsIPrompt ** aPrompt,
532 : nsIStringBundle ** aStringBundle);
533 : NS_IMETHOD GetChildOffset(nsIDOMNode * aChild, nsIDOMNode * aParent,
534 : PRInt32 * aOffset);
535 : nsIScrollableFrame* GetRootScrollFrame();
536 : NS_IMETHOD EnsureScriptEnvironment();
537 : NS_IMETHOD EnsureEditorData();
538 : nsresult EnsureTransferableHookData();
539 : NS_IMETHOD EnsureFind();
540 : nsresult RefreshURIFromQueue();
541 : NS_IMETHOD DisplayLoadError(nsresult aError, nsIURI *aURI,
542 : const PRUnichar *aURL,
543 : nsIChannel* aFailedChannel = nsnull);
544 : NS_IMETHOD LoadErrorPage(nsIURI *aURI, const PRUnichar *aURL,
545 : const char *aErrorPage,
546 : const PRUnichar *aErrorType,
547 : const PRUnichar *aDescription,
548 : const char *aCSSClass,
549 : nsIChannel* aFailedChannel);
550 : bool IsNavigationAllowed(bool aDisplayPrintErrorDialog = true);
551 : bool IsPrintingOrPP(bool aDisplayErrorDialog = true);
552 :
553 : nsresult SetBaseUrlForWyciwyg(nsIContentViewer * aContentViewer);
554 :
555 : static inline PRUint32
556 0 : PRTimeToSeconds(PRTime t_usec)
557 : {
558 : PRTime usec_per_sec;
559 : PRUint32 t_sec;
560 0 : LL_I2L(usec_per_sec, PR_USEC_PER_SEC);
561 0 : LL_DIV(t_usec, t_usec, usec_per_sec);
562 0 : LL_L2I(t_sec, t_usec);
563 0 : return t_sec;
564 : }
565 :
566 : bool IsFrame();
567 :
568 : //
569 : // Helper method that is called when a new document (including any
570 : // sub-documents - ie. frames) has been completely loaded.
571 : //
572 : virtual nsresult EndPageLoad(nsIWebProgress * aProgress,
573 : nsIChannel * aChannel,
574 : nsresult aResult);
575 :
576 : // Sets the current document's current state object to the given SHEntry's
577 : // state object. The current state object is eventually given to the page
578 : // in the PopState event.
579 : nsresult SetDocCurrentStateObj(nsISHEntry *shEntry);
580 :
581 : nsresult CheckLoadingPermissions();
582 :
583 : // Security checks to prevent frameset spoofing. See comments at
584 : // implementation sites.
585 : static bool CanAccessItem(nsIDocShellTreeItem* aTargetItem,
586 : nsIDocShellTreeItem* aAccessingItem,
587 : bool aConsiderOpener = true);
588 : static bool ValidateOrigin(nsIDocShellTreeItem* aOriginTreeItem,
589 : nsIDocShellTreeItem* aTargetTreeItem);
590 :
591 : // Returns true if would have called FireOnLocationChange,
592 : // but did not because aFireOnLocationChange was false on entry.
593 : // In this case it is the caller's responsibility to ensure
594 : // FireOnLocationChange is called.
595 : // In all other cases false is returned.
596 : bool SetCurrentURI(nsIURI *aURI, nsIRequest *aRequest,
597 : bool aFireOnLocationChange,
598 : PRUint32 aLocationFlags);
599 :
600 : // The following methods deal with saving and restoring content viewers
601 : // in session history.
602 :
603 : // mContentViewer points to the current content viewer associated with
604 : // this docshell. When loading a new document, the content viewer is
605 : // either destroyed or stored into a session history entry. To make sure
606 : // that destruction happens in a controlled fashion, a given content viewer
607 : // is always owned in exactly one of these ways:
608 : // 1) The content viewer is active and owned by a docshell's
609 : // mContentViewer.
610 : // 2) The content viewer is still being displayed while we begin loading
611 : // a new document. The content viewer is owned by the _new_
612 : // content viewer's mPreviousViewer, and has a pointer to the
613 : // nsISHEntry where it will eventually be stored. The content viewer
614 : // has been close()d by the docshell, which detaches the document from
615 : // the window object.
616 : // 3) The content viewer is cached in session history. The nsISHEntry
617 : // has the only owning reference to the content viewer. The viewer
618 : // has released its nsISHEntry pointer to prevent circular ownership.
619 : //
620 : // When restoring a content viewer from session history, open() is called
621 : // to reattach the document to the window object. The content viewer is
622 : // then placed into mContentViewer and removed from the history entry.
623 : // (mContentViewer is put into session history as described above, if
624 : // applicable).
625 :
626 : // Determines whether we can safely cache the current mContentViewer in
627 : // session history. This checks a number of factors such as cache policy,
628 : // pending requests, and unload handlers.
629 : // |aLoadType| should be the load type that will replace the current
630 : // presentation. |aNewRequest| should be the request for the document to
631 : // be loaded in place of the current document, or null if such a request
632 : // has not been created yet. |aNewDocument| should be the document that will
633 : // replace the current document.
634 : bool CanSavePresentation(PRUint32 aLoadType,
635 : nsIRequest *aNewRequest,
636 : nsIDocument *aNewDocument);
637 :
638 : // Captures the state of the supporting elements of the presentation
639 : // (the "window" object, docshell tree, meta-refresh loads, and security
640 : // state) and stores them on |mOSHE|.
641 : nsresult CaptureState();
642 :
643 : // Begin the toplevel restore process for |aSHEntry|.
644 : // This simulates a channel open, and defers the real work until
645 : // RestoreFromHistory is called from a PLEvent.
646 : nsresult RestorePresentation(nsISHEntry *aSHEntry, bool *aRestoring);
647 :
648 : // Call BeginRestore(nsnull, false) for each child of this shell.
649 : nsresult BeginRestoreChildren();
650 :
651 : // Method to get our current position and size without flushing
652 : void DoGetPositionAndSize(PRInt32 * x, PRInt32 * y, PRInt32 * cx,
653 : PRInt32 * cy);
654 :
655 : // Call this when a URI load is handed to us (via OnLinkClick or
656 : // InternalLoad). This makes sure that we're not inside unload, or that if
657 : // we are it's still OK to load this URI.
658 : bool IsOKToLoadURI(nsIURI* aURI);
659 :
660 : void ReattachEditorToWindow(nsISHEntry *aSHEntry);
661 :
662 : nsresult GetSessionStorageForURI(nsIURI* aURI,
663 : const nsSubstring& aDocumentURI,
664 : bool create,
665 : nsIDOMStorage** aStorage);
666 :
667 : // helpers for executing commands
668 : nsresult GetControllerForCommand(const char *inCommand,
669 : nsIController** outController);
670 : nsresult IsCommandEnabled(const char * inCommand, bool* outEnabled);
671 : nsresult DoCommand(const char * inCommand);
672 : nsresult EnsureCommandHandler();
673 :
674 : nsIChannel* GetCurrentDocChannel();
675 : protected:
676 : // Override the parent setter from nsDocLoader
677 : virtual nsresult SetDocLoaderParent(nsDocLoader * aLoader);
678 :
679 : void ClearFrameHistory(nsISHEntry* aEntry);
680 :
681 : nsresult MaybeInitTiming();
682 :
683 : // Event type dispatched by RestorePresentation
684 0 : class RestorePresentationEvent : public nsRunnable {
685 : public:
686 : NS_DECL_NSIRUNNABLE
687 0 : RestorePresentationEvent(nsDocShell *ds) : mDocShell(ds) {}
688 0 : void Revoke() { mDocShell = nsnull; }
689 : private:
690 : nsRefPtr<nsDocShell> mDocShell;
691 : };
692 :
693 : // hash of session storages, keyed by domain
694 : nsInterfaceHashtable<nsCStringHashKey, nsIDOMStorage> mStorages;
695 :
696 : // Dimensions of the docshell
697 : nsIntRect mBounds;
698 : nsString mName;
699 : nsString mTitle;
700 :
701 : /**
702 : * Content-Type Hint of the most-recently initiated load. Used for
703 : * session history entries.
704 : */
705 : nsCString mContentTypeHint;
706 : nsIntPoint mDefaultScrollbarPref; // persistent across doc loads
707 :
708 : nsCOMPtr<nsISupportsArray> mRefreshURIList;
709 : nsCOMPtr<nsISupportsArray> mSavedRefreshURIList;
710 : nsRefPtr<nsDSURIContentListener> mContentListener;
711 : nsCOMPtr<nsIContentViewer> mContentViewer;
712 : nsCOMPtr<nsIWidget> mParentWidget;
713 :
714 : // mCurrentURI should be marked immutable on set if possible.
715 : nsCOMPtr<nsIURI> mCurrentURI;
716 : nsCOMPtr<nsIURI> mReferrerURI;
717 : nsCOMPtr<nsIScriptGlobalObject> mScriptGlobal;
718 : nsCOMPtr<nsISHistory> mSessionHistory;
719 : nsCOMPtr<nsIGlobalHistory2> mGlobalHistory;
720 : nsCOMPtr<nsIWebBrowserFind> mFind;
721 : nsCOMPtr<nsICommandManager> mCommandManager;
722 : // Reference to the SHEntry for this docshell until the page is destroyed.
723 : // Somebody give me better name
724 : nsCOMPtr<nsISHEntry> mOSHE;
725 : // Reference to the SHEntry for this docshell until the page is loaded
726 : // Somebody give me better name.
727 : // If mLSHE is non-null, non-pushState subframe loads don't create separate
728 : // root history entries. That is, frames loaded during the parent page
729 : // load don't generate history entries the way frame navigation after the
730 : // parent has loaded does. (This isn't the only purpose of mLSHE.)
731 : nsCOMPtr<nsISHEntry> mLSHE;
732 :
733 : // Holds a weak pointer to a RestorePresentationEvent object if any that
734 : // holds a weak pointer back to us. We use this pointer to possibly revoke
735 : // the event whenever necessary.
736 : nsRevocableEventPtr<RestorePresentationEvent> mRestorePresentationEvent;
737 :
738 : // Editor data, if this document is designMode or contentEditable.
739 : nsAutoPtr<nsDocShellEditorData> mEditorData;
740 :
741 : // Transferable hooks/callbacks
742 : nsCOMPtr<nsIClipboardDragDropHookList> mTransferableHookData;
743 :
744 : // Secure browser UI object
745 : nsCOMPtr<nsISecureBrowserUI> mSecurityUI;
746 :
747 : // The URI we're currently loading. This is only relevant during the
748 : // firing of a pagehide/unload. The caller of FirePageHideNotification()
749 : // is responsible for setting it and unsetting it. It may be null if the
750 : // pagehide/unload is happening for some reason other than just loading a
751 : // new URI.
752 : nsCOMPtr<nsIURI> mLoadingURI;
753 :
754 : // Set in LoadErrorPage from the method argument and used later
755 : // in CreateContentViewer. We have to delay an shistory entry creation
756 : // for which these objects are needed.
757 : nsCOMPtr<nsIURI> mFailedURI;
758 : nsCOMPtr<nsIChannel> mFailedChannel;
759 : PRUint32 mFailedLoadType;
760 :
761 : // WEAK REFERENCES BELOW HERE.
762 : // Note these are intentionally not addrefd. Doing so will create a cycle.
763 : // For that reasons don't use nsCOMPtr.
764 :
765 : nsIDocShellTreeOwner * mTreeOwner; // Weak Reference
766 : nsIDOMEventTarget * mChromeEventHandler; //Weak Reference
767 :
768 : eCharsetReloadState mCharsetReloadState;
769 :
770 : // Offset in the parent's child list.
771 : // -1 if the docshell is added dynamically to the parent shell.
772 : PRUint32 mChildOffset;
773 : PRUint32 mBusyFlags;
774 : PRUint32 mAppType;
775 : PRUint32 mLoadType;
776 :
777 : PRInt32 mMarginWidth;
778 : PRInt32 mMarginHeight;
779 :
780 : // This can either be a content docshell or a chrome docshell. After
781 : // Create() is called, the type is not expected to change.
782 : PRInt32 mItemType;
783 :
784 : // Index into the SHTransaction list, indicating the previous and current
785 : // transaction at the time that this DocShell begins to load
786 : PRInt32 mPreviousTransIndex;
787 : PRInt32 mLoadedTransIndex;
788 :
789 : bool mCreated;
790 : bool mAllowSubframes;
791 : bool mAllowPlugins;
792 : bool mAllowJavascript;
793 : bool mAllowMetaRedirects;
794 : bool mAllowImages;
795 : bool mAllowDNSPrefetch;
796 : bool mAllowWindowControl;
797 : bool mCreatingDocument; // (should be) debugging only
798 : bool mUseErrorPages;
799 : bool mObserveErrorPages;
800 : bool mAllowAuth;
801 : bool mAllowKeywordFixup;
802 : bool mIsOffScreenBrowser;
803 : bool mIsActive;
804 : bool mIsAppTab;
805 : bool mUseGlobalHistory;
806 : bool mInPrivateBrowsing;
807 : bool mIsBrowserFrame;
808 :
809 : // This boolean is set to true right before we fire pagehide and generally
810 : // unset when we embed a new content viewer. While it's true no navigation
811 : // is allowed in this docshell.
812 : bool mFiredUnloadEvent;
813 :
814 : // this flag is for bug #21358. a docshell may load many urls
815 : // which don't result in new documents being created (i.e. a new
816 : // content viewer) we want to make sure we don't call a on load
817 : // event more than once for a given content viewer.
818 : bool mEODForCurrentDocument;
819 : bool mURIResultedInDocument;
820 :
821 : bool mIsBeingDestroyed;
822 :
823 : bool mIsExecutingOnLoadHandler;
824 :
825 : // Indicates that a DocShell in this "docshell tree" is printing
826 : bool mIsPrintingOrPP;
827 :
828 : // Indicates to CreateContentViewer() that it is safe to cache the old
829 : // presentation of the page, and to SetupNewViewer() that the old viewer
830 : // should be passed a SHEntry to save itself into.
831 : bool mSavingOldViewer;
832 :
833 : // @see nsIDocShellHistory::createdDynamically
834 : bool mDynamicallyCreated;
835 : #ifdef DEBUG
836 : bool mInEnsureScriptEnv;
837 : #endif
838 : PRUint64 mHistoryID;
839 :
840 : static nsIURIFixup *sURIFixup;
841 :
842 : nsRefPtr<nsDOMNavigationTiming> mTiming;
843 :
844 : private:
845 : nsCOMPtr<nsIAtom> mForcedCharset;
846 : nsCOMPtr<nsIAtom> mParentCharset;
847 : PRInt32 mParentCharsetSource;
848 :
849 : #ifdef DEBUG
850 : // We're counting the number of |nsDocShells| to help find leaks
851 : static unsigned long gNumberOfDocShells;
852 : #endif /* DEBUG */
853 :
854 : public:
855 : class InterfaceRequestorProxy : public nsIInterfaceRequestor {
856 : public:
857 : InterfaceRequestorProxy(nsIInterfaceRequestor* p);
858 : virtual ~InterfaceRequestorProxy();
859 : NS_DECL_ISUPPORTS
860 : NS_DECL_NSIINTERFACEREQUESTOR
861 :
862 : protected:
863 : InterfaceRequestorProxy() {}
864 : nsWeakPtr mWeakPtr;
865 : };
866 : };
867 :
868 : #endif /* nsDocShell_h__ */
|