mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-19 13:47:31 +09:00
Issue #2282 - Align the Performance Observer navigation and resource with the spec. This now passes the conformance tests. https://bugzilla.mozilla.org/show_bug.cgi?id=1425458 Resource timing entries Workers - part 2 - PerformanceTimingData. https://bugzilla.mozilla.org/show_bug.cgi?id=1462605 PerformanceNavigationTiming.name must be the value of the address of the current document. https://bugzilla.mozilla.org/show_bug.cgi?id=1462883 Update PerformanceTimingData::mReportCrossOriginRedirect in SetPropertiesFromHttpChannel. https://bugzilla.mozilla.org/show_bug.cgi?id=1462879 PerformanceNavigationTiming must be notified correctly - part 1 - notify.
This commit is contained in:
parent
e65b46ba0f
commit
373fb9ae07
14 changed files with 484 additions and 343 deletions
|
|
@ -4224,6 +4224,15 @@ nsGlobalWindow::GetPerformance()
|
||||||
return AsInner()->GetPerformance();
|
return AsInner()->GetPerformance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsPIDOMWindowInner::QueuePerformanceNavigationTiming()
|
||||||
|
{
|
||||||
|
CreatePerformanceObjectIfNeeded();
|
||||||
|
if (mPerformance) {
|
||||||
|
mPerformance->QueueNavigationTimingEntry();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsPIDOMWindowInner::CreatePerformanceObjectIfNeeded()
|
nsPIDOMWindowInner::CreatePerformanceObjectIfNeeded()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -727,6 +727,8 @@ public:
|
||||||
|
|
||||||
mozilla::dom::Performance* GetPerformance();
|
mozilla::dom::Performance* GetPerformance();
|
||||||
|
|
||||||
|
void QueuePerformanceNavigationTiming();
|
||||||
|
|
||||||
bool HasMutationListeners(uint32_t aMutationEventType) const
|
bool HasMutationListeners(uint32_t aMutationEventType) const
|
||||||
{
|
{
|
||||||
if (!mOuterWindow) {
|
if (!mOuterWindow) {
|
||||||
|
|
|
||||||
|
|
@ -124,6 +124,8 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void QueueNavigationTimingEntry() = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Performance();
|
Performance();
|
||||||
explicit Performance(nsPIDOMWindowInner* aWindow);
|
explicit Performance(nsPIDOMWindowInner* aWindow);
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,34 @@
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
void
|
||||||
|
GetURLSpecFromChannel(nsITimedChannel* aChannel, nsAString& aSpec)
|
||||||
|
{
|
||||||
|
aSpec.AssignLiteral("document");
|
||||||
|
|
||||||
|
nsCOMPtr<nsIChannel> channel = do_QueryInterface(aChannel);
|
||||||
|
if (!channel) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsIURI> uri;
|
||||||
|
nsresult rv = channel->GetURI(getter_AddRefs(uri));
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv)) || !uri) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsAutoCString spec;
|
||||||
|
rv = uri->GetSpec(spec);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
aSpec = NS_ConvertUTF8toUTF16(spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // anonymous
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_CLASS(PerformanceMainThread)
|
NS_IMPL_CYCLE_COLLECTION_CLASS(PerformanceMainThread)
|
||||||
|
|
||||||
|
|
@ -60,6 +88,7 @@ PerformanceMainThread::PerformanceMainThread(nsPIDOMWindowInner* aWindow,
|
||||||
, mChannel(aChannel)
|
, mChannel(aChannel)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(aWindow, "Parent window object should be provided");
|
MOZ_ASSERT(aWindow, "Parent window object should be provided");
|
||||||
|
CreateNavigationTimingEntry();
|
||||||
}
|
}
|
||||||
|
|
||||||
PerformanceMainThread::~PerformanceMainThread()
|
PerformanceMainThread::~PerformanceMainThread()
|
||||||
|
|
@ -159,14 +188,14 @@ PerformanceMainThread::AddEntry(nsIHttpChannel* channel,
|
||||||
// The last argument is the "zero time" (offset). Since we don't want
|
// The last argument is the "zero time" (offset). Since we don't want
|
||||||
// any offset for the resource timing, this will be set to "0" - the
|
// any offset for the resource timing, this will be set to "0" - the
|
||||||
// resource timing returns a relative timing (no offset).
|
// resource timing returns a relative timing (no offset).
|
||||||
RefPtr<PerformanceTiming> performanceTiming =
|
UniquePtr<PerformanceTimingData> performanceTimingData(
|
||||||
new PerformanceTiming(this, timedChannel, channel,
|
new PerformanceTimingData(timedChannel, channel, 0));
|
||||||
0);
|
|
||||||
|
|
||||||
// The PerformanceResourceTiming object will use the PerformanceTiming
|
// The PerformanceResourceTiming object will use the PerformanceTiming
|
||||||
// object to get all the required timings.
|
// object to get all the required timings.
|
||||||
RefPtr<PerformanceResourceTiming> performanceEntry =
|
RefPtr<PerformanceResourceTiming> performanceEntry =
|
||||||
new PerformanceResourceTiming(performanceTiming, this, entryName, channel);
|
new PerformanceResourceTiming(std::move(performanceTimingData), this, entryName);
|
||||||
|
|
||||||
// If the initiator type had no valid value, then set it to the default
|
// If the initiator type had no valid value, then set it to the default
|
||||||
// ("other") value.
|
// ("other") value.
|
||||||
if (initiatorType.IsEmpty()) {
|
if (initiatorType.IsEmpty()) {
|
||||||
|
|
@ -299,17 +328,31 @@ PerformanceMainThread::CreationTime() const
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
PerformanceMainThread::EnsureDocEntry()
|
PerformanceMainThread::CreateNavigationTimingEntry()
|
||||||
{
|
{
|
||||||
if (!mDocEntry && nsContentUtils::IsPerformanceNavigationTimingEnabled()) {
|
MOZ_ASSERT(!mDocEntry, "mDocEntry should be null.");
|
||||||
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(mChannel);
|
|
||||||
RefPtr<PerformanceTiming> timing =
|
nsAutoString name;
|
||||||
new PerformanceTiming(this, mChannel, nullptr, 0);
|
GetURLSpecFromChannel(mChannel, name);
|
||||||
mDocEntry = new PerformanceNavigationTiming(timing, this,
|
|
||||||
httpChannel);
|
UniquePtr<PerformanceTimingData> timing(
|
||||||
|
new PerformanceTimingData(mChannel, nullptr, 0));
|
||||||
|
|
||||||
|
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(mChannel);
|
||||||
|
if (httpChannel) {
|
||||||
|
timing->SetPropertiesFromHttpChannel(httpChannel, mChannel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mDocEntry = new PerformanceNavigationTiming(std::move(timing), this, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PerformanceMainThread::QueueNavigationTimingEntry()
|
||||||
|
{
|
||||||
|
if (mDocEntry) {
|
||||||
|
QueueEntry(mDocEntry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
PerformanceMainThread::GetEntries(nsTArray<RefPtr<PerformanceEntry>>& aRetval)
|
PerformanceMainThread::GetEntries(nsTArray<RefPtr<PerformanceEntry>>& aRetval)
|
||||||
|
|
@ -317,7 +360,6 @@ PerformanceMainThread::GetEntries(nsTArray<RefPtr<PerformanceEntry>>& aRetval)
|
||||||
aRetval = mResourceEntries;
|
aRetval = mResourceEntries;
|
||||||
aRetval.AppendElements(mUserEntries);
|
aRetval.AppendElements(mUserEntries);
|
||||||
|
|
||||||
EnsureDocEntry();
|
|
||||||
if (mDocEntry) {
|
if (mDocEntry) {
|
||||||
aRetval.AppendElement(mDocEntry);
|
aRetval.AppendElement(mDocEntry);
|
||||||
}
|
}
|
||||||
|
|
@ -331,7 +373,7 @@ PerformanceMainThread::GetEntriesByType(const nsAString& aEntryType,
|
||||||
{
|
{
|
||||||
if (aEntryType.EqualsLiteral("navigation")) {
|
if (aEntryType.EqualsLiteral("navigation")) {
|
||||||
aRetval.Clear();
|
aRetval.Clear();
|
||||||
EnsureDocEntry();
|
|
||||||
if (mDocEntry) {
|
if (mDocEntry) {
|
||||||
aRetval.AppendElement(mDocEntry);
|
aRetval.AppendElement(mDocEntry);
|
||||||
}
|
}
|
||||||
|
|
@ -348,7 +390,7 @@ PerformanceMainThread::GetEntriesByName(const nsAString& aName,
|
||||||
{
|
{
|
||||||
if (aName.EqualsLiteral("document")) {
|
if (aName.EqualsLiteral("document")) {
|
||||||
aRetval.Clear();
|
aRetval.Clear();
|
||||||
EnsureDocEntry();
|
|
||||||
if (mDocEntry) {
|
if (mDocEntry) {
|
||||||
aRetval.AppendElement(mDocEntry);
|
aRetval.AppendElement(mDocEntry);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -62,9 +62,13 @@ public:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QueueNavigationTimingEntry() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
~PerformanceMainThread();
|
~PerformanceMainThread();
|
||||||
|
|
||||||
|
void CreateNavigationTimingEntry();
|
||||||
|
|
||||||
nsISupports* GetAsISupports() override
|
nsISupports* GetAsISupports() override
|
||||||
{
|
{
|
||||||
return this;
|
return this;
|
||||||
|
|
@ -76,7 +80,6 @@ protected:
|
||||||
GetPerformanceTimingFromString(const nsAString& aTimingName) override;
|
GetPerformanceTimingFromString(const nsAString& aTimingName) override;
|
||||||
|
|
||||||
void DispatchBufferFullEvent() override;
|
void DispatchBufferFullEvent() override;
|
||||||
void EnsureDocEntry();
|
|
||||||
|
|
||||||
RefPtr<PerformanceEntry> mDocEntry;
|
RefPtr<PerformanceEntry> mDocEntry;
|
||||||
RefPtr<nsDOMNavigationTiming> mDOMTiming;
|
RefPtr<nsDOMNavigationTiming> mDOMTiming;
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ PerformanceNavigation::WrapObject(JSContext *cx,
|
||||||
uint16_t
|
uint16_t
|
||||||
PerformanceNavigation::RedirectCount() const
|
PerformanceNavigation::RedirectCount() const
|
||||||
{
|
{
|
||||||
return GetPerformanceTiming()->GetRedirectCount();
|
return GetPerformanceTiming()->Data()->GetRedirectCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // dom namespace
|
} // dom namespace
|
||||||
|
|
|
||||||
|
|
@ -24,55 +24,55 @@ PerformanceNavigationTiming::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aG
|
||||||
DOMHighResTimeStamp
|
DOMHighResTimeStamp
|
||||||
PerformanceNavigationTiming::UnloadEventStart() const
|
PerformanceNavigationTiming::UnloadEventStart() const
|
||||||
{
|
{
|
||||||
return TimerClamping::ReduceMsTimeValue(mTiming->GetDOMTiming()->GetUnloadEventStartHighRes());
|
return mPerformance->GetDOMTiming()->GetUnloadEventStartHighRes();
|
||||||
}
|
}
|
||||||
|
|
||||||
DOMHighResTimeStamp
|
DOMHighResTimeStamp
|
||||||
PerformanceNavigationTiming::UnloadEventEnd() const
|
PerformanceNavigationTiming::UnloadEventEnd() const
|
||||||
{
|
{
|
||||||
return TimerClamping::ReduceMsTimeValue(mTiming->GetDOMTiming()->GetUnloadEventEndHighRes());
|
return mPerformance->GetDOMTiming()->GetUnloadEventEndHighRes();
|
||||||
}
|
}
|
||||||
|
|
||||||
DOMHighResTimeStamp
|
DOMHighResTimeStamp
|
||||||
PerformanceNavigationTiming::DomInteractive() const
|
PerformanceNavigationTiming::DomInteractive() const
|
||||||
{
|
{
|
||||||
return TimerClamping::ReduceMsTimeValue(mTiming->GetDOMTiming()->GetDomInteractiveHighRes());
|
return mPerformance->GetDOMTiming()->GetDomInteractiveHighRes();
|
||||||
}
|
}
|
||||||
|
|
||||||
DOMHighResTimeStamp
|
DOMHighResTimeStamp
|
||||||
PerformanceNavigationTiming::DomContentLoadedEventStart() const
|
PerformanceNavigationTiming::DomContentLoadedEventStart() const
|
||||||
{
|
{
|
||||||
return TimerClamping::ReduceMsTimeValue(mTiming->GetDOMTiming()->GetDomContentLoadedEventStartHighRes());
|
return mPerformance->GetDOMTiming()->GetDomContentLoadedEventStartHighRes();
|
||||||
}
|
}
|
||||||
|
|
||||||
DOMHighResTimeStamp
|
DOMHighResTimeStamp
|
||||||
PerformanceNavigationTiming::DomContentLoadedEventEnd() const
|
PerformanceNavigationTiming::DomContentLoadedEventEnd() const
|
||||||
{
|
{
|
||||||
return TimerClamping::ReduceMsTimeValue(mTiming->GetDOMTiming()->GetDomContentLoadedEventEndHighRes());
|
return mPerformance->GetDOMTiming()->GetDomContentLoadedEventEndHighRes();
|
||||||
}
|
}
|
||||||
|
|
||||||
DOMHighResTimeStamp
|
DOMHighResTimeStamp
|
||||||
PerformanceNavigationTiming::DomComplete() const
|
PerformanceNavigationTiming::DomComplete() const
|
||||||
{
|
{
|
||||||
return TimerClamping::ReduceMsTimeValue(mTiming->GetDOMTiming()->GetDomCompleteHighRes());
|
return mPerformance->GetDOMTiming()->GetDomCompleteHighRes();
|
||||||
}
|
}
|
||||||
|
|
||||||
DOMHighResTimeStamp
|
DOMHighResTimeStamp
|
||||||
PerformanceNavigationTiming::LoadEventStart() const
|
PerformanceNavigationTiming::LoadEventStart() const
|
||||||
{
|
{
|
||||||
return TimerClamping::ReduceMsTimeValue(mTiming->GetDOMTiming()->GetLoadEventStartHighRes());
|
return mPerformance->GetDOMTiming()->GetLoadEventStartHighRes();
|
||||||
}
|
}
|
||||||
|
|
||||||
DOMHighResTimeStamp
|
DOMHighResTimeStamp
|
||||||
PerformanceNavigationTiming::LoadEventEnd() const
|
PerformanceNavigationTiming::LoadEventEnd() const
|
||||||
{
|
{
|
||||||
return TimerClamping::ReduceMsTimeValue(mTiming->GetDOMTiming()->GetLoadEventEndHighRes());
|
return mPerformance->GetDOMTiming()->GetLoadEventEndHighRes();
|
||||||
}
|
}
|
||||||
|
|
||||||
NavigationType
|
NavigationType
|
||||||
PerformanceNavigationTiming::Type() const
|
PerformanceNavigationTiming::Type() const
|
||||||
{
|
{
|
||||||
switch(mTiming->GetDOMTiming()->GetType()) {
|
switch(mPerformance->GetDOMTiming()->GetType()) {
|
||||||
case nsDOMNavigationTiming::TYPE_NAVIGATE:
|
case nsDOMNavigationTiming::TYPE_NAVIGATE:
|
||||||
return NavigationType::Navigate;
|
return NavigationType::Navigate;
|
||||||
break;
|
break;
|
||||||
|
|
@ -92,5 +92,5 @@ PerformanceNavigationTiming::Type() const
|
||||||
uint16_t
|
uint16_t
|
||||||
PerformanceNavigationTiming::RedirectCount() const
|
PerformanceNavigationTiming::RedirectCount() const
|
||||||
{
|
{
|
||||||
return mTiming->GetRedirectCount();
|
return mTimingData->GetRedirectCount();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,14 +27,14 @@ public:
|
||||||
// so that timestamps are relative to startTime, as opposed to the
|
// so that timestamps are relative to startTime, as opposed to the
|
||||||
// performance.timing object for which timestamps are absolute and has a
|
// performance.timing object for which timestamps are absolute and has a
|
||||||
// zeroTime initialized to navigationStart
|
// zeroTime initialized to navigationStart
|
||||||
explicit PerformanceNavigationTiming(PerformanceTiming* aPerformanceTiming,
|
PerformanceNavigationTiming(UniquePtr<PerformanceTimingData>&& aPerformanceTiming,
|
||||||
Performance* aPerformance,
|
Performance* aPerformance,
|
||||||
nsIHttpChannel* aChannel)
|
const nsAString& aName)
|
||||||
: PerformanceResourceTiming(aPerformanceTiming, aPerformance,
|
: PerformanceResourceTiming(Move(aPerformanceTiming), aPerformance, aName)
|
||||||
NS_LITERAL_STRING("document"), aChannel) {
|
{
|
||||||
SetEntryType(NS_LITERAL_STRING("navigation"));
|
SetEntryType(NS_LITERAL_STRING("navigation"));
|
||||||
SetInitiatorType(NS_LITERAL_STRING("navigation"));
|
SetInitiatorType(NS_LITERAL_STRING("navigation"));
|
||||||
}
|
}
|
||||||
|
|
||||||
DOMHighResTimeStamp Duration() const override
|
DOMHighResTimeStamp Duration() const override
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ using namespace mozilla::dom;
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_INHERITED(PerformanceResourceTiming,
|
NS_IMPL_CYCLE_COLLECTION_INHERITED(PerformanceResourceTiming,
|
||||||
PerformanceEntry,
|
PerformanceEntry,
|
||||||
mTiming)
|
mPerformance)
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(PerformanceResourceTiming,
|
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(PerformanceResourceTiming,
|
||||||
PerformanceEntry)
|
PerformanceEntry)
|
||||||
|
|
@ -23,45 +23,14 @@ NS_INTERFACE_MAP_END_INHERITING(PerformanceEntry)
|
||||||
NS_IMPL_ADDREF_INHERITED(PerformanceResourceTiming, PerformanceEntry)
|
NS_IMPL_ADDREF_INHERITED(PerformanceResourceTiming, PerformanceEntry)
|
||||||
NS_IMPL_RELEASE_INHERITED(PerformanceResourceTiming, PerformanceEntry)
|
NS_IMPL_RELEASE_INHERITED(PerformanceResourceTiming, PerformanceEntry)
|
||||||
|
|
||||||
PerformanceResourceTiming::PerformanceResourceTiming(PerformanceTiming* aPerformanceTiming,
|
PerformanceResourceTiming::PerformanceResourceTiming(UniquePtr<PerformanceTimingData>&& aPerformanceTiming,
|
||||||
Performance* aPerformance,
|
Performance* aPerformance,
|
||||||
const nsAString& aName,
|
const nsAString& aName)
|
||||||
nsIHttpChannel* aChannel)
|
: PerformanceEntry(aPerformance->GetParentObject(), aName, NS_LITERAL_STRING("resource"))
|
||||||
: PerformanceEntry(aPerformance, aName, NS_LITERAL_STRING("resource")),
|
, mTimingData(Move(aPerformanceTiming))
|
||||||
mTiming(aPerformanceTiming),
|
, mPerformance(aPerformance)
|
||||||
mEncodedBodySize(0),
|
|
||||||
mTransferSize(0),
|
|
||||||
mDecodedBodySize(0)
|
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(aPerformance, "Parent performance object should be provided");
|
MOZ_ASSERT(aPerformance, "Parent performance object should be provided");
|
||||||
SetPropertiesFromChannel(aChannel);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
PerformanceResourceTiming::SetPropertiesFromChannel(nsIHttpChannel* aChannel)
|
|
||||||
{
|
|
||||||
if (!aChannel) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsAutoCString protocol;
|
|
||||||
Unused << aChannel->GetProtocolVersion(protocol);
|
|
||||||
SetNextHopProtocol(NS_ConvertUTF8toUTF16(protocol));
|
|
||||||
|
|
||||||
uint64_t encodedBodySize = 0;
|
|
||||||
Unused << aChannel->GetEncodedBodySize(&encodedBodySize);
|
|
||||||
SetEncodedBodySize(encodedBodySize);
|
|
||||||
|
|
||||||
uint64_t transferSize = 0;
|
|
||||||
Unused << aChannel->GetTransferSize(&transferSize);
|
|
||||||
SetTransferSize(transferSize);
|
|
||||||
|
|
||||||
uint64_t decodedBodySize = 0;
|
|
||||||
Unused << aChannel->GetDecodedBodySize(&decodedBodySize);
|
|
||||||
if (decodedBodySize == 0) {
|
|
||||||
decodedBodySize = encodedBodySize;
|
|
||||||
}
|
|
||||||
SetDecodedBodySize(decodedBodySize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PerformanceResourceTiming::~PerformanceResourceTiming()
|
PerformanceResourceTiming::~PerformanceResourceTiming()
|
||||||
|
|
@ -78,13 +47,13 @@ PerformanceResourceTiming::StartTime() const
|
||||||
// Ignore zero values. The RedirectStart and WorkerStart values
|
// Ignore zero values. The RedirectStart and WorkerStart values
|
||||||
// can come from earlier redirected channels prior to the AsyncOpen
|
// can come from earlier redirected channels prior to the AsyncOpen
|
||||||
// time being recorded.
|
// time being recorded.
|
||||||
DOMHighResTimeStamp redirect = mTiming->RedirectStartHighRes();
|
DOMHighResTimeStamp redirect = mTimingData->RedirectStartHighRes(mPerformance);
|
||||||
redirect = redirect ? redirect : DBL_MAX;
|
redirect = redirect ? redirect : DBL_MAX;
|
||||||
|
|
||||||
DOMHighResTimeStamp worker = mTiming->WorkerStartHighRes();
|
DOMHighResTimeStamp worker = mTimingData->WorkerStartHighRes(mPerformance);
|
||||||
worker = worker ? worker : DBL_MAX;
|
worker = worker ? worker : DBL_MAX;
|
||||||
|
|
||||||
DOMHighResTimeStamp asyncOpen = mTiming->AsyncOpenHighRes();
|
DOMHighResTimeStamp asyncOpen = mTimingData->AsyncOpenHighRes(mPerformance);
|
||||||
|
|
||||||
return std::min(asyncOpen, std::min(redirect, worker));
|
return std::min(asyncOpen, std::min(redirect, worker));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,8 @@
|
||||||
#ifndef mozilla_dom_PerformanceResourceTiming_h___
|
#ifndef mozilla_dom_PerformanceResourceTiming_h___
|
||||||
#define mozilla_dom_PerformanceResourceTiming_h___
|
#define mozilla_dom_PerformanceResourceTiming_h___
|
||||||
|
|
||||||
|
#include "mozilla/UniquePtr.h"
|
||||||
#include "nsCOMPtr.h"
|
#include "nsCOMPtr.h"
|
||||||
#include "nsIChannel.h"
|
|
||||||
#include "nsITimedChannel.h"
|
|
||||||
#include "Performance.h"
|
#include "Performance.h"
|
||||||
#include "PerformanceEntry.h"
|
#include "PerformanceEntry.h"
|
||||||
#include "PerformanceTiming.h"
|
#include "PerformanceTiming.h"
|
||||||
|
|
@ -27,10 +26,9 @@ public:
|
||||||
PerformanceResourceTiming,
|
PerformanceResourceTiming,
|
||||||
PerformanceEntry)
|
PerformanceEntry)
|
||||||
|
|
||||||
PerformanceResourceTiming(PerformanceTiming* aPerformanceTiming,
|
PerformanceResourceTiming(UniquePtr<PerformanceTimingData>&& aPerformanceTimingData,
|
||||||
Performance* aPerformance,
|
Performance* aPerformance,
|
||||||
const nsAString& aName,
|
const nsAString& aName);
|
||||||
nsIHttpChannel* aChannel = nullptr);
|
|
||||||
|
|
||||||
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||||
|
|
||||||
|
|
@ -54,93 +52,85 @@ public:
|
||||||
|
|
||||||
void GetNextHopProtocol(nsAString& aNextHopProtocol) const
|
void GetNextHopProtocol(nsAString& aNextHopProtocol) const
|
||||||
{
|
{
|
||||||
if (mTiming && mTiming->TimingAllowed()) {
|
if (mTimingData) {
|
||||||
aNextHopProtocol = mNextHopProtocol;
|
aNextHopProtocol = mTimingData->NextHopProtocol();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetNextHopProtocol(const nsAString& aNextHopProtocol)
|
|
||||||
{
|
|
||||||
mNextHopProtocol = aNextHopProtocol;
|
|
||||||
}
|
|
||||||
|
|
||||||
DOMHighResTimeStamp WorkerStart() const {
|
DOMHighResTimeStamp WorkerStart() const {
|
||||||
return mTiming && mTiming->TimingAllowed()
|
return mTimingData
|
||||||
? mTiming->WorkerStartHighRes()
|
? mTimingData->WorkerStartHighRes(mPerformance)
|
||||||
: 0;
|
: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
DOMHighResTimeStamp FetchStart() const {
|
DOMHighResTimeStamp FetchStart() const {
|
||||||
if (mTiming) {
|
return mTimingData
|
||||||
return mTiming->TimingAllowed()
|
? mTimingData->FetchStartHighRes(mPerformance)
|
||||||
? mTiming->FetchStartHighRes()
|
: 0;
|
||||||
: StartTime();
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DOMHighResTimeStamp RedirectStart() const {
|
DOMHighResTimeStamp RedirectStart() const {
|
||||||
// We have to check if all the redirect URIs had the same origin (since
|
// We have to check if all the redirect URIs had the same origin (since
|
||||||
// there is no check in RedirectEndHighRes())
|
// there is no check in RedirectEndHighRes())
|
||||||
return mTiming && mTiming->ShouldReportCrossOriginRedirect()
|
return mTimingData && mTimingData->ShouldReportCrossOriginRedirect()
|
||||||
? mTiming->RedirectStartHighRes()
|
? mTimingData->RedirectStartHighRes(mPerformance)
|
||||||
: 0;
|
: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
DOMHighResTimeStamp RedirectEnd() const {
|
DOMHighResTimeStamp RedirectEnd() const {
|
||||||
// We have to check if all the redirect URIs had the same origin (since
|
// We have to check if all the redirect URIs had the same origin (since
|
||||||
// there is no check in RedirectEndHighRes())
|
// there is no check in RedirectEndHighRes())
|
||||||
return mTiming && mTiming->ShouldReportCrossOriginRedirect()
|
return mTimingData && mTimingData->ShouldReportCrossOriginRedirect()
|
||||||
? mTiming->RedirectEndHighRes()
|
? mTimingData->RedirectEndHighRes(mPerformance)
|
||||||
: 0;
|
: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
DOMHighResTimeStamp DomainLookupStart() const {
|
DOMHighResTimeStamp DomainLookupStart() const {
|
||||||
return mTiming && mTiming->TimingAllowed()
|
return mTimingData && mTimingData->TimingAllowed()
|
||||||
? mTiming->DomainLookupStartHighRes()
|
? mTimingData->DomainLookupStartHighRes(mPerformance)
|
||||||
: 0;
|
: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
DOMHighResTimeStamp DomainLookupEnd() const {
|
DOMHighResTimeStamp DomainLookupEnd() const {
|
||||||
return mTiming && mTiming->TimingAllowed()
|
return mTimingData && mTimingData->TimingAllowed()
|
||||||
? mTiming->DomainLookupEndHighRes()
|
? mTimingData->DomainLookupEndHighRes(mPerformance)
|
||||||
: 0;
|
: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
DOMHighResTimeStamp ConnectStart() const {
|
DOMHighResTimeStamp ConnectStart() const {
|
||||||
return mTiming && mTiming->TimingAllowed()
|
return mTimingData && mTimingData->TimingAllowed()
|
||||||
? mTiming->ConnectStartHighRes()
|
? mTimingData->ConnectStartHighRes(mPerformance)
|
||||||
: 0;
|
: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
DOMHighResTimeStamp ConnectEnd() const {
|
DOMHighResTimeStamp ConnectEnd() const {
|
||||||
return mTiming && mTiming->TimingAllowed()
|
return mTimingData && mTimingData->TimingAllowed()
|
||||||
? mTiming->ConnectEndHighRes()
|
? mTimingData->ConnectEndHighRes(mPerformance)
|
||||||
: 0;
|
: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
DOMHighResTimeStamp RequestStart() const {
|
DOMHighResTimeStamp RequestStart() const {
|
||||||
return mTiming && mTiming->TimingAllowed()
|
return mTimingData && mTimingData->TimingAllowed()
|
||||||
? mTiming->RequestStartHighRes()
|
? mTimingData->RequestStartHighRes(mPerformance)
|
||||||
: 0;
|
: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
DOMHighResTimeStamp ResponseStart() const {
|
DOMHighResTimeStamp ResponseStart() const {
|
||||||
return mTiming && mTiming->TimingAllowed()
|
return mTimingData && mTimingData->TimingAllowed()
|
||||||
? mTiming->ResponseStartHighRes()
|
? mTimingData->ResponseStartHighRes(mPerformance)
|
||||||
: 0;
|
: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
DOMHighResTimeStamp ResponseEnd() const {
|
DOMHighResTimeStamp ResponseEnd() const {
|
||||||
return mTiming
|
return mTimingData
|
||||||
? mTiming->ResponseEndHighRes()
|
? mTimingData->ResponseEndHighRes(mPerformance)
|
||||||
: 0;
|
: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
DOMHighResTimeStamp SecureConnectionStart() const
|
DOMHighResTimeStamp SecureConnectionStart() const
|
||||||
{
|
{
|
||||||
return mTiming && mTiming->TimingAllowed()
|
return mTimingData && mTimingData->TimingAllowed()
|
||||||
? mTiming->SecureConnectionStartHighRes()
|
? mTimingData->SecureConnectionStartHighRes(mPerformance)
|
||||||
: 0;
|
: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -151,44 +141,25 @@ public:
|
||||||
|
|
||||||
uint64_t TransferSize() const
|
uint64_t TransferSize() const
|
||||||
{
|
{
|
||||||
return mTiming && mTiming->TimingAllowed() ? mTransferSize : 0;
|
return mTimingData ? mTimingData->TransferSize() : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t EncodedBodySize() const
|
uint64_t EncodedBodySize() const
|
||||||
{
|
{
|
||||||
return mTiming && mTiming->TimingAllowed() ? mEncodedBodySize : 0;
|
return mTimingData ? mTimingData->EncodedBodySize() : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t DecodedBodySize() const
|
uint64_t DecodedBodySize() const
|
||||||
{
|
{
|
||||||
return mTiming && mTiming->TimingAllowed() ? mDecodedBodySize : 0;
|
return mTimingData ? mTimingData->DecodedBodySize() : 0;
|
||||||
}
|
|
||||||
|
|
||||||
void SetEncodedBodySize(uint64_t aEncodedBodySize)
|
|
||||||
{
|
|
||||||
mEncodedBodySize = aEncodedBodySize;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetTransferSize(uint64_t aTransferSize)
|
|
||||||
{
|
|
||||||
mTransferSize = aTransferSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetDecodedBodySize(uint64_t aDecodedBodySize)
|
|
||||||
{
|
|
||||||
mDecodedBodySize = aDecodedBodySize;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual ~PerformanceResourceTiming();
|
virtual ~PerformanceResourceTiming();
|
||||||
void SetPropertiesFromChannel(nsIHttpChannel* aChannel);
|
|
||||||
|
|
||||||
nsString mInitiatorType;
|
nsString mInitiatorType;
|
||||||
nsString mNextHopProtocol;
|
UniquePtr<PerformanceTimingData> mTimingData;
|
||||||
RefPtr<PerformanceTiming> mTiming;
|
RefPtr<Performance> mPerformance;
|
||||||
uint64_t mEncodedBodySize;
|
|
||||||
uint64_t mTransferSize;
|
|
||||||
uint64_t mDecodedBodySize;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
|
|
|
||||||
|
|
@ -19,34 +19,39 @@ PerformanceTiming::PerformanceTiming(Performance* aPerformance,
|
||||||
nsITimedChannel* aChannel,
|
nsITimedChannel* aChannel,
|
||||||
nsIHttpChannel* aHttpChannel,
|
nsIHttpChannel* aHttpChannel,
|
||||||
DOMHighResTimeStamp aZeroTime)
|
DOMHighResTimeStamp aZeroTime)
|
||||||
: mPerformance(aPerformance),
|
: mPerformance(aPerformance)
|
||||||
mFetchStart(0.0),
|
|
||||||
mZeroTime(TimerClamping::ReduceMsTimeValue(aZeroTime)),
|
|
||||||
mRedirectCount(0),
|
|
||||||
mTimingAllowed(true),
|
|
||||||
mAllRedirectsSameOrigin(true),
|
|
||||||
mInitialized(!!aChannel),
|
|
||||||
mReportCrossOriginRedirect(true)
|
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(aPerformance, "Parent performance object should be provided");
|
MOZ_ASSERT(aPerformance, "Parent performance object should be provided");
|
||||||
|
|
||||||
|
mTimingData.reset(new PerformanceTimingData(aChannel, aHttpChannel,
|
||||||
|
aZeroTime));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy the timing info from the channel so we don't need to keep the channel
|
||||||
|
// alive just to get the timestamps.
|
||||||
|
PerformanceTimingData::PerformanceTimingData(nsITimedChannel* aChannel,
|
||||||
|
nsIHttpChannel* aHttpChannel,
|
||||||
|
DOMHighResTimeStamp aZeroTime)
|
||||||
|
: mZeroTime(0.0)
|
||||||
|
, mFetchStart(0.0)
|
||||||
|
, mEncodedBodySize(0)
|
||||||
|
, mTransferSize(0)
|
||||||
|
, mDecodedBodySize(0)
|
||||||
|
, mRedirectCount(0)
|
||||||
|
, mAllRedirectsSameOrigin(true)
|
||||||
|
, mReportCrossOriginRedirect(true)
|
||||||
|
, mSecureConnection(false)
|
||||||
|
, mTimingAllowed(true)
|
||||||
|
, mInitialized(false)
|
||||||
|
{
|
||||||
|
mInitialized = !!aChannel;
|
||||||
|
|
||||||
|
mZeroTime = TimerClamping::ReduceMsTimeValue(aZeroTime);
|
||||||
|
|
||||||
if (!nsContentUtils::IsPerformanceTimingEnabled()) {
|
if (!nsContentUtils::IsPerformanceTimingEnabled()) {
|
||||||
mZeroTime = 0;
|
mZeroTime = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The aHttpChannel argument is null if this PerformanceTiming object is
|
|
||||||
// being used for navigation timing (which is only relevant for documents).
|
|
||||||
// It has a non-null value if this PerformanceTiming object is being used
|
|
||||||
// for resource timing, which can include document loads, both toplevel and
|
|
||||||
// in subframes, and resources linked from a document.
|
|
||||||
if (aHttpChannel) {
|
|
||||||
mTimingAllowed = CheckAllowedOrigin(aHttpChannel, aChannel);
|
|
||||||
bool redirectsPassCheck = false;
|
|
||||||
aChannel->GetAllRedirectsPassTimingAllowCheck(&redirectsPassCheck);
|
|
||||||
mReportCrossOriginRedirect = mTimingAllowed && redirectsPassCheck;
|
|
||||||
}
|
|
||||||
|
|
||||||
mSecureConnection = false;
|
|
||||||
nsCOMPtr<nsIURI> uri;
|
nsCOMPtr<nsIURI> uri;
|
||||||
if (aHttpChannel) {
|
if (aHttpChannel) {
|
||||||
aHttpChannel->GetURI(getter_AddRefs(uri));
|
aHttpChannel->GetURI(getter_AddRefs(uri));
|
||||||
|
|
@ -63,14 +68,7 @@ PerformanceTiming::PerformanceTiming(Performance* aPerformance,
|
||||||
mSecureConnection = false;
|
mSecureConnection = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
InitializeTimingInfo(aChannel);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy the timing info from the channel so we don't need to keep the channel
|
|
||||||
// alive just to get the timestamps.
|
|
||||||
void
|
|
||||||
PerformanceTiming::InitializeTimingInfo(nsITimedChannel* aChannel)
|
|
||||||
{
|
|
||||||
if (aChannel) {
|
if (aChannel) {
|
||||||
aChannel->GetAsyncOpen(&mAsyncOpen);
|
aChannel->GetAsyncOpen(&mAsyncOpen);
|
||||||
aChannel->GetDispatchFetchEventStart(&mWorkerStart);
|
aChannel->GetDispatchFetchEventStart(&mWorkerStart);
|
||||||
|
|
@ -90,11 +88,11 @@ PerformanceTiming::InitializeTimingInfo(nsITimedChannel* aChannel)
|
||||||
aChannel->GetCacheReadEnd(&mCacheReadEnd);
|
aChannel->GetCacheReadEnd(&mCacheReadEnd);
|
||||||
|
|
||||||
// The performance timing api essentially requires that the event timestamps
|
// The performance timing api essentially requires that the event timestamps
|
||||||
// have a strict relation with each other. The truth, however, is the browser
|
// have a strict relation with each other. The truth, however, is the
|
||||||
// engages in a number of speculative activities that sometimes mean connections
|
// browser engages in a number of speculative activities that sometimes mean
|
||||||
// and lookups begin at different times. Workaround that here by clamping
|
// connections and lookups begin at different times. Workaround that here by
|
||||||
// these values to what we expect FetchStart to be. This means the later of
|
// clamping these values to what we expect FetchStart to be. This means the
|
||||||
// AsyncOpen or WorkerStart times.
|
// later of AsyncOpen or WorkerStart times.
|
||||||
if (!mAsyncOpen.IsNull()) {
|
if (!mAsyncOpen.IsNull()) {
|
||||||
// We want to clamp to the expected FetchStart value. This is later of
|
// We want to clamp to the expected FetchStart value. This is later of
|
||||||
// the AsyncOpen and WorkerStart values.
|
// the AsyncOpen and WorkerStart values.
|
||||||
|
|
@ -125,6 +123,43 @@ PerformanceTiming::InitializeTimingInfo(nsITimedChannel* aChannel)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The aHttpChannel argument is null if this PerformanceTiming object is
|
||||||
|
// being used for navigation timing (which is only relevant for documents).
|
||||||
|
// It has a non-null value if this PerformanceTiming object is being used
|
||||||
|
// for resource timing, which can include document loads, both toplevel and
|
||||||
|
// in subframes, and resources linked from a document.
|
||||||
|
if (aHttpChannel) {
|
||||||
|
mTimingAllowed = CheckAllowedOrigin(aHttpChannel, aChannel);
|
||||||
|
bool redirectsPassCheck = false;
|
||||||
|
aChannel->GetAllRedirectsPassTimingAllowCheck(&redirectsPassCheck);
|
||||||
|
mReportCrossOriginRedirect = mTimingAllowed && redirectsPassCheck;
|
||||||
|
|
||||||
|
SetPropertiesFromHttpChannel(aHttpChannel, aChannel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PerformanceTimingData::SetPropertiesFromHttpChannel(nsIHttpChannel* aHttpChannel,
|
||||||
|
nsITimedChannel* aChannel)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(aHttpChannel);
|
||||||
|
|
||||||
|
nsAutoCString protocol;
|
||||||
|
Unused << aHttpChannel->GetProtocolVersion(protocol);
|
||||||
|
mNextHopProtocol = NS_ConvertUTF8toUTF16(protocol);
|
||||||
|
|
||||||
|
Unused << aHttpChannel->GetEncodedBodySize(&mEncodedBodySize);
|
||||||
|
Unused << aHttpChannel->GetTransferSize(&mTransferSize);
|
||||||
|
Unused << aHttpChannel->GetDecodedBodySize(&mDecodedBodySize);
|
||||||
|
if (mDecodedBodySize == 0) {
|
||||||
|
mDecodedBodySize = mEncodedBodySize;
|
||||||
|
}
|
||||||
|
|
||||||
|
mTimingAllowed = CheckAllowedOrigin(aHttpChannel, aChannel);
|
||||||
|
bool redirectsPassCheck = false;
|
||||||
|
aChannel->GetAllRedirectsPassTimingAllowCheck(&redirectsPassCheck);
|
||||||
|
mReportCrossOriginRedirect = mTimingAllowed && redirectsPassCheck;
|
||||||
}
|
}
|
||||||
|
|
||||||
PerformanceTiming::~PerformanceTiming()
|
PerformanceTiming::~PerformanceTiming()
|
||||||
|
|
@ -132,8 +167,10 @@ PerformanceTiming::~PerformanceTiming()
|
||||||
}
|
}
|
||||||
|
|
||||||
DOMHighResTimeStamp
|
DOMHighResTimeStamp
|
||||||
PerformanceTiming::FetchStartHighRes()
|
PerformanceTimingData::FetchStartHighRes(Performance* aPerformance)
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(aPerformance);
|
||||||
|
|
||||||
if (!mFetchStart) {
|
if (!mFetchStart) {
|
||||||
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized()) {
|
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized()) {
|
||||||
return mZeroTime;
|
return mZeroTime;
|
||||||
|
|
@ -142,9 +179,9 @@ PerformanceTiming::FetchStartHighRes()
|
||||||
"valid if the performance timing is enabled");
|
"valid if the performance timing is enabled");
|
||||||
if (!mAsyncOpen.IsNull()) {
|
if (!mAsyncOpen.IsNull()) {
|
||||||
if (!mWorkerStart.IsNull() && mWorkerStart > mAsyncOpen) {
|
if (!mWorkerStart.IsNull() && mWorkerStart > mAsyncOpen) {
|
||||||
mFetchStart = TimeStampToDOMHighRes(mWorkerStart);
|
mFetchStart = TimeStampToDOMHighRes(aPerformance, mWorkerRequestStart);
|
||||||
} else {
|
} else {
|
||||||
mFetchStart = TimeStampToDOMHighRes(mAsyncOpen);
|
mFetchStart = TimeStampToDOMHighRes(aPerformance, mAsyncOpen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -154,12 +191,12 @@ PerformanceTiming::FetchStartHighRes()
|
||||||
DOMTimeMilliSec
|
DOMTimeMilliSec
|
||||||
PerformanceTiming::FetchStart()
|
PerformanceTiming::FetchStart()
|
||||||
{
|
{
|
||||||
return static_cast<int64_t>(FetchStartHighRes());
|
return static_cast<int64_t>(mTimingData->FetchStartHighRes(mPerformance));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
PerformanceTiming::CheckAllowedOrigin(nsIHttpChannel* aResourceChannel,
|
PerformanceTimingData::CheckAllowedOrigin(nsIHttpChannel* aResourceChannel,
|
||||||
nsITimedChannel* aChannel)
|
nsITimedChannel* aChannel)
|
||||||
{
|
{
|
||||||
if (!IsInitialized()) {
|
if (!IsInitialized()) {
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -187,14 +224,8 @@ PerformanceTiming::CheckAllowedOrigin(nsIHttpChannel* aResourceChannel,
|
||||||
return aChannel->TimingAllowCheck(principal);
|
return aChannel->TimingAllowCheck(principal);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
|
||||||
PerformanceTiming::TimingAllowed() const
|
|
||||||
{
|
|
||||||
return mTimingAllowed;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t
|
uint8_t
|
||||||
PerformanceTiming::GetRedirectCount() const
|
PerformanceTimingData::GetRedirectCount() const
|
||||||
{
|
{
|
||||||
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized()) {
|
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized()) {
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -206,7 +237,7 @@ PerformanceTiming::GetRedirectCount() const
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
PerformanceTiming::ShouldReportCrossOriginRedirect() const
|
PerformanceTimingData::ShouldReportCrossOriginRedirect() const
|
||||||
{
|
{
|
||||||
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized()) {
|
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized()) {
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -219,23 +250,27 @@ PerformanceTiming::ShouldReportCrossOriginRedirect() const
|
||||||
}
|
}
|
||||||
|
|
||||||
DOMHighResTimeStamp
|
DOMHighResTimeStamp
|
||||||
PerformanceTiming::AsyncOpenHighRes()
|
PerformanceTimingData::AsyncOpenHighRes(Performance* aPerformance)
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(aPerformance);
|
||||||
|
|
||||||
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized() ||
|
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized() ||
|
||||||
mAsyncOpen.IsNull()) {
|
mAsyncOpen.IsNull()) {
|
||||||
return mZeroTime;
|
return mZeroTime;
|
||||||
}
|
}
|
||||||
return TimeStampToReducedDOMHighResOrFetchStart(mAsyncOpen);
|
return TimerClamping::ReduceMsTimeValue(TimeStampToDOMHighRes(aPerformance, mAsyncOpen));
|
||||||
}
|
}
|
||||||
|
|
||||||
DOMHighResTimeStamp
|
DOMHighResTimeStamp
|
||||||
PerformanceTiming::WorkerStartHighRes()
|
PerformanceTimingData::WorkerStartHighRes(Performance* aPerformance)
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(aPerformance);
|
||||||
|
|
||||||
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized() ||
|
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized() ||
|
||||||
mWorkerStart.IsNull()) {
|
mWorkerStart.IsNull()) {
|
||||||
return mZeroTime;
|
return mZeroTime;
|
||||||
}
|
}
|
||||||
return TimeStampToReducedDOMHighResOrFetchStart(mWorkerStart);
|
return TimerClamping::ReduceMsTimeValue(TimeStampToDOMHighRes(aPerformance, mWorkerStart));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -249,24 +284,27 @@ PerformanceTiming::WorkerStartHighRes()
|
||||||
* @return a valid timing if the Performance Timing is enabled
|
* @return a valid timing if the Performance Timing is enabled
|
||||||
*/
|
*/
|
||||||
DOMHighResTimeStamp
|
DOMHighResTimeStamp
|
||||||
PerformanceTiming::RedirectStartHighRes()
|
PerformanceTimingData::RedirectStartHighRes(Performance* aPerformance)
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(aPerformance);
|
||||||
|
|
||||||
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized()) {
|
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized()) {
|
||||||
return mZeroTime;
|
return mZeroTime;
|
||||||
}
|
}
|
||||||
return TimeStampToReducedDOMHighResOrFetchStart(mRedirectStart);
|
return TimeStampToReducedDOMHighResOrFetchStart(aPerformance, mRedirectStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
DOMTimeMilliSec
|
DOMTimeMilliSec
|
||||||
PerformanceTiming::RedirectStart()
|
PerformanceTiming::RedirectStart()
|
||||||
{
|
{
|
||||||
if (!IsInitialized()) {
|
if (!mTimingData->IsInitialized()) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
// We have to check if all the redirect URIs had the same origin (since there
|
// We have to check if all the redirect URIs had the same origin (since there
|
||||||
// is no check in RedirectStartHighRes())
|
// is no check in RedirectStartHighRes())
|
||||||
if (mAllRedirectsSameOrigin && mRedirectCount) {
|
if (mTimingData->AllRedirectsSameOrigin() &&
|
||||||
return static_cast<int64_t>(RedirectStartHighRes());
|
mTimingData->RedirectCountReal()) {
|
||||||
|
return static_cast<int64_t>(mTimingData->RedirectStartHighRes(mPerformance));
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -282,130 +320,155 @@ PerformanceTiming::RedirectStart()
|
||||||
* @return a valid timing if the Performance Timing is enabled
|
* @return a valid timing if the Performance Timing is enabled
|
||||||
*/
|
*/
|
||||||
DOMHighResTimeStamp
|
DOMHighResTimeStamp
|
||||||
PerformanceTiming::RedirectEndHighRes()
|
PerformanceTimingData::RedirectEndHighRes(Performance* aPerformance)
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(aPerformance);
|
||||||
|
|
||||||
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized()) {
|
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized()) {
|
||||||
return mZeroTime;
|
return mZeroTime;
|
||||||
}
|
}
|
||||||
return TimeStampToReducedDOMHighResOrFetchStart(mRedirectEnd);
|
return TimeStampToReducedDOMHighResOrFetchStart(aPerformance, mRedirectEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
DOMTimeMilliSec
|
DOMTimeMilliSec
|
||||||
PerformanceTiming::RedirectEnd()
|
PerformanceTiming::RedirectEnd()
|
||||||
{
|
{
|
||||||
if (!IsInitialized()) {
|
if (!mTimingData->IsInitialized()) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
// We have to check if all the redirect URIs had the same origin (since there
|
// We have to check if all the redirect URIs had the same origin (since there
|
||||||
// is no check in RedirectEndHighRes())
|
// is no check in RedirectEndHighRes())
|
||||||
if (mAllRedirectsSameOrigin && mRedirectCount) {
|
if (mTimingData->AllRedirectsSameOrigin() &&
|
||||||
return static_cast<int64_t>(RedirectEndHighRes());
|
mTimingData->RedirectCountReal()) {
|
||||||
|
return static_cast<int64_t>(mTimingData->RedirectEndHighRes(mPerformance));
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
DOMHighResTimeStamp
|
DOMHighResTimeStamp
|
||||||
PerformanceTiming::DomainLookupStartHighRes()
|
PerformanceTimingData::DomainLookupStartHighRes(Performance* aPerformance)
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(aPerformance);
|
||||||
|
|
||||||
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized()) {
|
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized()) {
|
||||||
return mZeroTime;
|
return mZeroTime;
|
||||||
}
|
}
|
||||||
return TimeStampToReducedDOMHighResOrFetchStart(mDomainLookupStart);
|
return TimeStampToReducedDOMHighResOrFetchStart(aPerformance,
|
||||||
|
mDomainLookupStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
DOMTimeMilliSec
|
DOMTimeMilliSec
|
||||||
PerformanceTiming::DomainLookupStart()
|
PerformanceTiming::DomainLookupStart()
|
||||||
{
|
{
|
||||||
return static_cast<int64_t>(DomainLookupStartHighRes());
|
return static_cast<int64_t>(mTimingData->DomainLookupStartHighRes(mPerformance));
|
||||||
}
|
}
|
||||||
|
|
||||||
DOMHighResTimeStamp
|
DOMHighResTimeStamp
|
||||||
PerformanceTiming::DomainLookupEndHighRes()
|
PerformanceTimingData::DomainLookupEndHighRes(Performance* aPerformance)
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(aPerformance);
|
||||||
|
|
||||||
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized()) {
|
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized()) {
|
||||||
return mZeroTime;
|
return mZeroTime;
|
||||||
}
|
}
|
||||||
// Bug 1155008 - nsHttpTransaction is racy. Return DomainLookupStart when null
|
return mDomainLookupEnd.IsNull()
|
||||||
return mDomainLookupEnd.IsNull() ? DomainLookupStartHighRes()
|
? DomainLookupStartHighRes(aPerformance)
|
||||||
: TimerClamping::ReduceMsTimeValue(TimeStampToDOMHighRes(mDomainLookupEnd));
|
: TimerClamping::ReduceMsTimeValue(
|
||||||
|
TimeStampToDOMHighRes(aPerformance, mDomainLookupEnd));
|
||||||
}
|
}
|
||||||
|
|
||||||
DOMTimeMilliSec
|
DOMTimeMilliSec
|
||||||
PerformanceTiming::DomainLookupEnd()
|
PerformanceTiming::DomainLookupEnd()
|
||||||
{
|
{
|
||||||
return static_cast<int64_t>(DomainLookupEndHighRes());
|
return static_cast<int64_t>(mTimingData->DomainLookupEndHighRes(mPerformance));
|
||||||
}
|
}
|
||||||
|
|
||||||
DOMHighResTimeStamp
|
DOMHighResTimeStamp
|
||||||
PerformanceTiming::ConnectStartHighRes()
|
PerformanceTimingData::ConnectStartHighRes(Performance* aPerformance)
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(aPerformance);
|
||||||
|
|
||||||
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized()) {
|
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized()) {
|
||||||
return mZeroTime;
|
return mZeroTime;
|
||||||
}
|
}
|
||||||
return mConnectStart.IsNull() ? DomainLookupEndHighRes()
|
return mConnectStart.IsNull()
|
||||||
: TimerClamping::ReduceMsTimeValue(TimeStampToDOMHighRes(mConnectStart));
|
? DomainLookupEndHighRes(aPerformance)
|
||||||
|
: TimerClamping::ReduceMsTimeValue(
|
||||||
|
TimeStampToDOMHighRes(aPerformance, mConnectStart));
|
||||||
}
|
}
|
||||||
|
|
||||||
DOMTimeMilliSec
|
DOMTimeMilliSec
|
||||||
PerformanceTiming::ConnectStart()
|
PerformanceTiming::ConnectStart()
|
||||||
{
|
{
|
||||||
return static_cast<int64_t>(ConnectStartHighRes());
|
return static_cast<int64_t>(mTimingData->ConnectStartHighRes(mPerformance));
|
||||||
}
|
}
|
||||||
|
|
||||||
DOMHighResTimeStamp
|
DOMHighResTimeStamp
|
||||||
PerformanceTiming::SecureConnectionStartHighRes()
|
PerformanceTimingData::SecureConnectionStartHighRes(Performance* aPerformance)
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(aPerformance);
|
||||||
|
|
||||||
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized()) {
|
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized()) {
|
||||||
return mZeroTime;
|
return mZeroTime;
|
||||||
}
|
}
|
||||||
return !mSecureConnection
|
return !mSecureConnection
|
||||||
? 0 // We use 0 here, because mZeroTime is sometimes set to the navigation
|
? 0 // We use 0 here, because mZeroTime is sometimes set to the navigation
|
||||||
// start time.
|
// start time.
|
||||||
: (mSecureConnectionStart.IsNull() ? mZeroTime
|
: (mSecureConnectionStart.IsNull()
|
||||||
: TimerClamping::ReduceMsTimeValue(TimeStampToDOMHighRes(mSecureConnectionStart)));
|
? mZeroTime
|
||||||
|
: TimerClamping::ReduceMsTimeValue(
|
||||||
|
TimeStampToDOMHighRes(aPerformance, mSecureConnectionStart)));
|
||||||
}
|
}
|
||||||
|
|
||||||
DOMTimeMilliSec
|
DOMTimeMilliSec
|
||||||
PerformanceTiming::SecureConnectionStart()
|
PerformanceTiming::SecureConnectionStart()
|
||||||
{
|
{
|
||||||
return static_cast<int64_t>(SecureConnectionStartHighRes());
|
return static_cast<int64_t>(mTimingData->SecureConnectionStartHighRes(mPerformance));
|
||||||
}
|
}
|
||||||
|
|
||||||
DOMHighResTimeStamp
|
DOMHighResTimeStamp
|
||||||
PerformanceTiming::ConnectEndHighRes()
|
PerformanceTimingData::ConnectEndHighRes(Performance* aPerformance)
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(aPerformance);
|
||||||
|
|
||||||
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized()) {
|
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized()) {
|
||||||
return mZeroTime;
|
return mZeroTime;
|
||||||
}
|
}
|
||||||
// Bug 1155008 - nsHttpTransaction is racy. Return ConnectStart when null
|
// Bug 1155008 - nsHttpTransaction is racy. Return ConnectStart when null
|
||||||
return mConnectEnd.IsNull() ? ConnectStartHighRes()
|
return mConnectEnd.IsNull()
|
||||||
: TimerClamping::ReduceMsTimeValue(TimeStampToDOMHighRes(mConnectEnd));
|
? ConnectStartHighRes(aPerformance)
|
||||||
|
: TimerClamping::ReduceMsTimeValue(
|
||||||
|
TimeStampToDOMHighRes(aPerformance, mConnectEnd));
|
||||||
}
|
}
|
||||||
|
|
||||||
DOMTimeMilliSec
|
DOMTimeMilliSec
|
||||||
PerformanceTiming::ConnectEnd()
|
PerformanceTiming::ConnectEnd()
|
||||||
{
|
{
|
||||||
return static_cast<int64_t>(ConnectEndHighRes());
|
return static_cast<int64_t>(mTimingData->ConnectEndHighRes(mPerformance));
|
||||||
}
|
}
|
||||||
|
|
||||||
DOMHighResTimeStamp
|
DOMHighResTimeStamp
|
||||||
PerformanceTiming::RequestStartHighRes()
|
PerformanceTimingData::RequestStartHighRes(Performance* aPerformance)
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(aPerformance);
|
||||||
|
|
||||||
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized()) {
|
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized()) {
|
||||||
return mZeroTime;
|
return mZeroTime;
|
||||||
}
|
}
|
||||||
return TimeStampToReducedDOMHighResOrFetchStart(mRequestStart);
|
return TimeStampToReducedDOMHighResOrFetchStart(aPerformance, mRequestStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
DOMTimeMilliSec
|
DOMTimeMilliSec
|
||||||
PerformanceTiming::RequestStart()
|
PerformanceTiming::RequestStart()
|
||||||
{
|
{
|
||||||
return static_cast<int64_t>(RequestStartHighRes());
|
return static_cast<int64_t>(mTimingData->RequestStartHighRes(mPerformance));
|
||||||
}
|
}
|
||||||
|
|
||||||
DOMHighResTimeStamp
|
DOMHighResTimeStamp
|
||||||
PerformanceTiming::ResponseStartHighRes()
|
PerformanceTimingData::ResponseStartHighRes(Performance* aPerformance)
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(aPerformance);
|
||||||
|
|
||||||
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized()) {
|
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized()) {
|
||||||
return mZeroTime;
|
return mZeroTime;
|
||||||
}
|
}
|
||||||
|
|
@ -413,18 +476,20 @@ PerformanceTiming::ResponseStartHighRes()
|
||||||
(!mCacheReadStart.IsNull() && mCacheReadStart < mResponseStart)) {
|
(!mCacheReadStart.IsNull() && mCacheReadStart < mResponseStart)) {
|
||||||
mResponseStart = mCacheReadStart;
|
mResponseStart = mCacheReadStart;
|
||||||
}
|
}
|
||||||
return TimeStampToReducedDOMHighResOrFetchStart(mResponseStart);
|
return TimeStampToReducedDOMHighResOrFetchStart(aPerformance, mResponseStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
DOMTimeMilliSec
|
DOMTimeMilliSec
|
||||||
PerformanceTiming::ResponseStart()
|
PerformanceTiming::ResponseStart()
|
||||||
{
|
{
|
||||||
return static_cast<int64_t>(ResponseStartHighRes());
|
return static_cast<int64_t>(mTimingData->ResponseStartHighRes(mPerformance));
|
||||||
}
|
}
|
||||||
|
|
||||||
DOMHighResTimeStamp
|
DOMHighResTimeStamp
|
||||||
PerformanceTiming::ResponseEndHighRes()
|
PerformanceTimingData::ResponseEndHighRes(Performance* aPerformance)
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(aPerformance);
|
||||||
|
|
||||||
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized()) {
|
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized()) {
|
||||||
return mZeroTime;
|
return mZeroTime;
|
||||||
}
|
}
|
||||||
|
|
@ -433,20 +498,16 @@ PerformanceTiming::ResponseEndHighRes()
|
||||||
mResponseEnd = mCacheReadEnd;
|
mResponseEnd = mCacheReadEnd;
|
||||||
}
|
}
|
||||||
// Bug 1155008 - nsHttpTransaction is racy. Return ResponseStart when null
|
// Bug 1155008 - nsHttpTransaction is racy. Return ResponseStart when null
|
||||||
return mResponseEnd.IsNull() ? ResponseStartHighRes()
|
return mResponseEnd.IsNull()
|
||||||
: TimerClamping::ReduceMsTimeValue(TimeStampToDOMHighRes(mResponseEnd));
|
? ResponseStartHighRes(aPerformance)
|
||||||
|
: TimerClamping::ReduceMsTimeValue(
|
||||||
|
TimeStampToDOMHighRes(aPerformance, mResponseEnd));
|
||||||
}
|
}
|
||||||
|
|
||||||
DOMTimeMilliSec
|
DOMTimeMilliSec
|
||||||
PerformanceTiming::ResponseEnd()
|
PerformanceTiming::ResponseEnd()
|
||||||
{
|
{
|
||||||
return static_cast<int64_t>(ResponseEndHighRes());
|
return static_cast<int64_t>(mTimingData->ResponseEndHighRes(mPerformance));
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
PerformanceTiming::IsInitialized() const
|
|
||||||
{
|
|
||||||
return mInitialized;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JSObject*
|
JSObject*
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,193 @@ class nsITimedChannel;
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
|
||||||
|
class PerformanceTimingData final
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PerformanceTimingData(nsITimedChannel* aChannel,
|
||||||
|
nsIHttpChannel* aHttpChannel,
|
||||||
|
DOMHighResTimeStamp aZeroTime);
|
||||||
|
|
||||||
|
void SetPropertiesFromHttpChannel(nsIHttpChannel* aHttpChannel, nsITimedChannel* aChannel);
|
||||||
|
|
||||||
|
bool IsInitialized() const
|
||||||
|
{
|
||||||
|
return mInitialized;
|
||||||
|
}
|
||||||
|
|
||||||
|
const nsString& NextHopProtocol() const
|
||||||
|
{
|
||||||
|
return mNextHopProtocol;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t TransferSize() const
|
||||||
|
{
|
||||||
|
return mTimingAllowed ? mTransferSize : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t EncodedBodySize() const
|
||||||
|
{
|
||||||
|
return mTimingAllowed ? mEncodedBodySize : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t DecodedBodySize() const
|
||||||
|
{
|
||||||
|
return mTimingAllowed ? mDecodedBodySize : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param aStamp
|
||||||
|
* The TimeStamp recorded for a specific event. This TimeStamp can
|
||||||
|
* be null.
|
||||||
|
* @return the duration of an event with a given TimeStamp, relative to the
|
||||||
|
* navigationStart TimeStamp (the moment the user landed on the
|
||||||
|
* page), if the given TimeStamp is valid. Otherwise, it will return
|
||||||
|
* the FetchStart timing value.
|
||||||
|
*/
|
||||||
|
inline DOMHighResTimeStamp
|
||||||
|
TimeStampToReducedDOMHighResOrFetchStart(Performance* aPerformance,
|
||||||
|
TimeStamp aStamp)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(aPerformance);
|
||||||
|
|
||||||
|
return (!aStamp.IsNull())
|
||||||
|
? TimerClamping::ReduceMsTimeValue(
|
||||||
|
TimeStampToDOMHighRes(aPerformance, aStamp))
|
||||||
|
: FetchStartHighRes(aPerformance);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The nsITimedChannel records an absolute timestamp for each event.
|
||||||
|
* The nsDOMNavigationTiming will record the moment when the user landed on
|
||||||
|
* the page. This is a window.performance unique timestamp, so it can be used
|
||||||
|
* for all the events (navigation timing and resource timing events).
|
||||||
|
*
|
||||||
|
* The algorithm operates in 2 steps:
|
||||||
|
* 1. The first step is to subtract the two timestamps: the argument (the
|
||||||
|
* event's timestamp) and the navigation start timestamp. This will result in
|
||||||
|
* a relative timestamp of the event (relative to the navigation start -
|
||||||
|
* window.performance.timing.navigationStart).
|
||||||
|
* 2. The second step is to add any required offset (the mZeroTime). For now,
|
||||||
|
* this offset value is either 0 (for the resource timing), or equal to
|
||||||
|
* "performance.navigationStart" (for navigation timing).
|
||||||
|
* For the resource timing, mZeroTime is set to 0, causing the result to be a
|
||||||
|
* relative time.
|
||||||
|
* For the navigation timing, mZeroTime is set to "performance.navigationStart"
|
||||||
|
* causing the result be an absolute time.
|
||||||
|
*
|
||||||
|
* @param aStamp
|
||||||
|
* The TimeStamp recorded for a specific event. This TimeStamp can't
|
||||||
|
* be null.
|
||||||
|
* @return number of milliseconds value as one of:
|
||||||
|
* - relative to the navigation start time, time the user has landed on the
|
||||||
|
* page
|
||||||
|
* - an absolute wall clock time since the unix epoch
|
||||||
|
*/
|
||||||
|
inline DOMHighResTimeStamp
|
||||||
|
TimeStampToDOMHighRes(Performance* aPerformance, TimeStamp aStamp) const
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(aPerformance);
|
||||||
|
MOZ_ASSERT(!aStamp.IsNull());
|
||||||
|
|
||||||
|
TimeDuration duration =
|
||||||
|
aStamp - aPerformance->GetDOMTiming()->GetNavigationStartTimeStamp();
|
||||||
|
return duration.ToMilliseconds() + mZeroTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The last channel's AsyncOpen time. This may occur before the FetchStart
|
||||||
|
// in some cases.
|
||||||
|
DOMHighResTimeStamp AsyncOpenHighRes(Performance* aPerformance);
|
||||||
|
|
||||||
|
// High resolution (used by resource timing)
|
||||||
|
DOMHighResTimeStamp WorkerStartHighRes(Performance* aPerformance);
|
||||||
|
DOMHighResTimeStamp FetchStartHighRes(Performance* aPerformance);
|
||||||
|
DOMHighResTimeStamp RedirectStartHighRes(Performance* aPerformance);
|
||||||
|
DOMHighResTimeStamp RedirectEndHighRes(Performance* aPerformance);
|
||||||
|
DOMHighResTimeStamp DomainLookupStartHighRes(Performance* aPerformance);
|
||||||
|
DOMHighResTimeStamp DomainLookupEndHighRes(Performance* aPerformance);
|
||||||
|
DOMHighResTimeStamp ConnectStartHighRes(Performance* aPerformance);
|
||||||
|
DOMHighResTimeStamp SecureConnectionStartHighRes(Performance* aPerformance);
|
||||||
|
DOMHighResTimeStamp ConnectEndHighRes(Performance* aPerformance);
|
||||||
|
DOMHighResTimeStamp RequestStartHighRes(Performance* aPerformance);
|
||||||
|
DOMHighResTimeStamp ResponseStartHighRes(Performance* aPerformance);
|
||||||
|
DOMHighResTimeStamp ResponseEndHighRes(Performance* aPerformance);
|
||||||
|
|
||||||
|
DOMHighResTimeStamp ZeroTime() const { return mZeroTime; }
|
||||||
|
|
||||||
|
uint8_t RedirectCountReal() const { return mRedirectCount; }
|
||||||
|
uint8_t GetRedirectCount() const;
|
||||||
|
|
||||||
|
bool AllRedirectsSameOrigin() const { return mAllRedirectsSameOrigin; }
|
||||||
|
|
||||||
|
// If this is false the values of redirectStart/End will be 0 This is false if
|
||||||
|
// no redirects occured, or if any of the responses failed the
|
||||||
|
// timing-allow-origin check in HttpBaseChannel::TimingAllowCheck
|
||||||
|
bool ShouldReportCrossOriginRedirect() const;
|
||||||
|
|
||||||
|
// Cached result of CheckAllowedOrigin. If false, security sensitive
|
||||||
|
// attributes of the resourceTiming object will be set to 0
|
||||||
|
bool TimingAllowed() const
|
||||||
|
{
|
||||||
|
return mTimingAllowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Checks if the resource is either same origin as the page that started
|
||||||
|
// the load, or if the response contains the Timing-Allow-Origin header
|
||||||
|
// with a value of * or matching the domain of the loading Principal
|
||||||
|
bool CheckAllowedOrigin(nsIHttpChannel* aResourceChannel,
|
||||||
|
nsITimedChannel* aChannel);
|
||||||
|
|
||||||
|
nsString mNextHopProtocol;
|
||||||
|
|
||||||
|
TimeStamp mAsyncOpen;
|
||||||
|
TimeStamp mRedirectStart;
|
||||||
|
TimeStamp mRedirectEnd;
|
||||||
|
TimeStamp mDomainLookupStart;
|
||||||
|
TimeStamp mDomainLookupEnd;
|
||||||
|
TimeStamp mConnectStart;
|
||||||
|
TimeStamp mSecureConnectionStart;
|
||||||
|
TimeStamp mConnectEnd;
|
||||||
|
TimeStamp mRequestStart;
|
||||||
|
TimeStamp mResponseStart;
|
||||||
|
TimeStamp mCacheReadStart;
|
||||||
|
TimeStamp mResponseEnd;
|
||||||
|
TimeStamp mCacheReadEnd;
|
||||||
|
|
||||||
|
// ServiceWorker interception timing information
|
||||||
|
TimeStamp mWorkerStart;
|
||||||
|
TimeStamp mWorkerRequestStart;
|
||||||
|
TimeStamp mWorkerResponseEnd;
|
||||||
|
|
||||||
|
// This is an offset that will be added to each timing ([ms] resolution).
|
||||||
|
// There are only 2 possible values: (1) logicaly equal to navigationStart
|
||||||
|
// TimeStamp (results are absolute timstamps - wallclock); (2) "0" (results
|
||||||
|
// are relative to the navigation start).
|
||||||
|
DOMHighResTimeStamp mZeroTime;
|
||||||
|
|
||||||
|
DOMHighResTimeStamp mFetchStart;
|
||||||
|
|
||||||
|
uint64_t mEncodedBodySize;
|
||||||
|
uint64_t mTransferSize;
|
||||||
|
uint64_t mDecodedBodySize;
|
||||||
|
|
||||||
|
uint8_t mRedirectCount;
|
||||||
|
|
||||||
|
bool mAllRedirectsSameOrigin;
|
||||||
|
|
||||||
|
// If the resourceTiming object should have non-zero redirectStart and
|
||||||
|
// redirectEnd attributes. It is false if there were no redirects, or if any
|
||||||
|
// of the responses didn't pass the timing-allow-check
|
||||||
|
bool mReportCrossOriginRedirect;
|
||||||
|
|
||||||
|
bool mSecureConnection;
|
||||||
|
|
||||||
|
bool mTimingAllowed;
|
||||||
|
|
||||||
|
bool mInitialized;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
// Script "performance.timing" object
|
// Script "performance.timing" object
|
||||||
class PerformanceTiming final : public nsWrapperCache
|
class PerformanceTiming final : public nsWrapperCache
|
||||||
{
|
{
|
||||||
|
|
@ -59,57 +246,6 @@ public:
|
||||||
return mPerformance;
|
return mPerformance;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param aStamp
|
|
||||||
* The TimeStamp recorded for a specific event. This TimeStamp can
|
|
||||||
* be null.
|
|
||||||
* @return the duration of an event with a given TimeStamp, relative to the
|
|
||||||
* navigationStart TimeStamp (the moment the user landed on the
|
|
||||||
* page), if the given TimeStamp is valid. Otherwise, it will return
|
|
||||||
* the FetchStart timing value.
|
|
||||||
*/
|
|
||||||
inline DOMHighResTimeStamp TimeStampToReducedDOMHighResOrFetchStart(TimeStamp aStamp)
|
|
||||||
{
|
|
||||||
return (!aStamp.IsNull())
|
|
||||||
? TimerClamping::ReduceMsTimeValue(TimeStampToDOMHighRes(aStamp))
|
|
||||||
: FetchStartHighRes();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The nsITimedChannel records an absolute timestamp for each event.
|
|
||||||
* The nsDOMNavigationTiming will record the moment when the user landed on
|
|
||||||
* the page. This is a window.performance unique timestamp, so it can be used
|
|
||||||
* for all the events (navigation timing and resource timing events).
|
|
||||||
*
|
|
||||||
* The algorithm operates in 2 steps:
|
|
||||||
* 1. The first step is to subtract the two timestamps: the argument (the
|
|
||||||
* envet's timesramp) and the navigation start timestamp. This will result in
|
|
||||||
* a relative timestamp of the event (relative to the navigation start -
|
|
||||||
* window.performance.timing.navigationStart).
|
|
||||||
* 2. The second step is to add any required offset (the mZeroTime). For now,
|
|
||||||
* this offset value is either 0 (for the resource timing), or equal to
|
|
||||||
* "performance.navigationStart" (for navigation timing).
|
|
||||||
* For the resource timing, mZeroTime is set to 0, causing the result to be a
|
|
||||||
* relative time.
|
|
||||||
* For the navigation timing, mZeroTime is set to "performance.navigationStart"
|
|
||||||
* causing the result be an absolute time.
|
|
||||||
*
|
|
||||||
* @param aStamp
|
|
||||||
* The TimeStamp recorded for a specific event. This TimeStamp can't
|
|
||||||
* be null.
|
|
||||||
* @return number of milliseconds value as one of:
|
|
||||||
* - relative to the navigation start time, time the user has landed on the
|
|
||||||
* page
|
|
||||||
* - an absolute wall clock time since the unix epoch
|
|
||||||
*/
|
|
||||||
inline DOMHighResTimeStamp TimeStampToDOMHighRes(TimeStamp aStamp) const
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(!aStamp.IsNull());
|
|
||||||
TimeDuration duration =
|
|
||||||
aStamp - GetDOMTiming()->GetNavigationStartTimeStamp();
|
|
||||||
return duration.ToMilliseconds() + mZeroTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual JSObject* WrapObject(JSContext *cx,
|
virtual JSObject* WrapObject(JSContext *cx,
|
||||||
JS::Handle<JSObject*> aGivenProto) override;
|
JS::Handle<JSObject*> aGivenProto) override;
|
||||||
|
|
||||||
|
|
@ -138,40 +274,6 @@ public:
|
||||||
return TimerClamping::ReduceMsTimeValue(GetDOMTiming()->GetUnloadEventEnd());
|
return TimerClamping::ReduceMsTimeValue(GetDOMTiming()->GetUnloadEventEnd());
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t GetRedirectCount() const;
|
|
||||||
|
|
||||||
// Checks if the resource is either same origin as the page that started
|
|
||||||
// the load, or if the response contains the Timing-Allow-Origin header
|
|
||||||
// with a value of * or matching the domain of the loading Principal
|
|
||||||
bool CheckAllowedOrigin(nsIHttpChannel* aResourceChannel, nsITimedChannel* aChannel);
|
|
||||||
|
|
||||||
// Cached result of CheckAllowedOrigin. If false, security sensitive
|
|
||||||
// attributes of the resourceTiming object will be set to 0
|
|
||||||
bool TimingAllowed() const;
|
|
||||||
|
|
||||||
// If this is false the values of redirectStart/End will be 0
|
|
||||||
// This is false if no redirects occured, or if any of the responses failed
|
|
||||||
// the timing-allow-origin check in HttpBaseChannel::TimingAllowCheck
|
|
||||||
bool ShouldReportCrossOriginRedirect() const;
|
|
||||||
|
|
||||||
// The last channel's AsyncOpen time. This may occur before the FetchStart
|
|
||||||
// in some cases.
|
|
||||||
DOMHighResTimeStamp AsyncOpenHighRes();
|
|
||||||
|
|
||||||
// High resolution (used by resource timing)
|
|
||||||
DOMHighResTimeStamp WorkerStartHighRes();
|
|
||||||
DOMHighResTimeStamp FetchStartHighRes();
|
|
||||||
DOMHighResTimeStamp RedirectStartHighRes();
|
|
||||||
DOMHighResTimeStamp RedirectEndHighRes();
|
|
||||||
DOMHighResTimeStamp DomainLookupStartHighRes();
|
|
||||||
DOMHighResTimeStamp DomainLookupEndHighRes();
|
|
||||||
DOMHighResTimeStamp ConnectStartHighRes();
|
|
||||||
DOMHighResTimeStamp SecureConnectionStartHighRes();
|
|
||||||
DOMHighResTimeStamp ConnectEndHighRes();
|
|
||||||
DOMHighResTimeStamp RequestStartHighRes();
|
|
||||||
DOMHighResTimeStamp ResponseStartHighRes();
|
|
||||||
DOMHighResTimeStamp ResponseEndHighRes();
|
|
||||||
|
|
||||||
// Low resolution (used by navigation timing)
|
// Low resolution (used by navigation timing)
|
||||||
DOMTimeMilliSec FetchStart();
|
DOMTimeMilliSec FetchStart();
|
||||||
DOMTimeMilliSec RedirectStart();
|
DOMTimeMilliSec RedirectStart();
|
||||||
|
|
@ -249,46 +351,16 @@ public:
|
||||||
return TimerClamping::ReduceMsTimeValue(GetDOMTiming()->GetTimeToNonBlankPaint());
|
return TimerClamping::ReduceMsTimeValue(GetDOMTiming()->GetTimeToNonBlankPaint());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PerformanceTimingData* Data() const
|
||||||
|
{
|
||||||
|
return mTimingData.get();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
~PerformanceTiming();
|
~PerformanceTiming();
|
||||||
|
|
||||||
bool IsInitialized() const;
|
|
||||||
void InitializeTimingInfo(nsITimedChannel* aChannel);
|
|
||||||
|
|
||||||
RefPtr<Performance> mPerformance;
|
RefPtr<Performance> mPerformance;
|
||||||
DOMHighResTimeStamp mFetchStart;
|
UniquePtr<PerformanceTimingData> mTimingData;
|
||||||
|
|
||||||
// This is an offset that will be added to each timing ([ms] resolution).
|
|
||||||
// There are only 2 possible values: (1) logicaly equal to navigationStart
|
|
||||||
// TimeStamp (results are absolute timstamps - wallclock); (2) "0" (results
|
|
||||||
// are relative to the navigation start).
|
|
||||||
DOMHighResTimeStamp mZeroTime;
|
|
||||||
|
|
||||||
TimeStamp mAsyncOpen;
|
|
||||||
TimeStamp mWorkerStart;
|
|
||||||
TimeStamp mRedirectStart;
|
|
||||||
TimeStamp mRedirectEnd;
|
|
||||||
TimeStamp mDomainLookupStart;
|
|
||||||
TimeStamp mDomainLookupEnd;
|
|
||||||
TimeStamp mConnectStart;
|
|
||||||
TimeStamp mSecureConnectionStart;
|
|
||||||
TimeStamp mConnectEnd;
|
|
||||||
TimeStamp mRequestStart;
|
|
||||||
TimeStamp mResponseStart;
|
|
||||||
TimeStamp mCacheReadStart;
|
|
||||||
TimeStamp mResponseEnd;
|
|
||||||
TimeStamp mCacheReadEnd;
|
|
||||||
uint8_t mRedirectCount;
|
|
||||||
bool mTimingAllowed;
|
|
||||||
bool mAllRedirectsSameOrigin;
|
|
||||||
bool mInitialized;
|
|
||||||
|
|
||||||
// If the resourceTiming object should have non-zero redirectStart and
|
|
||||||
// redirectEnd attributes. It is false if there were no redirects, or if
|
|
||||||
// any of the responses didn't pass the timing-allow-check
|
|
||||||
bool mReportCrossOriginRedirect;
|
|
||||||
|
|
||||||
bool mSecureConnection;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
|
|
|
||||||
|
|
@ -62,6 +62,11 @@ public:
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QueueNavigationTimingEntry() override
|
||||||
|
{
|
||||||
|
MOZ_CRASH("This should not be called on workers.");
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
~PerformanceWorker();
|
~PerformanceWorker();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1072,6 +1072,11 @@ nsDocumentViewer::LoadComplete(nsresult aStatus)
|
||||||
if (timing) {
|
if (timing) {
|
||||||
timing->NotifyLoadEventEnd();
|
timing->NotifyLoadEventEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsPIDOMWindowInner* innerWindow = window->GetCurrentInnerWindow();
|
||||||
|
if (innerWindow) {
|
||||||
|
innerWindow->QueuePerformanceNavigationTiming();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// XXX: Should fire error event to the document...
|
// XXX: Should fire error event to the document...
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue