| 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 d5db734f01ae28a75529e172a19b13955f5eee48..db86b63b688fb65cb3316f88c5cf576a27741ef8 100644
|
| --- a/third_party/WebKit/Source/core/timing/PerformanceNavigationTiming.cpp
|
| +++ b/third_party/WebKit/Source/core/timing/PerformanceNavigationTiming.cpp
|
| @@ -5,161 +5,329 @@
|
| #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,
|
| - 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,
|
| - "document",
|
| - "navigation",
|
| - timeOrigin),
|
| + LocalFrame* frame,
|
| + std::unique_ptr<ResourceTimingInfo> info,
|
| + double timeOrigin)
|
| + : PerformanceResourceTiming("document", "navigation", 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(std::move(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();
|
| +}
|
| +
|
| +ExecutionContext* PerformanceNavigationTiming::getExecutionContext() const {
|
| + return m_frame ? m_frame->document() : nullptr;
|
| +}
|
| +
|
| +bool PerformanceNavigationTiming::getAllowRedirectDetails() const {
|
| + ExecutionContext* context = getExecutionContext();
|
| + SecurityOrigin* securityOrigin = PerformanceBase::getSecurityOrigin(context);
|
| + 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";
|
| }
|
|
|
| +AtomicString PerformanceNavigationTiming::type() const {
|
| + DocumentLoader* loader = documentLoader();
|
| + if (!m_frame || !loader)
|
| + return ""; // Not available yet.
|
| + Document* document = m_frame->document();
|
| + return getNavigationType(loader->getNavigationType(), document);
|
| +}
|
| +
|
| unsigned short PerformanceNavigationTiming::redirectCount() const {
|
| - if (!m_allowRedirectDetails)
|
| + bool allowRedirectDetails = getAllowRedirectDetails();
|
| + DocumentLoadTiming* timing = documentLoadTiming();
|
| + if (!allowRedirectDetails || !timing)
|
| return 0;
|
| - return m_redirectCount;
|
| + return timing->redirectCount();
|
| }
|
|
|
| -DOMHighResTimeStamp PerformanceNavigationTiming::fetchStart() const {
|
| - return PerformanceBase::monotonicTimeToDOMHighResTimeStamp(m_timeOrigin,
|
| - m_fetchStart);
|
| +// Overriding PerformanceResourceTiming's attributes.
|
| +AtomicString PerformanceNavigationTiming::initiatorType() const {
|
| + return "navigation";
|
| +}
|
| +
|
| +DOMHighResTimeStamp PerformanceNavigationTiming::workerStart() const {
|
| + ResourceLoadTiming* timing = resourceLoadTiming();
|
| + if (!timing || timing->workerStart() == 0.0)
|
| + return 0.0;
|
| + return PerformanceBase::monotonicTimeToDOMHighResTimeStamp(
|
| + m_timeOrigin, timing->workerStart());
|
| }
|
|
|
| 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, timing->redirectEnd());
|
| +}
|
| +
|
| +DOMHighResTimeStamp PerformanceNavigationTiming::fetchStart() const {
|
| + DocumentLoadTiming* timing = documentLoadTiming();
|
| + if (!timing)
|
| + return 0.0;
|
| + return PerformanceBase::monotonicTimeToDOMHighResTimeStamp(
|
| + m_timeOrigin, timing->fetchStart());
|
| +}
|
| +
|
| +DOMHighResTimeStamp PerformanceNavigationTiming::domainLookupStart() const {
|
| + ResourceLoadTiming* timing = resourceLoadTiming();
|
| + if (!timing || timing->dnsStart() == 0.0)
|
| + return fetchStart();
|
| + return PerformanceBase::monotonicTimeToDOMHighResTimeStamp(
|
| + m_timeOrigin, timing->dnsStart());
|
| +}
|
| +
|
| +DOMHighResTimeStamp PerformanceNavigationTiming::domainLookupEnd() const {
|
| + ResourceLoadTiming* timing = resourceLoadTiming();
|
| + if (!timing || timing->dnsEnd() == 0.0)
|
| + return domainLookupStart();
|
| return PerformanceBase::monotonicTimeToDOMHighResTimeStamp(m_timeOrigin,
|
| - m_redirectEnd);
|
| + timing->dnsEnd());
|
| }
|
|
|
| -DOMHighResTimeStamp PerformanceNavigationTiming::responseEnd() const {
|
| +DOMHighResTimeStamp PerformanceNavigationTiming::connectStart() const {
|
| + DocumentLoader* loader = documentLoader();
|
| + if (!loader)
|
| + return domainLookupEnd();
|
| + ResourceLoadTiming* timing = resourceLoadTiming();
|
| + if (!timing || timing->connectStart() == 0.0 ||
|
| + m_resourceTimingInfo->finalResponse().connectionReused())
|
| + return domainLookupEnd();
|
| + double connectStart = timing->connectStart();
|
| + if (timing->dnsEnd() > 0.0 && timing->dnsEnd() > connectStart)
|
| + connectStart = timing->dnsEnd();
|
| +
|
| return PerformanceBase::monotonicTimeToDOMHighResTimeStamp(m_timeOrigin,
|
| - m_responseEnd);
|
| + connectStart);
|
| +}
|
| +
|
| +DOMHighResTimeStamp PerformanceNavigationTiming::connectEnd() const {
|
| + DocumentLoader* loader = documentLoader();
|
| + if (!loader)
|
| + return connectStart();
|
| + ResourceLoadTiming* timing = resourceLoadTiming();
|
| + if (!timing || timing->connectEnd() == 0.0 ||
|
| + m_resourceTimingInfo->finalResponse().connectionReused())
|
| + return connectStart();
|
| + return PerformanceBase::monotonicTimeToDOMHighResTimeStamp(
|
| + m_timeOrigin, timing->connectEnd());
|
| +}
|
| +
|
| +DOMHighResTimeStamp PerformanceNavigationTiming::secureConnectionStart() const {
|
| + DocumentLoader* loader = documentLoader();
|
| + if (!loader)
|
| + return 0.0;
|
| + ResourceLoadTiming* timing = resourceLoadTiming();
|
| + if (!timing ||
|
| + timing->sslStart() == 0.0) // Secure connection not negotiated.
|
| + return 0.0;
|
| + return PerformanceBase::monotonicTimeToDOMHighResTimeStamp(
|
| + m_timeOrigin, timing->sslStart());
|
| +}
|
| +
|
| +DOMHighResTimeStamp PerformanceNavigationTiming::requestStart() const {
|
| + ResourceLoadTiming* timing = resourceLoadTiming();
|
| + if (!timing || timing->sendStart() == 0.0)
|
| + return connectEnd();
|
| + return PerformanceBase::monotonicTimeToDOMHighResTimeStamp(
|
| + m_timeOrigin, timing->sendStart());
|
| +}
|
| +
|
| +DOMHighResTimeStamp PerformanceNavigationTiming::responseStart() const {
|
| + ResourceLoadTiming* timing = resourceLoadTiming();
|
| + if (!timing || timing->receiveHeadersEnd() == 0.0)
|
| + return requestStart();
|
| + return PerformanceBase::monotonicTimeToDOMHighResTimeStamp(
|
| + m_timeOrigin, timing->receiveHeadersEnd());
|
| +}
|
| +
|
| +DOMHighResTimeStamp PerformanceNavigationTiming::responseEnd() const {
|
| + DocumentLoadTiming* timing = documentLoadTiming();
|
| + if (!timing)
|
| + return 0.0;
|
| + return PerformanceBase::monotonicTimeToDOMHighResTimeStamp(
|
| + m_timeOrigin, timing->responseEnd());
|
| +}
|
| +
|
| +unsigned long long PerformanceNavigationTiming::transferSize() const {
|
| + return !m_resourceTimingInfo ? 0 : m_resourceTimingInfo->transferSize();
|
| +}
|
| +
|
| +unsigned long long PerformanceNavigationTiming::encodedBodySize() const {
|
| + return !m_resourceTimingInfo
|
| + ? 0
|
| + : m_resourceTimingInfo->finalResponse().encodedBodyLength();
|
| +}
|
| +
|
| +unsigned long long PerformanceNavigationTiming::decodedBodySize() const {
|
| + return !m_resourceTimingInfo
|
| + ? 0
|
| + : m_resourceTimingInfo->finalResponse().decodedBodyLength();
|
| +}
|
| +
|
| +// Overriding PerformanceEntry's attributes.
|
| +DOMHighResTimeStamp PerformanceNavigationTiming::duration() const {
|
| + return loadEventEnd();
|
| }
|
|
|
| void PerformanceNavigationTiming::buildJSONValue(
|
|
|