Bug 1762482 - update PerformanceMeasure to User Timing L3. r=sefeng,smaug
Differential Revision: https://phabricator.services.mozilla.com/D143858
This commit is contained in:
@@ -18,6 +18,7 @@
|
||||
#include "PerformanceWorker.h"
|
||||
#include "mozilla/BasePrincipal.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "mozilla/dom/MessagePortBinding.h"
|
||||
#include "mozilla/dom/PerformanceBinding.h"
|
||||
#include "mozilla/dom/PerformanceEntryEvent.h"
|
||||
#include "mozilla/dom/PerformanceNavigationBinding.h"
|
||||
@@ -33,6 +34,12 @@
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
||||
enum class Performance::ResolveTimestampAttribute {
|
||||
Start,
|
||||
End,
|
||||
Duration,
|
||||
};
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Performance)
|
||||
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
|
||||
|
||||
@@ -387,7 +394,7 @@ void Performance::ClearMarks(const Optional<nsAString>& aName) {
|
||||
ClearUserEntries(aName, u"mark"_ns);
|
||||
}
|
||||
|
||||
DOMHighResTimeStamp Performance::ResolveTimestampFromName(
|
||||
DOMHighResTimeStamp Performance::ConvertMarkToTimestampWithString(
|
||||
const nsAString& aName, ErrorResult& aRv) {
|
||||
AutoTArray<RefPtr<PerformanceEntry>, 1> arr;
|
||||
Optional<nsAString> typeParam;
|
||||
@@ -400,7 +407,9 @@ DOMHighResTimeStamp Performance::ResolveTimestampFromName(
|
||||
}
|
||||
|
||||
if (!IsPerformanceTimingAttribute(aName)) {
|
||||
aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
|
||||
nsPrintfCString errorMsg("Given mark name, %s, is unknown",
|
||||
NS_ConvertUTF16toUTF8(aName).get());
|
||||
aRv.ThrowSyntaxError(errorMsg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -413,41 +422,190 @@ DOMHighResTimeStamp Performance::ResolveTimestampFromName(
|
||||
return ts - CreationTime();
|
||||
}
|
||||
|
||||
void Performance::Measure(const nsAString& aName,
|
||||
const Optional<nsAString>& aStartMark,
|
||||
const Optional<nsAString>& aEndMark,
|
||||
ErrorResult& aRv) {
|
||||
// We add nothing when 'privacy.resistFingerprinting' is on.
|
||||
if (nsContentUtils::ShouldResistFingerprinting()) {
|
||||
return;
|
||||
DOMHighResTimeStamp Performance::ConvertMarkToTimestampWithDOMHighResTimeStamp(
|
||||
const ResolveTimestampAttribute aAttribute,
|
||||
const DOMHighResTimeStamp aTimestamp, ErrorResult& aRv) {
|
||||
if (aTimestamp < 0) {
|
||||
nsAutoCString attributeName;
|
||||
switch (aAttribute) {
|
||||
case ResolveTimestampAttribute::Start:
|
||||
attributeName = "start";
|
||||
break;
|
||||
case ResolveTimestampAttribute::End:
|
||||
attributeName = "end";
|
||||
break;
|
||||
case ResolveTimestampAttribute::Duration:
|
||||
attributeName = "duration";
|
||||
break;
|
||||
}
|
||||
|
||||
nsPrintfCString errorMsg("Given attribute %s cannot be negative",
|
||||
attributeName.get());
|
||||
aRv.ThrowTypeError(errorMsg);
|
||||
}
|
||||
return aTimestamp;
|
||||
}
|
||||
|
||||
DOMHighResTimeStamp Performance::ConvertMarkToTimestamp(
|
||||
const ResolveTimestampAttribute aAttribute,
|
||||
const OwningStringOrDouble& aMarkNameOrTimestamp, ErrorResult& aRv) {
|
||||
if (aMarkNameOrTimestamp.IsString()) {
|
||||
return ConvertMarkToTimestampWithString(aMarkNameOrTimestamp.GetAsString(),
|
||||
aRv);
|
||||
}
|
||||
|
||||
DOMHighResTimeStamp startTime;
|
||||
return ConvertMarkToTimestampWithDOMHighResTimeStamp(
|
||||
aAttribute, aMarkNameOrTimestamp.GetAsDouble(), aRv);
|
||||
}
|
||||
|
||||
DOMHighResTimeStamp Performance::ResolveEndTimeForMeasure(
|
||||
const Optional<nsAString>& aEndMark,
|
||||
const Maybe<const PerformanceMeasureOptions&>& aOptions, ErrorResult& aRv) {
|
||||
DOMHighResTimeStamp endTime;
|
||||
|
||||
if (aStartMark.WasPassed()) {
|
||||
startTime = ResolveTimestampFromName(aStartMark.Value(), aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// Navigation start is used in this case, but since DOMHighResTimeStamp is
|
||||
// in relation to navigation start, this will be zero if a name is not
|
||||
// passed.
|
||||
startTime = 0;
|
||||
}
|
||||
|
||||
if (aEndMark.WasPassed()) {
|
||||
endTime = ResolveTimestampFromName(aEndMark.Value(), aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
endTime = ConvertMarkToTimestampWithString(aEndMark.Value(), aRv);
|
||||
} else if (aOptions && aOptions->mEnd.WasPassed()) {
|
||||
endTime = ConvertMarkToTimestamp(ResolveTimestampAttribute::End,
|
||||
aOptions->mEnd.Value(), aRv);
|
||||
} else if (aOptions && aOptions->mStart.WasPassed() &&
|
||||
aOptions->mDuration.WasPassed()) {
|
||||
const DOMHighResTimeStamp start = ConvertMarkToTimestamp(
|
||||
ResolveTimestampAttribute::Start, aOptions->mStart.Value(), aRv);
|
||||
if (aRv.Failed()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const DOMHighResTimeStamp duration =
|
||||
ConvertMarkToTimestampWithDOMHighResTimeStamp(
|
||||
ResolveTimestampAttribute::Duration, aOptions->mDuration.Value(),
|
||||
aRv);
|
||||
if (aRv.Failed()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
endTime = start + duration;
|
||||
} else {
|
||||
endTime = Now();
|
||||
}
|
||||
|
||||
RefPtr<PerformanceMeasure> performanceMeasure =
|
||||
new PerformanceMeasure(GetParentObject(), aName, startTime, endTime);
|
||||
return endTime;
|
||||
}
|
||||
|
||||
DOMHighResTimeStamp Performance::ResolveStartTimeForMeasure(
|
||||
const Maybe<const nsAString&>& aStartMark,
|
||||
const Maybe<const PerformanceMeasureOptions&>& aOptions, ErrorResult& aRv) {
|
||||
DOMHighResTimeStamp startTime;
|
||||
if (aOptions && aOptions->mStart.WasPassed()) {
|
||||
startTime = ConvertMarkToTimestamp(ResolveTimestampAttribute::Start,
|
||||
aOptions->mStart.Value(), aRv);
|
||||
} else if (aOptions && aOptions->mDuration.WasPassed() &&
|
||||
aOptions->mEnd.WasPassed()) {
|
||||
const DOMHighResTimeStamp duration =
|
||||
ConvertMarkToTimestampWithDOMHighResTimeStamp(
|
||||
ResolveTimestampAttribute::Duration, aOptions->mDuration.Value(),
|
||||
aRv);
|
||||
if (aRv.Failed()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const DOMHighResTimeStamp end = ConvertMarkToTimestamp(
|
||||
ResolveTimestampAttribute::End, aOptions->mEnd.Value(), aRv);
|
||||
if (aRv.Failed()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
startTime = end - duration;
|
||||
} else if (aStartMark) {
|
||||
startTime = ConvertMarkToTimestampWithString(*aStartMark, aRv);
|
||||
} else {
|
||||
startTime = 0;
|
||||
}
|
||||
|
||||
return startTime;
|
||||
}
|
||||
|
||||
already_AddRefed<PerformanceMeasure> Performance::Measure(
|
||||
JSContext* aCx, const nsAString& aName,
|
||||
const StringOrPerformanceMeasureOptions& aStartOrMeasureOptions,
|
||||
const Optional<nsAString>& aEndMark, ErrorResult& aRv) {
|
||||
// When resisting fingerprinting, we don't add marks to the buffer. Since
|
||||
// measure relies on relationships between marks in the buffer, this method
|
||||
// will throw if we look for user-entered marks so we return a dummy measure
|
||||
// instead of continuing. We could instead return real values for performance
|
||||
// timing attributes and dummy values for user-entered marks but this adds
|
||||
// complexity that doesn't seem worth the effort because these fingerprinting
|
||||
// protections may not longer be necessary (since performance.now() already
|
||||
// has reduced precision).
|
||||
if (nsContentUtils::ShouldResistFingerprinting()) {
|
||||
return do_AddRef(new PerformanceMeasure(GetParentObject(), aName, 0, 0,
|
||||
JS::NullHandleValue));
|
||||
}
|
||||
|
||||
// Maybe is more readable than using the union type directly.
|
||||
Maybe<const PerformanceMeasureOptions&> options;
|
||||
if (aStartOrMeasureOptions.IsPerformanceMeasureOptions()) {
|
||||
options.emplace(aStartOrMeasureOptions.GetAsPerformanceMeasureOptions());
|
||||
}
|
||||
|
||||
const bool isOptionsNotEmpty =
|
||||
options.isSome() &&
|
||||
(!options->mDetail.isUndefined() || options->mStart.WasPassed() ||
|
||||
options->mEnd.WasPassed() || options->mDuration.WasPassed());
|
||||
if (isOptionsNotEmpty) {
|
||||
if (aEndMark.WasPassed()) {
|
||||
aRv.ThrowTypeError(
|
||||
"Cannot provide separate endMark argument if "
|
||||
"PerformanceMeasureOptions argument is given");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!options->mStart.WasPassed() && !options->mEnd.WasPassed()) {
|
||||
aRv.ThrowTypeError(
|
||||
"PerformanceMeasureOptions must have start and/or end member");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (options->mStart.WasPassed() && options->mDuration.WasPassed() &&
|
||||
options->mEnd.WasPassed()) {
|
||||
aRv.ThrowTypeError(
|
||||
"PerformanceMeasureOptions cannot have all of the following members: "
|
||||
"start, duration, and end");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
const DOMHighResTimeStamp endTime =
|
||||
ResolveEndTimeForMeasure(aEndMark, options, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Convert to Maybe for consistency with options.
|
||||
Maybe<const nsAString&> startMark;
|
||||
if (aStartOrMeasureOptions.IsString()) {
|
||||
startMark.emplace(aStartOrMeasureOptions.GetAsString());
|
||||
}
|
||||
const DOMHighResTimeStamp startTime =
|
||||
ResolveStartTimeForMeasure(startMark, options, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
JS::Rooted<JS::Value> detail(aCx);
|
||||
if (options && !options->mDetail.isNullOrUndefined()) {
|
||||
StructuredSerializeOptions serializeOptions;
|
||||
JS::Rooted<JS::Value> valueToClone(aCx, options->mDetail);
|
||||
nsContentUtils::StructuredClone(aCx, GetParentObject(), valueToClone,
|
||||
serializeOptions, &detail, aRv);
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
} else {
|
||||
detail.setNull();
|
||||
}
|
||||
|
||||
RefPtr<PerformanceMeasure> performanceMeasure = new PerformanceMeasure(
|
||||
GetParentObject(), aName, startTime, endTime, detail);
|
||||
InsertUserEntry(performanceMeasure);
|
||||
|
||||
if (profiler_thread_is_being_profiled_for_markers()) {
|
||||
@@ -456,12 +614,6 @@ void Performance::Measure(const nsAString& aName,
|
||||
TimeStamp endTimeStamp =
|
||||
CreationTimeStamp() + TimeDuration::FromMilliseconds(endTime);
|
||||
|
||||
// Convert to Maybe values so that Optional types do not need to be used in
|
||||
// the profiler.
|
||||
Maybe<nsString> startMark;
|
||||
if (aStartMark.WasPassed()) {
|
||||
startMark.emplace(aStartMark.Value());
|
||||
}
|
||||
Maybe<nsString> endMark;
|
||||
if (aEndMark.WasPassed()) {
|
||||
endMark.emplace(aEndMark.Value());
|
||||
@@ -477,6 +629,8 @@ void Performance::Measure(const nsAString& aName,
|
||||
UserTimingMarker{}, aName, /* aIsMeasure */ true,
|
||||
startMark, endMark);
|
||||
}
|
||||
|
||||
return performanceMeasure.forget();
|
||||
}
|
||||
|
||||
void Performance::ClearMeasures(const Optional<nsAString>& aName) {
|
||||
|
||||
@@ -21,9 +21,13 @@ class ErrorResult;
|
||||
|
||||
namespace dom {
|
||||
|
||||
class OwningStringOrDouble;
|
||||
class StringOrPerformanceMeasureOptions;
|
||||
class PerformanceEntry;
|
||||
class PerformanceMark;
|
||||
struct PerformanceMarkOptions;
|
||||
struct PerformanceMeasureOptions;
|
||||
class PerformanceMeasure;
|
||||
class PerformanceNavigation;
|
||||
class PerformancePaintTiming;
|
||||
class PerformanceObserver;
|
||||
@@ -84,8 +88,10 @@ class Performance : public DOMEventTargetHelper {
|
||||
|
||||
void ClearMarks(const Optional<nsAString>& aName);
|
||||
|
||||
void Measure(const nsAString& aName, const Optional<nsAString>& aStartMark,
|
||||
const Optional<nsAString>& aEndMark, ErrorResult& aRv);
|
||||
already_AddRefed<PerformanceMeasure> Measure(
|
||||
JSContext* aCx, const nsAString& aName,
|
||||
const StringOrPerformanceMeasureOptions& aStartOrMeasureOptions,
|
||||
const Optional<nsAString>& aEndMark, ErrorResult& aRv);
|
||||
|
||||
void ClearMeasures(const Optional<nsAString>& aName);
|
||||
|
||||
@@ -161,9 +167,6 @@ class Performance : public DOMEventTargetHelper {
|
||||
void ClearUserEntries(const Optional<nsAString>& aEntryName,
|
||||
const nsAString& aEntryType);
|
||||
|
||||
DOMHighResTimeStamp ResolveTimestampFromName(const nsAString& aName,
|
||||
ErrorResult& aRv);
|
||||
|
||||
virtual void DispatchBufferFullEvent() = 0;
|
||||
|
||||
virtual DOMHighResTimeStamp CreationTime() const = 0;
|
||||
@@ -206,6 +209,28 @@ class Performance : public DOMEventTargetHelper {
|
||||
private:
|
||||
MOZ_ALWAYS_INLINE bool CanAddResourceTimingEntry();
|
||||
void BufferEvent();
|
||||
|
||||
// The attributes of a PerformanceMeasureOptions that we call
|
||||
// ResolveTimestamp* on.
|
||||
enum class ResolveTimestampAttribute;
|
||||
|
||||
DOMHighResTimeStamp ConvertMarkToTimestampWithString(const nsAString& aName,
|
||||
ErrorResult& aRv);
|
||||
DOMHighResTimeStamp ConvertMarkToTimestampWithDOMHighResTimeStamp(
|
||||
const ResolveTimestampAttribute aAttribute, const double aTimestamp,
|
||||
ErrorResult& aRv);
|
||||
DOMHighResTimeStamp ConvertMarkToTimestamp(
|
||||
const ResolveTimestampAttribute aAttribute,
|
||||
const OwningStringOrDouble& aMarkNameOrTimestamp, ErrorResult& aRv);
|
||||
|
||||
DOMHighResTimeStamp ResolveEndTimeForMeasure(
|
||||
const Optional<nsAString>& aEndMark,
|
||||
const Maybe<const PerformanceMeasureOptions&>& aOptions,
|
||||
ErrorResult& aRv);
|
||||
DOMHighResTimeStamp ResolveStartTimeForMeasure(
|
||||
const Maybe<const nsAString&>& aStartMark,
|
||||
const Maybe<const PerformanceMeasureOptions&>& aOptions,
|
||||
ErrorResult& aRv);
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
||||
@@ -100,9 +100,10 @@ JSObject* PerformanceMark::WrapObject(JSContext* aCx,
|
||||
|
||||
void PerformanceMark::GetDetail(JSContext* aCx,
|
||||
JS::MutableHandle<JS::Value> aRetval) {
|
||||
// Return a copy so that the PerformanceMark.detail reference always returns
|
||||
// the same value. However, the contents of detail can be mutated. The spec
|
||||
// isn't clear if this is okay but it matches Chrome's behavior.
|
||||
// Return a copy so that this method always returns the value it is set to
|
||||
// (i.e. it'll return the same value even if the caller assigns to it). Note
|
||||
// that if detail is an object, its contents can be mutated and this is
|
||||
// expected.
|
||||
aRetval.set(mDetail);
|
||||
}
|
||||
|
||||
|
||||
@@ -13,18 +13,49 @@ using namespace mozilla::dom;
|
||||
PerformanceMeasure::PerformanceMeasure(nsISupports* aParent,
|
||||
const nsAString& aName,
|
||||
DOMHighResTimeStamp aStartTime,
|
||||
DOMHighResTimeStamp aEndTime)
|
||||
DOMHighResTimeStamp aEndTime,
|
||||
const JS::Handle<JS::Value>& aDetail)
|
||||
: PerformanceEntry(aParent, aName, u"measure"_ns),
|
||||
mStartTime(aStartTime),
|
||||
mDuration(aEndTime - aStartTime) {}
|
||||
mDuration(aEndTime - aStartTime),
|
||||
mDetail(aDetail) {
|
||||
mozilla::HoldJSObjects(this);
|
||||
}
|
||||
|
||||
PerformanceMeasure::~PerformanceMeasure() = default;
|
||||
PerformanceMeasure::~PerformanceMeasure() { mozilla::DropJSObjects(this); }
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(PerformanceMeasure)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(PerformanceMeasure,
|
||||
PerformanceEntry)
|
||||
tmp->mDetail.setUndefined();
|
||||
mozilla::DropJSObjects(tmp);
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(PerformanceMeasure,
|
||||
PerformanceEntry)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(PerformanceMeasure,
|
||||
PerformanceEntry)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mDetail)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||
|
||||
NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED_0(PerformanceMeasure,
|
||||
PerformanceEntry)
|
||||
|
||||
JSObject* PerformanceMeasure::WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) {
|
||||
return PerformanceMeasure_Binding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
void PerformanceMeasure::GetDetail(JSContext* aCx,
|
||||
JS::MutableHandle<JS::Value> aRetval) {
|
||||
// Return a copy so that this method always returns the value it is set to
|
||||
// (i.e. it'll return the same value even if the caller assigns to it). Note
|
||||
// that if detail is an object, its contents can be mutated and this is
|
||||
// expected.
|
||||
aRetval.set(mDetail);
|
||||
}
|
||||
|
||||
size_t PerformanceMeasure::SizeOfIncludingThis(
|
||||
mozilla::MallocSizeOf aMallocSizeOf) const {
|
||||
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
|
||||
|
||||
@@ -14,9 +14,14 @@ namespace mozilla::dom {
|
||||
// http://www.w3.org/TR/user-timing/#performancemeasure
|
||||
class PerformanceMeasure final : public PerformanceEntry {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(PerformanceMeasure,
|
||||
PerformanceEntry);
|
||||
|
||||
PerformanceMeasure(nsISupports* aParent, const nsAString& aName,
|
||||
DOMHighResTimeStamp aStartTime,
|
||||
DOMHighResTimeStamp aEndTime);
|
||||
DOMHighResTimeStamp aEndTime,
|
||||
const JS::Handle<JS::Value>& aDetail);
|
||||
|
||||
virtual JSObject* WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) override;
|
||||
@@ -25,6 +30,8 @@ class PerformanceMeasure final : public PerformanceEntry {
|
||||
|
||||
virtual DOMHighResTimeStamp Duration() const override { return mDuration; }
|
||||
|
||||
void GetDetail(JSContext* aCx, JS::MutableHandle<JS::Value> aRetval);
|
||||
|
||||
size_t SizeOfIncludingThis(
|
||||
mozilla::MallocSizeOf aMallocSizeOf) const override;
|
||||
|
||||
@@ -32,6 +39,9 @@ class PerformanceMeasure final : public PerformanceEntry {
|
||||
virtual ~PerformanceMeasure();
|
||||
DOMHighResTimeStamp mStartTime;
|
||||
DOMHighResTimeStamp mDuration;
|
||||
|
||||
private:
|
||||
JS::Heap<JS::Value> mDetail;
|
||||
};
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
||||
@@ -71,6 +71,14 @@ dictionary PerformanceMarkOptions {
|
||||
DOMHighResTimeStamp startTime;
|
||||
};
|
||||
|
||||
// https://w3c.github.io/user-timing/#extensions-performance-interface
|
||||
dictionary PerformanceMeasureOptions {
|
||||
any detail;
|
||||
(DOMString or DOMHighResTimeStamp) start;
|
||||
DOMHighResTimeStamp duration;
|
||||
(DOMString or DOMHighResTimeStamp) end;
|
||||
};
|
||||
|
||||
// https://w3c.github.io/user-timing/#extensions-performance-interface
|
||||
[Exposed=(Window,Worker)]
|
||||
partial interface Performance {
|
||||
@@ -78,7 +86,7 @@ partial interface Performance {
|
||||
PerformanceMark mark(DOMString markName, optional PerformanceMarkOptions markOptions = {});
|
||||
void clearMarks(optional DOMString markName);
|
||||
[Throws]
|
||||
void measure(DOMString measureName, optional DOMString startMark, optional DOMString endMark);
|
||||
PerformanceMeasure measure(DOMString measureName, optional (DOMString or PerformanceMeasureOptions) startOrMeasureOptions = {}, optional DOMString endMark);
|
||||
void clearMeasures(optional DOMString measureName);
|
||||
};
|
||||
|
||||
|
||||
@@ -10,4 +10,5 @@
|
||||
[Exposed=(Window,Worker)]
|
||||
interface PerformanceMeasure : PerformanceEntry
|
||||
{
|
||||
readonly attribute any detail;
|
||||
};
|
||||
|
||||
@@ -1,33 +1,2 @@
|
||||
[idlharness.https.any.serviceworker.html]
|
||||
expected: TIMEOUT
|
||||
|
||||
[idlharness.any.html]
|
||||
[PerformanceMeasure interface: attribute detail]
|
||||
expected: FAIL
|
||||
|
||||
[PerformanceMeasure interface: measure must inherit property "detail" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
|
||||
[idlharness.any.worker.html]
|
||||
[PerformanceMeasure interface: attribute detail]
|
||||
expected: FAIL
|
||||
|
||||
[PerformanceMeasure interface: measure must inherit property "detail" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
|
||||
[idlharness.any.sharedworker.html]
|
||||
[PerformanceMeasure interface: attribute detail]
|
||||
expected: FAIL
|
||||
|
||||
[PerformanceMeasure interface: measure must inherit property "detail" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
|
||||
[idlharness.any.serviceworker.html]
|
||||
[PerformanceMeasure interface: attribute detail]
|
||||
expected: FAIL
|
||||
|
||||
[PerformanceMeasure interface: measure must inherit property "detail" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
[mark-measure-return-objects.any.html]
|
||||
[L3: performance.measure(name, param1, param2) should return an entry.]
|
||||
expected: FAIL
|
||||
|
||||
[L3: performance.measure(name, param1) should return an entry.]
|
||||
expected: FAIL
|
||||
|
||||
[L3: performance.measure(name) should return an entry.]
|
||||
expected: FAIL
|
||||
|
||||
|
||||
[mark-measure-return-objects.any.worker.html]
|
||||
[L3: performance.measure(name, param1, param2) should return an entry.]
|
||||
expected: FAIL
|
||||
|
||||
[L3: performance.measure(name, param1) should return an entry.]
|
||||
expected: FAIL
|
||||
|
||||
[L3: performance.measure(name) should return an entry.]
|
||||
expected: FAIL
|
||||
@@ -1,21 +0,0 @@
|
||||
[measure-l3.any.html]
|
||||
[When the end mark is given and the start is unprovided, the end time of the measure entry should be the end mark's time, the start time should be 0.]
|
||||
expected: FAIL
|
||||
|
||||
[When start and end mark are both given, the start time and end time of the measure entry should be the the marks' time, repectively]
|
||||
expected: FAIL
|
||||
|
||||
[When the start mark is given and the end is unprovided, the start time of the measure entry should be the start mark's time, the end should be now.]
|
||||
expected: FAIL
|
||||
|
||||
|
||||
[measure-l3.any.worker.html]
|
||||
[When the end mark is given and the start is unprovided, the end time of the measure entry should be the end mark's time, the start time should be 0.]
|
||||
expected: FAIL
|
||||
|
||||
[When start and end mark are both given, the start time and end time of the measure entry should be the the marks' time, repectively]
|
||||
expected: FAIL
|
||||
|
||||
[When the start mark is given and the end is unprovided, the start time of the measure entry should be the start mark's time, the end should be now.]
|
||||
expected: FAIL
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
[measure-with-dict.any.html]
|
||||
[measure entries' detail and start/end are customizable]
|
||||
expected: FAIL
|
||||
|
||||
[measure should throw a TypeError when passed an invalid argument combination]
|
||||
expected: FAIL
|
||||
|
||||
|
||||
[measure-with-dict.any.worker.html]
|
||||
[measure entries' detail and start/end are customizable]
|
||||
expected: FAIL
|
||||
|
||||
[measure should throw a TypeError when passed an invalid argument combination]
|
||||
expected: FAIL
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
[measure_exception.html]
|
||||
[Invocation of performance.measure("Exception9", {"start": 1, "duration": 2, "end": 3}) should throw TypeError Exception.]
|
||||
expected: FAIL
|
||||
|
||||
[Invocation of performance.measure("Exception8", {"detail": "non-empty"}) should throw TypeError Exception.]
|
||||
expected: FAIL
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
[structured-serialize-detail.any.html]
|
||||
[When accessing detail from a measure entry and the detail is not provided, just return a null value.]
|
||||
expected: FAIL
|
||||
|
||||
[The detail property in the measure method should be the same reference.]
|
||||
expected: FAIL
|
||||
|
||||
[The detail property in the measure method should be structured-clone.]
|
||||
expected: FAIL
|
||||
|
||||
[Measure: Throw an exception when the detail property cannot be structured-serialized.]
|
||||
expected: FAIL
|
||||
|
||||
|
||||
[structured-serialize-detail.any.worker.html]
|
||||
[When accessing detail from a measure entry and the detail is not provided, just return a null value.]
|
||||
expected: FAIL
|
||||
|
||||
[The detail property in the measure method should be the same reference.]
|
||||
expected: FAIL
|
||||
|
||||
[The detail property in the measure method should be structured-clone.]
|
||||
expected: FAIL
|
||||
|
||||
[Measure: Throw an exception when the detail property cannot be structured-serialized.]
|
||||
expected: FAIL
|
||||
Reference in New Issue
Block a user