Chromium Code Reviews| Index: third_party/WebKit/Source/core/timing/PerformanceNavigationTiming.cpp |
| diff --git a/third_party/WebKit/Source/core/timing/PerformanceNavigationTiming.cpp b/third_party/WebKit/Source/core/timing/PerformanceNavigationTiming.cpp |
| index 7a1abafb002f56cdfc0163b912222f53e521d509..2b50bdfa966276e380f5124f80cdbc11eecd8ab6 100644 |
| --- a/third_party/WebKit/Source/core/timing/PerformanceNavigationTiming.cpp |
| +++ b/third_party/WebKit/Source/core/timing/PerformanceNavigationTiming.cpp |
| @@ -5,162 +5,263 @@ |
| #include "core/timing/PerformanceNavigationTiming.h" |
| #include "bindings/core/v8/V8ObjectBuilder.h" |
| +#include "core/dom/Document.h" |
| +#include "core/dom/DocumentTiming.h" |
| +#include "core/frame/LocalFrame.h" |
| +#include "core/loader/DocumentLoadTiming.h" |
| +#include "core/loader/DocumentLoader.h" |
| #include "core/timing/PerformanceBase.h" |
| +#include "platform/network/ResourceTimingInfo.h" |
| namespace blink { |
| PerformanceNavigationTiming::PerformanceNavigationTiming( |
| - double timeOrigin, |
| - const String& requestedUrl, |
| - double unloadEventStart, |
| - double unloadEventEnd, |
| - double loadEventStart, |
| - double loadEventEnd, |
| - unsigned short redirectCount, |
| - double domInteractive, |
| - double domContentLoadedEventStart, |
| - double domContentLoadedEventEnd, |
| - double domComplete, |
| - NavigationType type, |
| - double redirectStart, |
| - double redirectEnd, |
| - double fetchStart, |
| - double responseEnd, |
| - bool allowRedirectDetails, |
| - bool hasSameOriginAsPreviousDocument, |
| - ResourceLoadTiming* timing, |
| - double lastRedirectEndTime, |
| - double finishTime, |
| - unsigned long long transferSize, |
| - unsigned long long encodedBodyLength, |
| - unsigned long long decodedBodyLength, |
| - bool didReuseConnection) |
| - : PerformanceResourceTiming("navigation", |
| - timeOrigin, |
| - timing, |
| - lastRedirectEndTime, |
| - finishTime, |
| - transferSize, |
| - encodedBodyLength, |
| - decodedBodyLength, |
| - didReuseConnection, |
| - true /*allowTimingDetails*/, // TODO(sunjian): |
| - // Create an enum |
| - // for this. |
| - allowRedirectDetails, |
| - requestedUrl, |
| + LocalFrame* frame, |
| + ResourceTimingInfo* info, |
| + double timeOrigin) |
| + : PerformanceResourceTiming(info ? info->initialURL().getString() : "", |
| "navigation", |
| - timeOrigin), |
| + 0.0, |
| + 0.0), |
| m_timeOrigin(timeOrigin), |
| - m_unloadEventStart(unloadEventStart), |
| - m_unloadEventEnd(unloadEventEnd), |
| - m_loadEventStart(loadEventStart), |
| - m_loadEventEnd(loadEventEnd), |
| - m_redirectCount(redirectCount), |
| - m_domInteractive(domInteractive), |
| - m_domContentLoadedEventStart(domContentLoadedEventStart), |
| - m_domContentLoadedEventEnd(domContentLoadedEventEnd), |
| - m_domComplete(domComplete), |
| - m_type(type), |
| - m_redirectStart(redirectStart), |
| - m_redirectEnd(redirectEnd), |
| - m_fetchStart(fetchStart), |
| - m_responseEnd(responseEnd), |
| - m_allowRedirectDetails(allowRedirectDetails), |
| - m_hasSameOriginAsPreviousDocument(hasSameOriginAsPreviousDocument) {} |
| + m_resourceTimingInfo(info), |
| + m_frame(frame) {} |
| PerformanceNavigationTiming::~PerformanceNavigationTiming() {} |
| +DEFINE_TRACE(PerformanceNavigationTiming) { |
| + visitor->trace(m_frame); |
| + PerformanceEntry::trace(visitor); |
| +} |
| + |
| +DocumentLoadTiming* PerformanceNavigationTiming::documentLoadTiming() const { |
| + DocumentLoader* loader = documentLoader(); |
| + if (!loader) |
| + return nullptr; |
| + |
| + return &loader->timing(); |
| +} |
| + |
| +DocumentLoader* PerformanceNavigationTiming::documentLoader() const { |
| + if (!m_frame) |
| + return nullptr; |
| + |
| + return m_frame->loader().documentLoader(); |
| +} |
| + |
| +const DocumentTiming* PerformanceNavigationTiming::documentTiming() const { |
| + if (!m_frame) |
| + return nullptr; |
| + |
| + Document* document = m_frame->document(); |
| + if (!document) |
| + return nullptr; |
| + |
| + return &document->timing(); |
| +} |
| + |
| +ResourceLoadTiming* PerformanceNavigationTiming::resourceLoadTiming() const { |
| + if (!m_resourceTimingInfo) |
| + return nullptr; |
| + return m_resourceTimingInfo->finalResponse().resourceLoadTiming(); |
| +} |
| + |
| +bool PerformanceNavigationTiming::allowTimingDetails() const { |
| + return true; |
| +} |
| + |
| +bool PerformanceNavigationTiming::didReuseConnection() const { |
| + if (m_resourceTimingInfo) |
| + return m_resourceTimingInfo->finalResponse().connectionReused(); |
| + return false; |
| +} |
| + |
| +unsigned long long PerformanceNavigationTiming::getTransferSize() const { |
| + return !m_resourceTimingInfo ? 0 : m_resourceTimingInfo->transferSize(); |
| +} |
| + |
| +unsigned long long PerformanceNavigationTiming::getEncodedBodySize() const { |
| + return !m_resourceTimingInfo |
| + ? 0 |
| + : m_resourceTimingInfo->finalResponse().encodedBodyLength(); |
| +} |
| + |
| +unsigned long long PerformanceNavigationTiming::getDecodedBodySize() const { |
| + return !m_resourceTimingInfo |
| + ? 0 |
| + : m_resourceTimingInfo->finalResponse().decodedBodyLength(); |
| +} |
| + |
| +AtomicString PerformanceNavigationTiming::getInitiatorType() const { |
| + return "navigation"; |
| +} |
| + |
| +ExecutionContext* PerformanceNavigationTiming::getExecutionContext() const { |
|
Kunihiko Sakamoto
2017/02/16 08:42:29
This function is used only once. Inline?
sunjian
2017/02/16 22:30:49
Done.
|
| + return m_frame ? m_frame->document() : nullptr; |
| +} |
| + |
| +bool PerformanceNavigationTiming::getAllowRedirectDetails() const { |
| + ExecutionContext* context = getExecutionContext(); |
| + SecurityOrigin* securityOrigin = nullptr; |
| + if (context) |
| + securityOrigin = context->getSecurityOrigin(); |
| + if (!securityOrigin) |
| + return false; |
| + if (!m_resourceTimingInfo) |
| + return false; |
| + |
| + return PerformanceBase::allowsTimingRedirect( |
| + m_resourceTimingInfo->redirectChain(), |
| + m_resourceTimingInfo->finalResponse(), *securityOrigin, context); |
| +} |
| + |
| DOMHighResTimeStamp PerformanceNavigationTiming::unloadEventStart() const { |
| - if (!m_allowRedirectDetails || !m_hasSameOriginAsPreviousDocument) |
| + bool allowRedirectDetails = getAllowRedirectDetails(); |
| + DocumentLoadTiming* timing = documentLoadTiming(); |
| + |
| + if (!allowRedirectDetails || !timing || |
| + !timing->hasSameOriginAsPreviousDocument()) |
| return 0; |
| return PerformanceBase::monotonicTimeToDOMHighResTimeStamp( |
| - m_timeOrigin, m_unloadEventStart); |
| + m_timeOrigin, timing->unloadEventStart()); |
| } |
| DOMHighResTimeStamp PerformanceNavigationTiming::unloadEventEnd() const { |
| - if (!m_allowRedirectDetails || !m_hasSameOriginAsPreviousDocument) |
| - return 0; |
| + bool allowRedirectDetails = getAllowRedirectDetails(); |
| + DocumentLoadTiming* timing = documentLoadTiming(); |
| - return PerformanceBase::monotonicTimeToDOMHighResTimeStamp(m_timeOrigin, |
| - m_unloadEventEnd); |
| + if (!allowRedirectDetails || !timing || |
| + !timing->hasSameOriginAsPreviousDocument()) |
| + return 0; |
| + return PerformanceBase::monotonicTimeToDOMHighResTimeStamp( |
| + m_timeOrigin, timing->unloadEventEnd()); |
| } |
| DOMHighResTimeStamp PerformanceNavigationTiming::domInteractive() const { |
| - return PerformanceBase::monotonicTimeToDOMHighResTimeStamp(m_timeOrigin, |
| - m_domInteractive); |
| + const DocumentTiming* timing = documentTiming(); |
| + if (!timing) |
| + return 0.0; |
| + return PerformanceBase::monotonicTimeToDOMHighResTimeStamp( |
| + m_timeOrigin, timing->domInteractive()); |
| } |
| DOMHighResTimeStamp PerformanceNavigationTiming::domContentLoadedEventStart() |
| const { |
| + const DocumentTiming* timing = documentTiming(); |
| + if (!timing) |
| + return 0.0; |
| return PerformanceBase::monotonicTimeToDOMHighResTimeStamp( |
| - m_timeOrigin, m_domContentLoadedEventStart); |
| + m_timeOrigin, timing->domContentLoadedEventStart()); |
| } |
| DOMHighResTimeStamp PerformanceNavigationTiming::domContentLoadedEventEnd() |
| const { |
| + const DocumentTiming* timing = documentTiming(); |
| + if (!timing) |
| + return 0.0; |
| return PerformanceBase::monotonicTimeToDOMHighResTimeStamp( |
| - m_timeOrigin, m_domContentLoadedEventEnd); |
| + m_timeOrigin, timing->domContentLoadedEventEnd()); |
| } |
| DOMHighResTimeStamp PerformanceNavigationTiming::domComplete() const { |
| - return PerformanceBase::monotonicTimeToDOMHighResTimeStamp(m_timeOrigin, |
| - m_domComplete); |
| + const DocumentTiming* timing = documentTiming(); |
| + if (!timing) |
| + return 0.0; |
| + return PerformanceBase::monotonicTimeToDOMHighResTimeStamp( |
| + m_timeOrigin, timing->domComplete()); |
| } |
| DOMHighResTimeStamp PerformanceNavigationTiming::loadEventStart() const { |
| - return PerformanceBase::monotonicTimeToDOMHighResTimeStamp(m_timeOrigin, |
| - m_loadEventStart); |
| + DocumentLoadTiming* timing = documentLoadTiming(); |
| + if (!timing) |
| + return 0.0; |
| + return PerformanceBase::monotonicTimeToDOMHighResTimeStamp( |
| + m_timeOrigin, timing->loadEventStart()); |
| } |
| DOMHighResTimeStamp PerformanceNavigationTiming::loadEventEnd() const { |
| - return PerformanceBase::monotonicTimeToDOMHighResTimeStamp(m_timeOrigin, |
| - m_loadEventEnd); |
| + DocumentLoadTiming* timing = documentLoadTiming(); |
| + if (!timing) |
| + return 0.0; |
| + return PerformanceBase::monotonicTimeToDOMHighResTimeStamp( |
| + m_timeOrigin, timing->loadEventEnd()); |
| } |
| -AtomicString PerformanceNavigationTiming::type() const { |
| - switch (m_type) { |
| - case NavigationType::Reload: |
| +AtomicString PerformanceNavigationTiming::getNavigationType( |
| + NavigationType type, |
| + const Document* document) { |
| + if (document && |
| + document->pageVisibilityState() == PageVisibilityStatePrerender) { |
| + return "prerender"; |
| + } |
| + switch (type) { |
| + case NavigationTypeReload: |
| return "reload"; |
| - case NavigationType::BackForward: |
| + case NavigationTypeBackForward: |
| return "back_forward"; |
| - case NavigationType::Prerender: |
| - return "prerender"; |
| - case NavigationType::Navigate: |
| + case NavigationTypeLinkClicked: |
| + case NavigationTypeFormSubmitted: |
| + case NavigationTypeFormResubmitted: |
| + case NavigationTypeOther: |
| return "navigate"; |
| } |
| NOTREACHED(); |
| return "navigate"; |
| } |
| -unsigned short PerformanceNavigationTiming::redirectCount() const { |
| - if (!m_allowRedirectDetails) |
| - return 0; |
| - return m_redirectCount; |
| +AtomicString PerformanceNavigationTiming::type() const { |
| + DocumentLoader* loader = documentLoader(); |
| + DCHECK(m_frame); |
| + DCHECK(loader); |
| + Document* document = m_frame->document(); |
| + return getNavigationType(loader->getNavigationType(), document); |
| } |
| -DOMHighResTimeStamp PerformanceNavigationTiming::fetchStart() const { |
| - return PerformanceBase::monotonicTimeToDOMHighResTimeStamp(m_timeOrigin, |
| - m_fetchStart); |
| +unsigned short PerformanceNavigationTiming::redirectCount() const { |
| + bool allowRedirectDetails = getAllowRedirectDetails(); |
| + DocumentLoadTiming* timing = documentLoadTiming(); |
| + if (!allowRedirectDetails || !timing) |
| + return 0; |
| + return timing->redirectCount(); |
| } |
| DOMHighResTimeStamp PerformanceNavigationTiming::redirectStart() const { |
| - if (!m_allowRedirectDetails) |
| + bool allowRedirectDetails = getAllowRedirectDetails(); |
| + DocumentLoadTiming* timing = documentLoadTiming(); |
| + if (!allowRedirectDetails || !timing) |
| return 0; |
| - return PerformanceBase::monotonicTimeToDOMHighResTimeStamp(m_timeOrigin, |
| - m_redirectStart); |
| + return PerformanceBase::monotonicTimeToDOMHighResTimeStamp( |
| + m_timeOrigin, timing->redirectStart()); |
| } |
| DOMHighResTimeStamp PerformanceNavigationTiming::redirectEnd() const { |
| - if (!m_allowRedirectDetails) |
| + bool allowRedirectDetails = getAllowRedirectDetails(); |
| + DocumentLoadTiming* timing = documentLoadTiming(); |
| + if (!allowRedirectDetails || !timing) |
| return 0; |
| - return PerformanceBase::monotonicTimeToDOMHighResTimeStamp(m_timeOrigin, |
| - m_redirectEnd); |
| + return PerformanceBase::monotonicTimeToDOMHighResTimeStamp( |
| + m_timeOrigin, timing->redirectEnd()); |
| +} |
| + |
| +DOMHighResTimeStamp PerformanceNavigationTiming::fetchStart() const { |
| + DocumentLoadTiming* timing = documentLoadTiming(); |
| + if (!timing) |
| + return 0.0; |
| + return PerformanceBase::monotonicTimeToDOMHighResTimeStamp( |
| + m_timeOrigin, timing->fetchStart()); |
| } |
| DOMHighResTimeStamp PerformanceNavigationTiming::responseEnd() const { |
| - return PerformanceBase::monotonicTimeToDOMHighResTimeStamp(m_timeOrigin, |
| - m_responseEnd); |
| + DocumentLoadTiming* timing = documentLoadTiming(); |
| + if (!timing) |
| + return 0.0; |
| + return PerformanceBase::monotonicTimeToDOMHighResTimeStamp( |
| + m_timeOrigin, timing->responseEnd()); |
| +} |
| + |
| +// Overriding PerformanceEntry's attributes. |
| +DOMHighResTimeStamp PerformanceNavigationTiming::duration() const { |
| + return loadEventEnd(); |
| } |
| void PerformanceNavigationTiming::buildJSONValue( |