1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/docshell/base/nsDocShell.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,932 @@ 1.4 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- 1.5 + * vim: set ts=4 sw=4 et tw=80: 1.6 + * 1.7 + * This Source Code Form is subject to the terms of the Mozilla Public 1.8 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.9 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.10 + 1.11 +#ifndef nsDocShell_h__ 1.12 +#define nsDocShell_h__ 1.13 + 1.14 +#include "nsITimer.h" 1.15 +#include "nsIDocShell.h" 1.16 +#include "nsIDocShellTreeItem.h" 1.17 +#include "nsIBaseWindow.h" 1.18 +#include "nsIScrollable.h" 1.19 +#include "nsITextScroll.h" 1.20 +#include "nsIContentViewerContainer.h" 1.21 +#include "nsIDOMStorageManager.h" 1.22 +#include "nsDocLoader.h" 1.23 +#include "mozilla/WeakPtr.h" 1.24 + 1.25 +// Helper Classes 1.26 +#include "nsCOMPtr.h" 1.27 +#include "nsPoint.h" // mCurrent/mDefaultScrollbarPreferences 1.28 +#include "nsString.h" 1.29 +#include "nsAutoPtr.h" 1.30 +#include "nsThreadUtils.h" 1.31 + 1.32 +// Threshold value in ms for META refresh based redirects 1.33 +#define REFRESH_REDIRECT_TIMER 15000 1.34 + 1.35 +// Interfaces Needed 1.36 +#include "nsIDocCharset.h" 1.37 +#include "nsIInterfaceRequestor.h" 1.38 +#include "nsIRefreshURI.h" 1.39 +#include "nsIWebNavigation.h" 1.40 +#include "nsIWebPageDescriptor.h" 1.41 +#include "nsIWebProgressListener.h" 1.42 +#include "nsIDocShellLoadInfo.h" 1.43 +#include "nsIAuthPromptProvider.h" 1.44 +#include "nsILoadContext.h" 1.45 +#include "nsIWebShellServices.h" 1.46 +#include "nsILinkHandler.h" 1.47 +#include "nsIClipboardCommands.h" 1.48 +#include "nsCRT.h" 1.49 +#include "prtime.h" 1.50 +#include "nsRect.h" 1.51 + 1.52 +namespace mozilla { 1.53 +namespace dom { 1.54 +class EventTarget; 1.55 +} 1.56 +} 1.57 + 1.58 +class nsDocShell; 1.59 +class nsDOMNavigationTiming; 1.60 +class nsGlobalWindow; 1.61 +class nsIController; 1.62 +class nsIScrollableFrame; 1.63 +class OnLinkClickEvent; 1.64 +class nsDSURIContentListener; 1.65 +class nsDocShellEditorData; 1.66 +class nsIClipboardDragDropHookList; 1.67 +class nsICommandManager; 1.68 +class nsIContentViewer; 1.69 +class nsIDocument; 1.70 +class nsIDOMNode; 1.71 +class nsIDocShellTreeOwner; 1.72 +class nsIGlobalHistory2; 1.73 +class nsIHttpChannel; 1.74 +class nsIPrompt; 1.75 +class nsISHistory; 1.76 +class nsISecureBrowserUI; 1.77 +class nsIStringBundle; 1.78 +class nsISupportsArray; 1.79 +class nsIURIFixup; 1.80 +class nsIURILoader; 1.81 +class nsIWebBrowserFind; 1.82 +class nsIWidget; 1.83 + 1.84 +/* load commands were moved to nsIDocShell.h */ 1.85 +/* load types were moved to nsDocShellLoadTypes.h */ 1.86 + 1.87 +/* internally used ViewMode types */ 1.88 +enum ViewMode { 1.89 + viewNormal = 0x0, 1.90 + viewSource = 0x1 1.91 +}; 1.92 + 1.93 +//***************************************************************************** 1.94 +//*** nsRefreshTimer 1.95 +//***************************************************************************** 1.96 + 1.97 +class nsRefreshTimer : public nsITimerCallback 1.98 +{ 1.99 +public: 1.100 + nsRefreshTimer(); 1.101 + 1.102 + NS_DECL_THREADSAFE_ISUPPORTS 1.103 + NS_DECL_NSITIMERCALLBACK 1.104 + 1.105 + int32_t GetDelay() { return mDelay ;} 1.106 + 1.107 + nsRefPtr<nsDocShell> mDocShell; 1.108 + nsCOMPtr<nsIURI> mURI; 1.109 + int32_t mDelay; 1.110 + bool mRepeat; 1.111 + bool mMetaRefresh; 1.112 + 1.113 +protected: 1.114 + virtual ~nsRefreshTimer(); 1.115 +}; 1.116 + 1.117 +typedef enum { 1.118 + eCharsetReloadInit, 1.119 + eCharsetReloadRequested, 1.120 + eCharsetReloadStopOrigional 1.121 +} eCharsetReloadState; 1.122 + 1.123 +//***************************************************************************** 1.124 +//*** nsDocShell 1.125 +//***************************************************************************** 1.126 + 1.127 +class nsDocShell : public nsDocLoader, 1.128 + public nsIDocShell, 1.129 + public nsIWebNavigation, 1.130 + public nsIBaseWindow, 1.131 + public nsIScrollable, 1.132 + public nsITextScroll, 1.133 + public nsIDocCharset, 1.134 + public nsIContentViewerContainer, 1.135 + public nsIRefreshURI, 1.136 + public nsIWebProgressListener, 1.137 + public nsIWebPageDescriptor, 1.138 + public nsIAuthPromptProvider, 1.139 + public nsILoadContext, 1.140 + public nsIWebShellServices, 1.141 + public nsILinkHandler, 1.142 + public nsIClipboardCommands, 1.143 + public nsIDOMStorageManager, 1.144 + public mozilla::SupportsWeakPtr<nsDocShell> 1.145 +{ 1.146 + friend class nsDSURIContentListener; 1.147 + 1.148 +public: 1.149 + MOZ_DECLARE_REFCOUNTED_TYPENAME(nsDocShell) 1.150 + // Object Management 1.151 + nsDocShell(); 1.152 + 1.153 + NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW 1.154 + 1.155 + virtual nsresult Init(); 1.156 + 1.157 + NS_DECL_ISUPPORTS_INHERITED 1.158 + 1.159 + NS_DECL_NSIDOCSHELL 1.160 + NS_DECL_NSIDOCSHELLTREEITEM 1.161 + NS_DECL_NSIWEBNAVIGATION 1.162 + NS_DECL_NSIBASEWINDOW 1.163 + NS_DECL_NSISCROLLABLE 1.164 + NS_DECL_NSITEXTSCROLL 1.165 + NS_DECL_NSIDOCCHARSET 1.166 + NS_DECL_NSIINTERFACEREQUESTOR 1.167 + NS_DECL_NSIWEBPROGRESSLISTENER 1.168 + NS_DECL_NSIREFRESHURI 1.169 + NS_DECL_NSICONTENTVIEWERCONTAINER 1.170 + NS_DECL_NSIWEBPAGEDESCRIPTOR 1.171 + NS_DECL_NSIAUTHPROMPTPROVIDER 1.172 + NS_DECL_NSICLIPBOARDCOMMANDS 1.173 + NS_DECL_NSIWEBSHELLSERVICES 1.174 + NS_FORWARD_SAFE_NSIDOMSTORAGEMANAGER(TopSessionStorageManager()) 1.175 + 1.176 + NS_IMETHOD Stop() { 1.177 + // Need this here because otherwise nsIWebNavigation::Stop 1.178 + // overrides the docloader's Stop() 1.179 + return nsDocLoader::Stop(); 1.180 + } 1.181 + 1.182 + // Need to implement (and forward) nsISecurityEventSink, because 1.183 + // nsIWebProgressListener has methods with identical names... 1.184 + NS_FORWARD_NSISECURITYEVENTSINK(nsDocLoader::) 1.185 + 1.186 + // nsILinkHandler 1.187 + NS_IMETHOD OnLinkClick(nsIContent* aContent, 1.188 + nsIURI* aURI, 1.189 + const char16_t* aTargetSpec, 1.190 + const nsAString& aFileName, 1.191 + nsIInputStream* aPostDataStream, 1.192 + nsIInputStream* aHeadersDataStream, 1.193 + bool aIsTrusted); 1.194 + NS_IMETHOD OnLinkClickSync(nsIContent* aContent, 1.195 + nsIURI* aURI, 1.196 + const char16_t* aTargetSpec, 1.197 + const nsAString& aFileName, 1.198 + nsIInputStream* aPostDataStream = 0, 1.199 + nsIInputStream* aHeadersDataStream = 0, 1.200 + nsIDocShell** aDocShell = 0, 1.201 + nsIRequest** aRequest = 0); 1.202 + NS_IMETHOD OnOverLink(nsIContent* aContent, 1.203 + nsIURI* aURI, 1.204 + const char16_t* aTargetSpec); 1.205 + NS_IMETHOD OnLeaveLink(); 1.206 + 1.207 + nsDocShellInfoLoadType ConvertLoadTypeToDocShellLoadInfo(uint32_t aLoadType); 1.208 + uint32_t ConvertDocShellLoadInfoToLoadType(nsDocShellInfoLoadType aDocShellLoadType); 1.209 + 1.210 + // Don't use NS_DECL_NSILOADCONTEXT because some of nsILoadContext's methods 1.211 + // are shared with nsIDocShell (appID, etc.) and can't be declared twice. 1.212 + NS_IMETHOD GetAssociatedWindow(nsIDOMWindow**); 1.213 + NS_IMETHOD GetTopWindow(nsIDOMWindow**); 1.214 + NS_IMETHOD GetTopFrameElement(nsIDOMElement**); 1.215 + NS_IMETHOD IsAppOfType(uint32_t, bool*); 1.216 + NS_IMETHOD GetIsContent(bool*); 1.217 + NS_IMETHOD GetUsePrivateBrowsing(bool*); 1.218 + NS_IMETHOD SetUsePrivateBrowsing(bool); 1.219 + NS_IMETHOD SetPrivateBrowsing(bool); 1.220 + NS_IMETHOD GetUseRemoteTabs(bool*); 1.221 + NS_IMETHOD SetRemoteTabs(bool); 1.222 + 1.223 + // Restores a cached presentation from history (mLSHE). 1.224 + // This method swaps out the content viewer and simulates loads for 1.225 + // subframes. It then simulates the completion of the toplevel load. 1.226 + nsresult RestoreFromHistory(); 1.227 + 1.228 + // Perform a URI load from a refresh timer. This is just like the 1.229 + // ForceRefreshURI method on nsIRefreshURI, but makes sure to take 1.230 + // the timer involved out of mRefreshURIList if it's there. 1.231 + // aTimer must not be null. 1.232 + nsresult ForceRefreshURIFromTimer(nsIURI * aURI, int32_t aDelay, 1.233 + bool aMetaRefresh, nsITimer* aTimer); 1.234 + 1.235 + friend class OnLinkClickEvent; 1.236 + 1.237 + // We need dummy OnLocationChange in some cases to update the UI without 1.238 + // updating security info. 1.239 + void FireDummyOnLocationChange() 1.240 + { 1.241 + FireOnLocationChange(this, nullptr, mCurrentURI, 1.242 + LOCATION_CHANGE_SAME_DOCUMENT); 1.243 + } 1.244 + 1.245 + nsresult HistoryTransactionRemoved(int32_t aIndex); 1.246 +protected: 1.247 + // Object Management 1.248 + virtual ~nsDocShell(); 1.249 + virtual void DestroyChildren(); 1.250 + 1.251 + // Content Viewer Management 1.252 + NS_IMETHOD EnsureContentViewer(); 1.253 + // aPrincipal can be passed in if the caller wants. If null is 1.254 + // passed in, the about:blank principal will end up being used. 1.255 + nsresult CreateAboutBlankContentViewer(nsIPrincipal* aPrincipal, 1.256 + nsIURI* aBaseURI, 1.257 + bool aTryToSaveOldPresentation = true); 1.258 + NS_IMETHOD CreateContentViewer(const char * aContentType, 1.259 + nsIRequest * request, nsIStreamListener ** aContentHandler); 1.260 + NS_IMETHOD NewContentViewerObj(const char * aContentType, 1.261 + nsIRequest * request, nsILoadGroup * aLoadGroup, 1.262 + nsIStreamListener ** aContentHandler, nsIContentViewer ** aViewer); 1.263 + NS_IMETHOD SetupNewViewer(nsIContentViewer * aNewViewer); 1.264 + 1.265 + void SetupReferrerFromChannel(nsIChannel * aChannel); 1.266 + 1.267 + NS_IMETHOD GetEldestPresContext(nsPresContext** aPresContext); 1.268 + 1.269 + // Get the principal that we'll set on the channel if we're inheriting. If 1.270 + // aConsiderCurrentDocument is true, we try to use the current document if 1.271 + // at all possible. If that fails, we fall back on the parent document. 1.272 + // If that fails too, we force creation of a content viewer and use the 1.273 + // resulting principal. If aConsiderCurrentDocument is false, we just look 1.274 + // at the parent. 1.275 + nsIPrincipal* GetInheritedPrincipal(bool aConsiderCurrentDocument); 1.276 + 1.277 + // Actually open a channel and perform a URI load. Note: whatever owner is 1.278 + // passed to this function will be set on the channel. Callers who wish to 1.279 + // not have an owner on the channel should just pass null. 1.280 + // If aSrcdoc is not void, the load will be considered as a srcdoc load, 1.281 + // and the contents of aSrcdoc will be loaded instead of aURI. 1.282 + virtual nsresult DoURILoad(nsIURI * aURI, 1.283 + nsIURI * aReferrer, 1.284 + bool aSendReferrer, 1.285 + nsISupports * aOwner, 1.286 + const char * aTypeHint, 1.287 + const nsAString & aFileName, 1.288 + nsIInputStream * aPostData, 1.289 + nsIInputStream * aHeadersData, 1.290 + bool firstParty, 1.291 + nsIDocShell ** aDocShell, 1.292 + nsIRequest ** aRequest, 1.293 + bool aIsNewWindowTarget, 1.294 + bool aBypassClassifier, 1.295 + bool aForceAllowCookies, 1.296 + const nsAString &aSrcdoc, 1.297 + nsIURI * baseURI); 1.298 + NS_IMETHOD AddHeadersToChannel(nsIInputStream * aHeadersData, 1.299 + nsIChannel * aChannel); 1.300 + virtual nsresult DoChannelLoad(nsIChannel * aChannel, 1.301 + nsIURILoader * aURILoader, 1.302 + bool aBypassClassifier); 1.303 + 1.304 + nsresult ScrollToAnchor(nsACString & curHash, nsACString & newHash, 1.305 + uint32_t aLoadType); 1.306 + 1.307 + // Tries to serialize a given variant using structured clone. This only 1.308 + // works if the variant is backed by a JSVal. 1.309 + nsresult SerializeJSValVariant(JSContext *aCx, nsIVariant *aData, 1.310 + nsAString &aResult); 1.311 + 1.312 + // Returns true if would have called FireOnLocationChange, 1.313 + // but did not because aFireOnLocationChange was false on entry. 1.314 + // In this case it is the caller's responsibility to ensure 1.315 + // FireOnLocationChange is called. 1.316 + // In all other cases false is returned. 1.317 + bool OnLoadingSite(nsIChannel * aChannel, 1.318 + bool aFireOnLocationChange, 1.319 + bool aAddToGlobalHistory = true); 1.320 + 1.321 + // Returns true if would have called FireOnLocationChange, 1.322 + // but did not because aFireOnLocationChange was false on entry. 1.323 + // In this case it is the caller's responsibility to ensure 1.324 + // FireOnLocationChange is called. 1.325 + // In all other cases false is returned. 1.326 + // Either aChannel or aOwner must be null. If aChannel is 1.327 + // present, the owner should be gotten from it. 1.328 + // If OnNewURI calls AddToSessionHistory, it will pass its 1.329 + // aCloneSHChildren argument as aCloneChildren. 1.330 + bool OnNewURI(nsIURI * aURI, nsIChannel * aChannel, nsISupports* aOwner, 1.331 + uint32_t aLoadType, 1.332 + bool aFireOnLocationChange, 1.333 + bool aAddToGlobalHistory, 1.334 + bool aCloneSHChildren); 1.335 + 1.336 + virtual void SetReferrerURI(nsIURI * aURI); 1.337 + 1.338 + // Session History 1.339 + virtual bool ShouldAddToSessionHistory(nsIURI * aURI); 1.340 + // Either aChannel or aOwner must be null. If aChannel is 1.341 + // present, the owner should be gotten from it. 1.342 + // If aCloneChildren is true, then our current session history's 1.343 + // children will be cloned onto the new entry. This should be 1.344 + // used when we aren't actually changing the document while adding 1.345 + // the new session history entry. 1.346 + virtual nsresult AddToSessionHistory(nsIURI * aURI, nsIChannel * aChannel, 1.347 + nsISupports* aOwner, 1.348 + bool aCloneChildren, 1.349 + nsISHEntry ** aNewEntry); 1.350 + nsresult DoAddChildSHEntry(nsISHEntry* aNewEntry, int32_t aChildOffset, 1.351 + bool aCloneChildren); 1.352 + 1.353 + NS_IMETHOD LoadHistoryEntry(nsISHEntry * aEntry, uint32_t aLoadType); 1.354 + NS_IMETHOD PersistLayoutHistoryState(); 1.355 + 1.356 + // Clone a session history tree for subframe navigation. 1.357 + // The tree rooted at |aSrcEntry| will be cloned into |aDestEntry|, except 1.358 + // for the entry with id |aCloneID|, which will be replaced with 1.359 + // |aReplaceEntry|. |aSrcShell| is a (possibly null) docshell which 1.360 + // corresponds to |aSrcEntry| via its mLSHE or mOHE pointers, and will 1.361 + // have that pointer updated to point to the cloned history entry. 1.362 + // If aCloneChildren is true then the children of the entry with id 1.363 + // |aCloneID| will be cloned into |aReplaceEntry|. 1.364 + static nsresult CloneAndReplace(nsISHEntry *aSrcEntry, 1.365 + nsDocShell *aSrcShell, 1.366 + uint32_t aCloneID, 1.367 + nsISHEntry *aReplaceEntry, 1.368 + bool aCloneChildren, 1.369 + nsISHEntry **aDestEntry); 1.370 + 1.371 + // Child-walking callback for CloneAndReplace 1.372 + static nsresult CloneAndReplaceChild(nsISHEntry *aEntry, 1.373 + nsDocShell *aShell, 1.374 + int32_t aChildIndex, void *aData); 1.375 + 1.376 + nsresult GetRootSessionHistory(nsISHistory ** aReturn); 1.377 + nsresult GetHttpChannel(nsIChannel * aChannel, nsIHttpChannel ** aReturn); 1.378 + bool ShouldDiscardLayoutState(nsIHttpChannel * aChannel); 1.379 + 1.380 + // Determine whether this docshell corresponds to the given history entry, 1.381 + // via having a pointer to it in mOSHE or mLSHE. 1.382 + bool HasHistoryEntry(nsISHEntry *aEntry) const 1.383 + { 1.384 + return aEntry && (aEntry == mOSHE || aEntry == mLSHE); 1.385 + } 1.386 + 1.387 + // Update any pointers (mOSHE or mLSHE) to aOldEntry to point to aNewEntry 1.388 + void SwapHistoryEntries(nsISHEntry *aOldEntry, nsISHEntry *aNewEntry); 1.389 + 1.390 + // Call this method to swap in a new history entry to m[OL]SHE, rather than 1.391 + // setting it directly. This completes the navigation in all docshells 1.392 + // in the case of a subframe navigation. 1.393 + void SetHistoryEntry(nsCOMPtr<nsISHEntry> *aPtr, nsISHEntry *aEntry); 1.394 + 1.395 + // Child-walking callback for SetHistoryEntry 1.396 + static nsresult SetChildHistoryEntry(nsISHEntry *aEntry, 1.397 + nsDocShell *aShell, 1.398 + int32_t aEntryIndex, void *aData); 1.399 + 1.400 + // Callback prototype for WalkHistoryEntries. 1.401 + // aEntry is the child history entry, aShell is its corresponding docshell, 1.402 + // aChildIndex is the child's index in its parent entry, and aData is 1.403 + // the opaque pointer passed to WalkHistoryEntries. 1.404 + typedef nsresult (*WalkHistoryEntriesFunc)(nsISHEntry *aEntry, 1.405 + nsDocShell *aShell, 1.406 + int32_t aChildIndex, 1.407 + void *aData); 1.408 + 1.409 + // For each child of aRootEntry, find the corresponding docshell which is 1.410 + // a child of aRootShell, and call aCallback. The opaque pointer aData 1.411 + // is passed to the callback. 1.412 + static nsresult WalkHistoryEntries(nsISHEntry *aRootEntry, 1.413 + nsDocShell *aRootShell, 1.414 + WalkHistoryEntriesFunc aCallback, 1.415 + void *aData); 1.416 + 1.417 + // overridden from nsDocLoader, this provides more information than the 1.418 + // normal OnStateChange with flags STATE_REDIRECTING 1.419 + virtual void OnRedirectStateChange(nsIChannel* aOldChannel, 1.420 + nsIChannel* aNewChannel, 1.421 + uint32_t aRedirectFlags, 1.422 + uint32_t aStateFlags); 1.423 + 1.424 + /** 1.425 + * Helper function that determines if channel is an HTTP POST. 1.426 + * 1.427 + * @param aChannel 1.428 + * The channel to test 1.429 + * 1.430 + * @return True iff channel is an HTTP post. 1.431 + */ 1.432 + bool ChannelIsPost(nsIChannel* aChannel); 1.433 + 1.434 + /** 1.435 + * Helper function that finds the last URI and its transition flags for a 1.436 + * channel. 1.437 + * 1.438 + * This method first checks the channel's property bag to see if previous 1.439 + * info has been saved. If not, it gives back the referrer of the channel. 1.440 + * 1.441 + * @param aChannel 1.442 + * The channel we are transitioning to 1.443 + * @param aURI 1.444 + * Output parameter with the previous URI, not addref'd 1.445 + * @param aChannelRedirectFlags 1.446 + * If a redirect, output parameter with the previous redirect flags 1.447 + * from nsIChannelEventSink 1.448 + */ 1.449 + void ExtractLastVisit(nsIChannel* aChannel, 1.450 + nsIURI** aURI, 1.451 + uint32_t* aChannelRedirectFlags); 1.452 + 1.453 + /** 1.454 + * Helper function that caches a URI and a transition for saving later. 1.455 + * 1.456 + * @param aChannel 1.457 + * Channel that will have these properties saved 1.458 + * @param aURI 1.459 + * The URI to save for later 1.460 + * @param aChannelRedirectFlags 1.461 + * The nsIChannelEventSink redirect flags to save for later 1.462 + */ 1.463 + void SaveLastVisit(nsIChannel* aChannel, 1.464 + nsIURI* aURI, 1.465 + uint32_t aChannelRedirectFlags); 1.466 + 1.467 + /** 1.468 + * Helper function for adding a URI visit using IHistory. If IHistory is 1.469 + * not available, the method tries nsIGlobalHistory2. 1.470 + * 1.471 + * The IHistory API maintains chains of visits, tracking both HTTP referrers 1.472 + * and redirects for a user session. VisitURI requires the current URI and 1.473 + * the previous URI in the chain. 1.474 + * 1.475 + * Visits can be saved either during a redirect or when the request has 1.476 + * reached its final destination. The previous URI in the visit may be 1.477 + * from another redirect or it may be the referrer. 1.478 + * 1.479 + * @pre aURI is not null. 1.480 + * 1.481 + * @param aURI 1.482 + * The URI that was just visited 1.483 + * @param aReferrerURI 1.484 + * The referrer URI of this request 1.485 + * @param aPreviousURI 1.486 + * The previous URI of this visit (may be the same as aReferrerURI) 1.487 + * @param aChannelRedirectFlags 1.488 + * For redirects, the redirect flags from nsIChannelEventSink 1.489 + * (0 otherwise) 1.490 + * @param aResponseStatus 1.491 + * For HTTP channels, the response code (0 otherwise). 1.492 + */ 1.493 + void AddURIVisit(nsIURI* aURI, 1.494 + nsIURI* aReferrerURI, 1.495 + nsIURI* aPreviousURI, 1.496 + uint32_t aChannelRedirectFlags, 1.497 + uint32_t aResponseStatus=0); 1.498 + 1.499 + // Helper Routines 1.500 + nsresult ConfirmRepost(bool * aRepost); 1.501 + NS_IMETHOD GetPromptAndStringBundle(nsIPrompt ** aPrompt, 1.502 + nsIStringBundle ** aStringBundle); 1.503 + NS_IMETHOD GetChildOffset(nsIDOMNode * aChild, nsIDOMNode * aParent, 1.504 + int32_t * aOffset); 1.505 + nsIScrollableFrame* GetRootScrollFrame(); 1.506 + NS_IMETHOD EnsureScriptEnvironment(); 1.507 + NS_IMETHOD EnsureEditorData(); 1.508 + nsresult EnsureTransferableHookData(); 1.509 + NS_IMETHOD EnsureFind(); 1.510 + nsresult RefreshURIFromQueue(); 1.511 + NS_IMETHOD LoadErrorPage(nsIURI *aURI, const char16_t *aURL, 1.512 + const char *aErrorPage, 1.513 + const char16_t *aErrorType, 1.514 + const char16_t *aDescription, 1.515 + const char *aCSSClass, 1.516 + nsIChannel* aFailedChannel); 1.517 + bool IsNavigationAllowed(bool aDisplayPrintErrorDialog = true); 1.518 + bool IsPrintingOrPP(bool aDisplayErrorDialog = true); 1.519 + 1.520 + nsresult SetBaseUrlForWyciwyg(nsIContentViewer * aContentViewer); 1.521 + 1.522 + static inline uint32_t 1.523 + PRTimeToSeconds(PRTime t_usec) 1.524 + { 1.525 + PRTime usec_per_sec = PR_USEC_PER_SEC; 1.526 + return uint32_t(t_usec /= usec_per_sec); 1.527 + } 1.528 + 1.529 + inline bool UseErrorPages() 1.530 + { 1.531 + return (mObserveErrorPages ? sUseErrorPages : mUseErrorPages); 1.532 + } 1.533 + 1.534 + bool IsFrame(); 1.535 + 1.536 + // 1.537 + // Helper method that is called when a new document (including any 1.538 + // sub-documents - ie. frames) has been completely loaded. 1.539 + // 1.540 + virtual nsresult EndPageLoad(nsIWebProgress * aProgress, 1.541 + nsIChannel * aChannel, 1.542 + nsresult aResult); 1.543 + 1.544 + // Sets the current document's current state object to the given SHEntry's 1.545 + // state object. The current state object is eventually given to the page 1.546 + // in the PopState event. 1.547 + nsresult SetDocCurrentStateObj(nsISHEntry *shEntry); 1.548 + 1.549 + nsresult CheckLoadingPermissions(); 1.550 + 1.551 + // Security checks to prevent frameset spoofing. See comments at 1.552 + // implementation sites. 1.553 + static bool CanAccessItem(nsIDocShellTreeItem* aTargetItem, 1.554 + nsIDocShellTreeItem* aAccessingItem, 1.555 + bool aConsiderOpener = true); 1.556 + static bool ValidateOrigin(nsIDocShellTreeItem* aOriginTreeItem, 1.557 + nsIDocShellTreeItem* aTargetTreeItem); 1.558 + 1.559 + // Returns true if would have called FireOnLocationChange, 1.560 + // but did not because aFireOnLocationChange was false on entry. 1.561 + // In this case it is the caller's responsibility to ensure 1.562 + // FireOnLocationChange is called. 1.563 + // In all other cases false is returned. 1.564 + bool SetCurrentURI(nsIURI *aURI, nsIRequest *aRequest, 1.565 + bool aFireOnLocationChange, 1.566 + uint32_t aLocationFlags); 1.567 + 1.568 + // The following methods deal with saving and restoring content viewers 1.569 + // in session history. 1.570 + 1.571 + // mContentViewer points to the current content viewer associated with 1.572 + // this docshell. When loading a new document, the content viewer is 1.573 + // either destroyed or stored into a session history entry. To make sure 1.574 + // that destruction happens in a controlled fashion, a given content viewer 1.575 + // is always owned in exactly one of these ways: 1.576 + // 1) The content viewer is active and owned by a docshell's 1.577 + // mContentViewer. 1.578 + // 2) The content viewer is still being displayed while we begin loading 1.579 + // a new document. The content viewer is owned by the _new_ 1.580 + // content viewer's mPreviousViewer, and has a pointer to the 1.581 + // nsISHEntry where it will eventually be stored. The content viewer 1.582 + // has been close()d by the docshell, which detaches the document from 1.583 + // the window object. 1.584 + // 3) The content viewer is cached in session history. The nsISHEntry 1.585 + // has the only owning reference to the content viewer. The viewer 1.586 + // has released its nsISHEntry pointer to prevent circular ownership. 1.587 + // 1.588 + // When restoring a content viewer from session history, open() is called 1.589 + // to reattach the document to the window object. The content viewer is 1.590 + // then placed into mContentViewer and removed from the history entry. 1.591 + // (mContentViewer is put into session history as described above, if 1.592 + // applicable). 1.593 + 1.594 + // Determines whether we can safely cache the current mContentViewer in 1.595 + // session history. This checks a number of factors such as cache policy, 1.596 + // pending requests, and unload handlers. 1.597 + // |aLoadType| should be the load type that will replace the current 1.598 + // presentation. |aNewRequest| should be the request for the document to 1.599 + // be loaded in place of the current document, or null if such a request 1.600 + // has not been created yet. |aNewDocument| should be the document that will 1.601 + // replace the current document. 1.602 + bool CanSavePresentation(uint32_t aLoadType, 1.603 + nsIRequest *aNewRequest, 1.604 + nsIDocument *aNewDocument); 1.605 + 1.606 + // Captures the state of the supporting elements of the presentation 1.607 + // (the "window" object, docshell tree, meta-refresh loads, and security 1.608 + // state) and stores them on |mOSHE|. 1.609 + nsresult CaptureState(); 1.610 + 1.611 + // Begin the toplevel restore process for |aSHEntry|. 1.612 + // This simulates a channel open, and defers the real work until 1.613 + // RestoreFromHistory is called from a PLEvent. 1.614 + nsresult RestorePresentation(nsISHEntry *aSHEntry, bool *aRestoring); 1.615 + 1.616 + // Call BeginRestore(nullptr, false) for each child of this shell. 1.617 + nsresult BeginRestoreChildren(); 1.618 + 1.619 + // Method to get our current position and size without flushing 1.620 + void DoGetPositionAndSize(int32_t * x, int32_t * y, int32_t * cx, 1.621 + int32_t * cy); 1.622 + 1.623 + // Call this when a URI load is handed to us (via OnLinkClick or 1.624 + // InternalLoad). This makes sure that we're not inside unload, or that if 1.625 + // we are it's still OK to load this URI. 1.626 + bool IsOKToLoadURI(nsIURI* aURI); 1.627 + 1.628 + void ReattachEditorToWindow(nsISHEntry *aSHEntry); 1.629 + 1.630 + nsCOMPtr<nsIDOMStorageManager> mSessionStorageManager; 1.631 + nsIDOMStorageManager* TopSessionStorageManager(); 1.632 + 1.633 + // helpers for executing commands 1.634 + nsresult GetControllerForCommand(const char *inCommand, 1.635 + nsIController** outController); 1.636 + nsresult EnsureCommandHandler(); 1.637 + 1.638 + nsIChannel* GetCurrentDocChannel(); 1.639 + 1.640 + bool ShouldBlockLoadingForBackButton(); 1.641 + 1.642 + // Convenience method for getting our parent docshell. Can return null 1.643 + already_AddRefed<nsDocShell> GetParentDocshell(); 1.644 +protected: 1.645 + nsresult GetCurScrollPos(int32_t scrollOrientation, int32_t * curPos); 1.646 + nsresult SetCurScrollPosEx(int32_t curHorizontalPos, int32_t curVerticalPos); 1.647 + 1.648 + // Override the parent setter from nsDocLoader 1.649 + virtual nsresult SetDocLoaderParent(nsDocLoader * aLoader); 1.650 + 1.651 + void ClearFrameHistory(nsISHEntry* aEntry); 1.652 + 1.653 + /** 1.654 + * Initializes mTiming if it isn't yet. 1.655 + * After calling this, mTiming is non-null. 1.656 + */ 1.657 + void MaybeInitTiming(); 1.658 + 1.659 + // Event type dispatched by RestorePresentation 1.660 + class RestorePresentationEvent : public nsRunnable { 1.661 + public: 1.662 + NS_DECL_NSIRUNNABLE 1.663 + RestorePresentationEvent(nsDocShell *ds) : mDocShell(ds) {} 1.664 + void Revoke() { mDocShell = nullptr; } 1.665 + private: 1.666 + nsRefPtr<nsDocShell> mDocShell; 1.667 + }; 1.668 + 1.669 + bool JustStartedNetworkLoad(); 1.670 + 1.671 + enum FrameType { 1.672 + eFrameTypeRegular, 1.673 + eFrameTypeBrowser, 1.674 + eFrameTypeApp 1.675 + }; 1.676 + 1.677 + static const nsCString FrameTypeToString(FrameType aFrameType) 1.678 + { 1.679 + switch (aFrameType) { 1.680 + case FrameType::eFrameTypeApp: 1.681 + return NS_LITERAL_CSTRING("app"); 1.682 + case FrameType::eFrameTypeBrowser: 1.683 + return NS_LITERAL_CSTRING("browser"); 1.684 + case FrameType::eFrameTypeRegular: 1.685 + return NS_LITERAL_CSTRING("regular"); 1.686 + default: 1.687 + NS_ERROR("Unknown frame type"); 1.688 + return EmptyCString(); 1.689 + } 1.690 + } 1.691 + 1.692 + FrameType GetInheritedFrameType(); 1.693 + 1.694 + bool HasUnloadedParent(); 1.695 + 1.696 + // Dimensions of the docshell 1.697 + nsIntRect mBounds; 1.698 + nsString mName; 1.699 + nsString mTitle; 1.700 + 1.701 + /** 1.702 + * Content-Type Hint of the most-recently initiated load. Used for 1.703 + * session history entries. 1.704 + */ 1.705 + nsCString mContentTypeHint; 1.706 + nsIntPoint mDefaultScrollbarPref; // persistent across doc loads 1.707 + 1.708 + nsCOMPtr<nsISupportsArray> mRefreshURIList; 1.709 + nsCOMPtr<nsISupportsArray> mSavedRefreshURIList; 1.710 + nsRefPtr<nsDSURIContentListener> mContentListener; 1.711 + nsCOMPtr<nsIContentViewer> mContentViewer; 1.712 + nsCOMPtr<nsIWidget> mParentWidget; 1.713 + 1.714 + // mCurrentURI should be marked immutable on set if possible. 1.715 + nsCOMPtr<nsIURI> mCurrentURI; 1.716 + nsCOMPtr<nsIURI> mReferrerURI; 1.717 + nsRefPtr<nsGlobalWindow> mScriptGlobal; 1.718 + nsCOMPtr<nsISHistory> mSessionHistory; 1.719 + nsCOMPtr<nsIGlobalHistory2> mGlobalHistory; 1.720 + nsCOMPtr<nsIWebBrowserFind> mFind; 1.721 + nsCOMPtr<nsICommandManager> mCommandManager; 1.722 + // Reference to the SHEntry for this docshell until the page is destroyed. 1.723 + // Somebody give me better name 1.724 + nsCOMPtr<nsISHEntry> mOSHE; 1.725 + // Reference to the SHEntry for this docshell until the page is loaded 1.726 + // Somebody give me better name. 1.727 + // If mLSHE is non-null, non-pushState subframe loads don't create separate 1.728 + // root history entries. That is, frames loaded during the parent page 1.729 + // load don't generate history entries the way frame navigation after the 1.730 + // parent has loaded does. (This isn't the only purpose of mLSHE.) 1.731 + nsCOMPtr<nsISHEntry> mLSHE; 1.732 + 1.733 + // Holds a weak pointer to a RestorePresentationEvent object if any that 1.734 + // holds a weak pointer back to us. We use this pointer to possibly revoke 1.735 + // the event whenever necessary. 1.736 + nsRevocableEventPtr<RestorePresentationEvent> mRestorePresentationEvent; 1.737 + 1.738 + // Editor data, if this document is designMode or contentEditable. 1.739 + nsAutoPtr<nsDocShellEditorData> mEditorData; 1.740 + 1.741 + // Transferable hooks/callbacks 1.742 + nsCOMPtr<nsIClipboardDragDropHookList> mTransferableHookData; 1.743 + 1.744 + // Secure browser UI object 1.745 + nsCOMPtr<nsISecureBrowserUI> mSecurityUI; 1.746 + 1.747 + // The URI we're currently loading. This is only relevant during the 1.748 + // firing of a pagehide/unload. The caller of FirePageHideNotification() 1.749 + // is responsible for setting it and unsetting it. It may be null if the 1.750 + // pagehide/unload is happening for some reason other than just loading a 1.751 + // new URI. 1.752 + nsCOMPtr<nsIURI> mLoadingURI; 1.753 + 1.754 + // Set in LoadErrorPage from the method argument and used later 1.755 + // in CreateContentViewer. We have to delay an shistory entry creation 1.756 + // for which these objects are needed. 1.757 + nsCOMPtr<nsIURI> mFailedURI; 1.758 + nsCOMPtr<nsIChannel> mFailedChannel; 1.759 + uint32_t mFailedLoadType; 1.760 + 1.761 + // Set in DoURILoad when either the LOAD_RELOAD_ALLOW_MIXED_CONTENT flag or 1.762 + // the LOAD_NORMAL_ALLOW_MIXED_CONTENT flag is set. 1.763 + // Checked in nsMixedContentBlocker, to see if the channels match. 1.764 + nsCOMPtr<nsIChannel> mMixedContentChannel; 1.765 + 1.766 + // WEAK REFERENCES BELOW HERE. 1.767 + // Note these are intentionally not addrefd. Doing so will create a cycle. 1.768 + // For that reasons don't use nsCOMPtr. 1.769 + 1.770 + nsIDocShellTreeOwner * mTreeOwner; // Weak Reference 1.771 + mozilla::dom::EventTarget* mChromeEventHandler; //Weak Reference 1.772 + 1.773 + eCharsetReloadState mCharsetReloadState; 1.774 + 1.775 + // Offset in the parent's child list. 1.776 + // -1 if the docshell is added dynamically to the parent shell. 1.777 + uint32_t mChildOffset; 1.778 + uint32_t mBusyFlags; 1.779 + uint32_t mAppType; 1.780 + uint32_t mLoadType; 1.781 + 1.782 + int32_t mMarginWidth; 1.783 + int32_t mMarginHeight; 1.784 + 1.785 + // This can either be a content docshell or a chrome docshell. After 1.786 + // Create() is called, the type is not expected to change. 1.787 + int32_t mItemType; 1.788 + 1.789 + // Index into the SHTransaction list, indicating the previous and current 1.790 + // transaction at the time that this DocShell begins to load 1.791 + int32_t mPreviousTransIndex; 1.792 + int32_t mLoadedTransIndex; 1.793 + 1.794 + uint32_t mSandboxFlags; 1.795 + nsWeakPtr mOnePermittedSandboxedNavigator; 1.796 + 1.797 + // mFullscreenAllowed stores how we determine whether fullscreen is allowed 1.798 + // when GetFullscreenAllowed() is called. Fullscreen is allowed in a 1.799 + // docshell when all containing iframes have the allowfullscreen 1.800 + // attribute set to true. When mFullscreenAllowed is CHECK_ATTRIBUTES 1.801 + // we check this docshell's containing frame for the allowfullscreen 1.802 + // attribute, and recurse onto the parent docshell to ensure all containing 1.803 + // frames also have the allowfullscreen attribute. If we find an ancestor 1.804 + // docshell with mFullscreenAllowed not equal to CHECK_ATTRIBUTES, we've 1.805 + // reached a content boundary, and mFullscreenAllowed denotes whether the 1.806 + // parent across the content boundary has allowfullscreen=true in all its 1.807 + // containing iframes. mFullscreenAllowed defaults to CHECK_ATTRIBUTES and 1.808 + // is set otherwise when docshells which are content boundaries are created. 1.809 + enum FullscreenAllowedState { 1.810 + CHECK_ATTRIBUTES, 1.811 + PARENT_ALLOWS, 1.812 + PARENT_PROHIBITS 1.813 + }; 1.814 + FullscreenAllowedState mFullscreenAllowed; 1.815 + 1.816 + // Cached value of the "browser.xul.error_pages.enabled" preference. 1.817 + static bool sUseErrorPages; 1.818 + 1.819 + bool mCreated; 1.820 + bool mAllowSubframes; 1.821 + bool mAllowPlugins; 1.822 + bool mAllowJavascript; 1.823 + bool mAllowMetaRedirects; 1.824 + bool mAllowImages; 1.825 + bool mAllowMedia; 1.826 + bool mAllowDNSPrefetch; 1.827 + bool mAllowWindowControl; 1.828 + bool mAllowContentRetargeting; 1.829 + bool mCreatingDocument; // (should be) debugging only 1.830 + bool mUseErrorPages; 1.831 + bool mObserveErrorPages; 1.832 + bool mAllowAuth; 1.833 + bool mAllowKeywordFixup; 1.834 + bool mIsOffScreenBrowser; 1.835 + bool mIsActive; 1.836 + bool mIsAppTab; 1.837 + bool mUseGlobalHistory; 1.838 + bool mInPrivateBrowsing; 1.839 + bool mUseRemoteTabs; 1.840 + bool mDeviceSizeIsPageSize; 1.841 + 1.842 + // Because scriptability depends on the mAllowJavascript values of our 1.843 + // ancestors, we cache the effective scriptability and recompute it when 1.844 + // it might have changed; 1.845 + bool mCanExecuteScripts; 1.846 + void RecomputeCanExecuteScripts(); 1.847 + 1.848 + // This boolean is set to true right before we fire pagehide and generally 1.849 + // unset when we embed a new content viewer. While it's true no navigation 1.850 + // is allowed in this docshell. 1.851 + bool mFiredUnloadEvent; 1.852 + 1.853 + // this flag is for bug #21358. a docshell may load many urls 1.854 + // which don't result in new documents being created (i.e. a new 1.855 + // content viewer) we want to make sure we don't call a on load 1.856 + // event more than once for a given content viewer. 1.857 + bool mEODForCurrentDocument; 1.858 + bool mURIResultedInDocument; 1.859 + 1.860 + bool mIsBeingDestroyed; 1.861 + 1.862 + bool mIsExecutingOnLoadHandler; 1.863 + 1.864 + // Indicates that a DocShell in this "docshell tree" is printing 1.865 + bool mIsPrintingOrPP; 1.866 + 1.867 + // Indicates to CreateContentViewer() that it is safe to cache the old 1.868 + // presentation of the page, and to SetupNewViewer() that the old viewer 1.869 + // should be passed a SHEntry to save itself into. 1.870 + bool mSavingOldViewer; 1.871 + 1.872 + // @see nsIDocShellHistory::createdDynamically 1.873 + bool mDynamicallyCreated; 1.874 +#ifdef DEBUG 1.875 + bool mInEnsureScriptEnv; 1.876 +#endif 1.877 + bool mAffectPrivateSessionLifetime; 1.878 + bool mInvisible; 1.879 + uint64_t mHistoryID; 1.880 + uint32_t mDefaultLoadFlags; 1.881 + 1.882 + static nsIURIFixup *sURIFixup; 1.883 + 1.884 + nsRefPtr<nsDOMNavigationTiming> mTiming; 1.885 + 1.886 + // Are we a regular frame, a browser frame, or an app frame? 1.887 + FrameType mFrameType; 1.888 + 1.889 + // We only expect mOwnOrContainingAppId to be something other than 1.890 + // UNKNOWN_APP_ID if mFrameType != eFrameTypeRegular. For vanilla iframes 1.891 + // inside an app, we'll retrieve the containing app-id by walking up the 1.892 + // docshell hierarchy. 1.893 + // 1.894 + // (This needs to be the docshell's own /or containing/ app id because the 1.895 + // containing app frame might be in another process, in which case we won't 1.896 + // find it by walking up the docshell hierarchy.) 1.897 + uint32_t mOwnOrContainingAppId; 1.898 + 1.899 +private: 1.900 + nsCString mForcedCharset; 1.901 + nsCString mParentCharset; 1.902 + int32_t mParentCharsetSource; 1.903 + nsCOMPtr<nsIPrincipal> mParentCharsetPrincipal; 1.904 + nsTObserverArray<nsWeakPtr> mPrivacyObservers; 1.905 + nsTObserverArray<nsWeakPtr> mReflowObservers; 1.906 + nsTObserverArray<nsWeakPtr> mScrollObservers; 1.907 + nsCString mOriginalUriString; 1.908 + 1.909 + // Separate function to do the actual name (i.e. not _top, _self etc.) 1.910 + // searching for FindItemWithName. 1.911 + nsresult DoFindItemWithName(const char16_t* aName, 1.912 + nsISupports* aRequestor, 1.913 + nsIDocShellTreeItem* aOriginalRequestor, 1.914 + nsIDocShellTreeItem** _retval); 1.915 + 1.916 +#ifdef DEBUG 1.917 + // We're counting the number of |nsDocShells| to help find leaks 1.918 + static unsigned long gNumberOfDocShells; 1.919 +#endif /* DEBUG */ 1.920 + 1.921 +public: 1.922 + class InterfaceRequestorProxy : public nsIInterfaceRequestor { 1.923 + public: 1.924 + InterfaceRequestorProxy(nsIInterfaceRequestor* p); 1.925 + virtual ~InterfaceRequestorProxy(); 1.926 + NS_DECL_THREADSAFE_ISUPPORTS 1.927 + NS_DECL_NSIINTERFACEREQUESTOR 1.928 + 1.929 + protected: 1.930 + InterfaceRequestorProxy() {} 1.931 + nsWeakPtr mWeakPtr; 1.932 + }; 1.933 +}; 1.934 + 1.935 +#endif /* nsDocShell_h__ */