uriloader/base/nsDocLoader.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
     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 */
     9 #ifndef nsDocLoader_h__
    10 #define nsDocLoader_h__
    12 #include "nsIDocumentLoader.h"
    13 #include "nsIWebProgress.h"
    14 #include "nsIWebProgressListener.h"
    15 #include "nsIRequestObserver.h"
    16 #include "nsWeakReference.h"
    17 #include "nsILoadGroup.h"
    18 #include "nsCOMArray.h"
    19 #include "nsTObserverArray.h"
    20 #include "nsVoidArray.h"
    21 #include "nsString.h"
    22 #include "nsIChannel.h"
    23 #include "nsIProgressEventSink.h"
    24 #include "nsIInterfaceRequestor.h"
    25 #include "nsIInterfaceRequestorUtils.h"
    26 #include "nsIChannelEventSink.h"
    27 #include "nsISecurityEventSink.h"
    28 #include "nsISupportsPriority.h"
    29 #include "nsCOMPtr.h"
    30 #include "pldhash.h"
    31 #include "nsAutoPtr.h"
    33 #include "mozilla/LinkedList.h"
    35 struct nsListenerInfo;
    37 /****************************************************************************
    38  * nsDocLoader implementation...
    39  ****************************************************************************/
    41 #define NS_THIS_DOCLOADER_IMPL_CID                    \
    42  { /* b4ec8387-98aa-4c08-93b6-6d23069c06f2 */         \
    43      0xb4ec8387,                                      \
    44      0x98aa,                                          \
    45      0x4c08,                                          \
    46      {0x93, 0xb6, 0x6d, 0x23, 0x06, 0x9c, 0x06, 0xf2} \
    47  }
    49 class nsDocLoader : public nsIDocumentLoader, 
    50                     public nsIRequestObserver,
    51                     public nsSupportsWeakReference,
    52                     public nsIProgressEventSink,
    53                     public nsIWebProgress,
    54                     public nsIInterfaceRequestor,
    55                     public nsIChannelEventSink,
    56                     public nsISecurityEventSink,
    57                     public nsISupportsPriority
    58 {
    59 public:
    60     NS_DECLARE_STATIC_IID_ACCESSOR(NS_THIS_DOCLOADER_IMPL_CID)
    62     nsDocLoader();
    64     virtual nsresult Init();
    66     static already_AddRefed<nsDocLoader> GetAsDocLoader(nsISupports* aSupports);
    67     // Needed to deal with ambiguous inheritance from nsISupports...
    68     static nsISupports* GetAsSupports(nsDocLoader* aDocLoader) {
    69         return static_cast<nsIDocumentLoader*>(aDocLoader);
    70     }
    72     // Add aDocLoader as a child to the docloader service.
    73     static nsresult AddDocLoaderAsChildOfRoot(nsDocLoader* aDocLoader);
    75     NS_DECL_ISUPPORTS
    76     NS_DECL_NSIDOCUMENTLOADER
    78     // nsIProgressEventSink
    79     NS_DECL_NSIPROGRESSEVENTSINK
    81     NS_DECL_NSISECURITYEVENTSINK
    83     // nsIRequestObserver methods: (for observing the load group)
    84     NS_DECL_NSIREQUESTOBSERVER
    85     NS_DECL_NSIWEBPROGRESS
    87     NS_DECL_NSIINTERFACEREQUESTOR
    88     NS_DECL_NSICHANNELEVENTSINK
    89     NS_DECL_NSISUPPORTSPRIORITY
    91     // Implementation specific methods...
    93     // Remove aChild from our childlist.  This nulls out the child's mParent
    94     // pointer.
    95     nsresult RemoveChildLoader(nsDocLoader *aChild);
    96     // Add aChild to our child list.  This will set aChild's mParent pointer to
    97     // |this|.
    98     nsresult AddChildLoader(nsDocLoader* aChild);
    99     nsDocLoader* GetParent() const { return mParent; }
   101 protected:
   102     virtual ~nsDocLoader();
   104     virtual nsresult SetDocLoaderParent(nsDocLoader * aLoader);
   106     bool IsBusy();
   108     void Destroy();
   109     virtual void DestroyChildren();
   111     nsIDocumentLoader* ChildAt(int32_t i) {
   112         return mChildList.SafeElementAt(i, nullptr);
   113     }
   115     void FireOnProgressChange(nsDocLoader* aLoadInitiator,
   116                               nsIRequest *request,
   117                               int64_t aProgress,
   118                               int64_t aProgressMax,
   119                               int64_t aProgressDelta,
   120                               int64_t aTotalProgress,
   121                               int64_t aMaxTotalProgress);
   123     // This should be at least 2 long since we'll generally always
   124     // have the current page and the global docloader on the ancestor
   125     // list.  But to deal with frames it's better to make it a bit
   126     // longer, and it's always a stack temporary so there's no real
   127     // reason not to.
   128     typedef nsAutoTArray<nsRefPtr<nsDocLoader>, 8> WebProgressList;
   129     void GatherAncestorWebProgresses(WebProgressList& aList);
   131     void FireOnStateChange(nsIWebProgress *aProgress,
   132                            nsIRequest* request,
   133                            int32_t aStateFlags,
   134                            nsresult aStatus);
   136     // The guts of FireOnStateChange, but does not call itself on our ancestors.
   137     // The arguments that are const are const so that we can detect cases when
   138     // DoFireOnStateChange wants to propagate changes to the next web progress
   139     // at compile time.  The ones that are not, are references so that such
   140     // changes can be propagated.
   141     void DoFireOnStateChange(nsIWebProgress * const aProgress,
   142                              nsIRequest* const request,
   143                              int32_t &aStateFlags,
   144                              const nsresult aStatus);
   146     void FireOnStatusChange(nsIWebProgress *aWebProgress,
   147                             nsIRequest *aRequest,
   148                             nsresult aStatus,
   149                             const char16_t* aMessage);
   151     void FireOnLocationChange(nsIWebProgress* aWebProgress,
   152                               nsIRequest* aRequest,
   153                               nsIURI *aUri,
   154                               uint32_t aFlags);
   156     bool RefreshAttempted(nsIWebProgress* aWebProgress,
   157                             nsIURI *aURI,
   158                             int32_t aDelay,
   159                             bool aSameURI);
   161     // this function is overridden by the docshell, it is provided so that we
   162     // can pass more information about redirect state (the normal OnStateChange
   163     // doesn't get the new channel).
   164     // @param aRedirectFlags The flags being sent to OnStateChange that
   165     //                       indicate the type of redirect.
   166     // @param aStateFlags    The channel flags normally sent to OnStateChange.
   167     virtual void OnRedirectStateChange(nsIChannel* aOldChannel,
   168                                        nsIChannel* aNewChannel,
   169                                        uint32_t aRedirectFlags,
   170                                        uint32_t aStateFlags) {}
   172     void doStartDocumentLoad();
   173     void doStartURLLoad(nsIRequest *request);
   174     void doStopURLLoad(nsIRequest *request, nsresult aStatus);
   175     void doStopDocumentLoad(nsIRequest *request, nsresult aStatus);
   177     // Inform a parent docloader that aChild is about to call its onload
   178     // handler.
   179     bool ChildEnteringOnload(nsIDocumentLoader* aChild) {
   180         // It's ok if we're already in the list -- we'll just be in there twice
   181         // and then the RemoveObject calls from ChildDoneWithOnload will remove
   182         // us.
   183         return mChildrenInOnload.AppendObject(aChild);
   184     }
   186     // Inform a parent docloader that aChild is done calling its onload
   187     // handler.
   188     void ChildDoneWithOnload(nsIDocumentLoader* aChild) {
   189         mChildrenInOnload.RemoveObject(aChild);
   190         DocLoaderIsEmpty(true);
   191     }        
   193 protected:
   194     struct nsStatusInfo : public mozilla::LinkedListElement<nsStatusInfo>
   195     {
   196         nsString mStatusMessage;
   197         nsresult mStatusCode;
   198         // Weak mRequest is ok; we'll be told if it decides to go away.
   199         nsIRequest * const mRequest;
   201         nsStatusInfo(nsIRequest* aRequest) :
   202             mRequest(aRequest)
   203         {
   204             MOZ_COUNT_CTOR(nsStatusInfo);
   205         }
   206         ~nsStatusInfo()
   207         {
   208             MOZ_COUNT_DTOR(nsStatusInfo);
   209         }
   210     };
   212     struct nsRequestInfo : public PLDHashEntryHdr
   213     {
   214         nsRequestInfo(const void* key)
   215             : mKey(key), mCurrentProgress(0), mMaxProgress(0), mUploading(false)
   216             , mLastStatus(nullptr)
   217         {
   218             MOZ_COUNT_CTOR(nsRequestInfo);
   219         }
   221         ~nsRequestInfo()
   222         {
   223             MOZ_COUNT_DTOR(nsRequestInfo);
   224         }
   226         nsIRequest* Request() {
   227             return static_cast<nsIRequest*>(const_cast<void*>(mKey));
   228         }
   230         const void* mKey; // Must be first for the pldhash stubs to work
   231         int64_t mCurrentProgress;
   232         int64_t mMaxProgress;
   233         bool mUploading;
   235         nsAutoPtr<nsStatusInfo> mLastStatus;
   236     };
   238     static bool RequestInfoHashInitEntry(PLDHashTable* table, PLDHashEntryHdr* entry,
   239                                          const void* key);
   240     static void RequestInfoHashClearEntry(PLDHashTable* table, PLDHashEntryHdr* entry);
   242     // IMPORTANT: The ownership implicit in the following member
   243     // variables has been explicitly checked and set using nsCOMPtr
   244     // for owning pointers and raw COM interface pointers for weak
   245     // (ie, non owning) references. If you add any members to this
   246     // class, please make the ownership explicit (pinkerton, scc).
   248     nsCOMPtr<nsIRequest>       mDocumentRequest;       // [OWNER] ???compare with document
   250     nsDocLoader*               mParent;                // [WEAK]
   252     nsVoidArray                mListenerInfoList;
   254     nsCOMPtr<nsILoadGroup>        mLoadGroup;
   255     // We hold weak refs to all our kids
   256     nsTObserverArray<nsDocLoader*> mChildList;
   258     // The following member variables are related to the new nsIWebProgress 
   259     // feedback interfaces that travis cooked up.
   260     int32_t mProgressStateFlags;
   262     int64_t mCurrentSelfProgress;
   263     int64_t mMaxSelfProgress;
   265     int64_t mCurrentTotalProgress;
   266     int64_t mMaxTotalProgress;
   268     PLDHashTable mRequestInfoHash;
   269     int64_t mCompletedTotalProgress;
   271     mozilla::LinkedList<nsStatusInfo> mStatusInfoList;
   273     /*
   274      * This flag indicates that the loader is loading a document.  It is set
   275      * from the call to LoadDocument(...) until the OnConnectionsComplete(...)
   276      * notification is fired...
   277      */
   278     bool mIsLoadingDocument;
   280     /* Flag to indicate that we're in the process of restoring a document. */
   281     bool mIsRestoringDocument;
   283     /* Flag to indicate that we're in the process of flushing layout
   284        under DocLoaderIsEmpty() and should not do another flush. */
   285     bool mDontFlushLayout;
   287     /* Flag to indicate whether we should consider ourselves as currently
   288        flushing layout for the purposes of IsBusy. For example, if Stop has
   289        been called then IsBusy should return false even if we are still
   290        flushing. */
   291     bool mIsFlushingLayout;
   293 private:
   294     // A list of kids that are in the middle of their onload calls and will let
   295     // us know once they're done.  We don't want to fire onload for "normal"
   296     // DocLoaderIsEmpty calls (those coming from requests finishing in our
   297     // loadgroup) unless this is empty.
   298     nsCOMArray<nsIDocumentLoader> mChildrenInOnload;
   300     // DocLoaderIsEmpty should be called whenever the docloader may be empty.
   301     // This method is idempotent and does nothing if the docloader is not in
   302     // fact empty.  This method _does_ make sure that layout is flushed if our
   303     // loadgroup has no active requests before checking for "real" emptiness if
   304     // aFlushLayout is true.
   305     void DocLoaderIsEmpty(bool aFlushLayout);
   307     nsListenerInfo *GetListenerInfo(nsIWebProgressListener* aListener);
   309     int64_t GetMaxTotalProgress();
   311     nsresult AddRequestInfo(nsIRequest* aRequest);
   312     void RemoveRequestInfo(nsIRequest* aRequest);
   313     nsRequestInfo *GetRequestInfo(nsIRequest* aRequest);
   314     void ClearRequestInfoHash();
   315     int64_t CalculateMaxProgress();
   316     static PLDHashOperator CalcMaxProgressCallback(PLDHashTable* table,
   317                                                    PLDHashEntryHdr* hdr,
   318                                                    uint32_t number, void* arg);
   319 ///    void DumpChannelInfo(void);
   321     // used to clear our internal progress state between loads...
   322     void ClearInternalProgress(); 
   323 };
   325 NS_DEFINE_STATIC_IID_ACCESSOR(nsDocLoader, NS_THIS_DOCLOADER_IMPL_CID)
   327 #endif /* nsDocLoader_h__ */

mercurial