+
X
Mozilla Home
Privacy
Cookies
Legal
Bugzilla
Browse
Advanced Search
New Bug
Reports
Documentation
Log In
Log In with GitHub
or
Remember me
Browse
Advanced Search
New Bug
Reports
Documentation
Attachment 524173 Details for
Bug 570341
[patch]
Implementation and some tests
timing_20110406.diff (text/plain), 82.11 KB, created by
Igor Bazarny
(
hide
)
Description:
Implementation and some tests
Filename:
MIME Type:
Creator:
Igor Bazarny
Size:
82.11 KB
patch
obsolete
>diff -r 385684ad7eed content/base/public/nsIDocument.h >--- a/content/base/public/nsIDocument.h Tue Apr 05 09:19:34 2011 -0700 >+++ b/content/base/public/nsIDocument.h Wed Apr 06 15:14:13 2011 +0200 >@@ -104,16 +104,17 @@ class nsIDocumentObserver; > class nsBindingManager; > class nsIDOMNodeList; > class mozAutoSubtreeModified; > struct JSObject; > class nsFrameLoader; > class nsIBoxObject; > class imgIRequest; > class nsISHEntry; >+class nsIDOMPerformanceTiming; > > namespace mozilla { > namespace css { > class Loader; > } // namespace css > > namespace dom { > class Link; >@@ -1511,16 +1512,21 @@ public: > virtual nsresult AddImage(imgIRequest* aImage) = 0; > virtual nsresult RemoveImage(imgIRequest* aImage) = 0; > > // Makes the images on this document locked/unlocked. By default, the locking > // state is unlocked/false. > virtual nsresult SetImageLockingState(PRBool aLocked) = 0; > > virtual nsresult GetMozCurrentStateObject(nsIVariant** aResult) = 0; >+ >+ virtual nsresult GetNavigationTiming(nsIDOMPerformanceTiming** aResult) const = 0; >+ >+ virtual nsresult SetNavigationTiming(nsIDOMPerformanceTiming* aTiming) = 0; >+ > > protected: > ~nsIDocument() > { > // XXX The cleanup of mNodeInfoManager (calling DropDocumentReference and > // releasing it) happens in the nsDocument destructor. We'd prefer to > // do it here but nsNodeInfoManager is a concrete class that we don't > // want to expose to users of the nsIDocument API outside of Gecko. >@@ -1686,16 +1692,17 @@ protected: > // document. > nsCOMPtr<nsIDocument> mOriginalDocument; > > // The bidi options for this document. What this bitfield means is > // defined in nsBidiUtils.h > PRUint32 mBidiOptions; > > nsCString mContentLanguage; >+ > private: > nsCString mContentType; > protected: > > // The document's security info > nsCOMPtr<nsISupports> mSecurityInfo; > > // if this document is part of a multipart document, >diff -r 385684ad7eed content/base/src/nsDocument.cpp >--- a/content/base/src/nsDocument.cpp Tue Apr 05 09:19:34 2011 -0700 >+++ b/content/base/src/nsDocument.cpp Wed Apr 06 15:14:13 2011 +0200 >@@ -181,16 +181,17 @@ static NS_DEFINE_CID(kDOMEventGroupCID, > #include "nsEscape.h" > #ifdef MOZ_MEDIA > #include "nsHTMLMediaElement.h" > #endif // MOZ_MEDIA > > #include "mozAutoDocUpdate.h" > #include "nsGlobalWindow.h" > #include "mozilla/dom/indexedDB/IndexedDatabaseManager.h" >+#include "nsDOMNavigationTiming.h" > > #ifdef MOZ_SMIL > #include "nsSMILAnimationController.h" > #include "imgIContainer.h" > #include "nsSVGUtils.h" > #endif // MOZ_SMIL > > #include "nsRefreshDriver.h" >@@ -4155,24 +4156,32 @@ void > nsDocument::DispatchContentLoadedEvents() > { > NS_TIME_FUNCTION; > // If you add early returns from this method, make sure you're > // calling UnblockOnload properly. > > // Unpin references to preloaded images > mPreloadingImages.Clear(); >+ >+ if (mTiming) { >+ mTiming->NotifyDOMContentLoadedStart(nsIDocument::GetDocumentURI()); >+ } > > // Fire a DOM event notifying listeners that this document has been > // loaded (excluding images and other loads initiated by this > // document). > nsContentUtils::DispatchTrustedEvent(this, static_cast<nsIDocument*>(this), > NS_LITERAL_STRING("DOMContentLoaded"), > PR_TRUE, PR_TRUE); > >+ if (mTiming) { >+ mTiming->NotifyDOMContentLoadedEnd(nsIDocument::GetDocumentURI()); >+ } >+ > // If this document is a [i]frame, fire a DOMFrameContentLoaded > // event on all parent documents notifying that the HTML (excluding > // other external files such as images and stylesheets) in a frame > // has finished loading. > > // target_frame is the [i]frame element that will be used as the > // target for the event. It's the [i]frame whose content is done > // loading. >@@ -4221,17 +4230,17 @@ nsDocument::DispatchContentLoadedEvents( > > if (context) { > nsEventDispatcher::Dispatch(parent, context, innerEvent, event, > &status); > } > } > } > } >- >+ > parent = parent->GetParentDocument(); > } while (parent); > } > > // If the document has a manifest attribute, fire a MozApplicationManifest > // event. > Element* root = GetRootElement(); > if (root && root->HasAttr(kNameSpaceID_None, nsGkAtoms::manifest)) { >@@ -7758,16 +7767,36 @@ nsDocument::CloneDocHelper(nsDocument* c > clone->mBaseTarget = mBaseTarget; > return NS_OK; > } > > void > nsDocument::SetReadyStateInternal(ReadyState rs) > { > mReadyState = rs; >+ if (mTiming) { >+ switch (rs) { >+ case READYSTATE_LOADING: >+ mTiming->NotifyDOMLoading(nsIDocument::GetDocumentURI()); >+ break; >+ case READYSTATE_INTERACTIVE: >+ mTiming->NotifyDOMInteractive(nsIDocument::GetDocumentURI()); >+ break; >+ case READYSTATE_COMPLETE: >+ mTiming->NotifyDOMComplete(nsIDocument::GetDocumentURI()); >+ break; >+ default: >+ NS_WARNING("Unexpected ReadyState value"); >+ break; >+ } >+ } >+ // At the time of loading start, we don't have timing object, record time. >+ if (READYSTATE_LOADING == rs) { >+ mLoadingTime = PR_Now() / PR_USEC_PER_MSEC; >+ } > > nsRefPtr<nsPLDOMEvent> plevent = > new nsPLDOMEvent(this, NS_LITERAL_STRING("readystatechange"), PR_FALSE, PR_FALSE); > if (plevent) { > plevent->RunDOMEventWhenSafe(); > } > } > >@@ -8252,16 +8281,31 @@ nsDocument::GetMozCurrentStateObject(nsI > } > > NS_IF_ADDREF(*aState = mCurrentStateObjectCached); > > return NS_OK; > } > > nsresult >+nsDocument::GetNavigationTiming(nsIDOMPerformanceTiming** aResult) const { >+ NS_IF_ADDREF(*aResult = mTiming); >+ return NS_OK; >+} >+ >+nsresult >+nsDocument::SetNavigationTiming(nsIDOMPerformanceTiming* aTiming) { >+ mTiming = static_cast<nsDOMNavigationTiming*>(aTiming); >+ if (mLoadingTime) { >+ mTiming->SetDOMLoading(nsIDocument::GetDocumentURI(), mLoadingTime); >+ } >+ return NS_OK; >+} >+ >+nsresult > nsDocument::AddImage(imgIRequest* aImage) > { > NS_ENSURE_ARG_POINTER(aImage); > > // See if the image is already in the hashtable. If it is, get the old count. > PRUint32 oldCount = 0; > mImageTracker.Get(aImage, &oldCount); > >diff -r 385684ad7eed content/base/src/nsDocument.h >--- a/content/base/src/nsDocument.h Tue Apr 05 09:19:34 2011 -0700 >+++ b/content/base/src/nsDocument.h Wed Apr 06 15:14:13 2011 +0200 >@@ -126,16 +126,18 @@ class nsIRadioVisitor; > class nsIFormControl; > struct nsRadioGroupStruct; > class nsOnloadBlocker; > class nsUnblockOnloadEvent; > class nsChildContentList; > class nsXMLEventsManager; > class nsHTMLStyleSheet; > class nsHTMLCSSStyleSheet; >+class nsIDOMNavigationTiming; >+class nsDOMNavigationTiming; > > /** > * Right now our identifier map entries contain information for 'name' > * and 'id' mappings of a given string. This is so that > * nsHTMLDocument::ResolveName only has to do one hash lookup instead > * of two. It's not clear whether this still matters for performance. > * > * We also store the document.all result list here. This is mainly so that >@@ -982,16 +984,20 @@ public: > virtual Element *LookupImageElement(const nsAString& aElementId); > > virtual NS_HIDDEN_(nsresult) AddImage(imgIRequest* aImage); > virtual NS_HIDDEN_(nsresult) RemoveImage(imgIRequest* aImage); > virtual NS_HIDDEN_(nsresult) SetImageLockingState(PRBool aLocked); > > virtual nsresult GetMozCurrentStateObject(nsIVariant** aResult); > >+ virtual nsresult GetNavigationTiming(nsIDOMPerformanceTiming** aResult) const; >+ >+ virtual nsresult SetNavigationTiming(nsIDOMPerformanceTiming* aTiming); >+ > protected: > friend class nsNodeUtils; > > /** > * Check that aId is not empty and log a message to the console > * service if it is. > * @returns PR_TRUE if aId looks correct, PR_FALSE otherwise. > */ >@@ -1116,16 +1122,19 @@ protected: > * 2) Removals from the DOM affect the table immediately > * 3) Additions to the DOM always update existing entries for names, and add > * new ones for IDs. > */ > nsTHashtable<nsIdentifierMapEntry> mIdentifierMap; > > nsClassHashtable<nsStringHashKey, nsRadioGroupStruct> mRadioGroups; > >+ // Recorded time of change to 'loading' state. >+ DOMTimeMilliSec mLoadingTime; >+ > // True if the document has been detached from its content viewer. > PRPackedBool mIsGoingAway:1; > // True if the document is being destroyed. > PRPackedBool mInDestructor:1; > > // True if this document has ever had an HTML or SVG <title> element > // bound to it > PRPackedBool mMayHaveTitleElement:1; >@@ -1174,16 +1183,17 @@ protected: > // any. This can change during the lifetime of the document. > nsCOMPtr<nsIApplicationCache> mApplicationCache; > > nsCOMPtr<nsIContent> mFirstBaseNodeWithHref; > > nsEventStates mDocumentState; > nsEventStates mGotDocumentState; > >+ nsRefPtr<nsDOMNavigationTiming> mTiming; > private: > friend class nsUnblockOnloadEvent; > > void PostUnblockOnloadEvent(); > void DoUnblockOnload(); > > nsresult CheckFrameOptions(); > nsresult InitCSP(); >diff -r 385684ad7eed docshell/base/Makefile.in >--- a/docshell/base/Makefile.in Tue Apr 05 09:19:34 2011 -0700 >+++ b/docshell/base/Makefile.in Wed Apr 06 15:14:13 2011 +0200 >@@ -113,10 +113,11 @@ CPPSRCS = \ > # we don't want the shared lib, but we want to force the creation of a > # static lib. > FORCE_STATIC_LIB = 1 > > include $(topsrcdir)/config/rules.mk > > LOCAL_INCLUDES += \ > -I$(srcdir)/../shistory/src \ >+ -I$(topsrcdir)/dom/base \ > -I$(topsrcdir)/layout/base \ > $(NULL) >diff -r 385684ad7eed docshell/base/nsDocShell.cpp >--- a/docshell/base/nsDocShell.cpp Tue Apr 05 09:19:34 2011 -0700 >+++ b/docshell/base/nsDocShell.cpp Wed Apr 06 15:14:13 2011 +0200 >@@ -228,16 +228,18 @@ static NS_DEFINE_CID(kAppShellCID, NS_AP > #include "nsContentErrors.h" > #include "nsIChannelPolicy.h" > #include "nsIContentSecurityPolicy.h" > > #ifdef MOZ_IPC > #include "nsXULAppAPI.h" > #endif > >+#include "nsDOMNavigationTiming.h" >+ > using namespace mozilla; > > // Number of documents currently loading > static PRInt32 gNumberOfDocumentsLoading = 0; > > // Global count of existing docshells. > static PRInt32 gDocShellCount = 0; > >@@ -669,16 +671,55 @@ DispatchPings(nsIContent *content, nsIUR > return; > > info.numPings = 0; > info.referrer = referrer; > > ForEachPing(content, SendPing, &info); > } > >+static nsDOMPerformanceNavigationType >+ConvertLoadTypeToNavigationType(PRUint32 aLoadType) >+{ >+ nsDOMPerformanceNavigationType result = nsIDOMPerformanceNavigation::TYPE_RESERVED; >+ switch (aLoadType) { >+ case LOAD_NORMAL: >+ case LOAD_NORMAL_EXTERNAL: >+ case LOAD_NORMAL_BYPASS_CACHE: >+ case LOAD_NORMAL_BYPASS_PROXY: >+ case LOAD_NORMAL_BYPASS_PROXY_AND_CACHE: >+ case LOAD_LINK: >+ result = nsIDOMPerformanceNavigation::TYPE_NAVIGATE; >+ break; >+ case LOAD_HISTORY: >+ result = nsIDOMPerformanceNavigation::TYPE_BACK_FORWARD; >+ break; >+ case LOAD_RELOAD_NORMAL: >+ case LOAD_RELOAD_CHARSET_CHANGE: >+ case LOAD_RELOAD_BYPASS_CACHE: >+ case LOAD_RELOAD_BYPASS_PROXY: >+ case LOAD_RELOAD_BYPASS_PROXY_AND_CACHE: >+ result = nsIDOMPerformanceNavigation::TYPE_RELOAD; >+ break; >+ case LOAD_NORMAL_REPLACE: >+ case LOAD_STOP_CONTENT: >+ case LOAD_STOP_CONTENT_AND_REPLACE: >+ case LOAD_REFRESH: >+ case LOAD_BYPASS_HISTORY: >+ case LOAD_ERROR_PAGE: >+ case LOAD_PUSHSTATE: >+ result = nsIDOMPerformanceNavigation::TYPE_RESERVED; >+ break; >+ default: >+ NS_NOTREACHED("Unexpected load type value"); >+ } >+ >+ return result; >+} >+ > static nsISHEntry* GetRootSHEntry(nsISHEntry *entry); > > //***************************************************************************** > //*** nsDocShell: Object Management > //***************************************************************************** > > static PRUint64 gDocshellIDCounter = 0; > >@@ -1533,16 +1574,30 @@ nsDocShell::FirePageHideNotification(PRB > // Now make sure our editor, if any, is detached before we go > // any farther. > DetachEditorFromWindow(); > } > > return NS_OK; > } > >+nsresult >+nsDocShell::InitTiming() >+{ >+ if (mTiming) { >+ return NS_OK; >+ } >+ mTiming = new nsDOMNavigationTiming(); >+ NS_ENSURE_TRUE(mTiming, NS_ERROR_OUT_OF_MEMORY); >+ >+ mTiming->NotifyNavigationStart(); >+ return NS_OK; >+} >+ >+ > // > // Bug 13871: Prevent frameset spoofing > // > // This routine answers: 'Is origin's document from same domain as > // target's document?' > // > // file: uris are considered the same domain for the purpose of > // frame navigation regardless of script accessibility (bug 420425) >@@ -5839,25 +5894,33 @@ nsDocShell::OnProgressChange(nsIWebProgr > > NS_IMETHODIMP > nsDocShell::OnStateChange(nsIWebProgress * aProgress, nsIRequest * aRequest, > PRUint32 aStateFlags, nsresult aStatus) > { > nsresult rv; > > if ((~aStateFlags & (STATE_START | STATE_IS_NETWORK)) == 0) { >+ // Save timing statistics. >+ nsCOMPtr<nsIChannel> channel(do_QueryInterface(aRequest)); >+ // Make sure timing is created >+ rv = InitTiming(); >+ NS_ENSURE_SUCCESS(rv, rv); >+ nsCOMPtr<nsIURI> uri; >+ channel->GetURI(getter_AddRefs(uri)); >+ if (mTiming) { >+ mTiming->NotifyFetchStart(uri, ConvertLoadTypeToNavigationType(mLoadType)); >+ } >+ > nsCOMPtr<nsIWyciwygChannel> wcwgChannel(do_QueryInterface(aRequest)); > nsCOMPtr<nsIWebProgress> webProgress = > do_QueryInterface(GetAsSupports(this)); > > // Was the wyciwyg document loaded on this docshell? > if (wcwgChannel && !mLSHE && (mItemType == typeContent) && aProgress == webProgress.get()) { >- nsCOMPtr<nsIURI> uri; >- wcwgChannel->GetURI(getter_AddRefs(uri)); >- > PRBool equalUri = PR_TRUE; > // Store the wyciwyg url in session history, only if it is > // being loaded fresh for the first time. We don't want > // multiple entries for successive loads > if (mCurrentURI && > NS_SUCCEEDED(uri->Equals(mCurrentURI, &equalUri)) && > !equalUri) { > >@@ -5967,19 +6030,27 @@ nsDocShell::OnRedirectStateChange(nsICha > NS_ASSERTION(aStateFlags & STATE_REDIRECTING, > "Calling OnRedirectStateChange when there is no redirect"); > if (!(aStateFlags & STATE_IS_DOCUMENT)) > return; // not a toplevel document > > nsCOMPtr<nsIURI> oldURI, newURI; > aOldChannel->GetURI(getter_AddRefs(oldURI)); > aNewChannel->GetURI(getter_AddRefs(newURI)); >+ > if (!oldURI || !newURI) { > return; > } >+ // On session restore we get a redirect from page to itself. Don't count it. >+ PRBool equals = PR_FALSE; >+ if (mTiming >+ && !(mLoadType == LOAD_HISTORY >+ && NS_SUCCEEDED(newURI->Equals(oldURI, &equals)) && equals)) { >+ mTiming->NotifyRedirect(oldURI, newURI); >+ } > > // Below a URI visit is saved (see AddURIVisit method doc). > // The visit chain looks something like: > // ... > // Site N - 1 > // => Site N > // (redirect to =>) Site N + 1 (we are here!) > >@@ -6055,17 +6126,20 @@ nsDocShell::EndPageLoad(nsIWebProgress * > nsIChannel * aChannel, nsresult aStatus) > { > if(!aChannel) > return NS_ERROR_NULL_POINTER; > > nsCOMPtr<nsIURI> url; > nsresult rv = aChannel->GetURI(getter_AddRefs(url)); > if (NS_FAILED(rv)) return rv; >- >+ >+ // Timing is picked up by the window, we don't need it anymore >+ mTiming = nsnull; >+ > // clean up reload state for meta charset > if (eCharsetReloadRequested == mCharsetReloadState) > mCharsetReloadState = eCharsetReloadStopOrigional; > else > mCharsetReloadState = eCharsetReloadInit; > > // Save a pointer to the currently-loading history entry. > // nsDocShell::EndPageLoad will clear mLSHE, but we may need this history >@@ -6091,16 +6165,17 @@ nsDocShell::EndPageLoad(nsIWebProgress * > // If all documents have completed their loading > // favor native event dispatch priorities > // over performance > if (--gNumberOfDocumentsLoading == 0) { > // Hint to use normal native event dispatch priorities > FavorPerformanceHint(PR_FALSE, NS_EVENT_STARVATION_DELAY_HINT); > } > } >+ > /* Check if the httpChannel has any cache-control related response headers, > * like no-store, no-cache. If so, update SHEntry so that > * when a user goes back/forward to this page, we appropriately do > * form value restoration or load from server. > */ > nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(aChannel)); > if (!httpChannel) // HttpChannel could be hiding underneath a Multipart channel. > GetHttpChannel(aChannel, getter_AddRefs(httpChannel)); >@@ -6484,27 +6559,37 @@ nsDocShell::CreateAboutBlankContentViewe > nsCOMPtr<nsIDocShell> kungFuDeathGrip(this); > > if (mContentViewer) { > // We've got a content viewer already. Make sure the user > // permits us to discard the current document and replace it > // with about:blank. And also ensure we fire the unload events > // in the current document. > >+ // Make sure timing is created. Unload gets fired first for >+ // document loaded from the session history. >+ rv = InitTiming(); >+ if (mTiming) { >+ mTiming->NotifyBeforeUnload(); >+ } >+ > PRBool okToUnload; > rv = mContentViewer->PermitUnload(PR_FALSE, &okToUnload); > > if (NS_SUCCEEDED(rv) && !okToUnload) { > // The user chose not to unload the page, interrupt the load. > return NS_ERROR_FAILURE; > } > > mSavingOldViewer = aTryToSaveOldPresentation && > CanSavePresentation(LOAD_NORMAL, nsnull, nsnull); > >+ if (mTiming) { >+ mTiming->NotifyUnloadAccepted(mCurrentURI); >+ } > // Make sure to blow away our mLoadingURI just in case. No loads > // from inside this pagehide. > mLoadingURI = nsnull; > > // Notify the current document that it is about to be unloaded!! > // > // It is important to fire the unload() notification *before* any state > // is changed within the DocShell - otherwise, javascript will get the >@@ -7759,16 +7844,19 @@ nsDocShell::SetupNewViewer(nsIContentVie > > if (docviewer) { > nsCOMPtr<nsIPresShell> shell; > docviewer->GetPresShell(getter_AddRefs(shell)); > > if (shell) { > shell->SetCanvasBackground(bgcolor); > } >+ docviewer->SetNavigationTiming(mTiming); >+ // Now timing is held and notified by viewer and doc, we don't need it. >+ // mTiming = nsnull; > } > > // XXX: It looks like the LayoutState gets restored again in Embed() > // right after the call to SetupNewViewer(...) > > // We don't show the mContentViewer yet, since we want to draw the old page > // until we have enough of the new page to show. Just return with the new > // viewer still set to hidden. >@@ -8462,30 +8550,38 @@ nsDocShell::InternalLoad(nsIURI * aURI, > } > } > > // mContentViewer->PermitUnload can destroy |this| docShell, which > // causes the next call of CanSavePresentation to crash. > // Hold onto |this| until we return, to prevent a crash from happening. > // (bug#331040) > nsCOMPtr<nsIDocShell> kungFuDeathGrip(this); >- >+ >+ rv = InitTiming(); >+ if (mTiming) { >+ mTiming->NotifyBeforeUnload(); >+ } > // Check if the page doesn't want to be unloaded. The javascript: > // protocol handler deals with this for javascript: URLs. > if (!bIsJavascript && mContentViewer) { > PRBool okToUnload; > rv = mContentViewer->PermitUnload(PR_FALSE, &okToUnload); > > if (NS_SUCCEEDED(rv) && !okToUnload) { > // The user chose not to unload the page, interrupt the > // load. > return NS_OK; > } > } > >+ if (mTiming) { >+ mTiming->NotifyUnloadAccepted(mCurrentURI); >+ } >+ > // Check for saving the presentation here, before calling Stop(). > // This is necessary so that we can catch any pending requests. > // Since the new request has not been created yet, we pass null for the > // new request parameter. > // Also pass nsnull for the document, since it doesn't affect the return > // value for our purposes here. > PRBool savePresentation = CanSavePresentation(aLoadType, nsnull, nsnull); > >@@ -11765,16 +11861,23 @@ nsDocShell::GetPrintPreview(nsIWebBrowse > nsCOMPtr<nsIWebBrowserPrint> result = do_QueryInterface(print); > result.forget(aPrintPreview); > return NS_OK; > #else > return NS_ERROR_NOT_IMPLEMENTED; > #endif > } > >+NS_IMETHODIMP >+nsDocShell::GetNavigationTiming(nsIDOMPerformanceTiming** aNavigationTiming) >+{ >+ NS_IF_ADDREF(*aNavigationTiming = mTiming); >+ return NS_OK; >+} >+ > > #ifdef DEBUG > unsigned long nsDocShell::gNumberOfDocShells = 0; > #endif > > NS_IMETHODIMP > nsDocShell::GetCanExecuteScripts(PRBool *aResult) > { >diff -r 385684ad7eed docshell/base/nsDocShell.h >--- a/docshell/base/nsDocShell.h Tue Apr 05 09:19:34 2011 -0700 >+++ b/docshell/base/nsDocShell.h Wed Apr 06 15:14:13 2011 +0200 >@@ -115,16 +115,17 @@ > #include "nsIClipboardCommands.h" > #include "nsICommandManager.h" > #include "nsCRT.h" > > class nsDocShell; > class nsIController; > class OnLinkClickEvent; > class nsIScrollableFrame; >+class nsDOMNavigationTiming; > > /* load commands were moved to nsIDocShell.h */ > /* load types were moved to nsDocShellLoadTypes.h */ > > /* internally used ViewMode types */ > enum ViewMode { > viewNormal = 0x0, > viewSource = 0x1 >@@ -680,16 +681,18 @@ protected: > > nsIChannel* GetCurrentDocChannel(); > protected: > // Override the parent setter from nsDocLoader > virtual nsresult SetDocLoaderParent(nsDocLoader * aLoader); > > void ClearFrameHistory(nsISHEntry* aEntry); > >+ nsresult InitTiming(); >+ > // Event type dispatched by RestorePresentation > class RestorePresentationEvent : public nsRunnable { > public: > NS_DECL_NSIRUNNABLE > RestorePresentationEvent(nsDocShell *ds) : mDocShell(ds) {} > void Revoke() { mDocShell = nsnull; } > private: > nsRefPtr<nsDocShell> mDocShell; >@@ -833,16 +836,18 @@ protected: > PRPackedBool mDynamicallyCreated; > #ifdef DEBUG > PRPackedBool mInEnsureScriptEnv; > #endif > PRUint64 mHistoryID; > > static nsIURIFixup *sURIFixup; > >+ nsRefPtr<nsDOMNavigationTiming> mTiming; >+ > #ifdef DEBUG > private: > // We're counting the number of |nsDocShells| to help find leaks > static unsigned long gNumberOfDocShells; > #endif /* DEBUG */ > > public: > class InterfaceRequestorProxy : public nsIInterfaceRequestor { >diff -r 385684ad7eed docshell/base/nsIDocShell.idl >--- a/docshell/base/nsIDocShell.idl Tue Apr 05 09:19:34 2011 -0700 >+++ b/docshell/base/nsIDocShell.idl Wed Apr 06 15:14:13 2011 +0200 >@@ -66,16 +66,17 @@ interface nsIInputStream; > interface nsIRequest; > interface nsISHEntry; > interface nsILayoutHistoryState; > interface nsISecureBrowserUI; > interface nsIDOMStorage; > interface nsIPrincipal; > interface nsIWebBrowserPrint; > interface nsIVariant; >+interface nsIDOMPerformanceTiming; > > [scriptable, uuid(f77271a1-0b22-4581-af6d-529125f1901d)] > interface nsIDocShell : nsISupports > { > /** > * Loads a given URI. This will give priority to loading the requested URI > * in the object implementing this interface. If it can't be loaded here > * however, the URL dispatcher will go through its normal process of content >@@ -543,9 +544,14 @@ interface nsIDocShell : nsISupports > */ > attribute boolean isAppTab; > > /** > * Create a new about:blank document and content viewer. > * @param aPrincipal the principal to use for the new document. > */ > void createAboutBlankContentViewer(in nsIPrincipal aPrincipal); >+ >+ /** >+ * Time statistics been collected during last navigations. >+ */ >+ readonly attribute nsIDOMPerformanceTiming navigationTiming; > }; >diff -r 385684ad7eed docshell/test/Makefile.in >--- a/docshell/test/Makefile.in Tue Apr 05 09:19:34 2011 -0700 >+++ b/docshell/test/Makefile.in Wed Apr 06 15:14:13 2011 +0200 >@@ -95,16 +95,18 @@ _TEST_FILES = \ > file_bug590573_2.html \ > test_bug598895.html \ > test_bug634834.html \ > file_bug634834.html \ > test_bug637644.html \ > test_framedhistoryframes.html \ > test_windowedhistoryframes.html \ > historyframes.html \ >+ test_bug570341.html \ >+ bug570341_recordevents.html \ > $(NULL) > > ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa) > _TEST_FILES += \ > test_bug511449.html \ > file_bug511449.html \ > $(NULL) > endif >diff -r 385684ad7eed docshell/test/bug570341_recordevents.html >--- /dev/null Thu Jan 01 00:00:00 1970 +0000 >+++ b/docshell/test/bug570341_recordevents.html Wed Apr 06 15:14:13 2011 +0200 >@@ -0,0 +1,30 @@ >+<html> >+<head> >+<script> >+ window._testing_start = Date.now(); >+ window._testing_readyStateAtStart = document.readyState; >+ document.addEventListener('DOMContentLoaded', >+ function () { >+ window._testing_domContentLoaded = Date.now(); >+ }, true); >+ document.addEventListener('readystatechange', function(){ >+ switch (document.readyState) { >+ case 'loading': >+ window._testing_domLoading = Date.now(); >+ break; >+ case 'interactive': >+ window._testing_domInteractive = Date.now(); >+ break; >+ case 'complete': >+ window._testing_domComplete = Date.now(); >+ break; >+ } >+ }, true); >+ function recordLoad() { >+ window._testing_load = Date.now(); >+ } >+</script> >+</head> >+<body onload="recordLoad()">This document collects time >+for events related to the page load progress.</body> >+</html> >diff -r 385684ad7eed docshell/test/test_bug570341.html >--- /dev/null Thu Jan 01 00:00:00 1970 +0000 >+++ b/docshell/test/test_bug570341.html Wed Apr 06 15:14:13 2011 +0200 >@@ -0,0 +1,128 @@ >+<!DOCTYPE HTML> >+<html> >+<!-- >+https://bugzilla.mozilla.org/show_bug.cgi?id=570341 >+--> >+<head> >+ <title>Test for Bug 570341</title> >+ <script type="application/javascript" src="/MochiKit/packed.js"></script> >+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> >+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> >+<script> >+window.onload = function() { >+ var start = Date.now(); >+ var unload = 0; >+ var win = frames[0]; >+ win.addEventListener('unload', function(){ >+ unload = Date.now(); >+ }, true); >+ frames[0].location = 'bug570341_recordevents.html' >+ var seenLoad = 0; >+ var interval = setInterval(function () { >+ var stopPolling = (win.performance && win.performance.loadEventEnd) || >+ (seenLoad && Date.now() >= seenLoad + 200); >+ if (stopPolling) { >+ clearInterval(interval); >+ checkValues(); >+ } >+ if (win._testing_load) { >+ seenLoad = Date.now(); >+ } >+ }, 100); >+ function checkValues(){ >+ var node = document.getElementById('display'); >+ var timing = (win.performance && win.performance.timing) || {}; >+ var moments = {}; >+ for (var p in timing) { >+ moments[p] = timing[p]; >+ } >+ moments['evt_unload'] = unload; >+ moments['evt_DOMContentLoaded'] = win._testing_domContentLoaded; >+ moments['js_start'] = win._testing_start; >+ switch(win._testing_readyStateAtStart) { >+ case 'loading': >+ moments['js_afterDOMLoading'] = moments['js_start']; >+ break; >+ case 'interactive': >+ moments['js_afterDOMInteractive'] = moments['js_start']; >+ break; >+ case 'complete': >+ moments['js_afterDOMComplete'] = moments['js_start']; >+ break; >+ } >+ moments['evt_DOMLoading'] = win._testing_domLoading; >+ moments['evt_DOMInteractive'] = win._testing_domInteractive; >+ moments['evt_DOMComplete'] = win._testing_domComplete; >+ moments['evt_load'] = win._testing_load; >+ >+ var sequences = [ >+ ['navigationStart', 'unloadEventStart', /* 'evt_unload' ,*/ 'unloadEventEnd', 'fetchStart'], >+ ['navigationStart', 'fetchStart', 'domainLookupStart', 'domainLookupEnd', >+ 'connectStart', 'connectEnd', 'requestStart', 'responseStart', 'responseEnd'], >+ ['responseStart', 'domLoading', 'domInteractive', 'domComplete'], >+ [/* 'domComplete', */ >+ 'domContentLoadedEventStart', 'evt_DOMContentLoaded', 'domContentLoadedEventEnd', >+ 'loadEventStart', 'evt_load', 'loadEventEnd'] >+ ] >+ >+ var sequences_todo = [ >+ ['evt_unload' , 'unloadEventEnd'], >+ ['domComplete', 'domContentLoadedEventStart'] >+ ]; >+ node.appendChild(document.createElement('br')); >+ node.appendChild(document.createTextNode('start: ' + start)); >+ for (var i = 0; i < sequences.length; ++i) { >+ var seq = sequences[i]; >+ node.appendChild(document.createElement('hr')); >+ for (var j = 0; j < seq.length; ++j) { >+ var prop = seq[j]; >+ if (j > 0) { >+ var prevProp = seq[j-1]; >+ ok(moments[prevProp] <= moments[prop], >+ ['Expected ', prevProp, ' to happen before ', prop, >+ ', got ', prevProp, ' = ', moments[prevProp], >+ ', ', prop, ' = ', moments[prop]].join('')); >+ } >+ node.appendChild(document.createElement('br')); >+ node.appendChild(document.createTextNode(prop + ': ' + moments[prop])); >+ } >+ } >+ node.appendChild(document.createElement('hr')); >+ for (var i = 0; i < sequences_todo.length; ++i) { >+ var seq = sequences_todo[i]; >+ node.appendChild(document.createElement('hr')); >+ for (var j = 0; j < seq.length; ++j) { >+ var prop = seq[j]; >+ if (j > 0) { >+ var prevProp = seq[j-1]; >+ todo(moments[prevProp] <= moments[prop], >+ ['Expected ', prevProp, ' to happen before ', prop, >+ ', got ', prevProp, ' = ', moments[prevProp], >+ ', ', prop, ' = ', moments[prop]].join('')); >+ } >+ node.appendChild(document.createElement('br')); >+ node.appendChild(document.createTextNode(prop + ': ' + moments[prop])); >+ } >+ } >+ node.appendChild(document.createElement('hr')); >+ SimpleTest.finish() >+ } >+} >+</script> >+</head> >+<body> >+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=570341">Mozilla Bug 570341</a> >+<div id="frames"> >+<iframe name="child0" src="navigation/blank.html"></iframe> >+</div> >+<p id="display"></p> >+<div id="content" style="display: none"> >+ >+</div> >+<pre id="test"> >+<script type="application/javascript"> >+SimpleTest.waitForExplicitFinish(); >+</script> >+</pre> >+</body> >+</html> >diff -r 385684ad7eed dom/base/Makefile.in >--- a/dom/base/Makefile.in Tue Apr 05 09:19:34 2011 -0700 >+++ b/dom/base/Makefile.in Wed Apr 06 15:14:13 2011 +0200 >@@ -101,16 +101,18 @@ CPPSRCS = \ > nsHistory.cpp \ > nsMimeTypeArray.cpp \ > nsPluginArray.cpp \ > nsWindowRoot.cpp \ > nsDOMClassInfo.cpp \ > nsScriptNameSpaceManager.cpp \ > nsDOMScriptObjectFactory.cpp \ > nsQueryContentEventResult.cpp \ >+ nsDOMNavigationTiming.cpp \ >+ nsPerformance.cpp \ > $(NULL) > > ifdef MOZ_IPC > EXPORTS += \ > nsContentPermissionHelper.h \ > $(NULL) > CPPSRCS += \ > nsContentPermissionHelper.cpp \ >diff -r 385684ad7eed dom/base/nsDOMClassInfo.cpp >--- a/dom/base/nsDOMClassInfo.cpp Tue Apr 05 09:19:34 2011 -0700 >+++ b/dom/base/nsDOMClassInfo.cpp Wed Apr 06 15:14:13 2011 +0200 >@@ -113,16 +113,19 @@ > #include "nsIDOMWindowInternal.h" > #include "nsPIDOMWindow.h" > #include "nsIDOMJSWindow.h" > #include "nsIDOMWindowCollection.h" > #include "nsIDOMHistory.h" > #include "nsIDOMMediaList.h" > #include "nsIDOMChromeWindow.h" > #include "nsIDOMConstructor.h" >+#include "nsIDOMPerformanceTiming.h" >+#include "nsIDOMPerformanceNavigation.h" >+#include "nsIDOMPerformance.h" > #include "nsClientRect.h" > > // DOM core includes > #include "nsDOMError.h" > #include "nsIDOMDOMException.h" > #include "nsIDOMNode.h" > #include "nsIDOM3Node.h" > #include "nsIDOM3Attr.h" >@@ -662,16 +665,22 @@ static nsDOMClassInfoData sClassInfoData > DOM_DEFAULT_SCRIPTABLE_FLAGS) > NS_DEFINE_CLASSINFO_DATA(MimeTypeArray, nsMimeTypeArraySH, > ARRAY_SCRIPTABLE_FLAGS) > NS_DEFINE_CLASSINFO_DATA(BarProp, nsDOMGenericSH, > DOM_DEFAULT_SCRIPTABLE_FLAGS) > NS_DEFINE_CLASSINFO_DATA(History, nsHistorySH, > ARRAY_SCRIPTABLE_FLAGS | > nsIXPCScriptable::WANT_PRECREATE) >+ NS_DEFINE_CLASSINFO_DATA(PerformanceTiming, nsDOMGenericSH, >+ DOM_DEFAULT_SCRIPTABLE_FLAGS) >+ NS_DEFINE_CLASSINFO_DATA(PerformanceNavigation, nsDOMGenericSH, >+ DOM_DEFAULT_SCRIPTABLE_FLAGS) >+ NS_DEFINE_CLASSINFO_DATA(Performance, nsDOMGenericSH, >+ DOM_DEFAULT_SCRIPTABLE_FLAGS) > NS_DEFINE_CLASSINFO_DATA(Screen, nsDOMGenericSH, > DOM_DEFAULT_SCRIPTABLE_FLAGS) > NS_DEFINE_CLASSINFO_DATA(DOMPrototype, nsDOMConstructorSH, > DOM_BASE_SCRIPTABLE_FLAGS | > nsIXPCScriptable::WANT_PRECREATE | > nsIXPCScriptable::WANT_HASINSTANCE | > nsIXPCScriptable::DONT_ENUM_QUERY_INTERFACE) > NS_DEFINE_CLASSINFO_DATA(DOMConstructor, nsDOMConstructorSH, >@@ -2326,16 +2335,30 @@ nsDOMClassInfo::Init() > DOM_CLASSINFO_MAP_BEGIN(BarProp, nsIDOMBarProp) > DOM_CLASSINFO_MAP_ENTRY(nsIDOMBarProp) > DOM_CLASSINFO_MAP_END > > DOM_CLASSINFO_MAP_BEGIN(History, nsIDOMHistory) > DOM_CLASSINFO_MAP_ENTRY(nsIDOMHistory) > DOM_CLASSINFO_MAP_END > >+ // if (nsGlobalWindow::HasPerformanceSupport()) { >+ DOM_CLASSINFO_MAP_BEGIN(PerformanceTiming, nsIDOMPerformanceTiming) >+ DOM_CLASSINFO_MAP_ENTRY(nsIDOMPerformanceTiming) >+ DOM_CLASSINFO_MAP_END >+ >+ DOM_CLASSINFO_MAP_BEGIN(PerformanceNavigation, nsIDOMPerformanceNavigation) >+ DOM_CLASSINFO_MAP_ENTRY(nsIDOMPerformanceNavigation) >+ DOM_CLASSINFO_MAP_END >+ >+ DOM_CLASSINFO_MAP_BEGIN(Performance, nsIDOMPerformance) >+ DOM_CLASSINFO_MAP_ENTRY(nsIDOMPerformance) >+ DOM_CLASSINFO_MAP_END >+ // } >+ > DOM_CLASSINFO_MAP_BEGIN(Screen, nsIDOMScreen) > DOM_CLASSINFO_MAP_ENTRY(nsIDOMScreen) > DOM_CLASSINFO_MAP_END > > DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(DOMPrototype, nsIDOMDOMConstructor) > DOM_CLASSINFO_MAP_ENTRY(nsIDOMDOMConstructor) > DOM_CLASSINFO_MAP_END > >diff -r 385684ad7eed dom/base/nsDOMClassInfoClasses.h >--- a/dom/base/nsDOMClassInfoClasses.h Tue Apr 05 09:19:34 2011 -0700 >+++ b/dom/base/nsDOMClassInfoClasses.h Wed Apr 06 15:14:13 2011 +0200 >@@ -40,16 +40,19 @@ DOMCI_CLASS(Window) > DOMCI_CLASS(Location) > DOMCI_CLASS(Navigator) > DOMCI_CLASS(Plugin) > DOMCI_CLASS(PluginArray) > DOMCI_CLASS(MimeType) > DOMCI_CLASS(MimeTypeArray) > DOMCI_CLASS(BarProp) > DOMCI_CLASS(History) >+DOMCI_CLASS(PerformanceTiming) >+DOMCI_CLASS(PerformanceNavigation) >+DOMCI_CLASS(Performance) > DOMCI_CLASS(Screen) > DOMCI_CLASS(DOMPrototype) > DOMCI_CLASS(DOMConstructor) > > // Core classes > DOMCI_CLASS(XMLDocument) > DOMCI_CLASS(DocumentType) > DOMCI_CLASS(DOMImplementation) >diff -r 385684ad7eed dom/base/nsDOMNavigationTiming.cpp >--- /dev/null Thu Jan 01 00:00:00 1970 +0000 >+++ b/dom/base/nsDOMNavigationTiming.cpp Wed Apr 06 15:14:13 2011 +0200 >@@ -0,0 +1,409 @@ >+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ >+/* ***** BEGIN LICENSE BLOCK ***** >+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1 >+ * >+ * The contents of this file are subject to the Mozilla Public License Version >+ * 1.1 (the "License"); you may not use this file except in compliance with >+ * the License. You may obtain a copy of the License at >+ * http://www.mozilla.org/MPL/ >+ * >+ * Software distributed under the License is distributed on an "AS IS" basis, >+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License >+ * for the specific language governing rights and limitations under the >+ * License. >+ * >+ * The Original Code is implementation of Web Timing draft specification >+ * http://dev.w3.org/2006/webapi/WebTiming/ >+ * >+ * The Initial Developer of the Original Code is Google Inc. >+ * Portions created by the Initial Developer are Copyright (C) 2010 >+ * the Initial Developer. All Rights Reserved. >+ * >+ * Contributor(s): >+ * Sergey Novikov <sergeyn@google.com> (original author) >+ * Igor Bazarny <igor.bazarny@gmail.com> (lots of improvements) >+ * >+ * Alternatively, the contents of this file may be used under the terms of >+ * either of the GNU General Public License Version 2 or later (the "GPL"), >+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), >+ * in which case the provisions of the GPL or the LGPL are applicable instead >+ * of those above. If you wish to allow use of your version of this file only >+ * under the terms of either the GPL or the LGPL, and not to allow others to >+ * use your version of this file under the terms of the MPL, indicate your >+ * decision by deleting the provisions above and replace them with the notice >+ * and other provisions required by the GPL or the LGPL. If you do not delete >+ * the provisions above, a recipient may use your version of this file under >+ * the terms of any one of the MPL, the GPL or the LGPL. >+ * >+ * ***** END LICENSE BLOCK ***** */ >+ >+#include "nsDOMNavigationTiming.h" >+#include "nsCOMPtr.h" >+#include "nscore.h" >+#include "prinrval.h" >+#include "nsContentUtils.h" >+ >+#include "nsIDOMEventTarget.h" >+#include "nsIDocument.h" >+#include "nsIScriptSecurityManager.h" >+ >+nsDOMNavigationTiming::nsDOMNavigationTiming() >+{ >+ Clear(); >+} >+ >+nsDOMNavigationTiming::~nsDOMNavigationTiming() >+{ >+} >+ >+void >+nsDOMNavigationTiming::Clear() >+{ >+ mNavigationType = nsIDOMPerformanceNavigation::TYPE_RESERVED; >+ mNavigationStart = 0; >+ mFetchStart = 0; >+ mRedirectStart = 0; >+ mRedirectEnd = 0; >+ mUnloadAttempt = 0; >+ mUnloadStart = 0; >+ mLastUnload = 0; >+ mLoadEventStart = 0; >+ mLoadEventEnd = 0; >+ mDOMLoading = 0; >+ mDOMInteractive = 0; >+ mDOMContentLoadedEventStart = 0; >+ mDOMContentLoadedEventEnd = 0; >+ mDOMComplete = 0; >+ mRedirectCheck = NOT_CHECKED; >+} >+ >+void >+nsDOMNavigationTiming::NotifyNavigationStart() >+{ >+ mNavigationStart = PR_Now() / PR_USEC_PER_MSEC; >+} >+ >+void >+nsDOMNavigationTiming::NotifyFetchStart(nsIURI* aURI, nsDOMPerformanceNavigationType aNavigationType) >+{ >+ mFetchStart = PR_Now() / PR_USEC_PER_MSEC; >+ mNavigationType = aNavigationType; >+ // At the unload event time we don't really know the loading uri. >+ // Need it for later check for unload timing access. >+ mLoadedURI = aURI; >+} >+ >+void >+nsDOMNavigationTiming::NotifyRedirect(nsIURI* aOldURI, nsIURI* aNewURI) >+{ >+ if (mRedirects.Count() == 0) { >+ mRedirectStart = mFetchStart; >+ } >+ mFetchStart = PR_Now() / PR_USEC_PER_MSEC; >+ mRedirectEnd = mFetchStart; >+ >+ // At the unload event time we don't really know the loading uri. >+ // Need it for later check for unload timing access. >+ mLoadedURI = aNewURI; >+ >+ mRedirects.AppendObject(aOldURI); >+} >+ >+void >+nsDOMNavigationTiming::NotifyBeforeUnload() >+{ >+ mUnloadAttempt = PR_Now() / PR_USEC_PER_MSEC; >+} >+ >+void >+nsDOMNavigationTiming::NotifyUnloadAccepted(nsIURI* aOldURI) >+{ >+ mUnloadStart = mUnloadAttempt; >+ mLastUnload = PR_Now() / PR_USEC_PER_MSEC; >+ mUnloadedURI = aOldURI; >+} >+ >+void >+nsDOMNavigationTiming::NotifyLastUnload() >+{ >+ mLastUnload = PR_Now() / PR_USEC_PER_MSEC; >+} >+ >+void >+nsDOMNavigationTiming::NotifyLoadEventStart() >+{ >+ mLoadEventStart = PR_Now() / PR_USEC_PER_MSEC; >+} >+ >+void >+nsDOMNavigationTiming::NotifyLoadEventEnd() >+{ >+ mLoadEventEnd = PR_Now() / PR_USEC_PER_MSEC; >+} >+ >+PRBool >+nsDOMNavigationTiming::ReportRedirects() >+{ >+ if (mRedirectCheck == NOT_CHECKED) { >+ if (mRedirects.Count() == 0) { >+ mRedirectCheck = NO_REDIRECTS; >+ } else { >+ mRedirectCheck = CHECK_PASSED; >+ nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager(); >+ for (int i = mRedirects.Count() - 1; i >= 0; --i) { >+ nsIURI * curr = mRedirects[i]; >+ nsresult rv = ssm->CheckSameOriginURI(curr, mLoadedURI, PR_FALSE); >+ if (!NS_SUCCEEDED(rv)) { >+ mRedirectCheck = CHECK_FAILED; >+ break; >+ } >+ } >+ // All we need to know is in mRedirectCheck now. Clear history. >+ mRedirects.Clear(); >+ } >+ } >+ return mRedirectCheck == CHECK_PASSED; >+} >+ >+void >+nsDOMNavigationTiming::SetDOMLoading(nsIURI* aURI, DOMTimeMilliSec aValue) >+{ >+ mLoadedURI = aURI; >+ mDOMLoading = aValue; >+} >+ >+void >+nsDOMNavigationTiming::NotifyDOMLoading(nsIURI* aURI) >+{ >+ mLoadedURI = aURI; >+ mDOMLoading = PR_Now() / PR_USEC_PER_MSEC; >+} >+ >+void >+nsDOMNavigationTiming::NotifyDOMInteractive(nsIURI* aURI) >+{ >+ mLoadedURI = aURI; >+ mDOMInteractive = PR_Now() / PR_USEC_PER_MSEC; >+} >+ >+void >+nsDOMNavigationTiming::NotifyDOMComplete(nsIURI* aURI) >+{ >+ mLoadedURI = aURI; >+ mDOMComplete = PR_Now() / PR_USEC_PER_MSEC; >+} >+ >+void >+nsDOMNavigationTiming::NotifyDOMContentLoadedStart(nsIURI* aURI) >+{ >+ mLoadedURI = aURI; >+ mDOMContentLoadedEventStart = PR_Now() / PR_USEC_PER_MSEC; >+} >+ >+void >+nsDOMNavigationTiming::NotifyDOMContentLoadedEnd(nsIURI* aURI) >+{ >+ mLoadedURI = aURI; >+ mDOMContentLoadedEventEnd = PR_Now() / PR_USEC_PER_MSEC; >+} >+ >+ >+NS_IMPL_ADDREF(nsDOMNavigationTiming) >+NS_IMPL_RELEASE(nsDOMNavigationTiming) >+ >+// QueryInterface implementation for nsDOMNavigationTiming >+NS_INTERFACE_MAP_BEGIN(nsDOMNavigationTiming) >+ NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMPerformanceNavigation) >+ NS_INTERFACE_MAP_ENTRY(nsIDOMPerformanceNavigation) >+ NS_INTERFACE_MAP_ENTRY(nsIDOMPerformanceTiming) >+NS_INTERFACE_MAP_END >+ >+NS_IMETHODIMP >+nsDOMNavigationTiming::GetType( >+ nsDOMPerformanceNavigationType* aNavigationType) >+{ >+ *aNavigationType = mNavigationType; >+ return NS_OK; >+} >+ >+NS_IMETHODIMP >+nsDOMNavigationTiming::GetRedirectCount(PRUint16* aRedirectCount) >+{ >+ *aRedirectCount = 0; >+ if (ReportRedirects()) { >+ *aRedirectCount = mRedirects.Count(); >+ } >+ return NS_OK; >+} >+ >+NS_IMETHODIMP >+nsDOMNavigationTiming::GetRedirectStart(DOMTimeMilliSec* aRedirectStart) >+{ >+ *aRedirectStart = 0; >+ if (ReportRedirects()) { >+ *aRedirectStart = mRedirectStart; >+ } >+ return NS_OK; >+} >+ >+NS_IMETHODIMP >+nsDOMNavigationTiming::GetRedirectEnd(DOMTimeMilliSec* aEnd) >+{ >+ *aEnd = 0; >+ if (ReportRedirects()) { >+ *aEnd = mRedirectEnd; >+ } >+ return NS_OK; >+} >+ >+NS_IMETHODIMP >+nsDOMNavigationTiming::GetNavigationStart(DOMTimeMilliSec* aNavigationStart) >+{ >+ *aNavigationStart = mNavigationStart; >+ return NS_OK; >+} >+ >+NS_IMETHODIMP >+nsDOMNavigationTiming::GetUnloadEventStart(DOMTimeMilliSec* aStart) >+{ >+ *aStart = 0; >+ nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager(); >+ nsresult rv = ssm->CheckSameOriginURI(mLoadedURI, mUnloadedURI, PR_FALSE); >+ if (NS_SUCCEEDED(rv)) { >+ *aStart = mUnloadStart; >+ } >+ return NS_OK; >+} >+ >+NS_IMETHODIMP >+nsDOMNavigationTiming::GetUnloadEventEnd(DOMTimeMilliSec* aEnd) >+{ >+ *aEnd = 0; >+ nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager(); >+ nsresult rv = ssm->CheckSameOriginURI(mLoadedURI, mUnloadedURI, PR_FALSE); >+ if (NS_SUCCEEDED(rv)) { >+ *aEnd = mLastUnload; >+ } >+ return NS_OK; >+} >+ >+NS_IMETHODIMP >+nsDOMNavigationTiming::GetFetchStart(DOMTimeMilliSec* aStart) >+{ >+ *aStart = mFetchStart; >+ return NS_OK; >+} >+ >+NS_IMETHODIMP >+nsDOMNavigationTiming::GetDomainLookupStart(DOMTimeMilliSec* aStart) >+{ >+ // TODO: Implement me! >+ *aStart = mFetchStart; >+ return NS_OK; >+} >+ >+NS_IMETHODIMP >+nsDOMNavigationTiming::GetDomainLookupEnd(DOMTimeMilliSec* aEnd) >+{ >+ // TODO: Implement me! >+ *aEnd = mFetchStart; >+ return NS_OK; >+} >+ >+NS_IMETHODIMP >+nsDOMNavigationTiming::GetConnectStart(DOMTimeMilliSec* aStart) >+{ >+ // TODO: Implement me! >+ *aStart = mFetchStart; >+ return NS_OK; >+} >+ >+NS_IMETHODIMP >+nsDOMNavigationTiming::GetConnectEnd(DOMTimeMilliSec* aEnd) >+{ >+ // TODO: Implement me! >+ *aEnd = mFetchStart; >+ return NS_OK; >+} >+ >+NS_IMETHODIMP >+nsDOMNavigationTiming::GetHandshakeStart(DOMTimeMilliSec* aStart) >+{ >+ // TODO: Implement me! >+ *aStart = mFetchStart; >+ return NS_OK; >+} >+ >+NS_IMETHODIMP >+nsDOMNavigationTiming::GetRequestStart(DOMTimeMilliSec* aStart) >+{ >+ // TODO: Implement me! >+ *aStart = mFetchStart; >+ return NS_OK; >+} >+ >+NS_IMETHODIMP >+nsDOMNavigationTiming::GetResponseStart(DOMTimeMilliSec* aStart) >+{ >+ // TODO: Implement me! >+ *aStart = mFetchStart; >+ return NS_OK; >+} >+ >+NS_IMETHODIMP >+nsDOMNavigationTiming::GetResponseEnd(DOMTimeMilliSec* aEnd) >+{ >+ // TODO: Implement me! >+ *aEnd = mFetchStart; >+ return NS_OK; >+} >+ >+NS_IMETHODIMP >+nsDOMNavigationTiming::GetDomLoading(DOMTimeMilliSec* aTime) >+{ >+ *aTime = mDOMLoading; >+ return NS_OK; >+} >+ >+NS_IMETHODIMP >+nsDOMNavigationTiming::GetDomInteractive(DOMTimeMilliSec* aTime) >+{ >+ *aTime = mDOMInteractive; >+ return NS_OK; >+} >+ >+NS_IMETHODIMP >+nsDOMNavigationTiming::GetDomContentLoadedEventStart(DOMTimeMilliSec* aStart) >+{ >+ *aStart = mDOMContentLoadedEventStart; >+ return NS_OK; >+} >+ >+NS_IMETHODIMP >+nsDOMNavigationTiming::GetDomContentLoadedEventEnd(DOMTimeMilliSec* aEnd) >+{ >+ *aEnd = mDOMContentLoadedEventEnd; >+ return NS_OK; >+} >+ >+NS_IMETHODIMP >+nsDOMNavigationTiming::GetDomComplete(DOMTimeMilliSec* aTime) >+{ >+ *aTime = mDOMComplete; >+ return NS_OK; >+} >+ >+NS_IMETHODIMP >+nsDOMNavigationTiming::GetLoadEventStart(DOMTimeMilliSec* aStart) >+{ >+ *aStart = mLoadEventStart; >+ return NS_OK; >+} >+ >+NS_IMETHODIMP >+nsDOMNavigationTiming::GetLoadEventEnd(DOMTimeMilliSec* aEnd) >+{ >+ *aEnd = mLoadEventEnd; >+ return NS_OK; >+} >+ >diff -r 385684ad7eed dom/base/nsDOMNavigationTiming.h >--- /dev/null Thu Jan 01 00:00:00 1970 +0000 >+++ b/dom/base/nsDOMNavigationTiming.h Wed Apr 06 15:14:13 2011 +0200 >@@ -0,0 +1,117 @@ >+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ >+/* ***** BEGIN LICENSE BLOCK ***** >+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1 >+ * >+ * The contents of this file are subject to the Mozilla Public License Version >+ * 1.1 (the "License"); you may not use this file except in compliance with >+ * the License. You may obtain a copy of the License at >+ * http://www.mozilla.org/MPL/ >+ * >+ * Software distributed under the License is distributed on an "AS IS" basis, >+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License >+ * for the specific language governing rights and limitations under the >+ * License. >+ * >+ * The Original Code is implementation of Web Timing draft specification >+ * http://dev.w3.org/2006/webapi/WebTiming/ >+ * >+ * The Initial Developer of the Original Code is Google Inc. >+ * Portions created by the Initial Developer are Copyright (C) 2010 >+ * the Initial Developer. All Rights Reserved. >+ * >+ * Contributor(s): >+ * Sergey Novikov <sergeyn@google.com> (original author) >+ * Igor Bazarny <igor.bazarny@gmail.com> (lots of improvements) >+ * >+ * Alternatively, the contents of this file may be used under the terms of >+ * either of the GNU General Public License Version 2 or later (the "GPL"), >+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), >+ * in which case the provisions of the GPL or the LGPL are applicable instead >+ * of those above. If you wish to allow use of your version of this file only >+ * under the terms of either the GPL or the LGPL, and not to allow others to >+ * use your version of this file under the terms of the MPL, indicate your >+ * decision by deleting the provisions above and replace them with the notice >+ * and other provisions required by the GPL or the LGPL. If you do not delete >+ * the provisions above, a recipient may use your version of this file under >+ * the terms of any one of the MPL, the GPL or the LGPL. >+ * >+ * ***** END LICENSE BLOCK ***** */ >+ >+#ifndef nsDOMNavigationTiming_h___ >+#define nsDOMNavigationTiming_h___ >+ >+#include "nsIDOMPerformanceTiming.h" >+#include "nsIDOMPerformanceNavigation.h" >+#include "nscore.h" >+#include "nsCOMPtr.h" >+#include "nsCOMArray.h" >+ >+class nsDOMNavigationTimingClock; >+class nsIURI; >+class nsIDocument; >+ >+class nsDOMNavigationTiming : public nsIDOMPerformanceTiming, >+ public nsIDOMPerformanceNavigation >+{ >+public: >+ nsDOMNavigationTiming(); >+ >+ NS_DECL_ISUPPORTS >+ NS_DECL_NSIDOMPERFORMANCETIMING >+ NS_DECL_NSIDOMPERFORMANCENAVIGATION >+ >+ void NotifyNavigationStart(); >+ void NotifyFetchStart(nsIURI* aURI, nsDOMPerformanceNavigationType aNavigationType); >+ void NotifyRedirect(nsIURI* aOldURI, nsIURI* aNewURI); >+ void NotifyBeforeUnload(); >+ void NotifyUnloadAccepted(nsIURI* aOldURI); >+ void NotifyLastUnload(); >+ void NotifyLoadEventStart(); >+ void NotifyLoadEventEnd(); >+ >+ // Document changes state to 'loading' before connecting to timing >+ void SetDOMLoading(nsIURI* aURI, DOMTimeMilliSec aValue); >+ void NotifyDOMLoading(nsIURI* aURI); >+ void NotifyDOMInteractive(nsIURI* aURI); >+ void NotifyDOMComplete(nsIURI* aURI); >+ void NotifyDOMContentLoadedStart(nsIURI* aURI); >+ void NotifyDOMContentLoadedEnd(nsIURI* aURI); >+ >+private: >+ nsDOMNavigationTiming(const nsDOMNavigationTiming &){}; >+ ~nsDOMNavigationTiming(); >+ >+ void Clear(); >+ PRBool ReportRedirects(); >+ >+ nsCOMPtr<nsIURI> mUnloadedURI; >+ nsCOMPtr<nsIURI> mLoadedURI; >+ nsCOMArray<nsIURI> mRedirects; >+ >+ typedef enum { NOT_CHECKED, >+ CHECK_PASSED, >+ NO_REDIRECTS, >+ CHECK_FAILED} RedirectCheckState; >+ RedirectCheckState mRedirectCheck; >+ >+ nsDOMPerformanceNavigationType mNavigationType; >+ DOMTimeMilliSec mNavigationStart; >+ DOMTimeMilliSec mFetchStart; >+ DOMTimeMilliSec mRedirectStart; >+ DOMTimeMilliSec mRedirectEnd; >+ DOMTimeMilliSec mUnloadAttempt; >+ DOMTimeMilliSec mUnloadStart; >+ DOMTimeMilliSec mLastUnload; >+ DOMTimeMilliSec mNavigationEnd; >+ DOMTimeMilliSec mLoadEventStart; >+ DOMTimeMilliSec mLoadEventEnd; >+ >+ DOMTimeMilliSec mDOMLoading; >+ DOMTimeMilliSec mDOMInteractive; >+ DOMTimeMilliSec mDOMContentLoadedEventStart; >+ DOMTimeMilliSec mDOMContentLoadedEventEnd; >+ DOMTimeMilliSec mDOMComplete; >+}; >+ >+#endif /* nsDOMNavigationTiming_h___ */ >+ >diff -r 385684ad7eed dom/base/nsGlobalWindow.cpp >--- a/dom/base/nsGlobalWindow.cpp Tue Apr 05 09:19:34 2011 -0700 >+++ b/dom/base/nsGlobalWindow.cpp Wed Apr 06 15:14:13 2011 +0200 >@@ -49,16 +49,18 @@ > #ifdef MOZ_IPC > #include "base/basictypes.h" > #endif > > // Local Includes > #include "nsGlobalWindow.h" > #include "nsScreen.h" > #include "nsHistory.h" >+#include "nsPerformance.h" >+#include "nsIDOMPerformanceTiming.h" > #include "nsBarProps.h" > #include "nsDOMStorage.h" > #include "nsDOMOfflineResourceList.h" > #include "nsDOMError.h" > > // Helper Classes > #include "nsXPIDLString.h" > #include "nsJSUtils.h" >@@ -1104,16 +1106,17 @@ nsGlobalWindow::CleanUp(PRBool aIgnoreMo > mScrollbars = nsnull; > mLocation = nsnull; > mHistory = nsnull; > mFrames = nsnull; > mApplicationCache = nsnull; > mIndexedDB = nsnull; > mPendingStorageEventsObsolete = nsnull; > >+ mPerformance = nsnull; > > ClearControllers(); > > mOpener = nsnull; // Forces Release > if (mContext) { > #ifdef DEBUG > nsCycleCollector_DEBUG_shouldBeFreed(mContext); > #endif >@@ -2179,16 +2182,28 @@ nsGlobalWindow::SetNewDocument(nsIDocume > // alive etc. > > if ((!reUseInnerWindow || aDocument != oldDoc) && !aState) { > nsCOMPtr<nsIHTMLDocument> html_doc(do_QueryInterface(mDocument)); > nsWindowSH::InstallGlobalScopePolluter(cx, newInnerWindow->mJSObject, > html_doc); > } > >+ // Pick up timing from the doc shell. >+ if (newInnerWindow) { // && nsGlobalWindow::HasPerformanceSupport() >+ nsIDocShell* docShell = GetDocShell(); >+ if (docShell) { >+ nsCOMPtr<nsIDOMPerformanceTiming> timing; >+ docShell->GetNavigationTiming(getter_AddRefs(timing)); >+ if (timing) { >+ newInnerWindow->mPerformance = new nsPerformance(timing); >+ } >+ } >+ } >+ > if (aDocument) { > aDocument->SetScriptGlobalObject(newInnerWindow); > } > > if (!aState) { > if (reUseInnerWindow) { > if (newInnerWindow->mDoc != aDocument) { > newInnerWindow->mDocument = do_QueryInterface(aDocument); >@@ -2733,17 +2748,16 @@ nsGlobalWindow::PostHandleEvent(nsEventC > nsEvent event(NS_IS_TRUSTED_EVENT(aVisitor.mEvent), NS_LOAD); > event.flags |= NS_EVENT_FLAG_CANT_BUBBLE; > > // Most of the time we could get a pres context to pass in here, > // but not always (i.e. if this window is not shown there won't > // be a pres context available). Since we're not firing a GUI > // event we don't need a pres context anyway so we just pass > // null as the pres context all the time here. >- > nsEventDispatcher::Dispatch(content, nsnull, &event, nsnull, &status); > } > } > > return NS_OK; > } > > nsresult >@@ -2967,16 +2981,29 @@ nsGlobalWindow::GetHistory(nsIDOMHistory > } > } > > NS_IF_ADDREF(*aHistory = mHistory); > return NS_OK; > } > > NS_IMETHODIMP >+nsGlobalWindow::GetPerformance(nsIDOMPerformance** aPerformance) >+{ >+ FORWARD_TO_INNER(GetPerformance, (aPerformance), NS_ERROR_NOT_INITIALIZED); >+ >+ *aPerformance = nsnull; >+ >+ //if (nsGlobalWindow::HasPerformanceSupport()) { >+ NS_IF_ADDREF(*aPerformance = mPerformance); >+ //} >+ return NS_OK; >+} >+ >+NS_IMETHODIMP > nsGlobalWindow::GetParent(nsIDOMWindow** aParent) > { > FORWARD_TO_OUTER(GetParent, (aParent), NS_ERROR_NOT_INITIALIZED); > > *aParent = nsnull; > if (!mDocShell) > return NS_OK; > >diff -r 385684ad7eed dom/base/nsGlobalWindow.h >--- a/dom/base/nsGlobalWindow.h Tue Apr 05 09:19:34 2011 -0700 >+++ b/dom/base/nsGlobalWindow.h Wed Apr 06 15:14:13 2011 +0200 >@@ -134,16 +134,17 @@ class nsIDOMEvent; > class nsIScrollableFrame; > class nsIControllers; > > class nsBarProp; > class nsLocation; > class nsNavigator; > class nsScreen; > class nsHistory; >+class nsPerformance; > class nsIDocShellLoadInfo; > class WindowStateHolder; > class nsGlobalWindowObserver; > class nsGlobalWindow; > class nsDummyJavaPluginOwner; > class PostMessageEvent; > class nsRunnable; > >@@ -575,16 +576,20 @@ public: > static nsGlobalWindow* GetOuterWindowWithId(PRUint64 aWindowID) { > return sOuterWindowsById ? sOuterWindowsById->Get(aWindowID) : nsnull; > } > > static bool HasIndexedDBSupport() { > return nsContentUtils::GetBoolPref("indexedDB.feature.enabled", PR_TRUE); > } > >+ static bool HasPerformanceSupport() { >+ return nsContentUtils::GetBoolPref("dom.enable_performance", PR_FALSE); >+ } >+ > private: > // Enable updates for the accelerometer. > void EnableAccelerationUpdates(); > > // Disables updates for the accelerometer. > void DisableAccelerationUpdates(); > > protected: >@@ -901,16 +906,17 @@ protected: > nsCOMPtr<nsIScriptContext> mContext; > nsWeakPtr mOpener; > nsCOMPtr<nsIControllers> mControllers; > nsCOMPtr<nsIArray> mArguments; > nsCOMPtr<nsIArray> mArgumentsLast; > nsCOMPtr<nsIPrincipal> mArgumentsOrigin; > nsRefPtr<nsNavigator> mNavigator; > nsRefPtr<nsScreen> mScreen; >+ nsRefPtr<nsPerformance> mPerformance; > nsRefPtr<nsDOMWindowList> mFrames; > nsRefPtr<nsBarProp> mMenubar; > nsRefPtr<nsBarProp> mToolbar; > nsRefPtr<nsBarProp> mLocationbar; > nsRefPtr<nsBarProp> mPersonalbar; > nsRefPtr<nsBarProp> mStatusbar; > nsRefPtr<nsBarProp> mScrollbars; > nsCOMPtr<nsIWeakReference> mWindowUtils; >diff -r 385684ad7eed dom/base/nsPerformance.cpp >--- /dev/null Thu Jan 01 00:00:00 1970 +0000 >+++ b/dom/base/nsPerformance.cpp Wed Apr 06 15:14:13 2011 +0200 >@@ -0,0 +1,279 @@ >+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ >+/* ***** BEGIN LICENSE BLOCK ***** >+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1 >+ * >+ * The contents of this file are subject to the Mozilla Public License Version >+ * 1.1 (the "License"); you may not use this file except in compliance with >+ * the License. You may obtain a copy of the License at >+ * http://www.mozilla.org/MPL/ >+ * >+ * Software distributed under the License is distributed on an "AS IS" basis, >+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License >+ * for the specific language governing rights and limitations under the >+ * License. >+ * >+ * The Original Code is implementation of Web Timing draft specification >+ * http://dev.w3.org/2006/webapi/WebTiming/ >+ * >+ * The Initial Developer of the Original Code is Google Inc. >+ * Portions created by the Initial Developer are Copyright (C) 2010 >+ * the Initial Developer. All Rights Reserved. >+ * >+ * Contributor(s): >+ * Sergey Novikov <sergeyn@google.com> (original author) >+ * Igor Bazarny <igor.bazarny@gmail.com> (update to match bearly-final spec) >+ * >+ * Alternatively, the contents of this file may be used under the terms of >+ * either of the GNU General Public License Version 2 or later (the "GPL"), >+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), >+ * in which case the provisions of the GPL or the LGPL are applicable instead >+ * of those above. If you wish to allow use of your version of this file only >+ * under the terms of either the GPL or the LGPL, and not to allow others to >+ * use your version of this file under the terms of the MPL, indicate your >+ * decision by deleting the provisions above and replace them with the notice >+ * and other provisions required by the GPL or the LGPL. If you do not delete >+ * the provisions above, a recipient may use your version of this file under >+ * the terms of any one of the MPL, the GPL or the LGPL. >+ * >+ * ***** END LICENSE BLOCK ***** */ >+ >+#include "nsPerformance.h" >+#include "nsCOMPtr.h" >+#include "nscore.h" >+#include "nsIDocShell.h" >+#include "nsDOMClassInfo.h" >+#include "nsDOMNavigationTiming.h" >+ >+DOMCI_DATA(PerformanceTiming, nsPerformanceTiming) >+ >+NS_IMPL_ADDREF(nsPerformanceTiming) >+NS_IMPL_RELEASE(nsPerformanceTiming) >+ >+// QueryInterface implementation for nsPerformanceTiming >+NS_INTERFACE_MAP_BEGIN(nsPerformanceTiming) >+ NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMPerformanceTiming) >+ NS_INTERFACE_MAP_ENTRY(nsIDOMPerformanceTiming) >+ NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(PerformanceTiming) >+NS_INTERFACE_MAP_END >+ >+nsPerformanceTiming::nsPerformanceTiming(nsDOMNavigationTiming* aData) >+{ >+ NS_ASSERTION(aData, "Timing data should be provided"); >+ mData = aData; >+} >+ >+nsPerformanceTiming::~nsPerformanceTiming() >+{ >+} >+ >+NS_IMETHODIMP >+nsPerformanceTiming::GetNavigationStart(DOMTimeMilliSec* aTime) >+{ >+ return mData->GetNavigationStart(aTime); >+} >+ >+NS_IMETHODIMP >+nsPerformanceTiming::GetUnloadEventStart(DOMTimeMilliSec* aTime) >+{ >+ return mData->GetUnloadEventStart(aTime); >+} >+ >+NS_IMETHODIMP >+nsPerformanceTiming::GetUnloadEventEnd(DOMTimeMilliSec* aTime) >+{ >+ return mData->GetUnloadEventEnd(aTime); >+} >+ >+NS_IMETHODIMP >+nsPerformanceTiming::GetRedirectStart(DOMTimeMilliSec* aTime) >+{ >+ return mData->GetRedirectStart(aTime); >+} >+ >+NS_IMETHODIMP >+nsPerformanceTiming::GetRedirectEnd(DOMTimeMilliSec* aTime) >+{ >+ return mData->GetRedirectEnd(aTime); >+} >+ >+NS_IMETHODIMP >+nsPerformanceTiming::GetFetchStart(DOMTimeMilliSec* aTime) >+{ >+ return mData->GetFetchStart(aTime); >+} >+ >+NS_IMETHODIMP >+nsPerformanceTiming::GetDomainLookupStart(DOMTimeMilliSec* aTime) >+{ >+ return mData->GetDomainLookupStart(aTime); >+} >+ >+NS_IMETHODIMP >+nsPerformanceTiming::GetDomainLookupEnd(DOMTimeMilliSec* aTime) >+{ >+ return mData->GetDomainLookupEnd(aTime); >+} >+ >+NS_IMETHODIMP >+nsPerformanceTiming::GetConnectStart(DOMTimeMilliSec* aTime) >+{ >+ return mData->GetConnectStart(aTime); >+} >+ >+NS_IMETHODIMP >+nsPerformanceTiming::GetConnectEnd(DOMTimeMilliSec* aTime) >+{ >+ return mData->GetConnectEnd(aTime); >+} >+ >+NS_IMETHODIMP >+nsPerformanceTiming::GetHandshakeStart(DOMTimeMilliSec* aTime) >+{ >+ return mData->GetHandshakeStart(aTime); >+} >+ >+NS_IMETHODIMP >+nsPerformanceTiming::GetRequestStart(DOMTimeMilliSec* aTime) >+{ >+ return mData->GetRequestStart(aTime); >+} >+ >+NS_IMETHODIMP >+nsPerformanceTiming::GetResponseStart(DOMTimeMilliSec* aTime) >+{ >+ return mData->GetResponseStart(aTime); >+} >+ >+NS_IMETHODIMP >+nsPerformanceTiming::GetResponseEnd(DOMTimeMilliSec* aTime) >+{ >+ return mData->GetResponseEnd(aTime); >+} >+ >+NS_IMETHODIMP >+nsPerformanceTiming::GetDomLoading(DOMTimeMilliSec* aTime) >+{ >+ return mData->GetDomLoading(aTime); >+} >+ >+NS_IMETHODIMP >+nsPerformanceTiming::GetDomInteractive(DOMTimeMilliSec* aTime) >+{ >+ return mData->GetDomInteractive(aTime); >+} >+ >+NS_IMETHODIMP >+nsPerformanceTiming::GetDomContentLoadedEventStart(DOMTimeMilliSec* aTime) >+{ >+ return mData->GetDomContentLoadedEventStart(aTime); >+} >+ >+NS_IMETHODIMP >+nsPerformanceTiming::GetDomContentLoadedEventEnd(DOMTimeMilliSec* aTime) >+{ >+ return mData->GetDomContentLoadedEventEnd(aTime); >+} >+ >+NS_IMETHODIMP >+nsPerformanceTiming::GetDomComplete(DOMTimeMilliSec* aTime) >+{ >+ return mData->GetDomComplete(aTime); >+} >+ >+NS_IMETHODIMP >+nsPerformanceTiming::GetLoadEventStart(DOMTimeMilliSec* aTime) >+{ >+ return mData->GetLoadEventStart(aTime); >+} >+ >+NS_IMETHODIMP >+nsPerformanceTiming::GetLoadEventEnd(DOMTimeMilliSec* aTime) >+{ >+ return mData->GetLoadEventEnd(aTime); >+} >+ >+ >+ >+DOMCI_DATA(PerformanceNavigation, nsPerformanceNavigation) >+ >+NS_IMPL_ADDREF(nsPerformanceNavigation) >+NS_IMPL_RELEASE(nsPerformanceNavigation) >+ >+// QueryInterface implementation for nsPerformanceNavigation >+NS_INTERFACE_MAP_BEGIN(nsPerformanceNavigation) >+ NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMPerformanceNavigation) >+ NS_INTERFACE_MAP_ENTRY(nsIDOMPerformanceNavigation) >+ NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(PerformanceNavigation) >+NS_INTERFACE_MAP_END >+ >+nsPerformanceNavigation::nsPerformanceNavigation(nsDOMNavigationTiming* aData) >+{ >+ NS_ASSERTION(aData, "Timing data should be provided"); >+ mData = aData; >+} >+ >+nsPerformanceNavigation::~nsPerformanceNavigation() >+{ >+} >+ >+NS_IMETHODIMP >+nsPerformanceNavigation::GetType( >+ nsDOMPerformanceNavigationType* aNavigationType) >+{ >+ return mData->GetType(aNavigationType); >+} >+ >+NS_IMETHODIMP >+nsPerformanceNavigation::GetRedirectCount(PRUint16* aRedirectCount) >+{ >+ return mData->GetRedirectCount(aRedirectCount); >+} >+ >+ >+DOMCI_DATA(Performance, nsPerformance) >+ >+NS_IMPL_ADDREF(nsPerformance) >+NS_IMPL_RELEASE(nsPerformance) >+ >+nsPerformance::nsPerformance(nsIDOMPerformanceTiming* aTiming) >+{ >+ NS_ASSERTION(aTiming, "Timing data should be provided"); >+ mData = static_cast<nsDOMNavigationTiming*>(aTiming); >+} >+ >+nsPerformance::~nsPerformance() >+{ >+} >+ >+// QueryInterface implementation for nsPerformance >+NS_INTERFACE_MAP_BEGIN(nsPerformance) >+ NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMPerformance) >+ NS_INTERFACE_MAP_ENTRY(nsIDOMPerformance) >+ NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(Performance) >+NS_INTERFACE_MAP_END >+ >+// >+// nsIDOMPerformance methods >+// >+NS_IMETHODIMP >+nsPerformance::GetTiming(nsIDOMPerformanceTiming** aTiming) >+{ >+ if (!mTiming) { >+ mTiming = new nsPerformanceTiming(mData); >+ } >+ NS_ENSURE_TRUE(mTiming, NS_ERROR_OUT_OF_MEMORY); >+ NS_IF_ADDREF(*aTiming = mTiming); >+ return NS_OK; >+} >+ >+NS_IMETHODIMP >+nsPerformance::GetNavigation(nsIDOMPerformanceNavigation** aNavigation) >+{ >+ if (!mNavigation) { >+ mNavigation = new nsPerformanceNavigation(mData); >+ } >+ NS_ENSURE_TRUE(mNavigation, NS_ERROR_OUT_OF_MEMORY); >+ NS_IF_ADDREF(*aNavigation = mNavigation); >+ return NS_OK; >+} >+ >diff -r 385684ad7eed dom/base/nsPerformance.h >--- /dev/null Thu Jan 01 00:00:00 1970 +0000 >+++ b/dom/base/nsPerformance.h Wed Apr 06 15:14:13 2011 +0200 >@@ -0,0 +1,95 @@ >+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ >+/* ***** BEGIN LICENSE BLOCK ***** >+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1 >+ * >+ * The contents of this file are subject to the Mozilla Public License Version >+ * 1.1 (the "License"); you may not use this file except in compliance with >+ * the License. You may obtain a copy of the License at >+ * http://www.mozilla.org/MPL/ >+ * >+ * Software distributed under the License is distributed on an "AS IS" basis, >+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License >+ * for the specific language governing rights and limitations under the >+ * License. >+ * >+ * The Original Code is implementation of Web Timing draft specification >+ * http://dev.w3.org/2006/webapi/WebTiming/ >+ * >+ * The Initial Developer of the Original Code is Google Inc. >+ * Portions created by the Initial Developer are Copyright (C) 2010 >+ * the Initial Developer. All Rights Reserved. >+ * >+ * Contributor(s): >+ * Sergey Novikov <sergeyn@google.com> (original author) >+ * Igor Bazarny <igor.bazarny@gmail.com> (update to match bearly-final spec) >+ * >+ * Alternatively, the contents of this file may be used under the terms of >+ * either of the GNU General Public License Version 2 or later (the "GPL"), >+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), >+ * in which case the provisions of the GPL or the LGPL are applicable instead >+ * of those above. If you wish to allow use of your version of this file only >+ * under the terms of either the GPL or the LGPL, and not to allow others to >+ * use your version of this file under the terms of the MPL, indicate your >+ * decision by deleting the provisions above and replace them with the notice >+ * and other provisions required by the GPL or the LGPL. If you do not delete >+ * the provisions above, a recipient may use your version of this file under >+ * the terms of any one of the MPL, the GPL or the LGPL. >+ * >+ * ***** END LICENSE BLOCK ***** */ >+#ifndef nsPerformance_h___ >+#define nsPerformance_h___ >+ >+#include "nsIDOMPerformance.h" >+#include "nsIDOMPerformanceTiming.h" >+#include "nsIDOMPerformanceNavigation.h" >+#include "nscore.h" >+#include "nsCOMPtr.h" >+#include "nsAutoPtr.h" >+ >+class nsIDocument; >+class nsIURI; >+class nsDOMNavigationTiming; >+ >+// Script "performance.timing" object >+class nsPerformanceTiming : public nsIDOMPerformanceTiming >+{ >+public: >+ nsPerformanceTiming(nsDOMNavigationTiming* data); >+ NS_DECL_ISUPPORTS >+ NS_DECL_NSIDOMPERFORMANCETIMING >+private: >+ ~nsPerformanceTiming(); >+ nsRefPtr<nsDOMNavigationTiming> mData; >+}; >+ >+// Script "performance.navigation" object >+class nsPerformanceNavigation : public nsIDOMPerformanceNavigation >+{ >+public: >+ nsPerformanceNavigation(nsDOMNavigationTiming* data); >+ NS_DECL_ISUPPORTS >+ NS_DECL_NSIDOMPERFORMANCENAVIGATION >+private: >+ ~nsPerformanceNavigation(); >+ nsRefPtr<nsDOMNavigationTiming> mData; >+}; >+ >+// Script "performance" object >+class nsPerformance : public nsIDOMPerformance >+{ >+public: >+ nsPerformance(nsIDOMPerformanceTiming* timing); >+ >+ NS_DECL_ISUPPORTS >+ NS_DECL_NSIDOMPERFORMANCE >+ >+private: >+ ~nsPerformance(); >+ >+ nsRefPtr<nsDOMNavigationTiming> mData; >+ nsCOMPtr<nsIDOMPerformanceTiming> mTiming; >+ nsCOMPtr<nsIDOMPerformanceNavigation> mNavigation; >+}; >+ >+#endif /* nsPerformance_h___ */ >+ >diff -r 385684ad7eed dom/interfaces/base/Makefile.in >--- a/dom/interfaces/base/Makefile.in Tue Apr 05 09:19:34 2011 -0700 >+++ b/dom/interfaces/base/Makefile.in Wed Apr 06 15:14:13 2011 +0200 >@@ -81,11 +81,14 @@ XPIDLSRCS = \ > nsIDOMNSFeatureFactory.idl \ > nsIDOMClientRect.idl \ > nsIDOMClientRectList.idl \ > nsIFocusManager.idl \ > nsIQueryContentEventResult.idl \ > nsITabChild.idl \ > nsITabParent.idl \ > nsIDOMGlobalPropertyInitializer.idl \ >+ nsIDOMPerformance.idl \ >+ nsIDOMPerformanceTiming.idl \ >+ nsIDOMPerformanceNavigation.idl \ > $(NULL) > > include $(topsrcdir)/config/rules.mk >diff -r 385684ad7eed dom/interfaces/base/domstubs.idl >--- a/dom/interfaces/base/domstubs.idl Tue Apr 05 09:19:34 2011 -0700 >+++ b/dom/interfaces/base/domstubs.idl Wed Apr 06 15:14:13 2011 +0200 >@@ -35,16 +35,17 @@ > * the provisions above, a recipient may use your version of this file under > * the terms of any one of the MPL, the GPL or the LGPL. > * > * ***** END LICENSE BLOCK ***** */ > > #include "nsISupports.idl" > > typedef unsigned long long DOMTimeStamp; >+typedef unsigned long long DOMTimeMilliSec; > > // Core > interface nsIDOMAttr; > interface nsIDOMCDATASection; > interface nsIDOMCharacterData; > interface nsIDOMComment; > interface nsIDOMDOMImplementation; > interface nsIDOMDocument; >diff -r 385684ad7eed dom/interfaces/base/nsIDOMPerformance.idl >--- /dev/null Thu Jan 01 00:00:00 1970 +0000 >+++ b/dom/interfaces/base/nsIDOMPerformance.idl Wed Apr 06 15:14:13 2011 +0200 >@@ -0,0 +1,50 @@ >+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ >+/* ***** BEGIN LICENSE BLOCK ***** >+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1 >+ * >+ * The contents of this file are subject to the Mozilla Public License Version >+ * 1.1 (the "License"); you may not use this file except in compliance with >+ * the License. You may obtain a copy of the License at >+ * http://www.mozilla.org/MPL/ >+ * >+ * Software distributed under the License is distributed on an "AS IS" basis, >+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License >+ * for the specific language governing rights and limitations under the >+ * License. >+ * >+ * The Original Code is implementation of Web Timing draft specification >+ * http://dev.w3.org/2006/webapi/WebTiming/ >+ * >+ * The Initial Developer of the Original Code is Google Inc. >+ * Portions created by the Initial Developer are Copyright (C) 2010 >+ * the Initial Developer. All Rights Reserved. >+ * >+ * Contributor(s): >+ * Sergey Novikov <sergeyn@google.com> (original author) >+ * Igor Bazarny <igor.bazarny@gmail.com> (update to match nearly-final spec) >+ * >+ * Alternatively, the contents of this file may be used under the terms of >+ * either of the GNU General Public License Version 2 or later (the "GPL"), >+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), >+ * in which case the provisions of the GPL or the LGPL are applicable instead >+ * of those above. If you wish to allow use of your version of this file only >+ * under the terms of either the GPL or the LGPL, and not to allow others to >+ * use your version of this file under the terms of the MPL, indicate your >+ * decision by deleting the provisions above and replace them with the notice >+ * and other provisions required by the GPL or the LGPL. If you do not delete >+ * the provisions above, a recipient may use your version of this file under >+ * the terms of any one of the MPL, the GPL or the LGPL. >+ * >+ * ***** END LICENSE BLOCK ***** */ >+ >+#include "nsISupports.idl" >+interface nsIDOMPerformanceTiming; >+interface nsIDOMPerformanceNavigation; >+ >+[scriptable, uuid(446faf26-000b-4e66-a5fd-ae37c5ed6beb)] >+interface nsIDOMPerformance : nsISupports >+{ >+ readonly attribute nsIDOMPerformanceTiming timing; >+ readonly attribute nsIDOMPerformanceNavigation navigation; >+}; >+ >diff -r 385684ad7eed dom/interfaces/base/nsIDOMPerformanceNavigation.idl >--- /dev/null Thu Jan 01 00:00:00 1970 +0000 >+++ b/dom/interfaces/base/nsIDOMPerformanceNavigation.idl Wed Apr 06 15:14:13 2011 +0200 >@@ -0,0 +1,55 @@ >+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ >+/* ***** BEGIN LICENSE BLOCK ***** >+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1 >+ * >+ * The contents of this file are subject to the Mozilla Public License Version >+ * 1.1 (the "License"); you may not use this file except in compliance with >+ * the License. You may obtain a copy of the License at >+ * http://www.mozilla.org/MPL/ >+ * >+ * Software distributed under the License is distributed on an "AS IS" basis, >+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License >+ * for the specific language governing rights and limitations under the >+ * License. >+ * >+ * The Original Code is implementation of Web Timing draft specification >+ * http://dev.w3.org/2006/webapi/WebTiming/ >+ * >+ * The Initial Developer of the Original Code is Google Inc. >+ * Portions created by the Initial Developer are Copyright (C) 2010 >+ * the Initial Developer. All Rights Reserved. >+ * >+ * Contributor(s): >+ * Sergey Novikov <sergeyn@google.com> (original author) >+ * Igor Bazarny <igor.bazarny@gmail.com> (update to match nearly-final spec) >+ * >+ * Alternatively, the contents of this file may be used under the terms of >+ * either of the GNU General Public License Version 2 or later (the "GPL"), >+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), >+ * in which case the provisions of the GPL or the LGPL are applicable instead >+ * of those above. If you wish to allow use of your version of this file only >+ * under the terms of either the GPL or the LGPL, and not to allow others to >+ * use your version of this file under the terms of the MPL, indicate your >+ * decision by deleting the provisions above and replace them with the notice >+ * and other provisions required by the GPL or the LGPL. If you do not delete >+ * the provisions above, a recipient may use your version of this file under >+ * the terms of any one of the MPL, the GPL or the LGPL. >+ * >+ * ***** END LICENSE BLOCK ***** */ >+ >+#include "domstubs.idl" >+ >+typedef unsigned short nsDOMPerformanceNavigationType; >+ >+[scriptable, uuid(a2132ad8-a841-4285-a140-338e8de6c2e0)] >+interface nsIDOMPerformanceNavigation : nsISupports >+{ >+ const nsDOMPerformanceNavigationType TYPE_NAVIGATE = 0; >+ const nsDOMPerformanceNavigationType TYPE_RELOAD = 1; >+ const nsDOMPerformanceNavigationType TYPE_BACK_FORWARD = 2; >+ const nsDOMPerformanceNavigationType TYPE_RESERVED = 255; >+ >+ readonly attribute nsDOMPerformanceNavigationType type; >+ readonly attribute unsigned short redirectCount; >+}; >+ >diff -r 385684ad7eed dom/interfaces/base/nsIDOMPerformanceTiming.idl >--- /dev/null Thu Jan 01 00:00:00 1970 +0000 >+++ b/dom/interfaces/base/nsIDOMPerformanceTiming.idl Wed Apr 06 15:14:13 2011 +0200 >@@ -0,0 +1,67 @@ >+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ >+/* ***** BEGIN LICENSE BLOCK ***** >+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1 >+ * >+ * The contents of this file are subject to the Mozilla Public License Version >+ * 1.1 (the "License"); you may not use this file except in compliance with >+ * the License. You may obtain a copy of the License at >+ * http://www.mozilla.org/MPL/ >+ * >+ * Software distributed under the License is distributed on an "AS IS" basis, >+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License >+ * for the specific language governing rights and limitations under the >+ * License. >+ * >+ * The Original Code is implementation of Web Timing draft specification >+ * http://dev.w3.org/2006/webapi/WebTiming/ >+ * >+ * The Initial Developer of the Original Code is Google Inc. >+ * Portions created by the Initial Developer are Copyright (C) 2010 >+ * the Initial Developer. All Rights Reserved. >+ * >+ * Contributor(s): >+ * Sergey Novikov <sergeyn@google.com> (original author) >+ * Igor Bazarny <igor.bazarny@gmail.com> (update to match nearly-final spec) >+ * >+ * Alternatively, the contents of this file may be used under the terms of >+ * either of the GNU General Public License Version 2 or later (the "GPL"), >+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), >+ * in which case the provisions of the GPL or the LGPL are applicable instead >+ * of those above. If you wish to allow use of your version of this file only >+ * under the terms of either the GPL or the LGPL, and not to allow others to >+ * use your version of this file under the terms of the MPL, indicate your >+ * decision by deleting the provisions above and replace them with the notice >+ * and other provisions required by the GPL or the LGPL. If you do not delete >+ * the provisions above, a recipient may use your version of this file under >+ * the terms of any one of the MPL, the GPL or the LGPL. >+ * >+ * ***** END LICENSE BLOCK ***** */ >+ >+#include "domstubs.idl" >+ >+[scriptable, uuid(2a630b50-61b6-41b3-996d-70be67fbbcb0)] >+interface nsIDOMPerformanceTiming : nsISupports >+{ >+ readonly attribute DOMTimeMilliSec navigationStart; >+ readonly attribute DOMTimeMilliSec unloadEventStart; >+ readonly attribute DOMTimeMilliSec unloadEventEnd; >+ readonly attribute DOMTimeMilliSec redirectStart; >+ readonly attribute DOMTimeMilliSec redirectEnd; >+ readonly attribute DOMTimeMilliSec fetchStart; >+ readonly attribute DOMTimeMilliSec domainLookupStart; >+ readonly attribute DOMTimeMilliSec domainLookupEnd; >+ readonly attribute DOMTimeMilliSec connectStart; >+ readonly attribute DOMTimeMilliSec connectEnd; >+ readonly attribute DOMTimeMilliSec handshakeStart; >+ readonly attribute DOMTimeMilliSec requestStart; >+ readonly attribute DOMTimeMilliSec responseStart; >+ readonly attribute DOMTimeMilliSec responseEnd; >+ readonly attribute DOMTimeMilliSec domLoading; >+ readonly attribute DOMTimeMilliSec domInteractive; >+ readonly attribute DOMTimeMilliSec domContentLoadedEventStart; >+ readonly attribute DOMTimeMilliSec domContentLoadedEventEnd; >+ readonly attribute DOMTimeMilliSec domComplete; >+ readonly attribute DOMTimeMilliSec loadEventStart; >+ readonly attribute DOMTimeMilliSec loadEventEnd; >+}; >+ >diff -r 385684ad7eed dom/interfaces/base/nsIDOMWindowInternal.idl >--- a/dom/interfaces/base/nsIDOMWindowInternal.idl Tue Apr 05 09:19:34 2011 -0700 >+++ b/dom/interfaces/base/nsIDOMWindowInternal.idl Wed Apr 06 15:14:13 2011 +0200 >@@ -37,20 +37,21 @@ > * > * ***** END LICENSE BLOCK ***** */ > > #include "nsIDOMWindow2.idl" > > interface nsIPrompt; > interface nsIControllers; > interface nsIDOMLocation; >+interface nsIDOMPerformance; > interface nsIVariant; > interface nsIAnimationFrameListener; > >-[scriptable, uuid(9d6a1157-0719-46a7-b49f-7ffeaa0b5c86)] >+[scriptable, uuid(5930f197-259e-4f6b-aeca-c96a74518cc6)] > interface nsIDOMWindowInternal : nsIDOMWindow2 > { > readonly attribute nsIDOMWindowInternal window; > > /* [replaceable] self */ > readonly attribute nsIDOMWindowInternal self; > > readonly attribute nsIDOMNavigator navigator; >@@ -227,16 +228,21 @@ interface nsIDOMWindowInternal : nsIDOMW > */ > void > mozRequestAnimationFrame([optional] in nsIAnimationFrameListener aListener); > > /** > * The current animation start time in milliseconds since the epoch. > */ > readonly attribute long long mozAnimationStartTime; >+ >+ /** >+ * A namespace to hold performance related data and statistics. >+ */ >+ readonly attribute nsIDOMPerformance performance; > }; > > [scriptable, uuid(8fc58f56-f769-4368-a098-edd08550cf1a)] > interface nsIDOMMozURLProperty : nsISupports > { > DOMString createObjectURL(in nsIDOMBlob blob); > void revokeObjectURL(in DOMString URL); > }; >diff -r 385684ad7eed layout/base/nsDocumentViewer.cpp >--- a/layout/base/nsDocumentViewer.cpp Tue Apr 05 09:19:34 2011 -0700 >+++ b/layout/base/nsDocumentViewer.cpp Wed Apr 06 15:14:13 2011 +0200 >@@ -113,16 +113,19 @@ > #include "nsIXULDocument.h" > #include "nsXULPopupManager.h" > #endif > #include "nsPrintfCString.h" > > #include "nsIClipboardHelper.h" > > #include "nsPIDOMWindow.h" >+#include "nsIDOMPerformance.h" >+#include "nsIDOMPerformanceTiming.h" >+#include "nsDOMNavigationTiming.h" > #include "nsPIWindowRoot.h" > #include "nsJSEnvironment.h" > #include "nsFocusManager.h" > > #include "nsIScrollableFrame.h" > #include "nsIHTMLDocument.h" > #include "nsITimelineService.h" > #include "nsGfxCIID.h" >@@ -330,16 +333,21 @@ public: > /** > * Find the view to use as the container view for MakeWindow. Returns > * null if this will be the root of a view manager hierarchy. In that > * case, if mParentWidget is null then this document should not even > * be displayed. > */ > virtual nsIView* FindContainerView(); > >+ /** >+ * Set collector for navigation timing data (load, unload events). >+ */ >+ virtual void SetNavigationTiming(nsDOMNavigationTiming* timing); >+ > // nsIContentViewerEdit > NS_DECL_NSICONTENTVIEWEREDIT > > // nsIContentViewerFile > NS_DECL_NSICONTENTVIEWERFILE > > // nsIMarkupDocumentViewer > NS_DECL_NSIMARKUPDOCUMENTVIEWER >@@ -449,16 +457,19 @@ protected: > nsCOMPtr<nsIPresShell> mPresShell; > > nsCOMPtr<nsISelectionListener> mSelectionListener; > nsCOMPtr<nsIDOMFocusListener> mFocusListener; > > nsCOMPtr<nsIContentViewer> mPreviousViewer; > nsCOMPtr<nsISHEntry> mSHEntry; > >+ // Navigation timing data collector >+ nsRefPtr<nsDOMNavigationTiming> mTiming; >+ > nsIWidget* mParentWidget; // purposely won't be ref counted. May be null > PRBool mAttachedToParent; // view is attached to the parent widget > > nsIntRect mBounds; > > // mTextZoom/mPageZoom record the textzoom/pagezoom of the first (galley) > // presshell only. > float mTextZoom; // Text zoom, defaults to 1.0 >@@ -988,16 +999,24 @@ DocumentViewerImpl::InitInternal(nsIWidg > // MakeWindow())... > > rv = InitPresentationStuff(!makeCX); > } > > return rv; > } > >+void DocumentViewerImpl::SetNavigationTiming(nsDOMNavigationTiming* timing) >+{ >+ mTiming = timing; >+ if (mDocument) { >+ mDocument->SetNavigationTiming(timing); >+ } >+} >+ > // > // LoadComplete(aStatus) > // > // aStatus - The status returned from loading the document. > // > // This method is called by the container when the document has been > // completely loaded. > // >@@ -1049,18 +1068,24 @@ DocumentViewerImpl::LoadComplete(nsresul > // onload to the document content since that would likely confuse scripts > // on the page. > > nsIDocShell *docShell = window->GetDocShell(); > NS_ENSURE_TRUE(docShell, NS_ERROR_UNEXPECTED); > > docShell->GetRestoringDocument(&restoring); > if (!restoring) { >+ if (mTiming) { >+ mTiming->NotifyLoadEventStart(); >+ } > nsEventDispatcher::Dispatch(window, mPresContext, &event, nsnull, > &status); >+ if (mTiming) { >+ mTiming->NotifyLoadEventEnd(); >+ } > #ifdef MOZ_TIMELINE > // if navigator.xul's load is complete, the main nav window is visible > // mark that point. > > nsIURI *uri = mDocument ? mDocument->GetDocumentURI() : nsnull; > > if (uri) { > //printf("DEBUG: getting spec for uri (%p)\n", uri.get()); >@@ -1316,16 +1341,20 @@ DocumentViewerImpl::PageHide(PRBool aIsU > > // Never permit popups from the unload handler, no matter how we get > // here. > nsAutoPopupStatePusher popupStatePusher(openAbused, PR_TRUE); > > nsEventDispatcher::Dispatch(window, mPresContext, &event, nsnull, &status); > } > >+ if (mTiming) { >+ mTiming->NotifyLastUnload(); >+ } >+ > #ifdef MOZ_XUL > // look for open menupopups and close them after the unload event, in case > // the unload event listeners open any new popups > nsContentUtils::HidePopupsInDocument(mDocument); > #endif > > return NS_OK; > } >diff -r 385684ad7eed layout/base/nsIDocumentViewer.h >--- a/layout/base/nsIDocumentViewer.h Tue Apr 05 09:19:34 2011 -0700 >+++ b/layout/base/nsIDocumentViewer.h Wed Apr 06 15:14:13 2011 +0200 >@@ -43,16 +43,18 @@ > #include "nsIContentViewer.h" > > class nsIDocument; > class nsPresContext; > class nsIPresShell; > class nsIStyleSheet; > class nsIView; > >+class nsDOMNavigationTiming; >+ > #define NS_IDOCUMENT_VIEWER_IID \ > { 0x5a5c9a1d, 0x49c4, 0x4f3f, \ > { 0x80, 0xcd, 0x12, 0x09, 0x5b, 0x1e, 0x1f, 0x61 } } > > /** > * A document viewer is a kind of content viewer that uses NGLayout > * to manage the presentation of the content. > */ >@@ -64,13 +66,15 @@ public: > NS_IMETHOD GetPresShell(nsIPresShell** aResult) = 0; > > NS_IMETHOD GetPresContext(nsPresContext** aResult) = 0; > > NS_IMETHOD SetDocumentInternal(nsIDocument* aDocument, > PRBool aForceReuseInnerWindow) = 0; > > virtual nsIView* FindContainerView() = 0; >+ >+ virtual void SetNavigationTiming(nsDOMNavigationTiming* timing) = 0; > }; > > NS_DEFINE_STATIC_IID_ACCESSOR(nsIDocumentViewer, NS_IDOCUMENT_VIEWER_IID) > > #endif /* nsIDocumentViewer_h___ */
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
Actions:
View
|
Diff
|
Review
Attachments on
bug 570341
:
449469
|
456252
|
456279
|
494409
|
504681
|
507393
|
523992
|
524173
|
524820
|
524938
|
525089
|
525386
|
531923
|
532204
|
534567
|
534661
|
534663
|
534776
|
536050
|
537130
|
540060
|
541142
|
541145
|
541149
|
541319
|
554254
点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载