2018-01-19 03:59:58 +08:00
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License , v . 2.0 . If a copy of the MPL was not distributed with this
* file , You can obtain one at http : //mozilla.org/MPL/2.0/. */
# include "nsDOMNavigationTiming.h"
# include "GeckoProfiler.h"
# include "nsCOMPtr.h"
# include "nsContentUtils.h"
# include "nsIScriptSecurityManager.h"
# include "prtime.h"
# include "nsIURI.h"
# include "nsPrintfCString.h"
# include "mozilla/dom/PerformanceNavigation.h"
# include "mozilla/TimeStamp.h"
2018-04-29 12:39:51 +02:00
using namespace mozilla ;
2018-01-19 03:59:58 +08:00
nsDOMNavigationTiming : : nsDOMNavigationTiming ( )
{
Clear ( ) ;
}
nsDOMNavigationTiming : : ~ nsDOMNavigationTiming ( )
{
}
void
nsDOMNavigationTiming : : Clear ( )
{
mNavigationType = TYPE_RESERVED ;
mNavigationStartHighRes = 0 ;
2018-04-29 14:15:18 +02:00
mBeforeUnloadStart = TimeStamp ( ) ;
mUnloadStart = TimeStamp ( ) ;
mUnloadEnd = TimeStamp ( ) ;
mLoadEventStart = TimeStamp ( ) ;
mLoadEventEnd = TimeStamp ( ) ;
mDOMLoading = TimeStamp ( ) ;
mDOMInteractive = TimeStamp ( ) ;
mDOMContentLoadedEventStart = TimeStamp ( ) ;
mDOMContentLoadedEventEnd = TimeStamp ( ) ;
mDOMComplete = TimeStamp ( ) ;
2018-01-19 03:59:58 +08:00
mDocShellHasBeenActiveSinceNavigationStart = false ;
}
DOMTimeMilliSec
2018-04-29 12:39:51 +02:00
nsDOMNavigationTiming : : TimeStampToDOM ( TimeStamp aStamp ) const
2018-01-19 03:59:58 +08:00
{
if ( aStamp . IsNull ( ) ) {
return 0 ;
}
2018-04-29 12:39:51 +02:00
2018-04-29 14:15:18 +02:00
TimeDuration duration = aStamp - mNavigationStart ;
2018-01-19 03:59:58 +08:00
return GetNavigationStart ( ) + static_cast < int64_t > ( duration . ToMilliseconds ( ) ) ;
}
void
nsDOMNavigationTiming : : NotifyNavigationStart ( DocShellState aDocShellState )
{
mNavigationStartHighRes = ( double ) PR_Now ( ) / PR_USEC_PER_MSEC ;
2018-04-29 14:15:18 +02:00
mNavigationStart = TimeStamp : : Now ( ) ;
2018-01-19 03:59:58 +08:00
mDocShellHasBeenActiveSinceNavigationStart = ( aDocShellState = = DocShellState : : eActive ) ;
}
void
nsDOMNavigationTiming : : NotifyFetchStart ( nsIURI * aURI , Type aNavigationType )
{
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 : : NotifyBeforeUnload ( )
{
2018-04-29 14:15:18 +02:00
mBeforeUnloadStart = TimeStamp : : Now ( ) ;
2018-01-19 03:59:58 +08:00
}
void
nsDOMNavigationTiming : : NotifyUnloadAccepted ( nsIURI * aOldURI )
{
mUnloadStart = mBeforeUnloadStart ;
mUnloadedURI = aOldURI ;
}
void
nsDOMNavigationTiming : : NotifyUnloadEventStart ( )
{
2018-04-29 14:15:18 +02:00
mUnloadStart = TimeStamp : : Now ( ) ;
2018-01-19 03:59:58 +08:00
}
void
nsDOMNavigationTiming : : NotifyUnloadEventEnd ( )
{
2018-04-29 14:15:18 +02:00
mUnloadEnd = TimeStamp : : Now ( ) ;
2018-01-19 03:59:58 +08:00
}
void
nsDOMNavigationTiming : : NotifyLoadEventStart ( )
{
2018-04-29 14:15:18 +02:00
if ( ! mLoadEventStart . IsNull ( ) ) {
return ;
2018-01-19 03:59:58 +08:00
}
2018-04-29 14:15:18 +02:00
mLoadEventStart = TimeStamp : : Now ( ) ;
2018-01-19 03:59:58 +08:00
}
void
nsDOMNavigationTiming : : NotifyLoadEventEnd ( )
{
2018-04-29 14:15:18 +02:00
if ( ! mLoadEventEnd . IsNull ( ) ) {
return ;
2018-01-19 03:59:58 +08:00
}
2018-04-29 14:15:18 +02:00
mLoadEventEnd = TimeStamp : : Now ( ) ;
2018-01-19 03:59:58 +08:00
}
void
2018-04-29 12:39:51 +02:00
nsDOMNavigationTiming : : SetDOMLoadingTimeStamp ( nsIURI * aURI , TimeStamp aValue )
2018-01-19 03:59:58 +08:00
{
2018-04-29 14:15:18 +02:00
if ( ! mDOMLoading . IsNull ( ) ) {
return ;
2018-01-19 03:59:58 +08:00
}
2018-04-29 14:15:18 +02:00
mLoadedURI = aURI ;
mDOMLoading = aValue ;
2018-01-19 03:59:58 +08:00
}
void
nsDOMNavigationTiming : : NotifyDOMLoading ( nsIURI * aURI )
{
2018-04-29 14:15:18 +02:00
if ( ! mDOMLoading . IsNull ( ) ) {
return ;
2018-01-19 03:59:58 +08:00
}
2018-04-29 14:15:18 +02:00
mLoadedURI = aURI ;
mDOMLoading = TimeStamp : : Now ( ) ;
2018-01-19 03:59:58 +08:00
}
void
nsDOMNavigationTiming : : NotifyDOMInteractive ( nsIURI * aURI )
{
2018-04-29 14:15:18 +02:00
if ( ! mDOMInteractive . IsNull ( ) ) {
return ;
2018-01-19 03:59:58 +08:00
}
2018-04-29 14:15:18 +02:00
mLoadedURI = aURI ;
mDOMInteractive = TimeStamp : : Now ( ) ;
2018-01-19 03:59:58 +08:00
}
void
nsDOMNavigationTiming : : NotifyDOMComplete ( nsIURI * aURI )
{
2018-04-29 14:15:18 +02:00
if ( ! mDOMComplete . IsNull ( ) ) {
return ;
2018-01-19 03:59:58 +08:00
}
2018-04-29 14:15:18 +02:00
mLoadedURI = aURI ;
mDOMComplete = TimeStamp : : Now ( ) ;
2018-01-19 03:59:58 +08:00
}
void
nsDOMNavigationTiming : : NotifyDOMContentLoadedStart ( nsIURI * aURI )
{
2018-04-29 14:15:18 +02:00
if ( ! mDOMContentLoadedEventStart . IsNull ( ) ) {
return ;
2018-01-19 03:59:58 +08:00
}
2018-04-29 14:15:18 +02:00
mLoadedURI = aURI ;
mDOMContentLoadedEventStart = TimeStamp : : Now ( ) ;
2018-01-19 03:59:58 +08:00
}
void
nsDOMNavigationTiming : : NotifyDOMContentLoadedEnd ( nsIURI * aURI )
{
2018-04-29 14:15:18 +02:00
if ( ! mDOMContentLoadedEventEnd . IsNull ( ) ) {
return ;
2018-01-19 03:59:58 +08:00
}
2018-04-29 14:15:18 +02:00
mLoadedURI = aURI ;
mDOMContentLoadedEventEnd = TimeStamp : : Now ( ) ;
2018-01-19 03:59:58 +08:00
}
void
nsDOMNavigationTiming : : NotifyNonBlankPaintForRootContentDocument ( )
{
MOZ_ASSERT ( NS_IsMainThread ( ) ) ;
2018-04-29 14:15:18 +02:00
MOZ_ASSERT ( ! mNavigationStart . IsNull ( ) ) ;
2018-01-19 03:59:58 +08:00
2018-04-29 14:15:18 +02:00
if ( ! mNonBlankPaint . IsNull ( ) ) {
2018-01-19 03:59:58 +08:00
return ;
}
2018-04-29 14:15:18 +02:00
mNonBlankPaint = TimeStamp : : Now ( ) ;
TimeDuration elapsed = mNonBlankPaint - mNavigationStart ;
2018-01-19 03:59:58 +08:00
if ( profiler_is_active ( ) ) {
nsAutoCString spec ;
if ( mLoadedURI ) {
mLoadedURI - > GetSpec ( spec ) ;
}
nsPrintfCString marker ( " Non-blank paint after %dms for URL %s, %s " ,
int ( elapsed . ToMilliseconds ( ) ) , spec . get ( ) ,
mDocShellHasBeenActiveSinceNavigationStart ? " foreground tab " : " this tab was inactive some of the time between navigation start and first non-blank paint " ) ;
PROFILER_MARKER ( marker . get ( ) ) ;
}
}
void
nsDOMNavigationTiming : : NotifyDocShellStateChanged ( DocShellState aDocShellState )
{
mDocShellHasBeenActiveSinceNavigationStart & =
( aDocShellState = = DocShellState : : eActive ) ;
}
2018-04-29 14:15:18 +02:00
mozilla : : TimeStamp
nsDOMNavigationTiming : : GetUnloadEventStartTimeStamp ( ) const
2018-01-19 03:59:58 +08:00
{
nsIScriptSecurityManager * ssm = nsContentUtils : : GetSecurityManager ( ) ;
nsresult rv = ssm - > CheckSameOriginURI ( mLoadedURI , mUnloadedURI , false ) ;
if ( NS_SUCCEEDED ( rv ) ) {
return mUnloadStart ;
}
2018-04-29 14:15:18 +02:00
return mozilla : : TimeStamp ( ) ;
2018-01-19 03:59:58 +08:00
}
2018-04-29 14:15:18 +02:00
mozilla : : TimeStamp
nsDOMNavigationTiming : : GetUnloadEventEndTimeStamp ( ) const
2018-01-19 03:59:58 +08:00
{
nsIScriptSecurityManager * ssm = nsContentUtils : : GetSecurityManager ( ) ;
nsresult rv = ssm - > CheckSameOriginURI ( mLoadedURI , mUnloadedURI , false ) ;
if ( NS_SUCCEEDED ( rv ) ) {
return mUnloadEnd ;
}
2018-04-29 14:15:18 +02:00
return mozilla : : TimeStamp ( ) ;
2018-01-19 03:59:58 +08:00
}