Bug 1667836 - Implement EventCounts Interface r=smaug

This interface is part of PerformanceEventTiming.

Spec: https://wicg.github.io/event-timing/#sec-event-counts

Differential Revision: https://phabricator.services.mozilla.com/D102037
This commit is contained in:
Sean Feng 2021-02-09 18:54:48 +00:00
Родитель a7786149e0
Коммит b03a010048
10 изменённых файлов: 228 добавлений и 7 удалений

Просмотреть файл

@ -0,0 +1,141 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "EventCounts.h"
#include "mozilla/dom/Event.h"
#include "mozilla/dom/EventCounts.h"
#include "mozilla/dom/PerformanceEventTimingBinding.h"
namespace mozilla::dom {
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(EventCounts, mParent)
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(EventCounts, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(EventCounts, Release)
EventCounts::EventCounts(nsISupports* aParent) : mParent(aParent) {
ErrorResult rv;
EventCounts_Binding::MaplikeHelpers::Set(
this, NS_ConvertUTF8toUTF16(Event::GetEventName(eMouseAuxClick)), 0, rv);
MOZ_ASSERT(!rv.Failed());
EventCounts_Binding::MaplikeHelpers::Set(
this, NS_ConvertUTF8toUTF16(Event::GetEventName(eMouseClick)), 0, rv);
MOZ_ASSERT(!rv.Failed());
EventCounts_Binding::MaplikeHelpers::Set(
this, NS_ConvertUTF8toUTF16(Event::GetEventName(eContextMenu)), 0, rv);
MOZ_ASSERT(!rv.Failed());
EventCounts_Binding::MaplikeHelpers::Set(
this, NS_ConvertUTF8toUTF16(Event::GetEventName(eMouseDoubleClick)), 0,
rv);
MOZ_ASSERT(!rv.Failed());
EventCounts_Binding::MaplikeHelpers::Set(
this, NS_ConvertUTF8toUTF16(Event::GetEventName(eMouseDown)), 0, rv);
MOZ_ASSERT(!rv.Failed());
EventCounts_Binding::MaplikeHelpers::Set(
this, NS_ConvertUTF8toUTF16(Event::GetEventName(eMouseEnter)), 0, rv);
MOZ_ASSERT(!rv.Failed());
EventCounts_Binding::MaplikeHelpers::Set(
this, NS_ConvertUTF8toUTF16(Event::GetEventName(eMouseLeave)), 0, rv);
MOZ_ASSERT(!rv.Failed());
EventCounts_Binding::MaplikeHelpers::Set(
this, NS_ConvertUTF8toUTF16(Event::GetEventName(eMouseOut)), 0, rv);
MOZ_ASSERT(!rv.Failed());
EventCounts_Binding::MaplikeHelpers::Set(
this, NS_ConvertUTF8toUTF16(Event::GetEventName(eMouseOver)), 0, rv);
MOZ_ASSERT(!rv.Failed());
EventCounts_Binding::MaplikeHelpers::Set(
this, NS_ConvertUTF8toUTF16(Event::GetEventName(eMouseUp)), 0, rv);
MOZ_ASSERT(!rv.Failed());
EventCounts_Binding::MaplikeHelpers::Set(
this, NS_ConvertUTF8toUTF16(Event::GetEventName(ePointerOver)), 0, rv);
MOZ_ASSERT(!rv.Failed());
EventCounts_Binding::MaplikeHelpers::Set(
this, NS_ConvertUTF8toUTF16(Event::GetEventName(ePointerEnter)), 0, rv);
MOZ_ASSERT(!rv.Failed());
EventCounts_Binding::MaplikeHelpers::Set(
this, NS_ConvertUTF8toUTF16(Event::GetEventName(ePointerDown)), 0, rv);
MOZ_ASSERT(!rv.Failed());
EventCounts_Binding::MaplikeHelpers::Set(
this, NS_ConvertUTF8toUTF16(Event::GetEventName(ePointerUp)), 0, rv);
MOZ_ASSERT(!rv.Failed());
EventCounts_Binding::MaplikeHelpers::Set(
this, NS_ConvertUTF8toUTF16(Event::GetEventName(ePointerCancel)), 0, rv);
MOZ_ASSERT(!rv.Failed());
EventCounts_Binding::MaplikeHelpers::Set(
this, NS_ConvertUTF8toUTF16(Event::GetEventName(ePointerOut)), 0, rv);
MOZ_ASSERT(!rv.Failed());
EventCounts_Binding::MaplikeHelpers::Set(
this, NS_ConvertUTF8toUTF16(Event::GetEventName(ePointerLeave)), 0, rv);
MOZ_ASSERT(!rv.Failed());
EventCounts_Binding::MaplikeHelpers::Set(
this, NS_ConvertUTF8toUTF16(Event::GetEventName(ePointerGotCapture)), 0,
rv);
MOZ_ASSERT(!rv.Failed());
EventCounts_Binding::MaplikeHelpers::Set(
this, NS_ConvertUTF8toUTF16(Event::GetEventName(ePointerLostCapture)), 0,
rv);
MOZ_ASSERT(!rv.Failed());
EventCounts_Binding::MaplikeHelpers::Set(
this, NS_ConvertUTF8toUTF16(Event::GetEventName(eTouchStart)), 0, rv);
MOZ_ASSERT(!rv.Failed());
EventCounts_Binding::MaplikeHelpers::Set(
this, NS_ConvertUTF8toUTF16(Event::GetEventName(eTouchEnd)), 0, rv);
MOZ_ASSERT(!rv.Failed());
EventCounts_Binding::MaplikeHelpers::Set(
this, NS_ConvertUTF8toUTF16(Event::GetEventName(eTouchCancel)), 0, rv);
MOZ_ASSERT(!rv.Failed());
EventCounts_Binding::MaplikeHelpers::Set(
this, NS_ConvertUTF8toUTF16(Event::GetEventName(eKeyDown)), 0, rv);
MOZ_ASSERT(!rv.Failed());
EventCounts_Binding::MaplikeHelpers::Set(
this, NS_ConvertUTF8toUTF16(Event::GetEventName(eKeyPress)), 0, rv);
MOZ_ASSERT(!rv.Failed());
EventCounts_Binding::MaplikeHelpers::Set(
this, NS_ConvertUTF8toUTF16(Event::GetEventName(eKeyUp)), 0, rv);
MOZ_ASSERT(!rv.Failed());
EventCounts_Binding::MaplikeHelpers::Set(
this, NS_ConvertUTF8toUTF16(Event::GetEventName(eEditorBeforeInput)), 0,
rv);
MOZ_ASSERT(!rv.Failed());
EventCounts_Binding::MaplikeHelpers::Set(
this, NS_ConvertUTF8toUTF16(Event::GetEventName(eEditorInput)), 0, rv);
MOZ_ASSERT(!rv.Failed());
EventCounts_Binding::MaplikeHelpers::Set(
this, NS_ConvertUTF8toUTF16(Event::GetEventName(eCompositionStart)), 0,
rv);
MOZ_ASSERT(!rv.Failed());
EventCounts_Binding::MaplikeHelpers::Set(
this, NS_ConvertUTF8toUTF16(Event::GetEventName(eCompositionUpdate)), 0,
rv);
MOZ_ASSERT(!rv.Failed());
EventCounts_Binding::MaplikeHelpers::Set(
this, NS_ConvertUTF8toUTF16(Event::GetEventName(eCompositionEnd)), 0, rv);
MOZ_ASSERT(!rv.Failed());
EventCounts_Binding::MaplikeHelpers::Set(
this, NS_ConvertUTF8toUTF16(Event::GetEventName(eDragStart)), 0, rv);
MOZ_ASSERT(!rv.Failed());
EventCounts_Binding::MaplikeHelpers::Set(
this, NS_ConvertUTF8toUTF16(Event::GetEventName(eDragEnd)), 0, rv);
MOZ_ASSERT(!rv.Failed());
EventCounts_Binding::MaplikeHelpers::Set(
this, NS_ConvertUTF8toUTF16(Event::GetEventName(eDragEnter)), 0, rv);
MOZ_ASSERT(!rv.Failed());
EventCounts_Binding::MaplikeHelpers::Set(
this, NS_ConvertUTF8toUTF16(Event::GetEventName(eDragLeave)), 0, rv);
MOZ_ASSERT(!rv.Failed());
EventCounts_Binding::MaplikeHelpers::Set(
this, NS_ConvertUTF8toUTF16(Event::GetEventName(eDragOver)), 0, rv);
MOZ_ASSERT(!rv.Failed());
EventCounts_Binding::MaplikeHelpers::Set(
this, NS_ConvertUTF8toUTF16(Event::GetEventName(eDrop)), 0, rv);
MOZ_ASSERT(!rv.Failed());
}
JSObject* EventCounts::WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) {
return EventCounts_Binding::Wrap(aCx, this, aGivenProto);
}
} // namespace mozilla::dom

Просмотреть файл

@ -0,0 +1,33 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_PerformanceEventCounts_h___
#define mozilla_dom_PerformanceEventCounts_h___
#include "nsCOMPtr.h"
#include "nsWrapperCache.h"
namespace mozilla {
namespace dom {
class EventCounts final : public nsWrapperCache {
public:
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(EventCounts)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(EventCounts)
explicit EventCounts(nsISupports* aParent);
nsISupports* GetParentObject() const { return mParent; }
JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override;
private:
~EventCounts() = default;
nsCOMPtr<nsISupports> mParent;
};
} // namespace dom
} // namespace mozilla
#endif

Просмотреть файл

@ -30,6 +30,7 @@ class PerformanceStorage;
class PerformanceTiming;
class PerformanceEventTiming;
class WorkerPrivate;
class EventCounts;
// Base class for main-thread and worker Performance API
class Performance : public DOMEventTargetHelper {
@ -125,6 +126,8 @@ class Performance : public DOMEventTargetHelper {
virtual void BufferEventTimingEntryIfNeeded(
PerformanceEventTiming* aEntry) = 0;
virtual class EventCounts* EventCounts() = 0;
virtual void QueueNavigationTimingEntry() = 0;
virtual void UpdateNavigationTimingEntry() = 0;

Просмотреть файл

@ -13,6 +13,8 @@
#include "PerformanceEventTiming.h"
#include "mozilla/dom/Document.h"
#include "mozilla/dom/Event.h"
#include "mozilla/dom/EventCounts.h"
#include "mozilla/dom/PerformanceEventTimingBinding.h"
#include "mozilla/dom/PerformanceNavigationTiming.h"
#include "mozilla/dom/PerformanceResourceTiming.h"
#include "mozilla/dom/PerformanceTiming.h"
@ -56,18 +58,20 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(PerformanceMainThread)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(PerformanceMainThread,
Performance)
NS_IMPL_CYCLE_COLLECTION_UNLINK(
mTiming, mNavigation, mDocEntry, mFCPTiming, mEventTimingEntries,
mFirstInputEvent, mPendingPointerDown, mPendingEventTimingEntries)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mTiming, mNavigation, mDocEntry, mFCPTiming,
mEventTimingEntries, mFirstInputEvent,
mPendingPointerDown,
mPendingEventTimingEntries, mEventCounts)
tmp->mMozMemory = nullptr;
mozilla::DropJSObjects(this);
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(PerformanceMainThread,
Performance)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(
mTiming, mNavigation, mDocEntry, mFCPTiming, mEventTimingEntries,
mFirstInputEvent, mPendingPointerDown, mPendingEventTimingEntries)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTiming, mNavigation, mDocEntry, mFCPTiming,
mEventTimingEntries, mFirstInputEvent,
mPendingPointerDown,
mPendingEventTimingEntries, mEventCounts)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(PerformanceMainThread,
@ -91,7 +95,8 @@ PerformanceMainThread::PerformanceMainThread(nsPIDOMWindowInner* aWindow,
: Performance(aWindow, aPrincipal),
mDOMTiming(aDOMTiming),
mChannel(aChannel),
mCrossOriginIsolated(aWindow->AsGlobal()->CrossOriginIsolated()) {
mCrossOriginIsolated(aWindow->AsGlobal()->CrossOriginIsolated()),
mEventCounts(new class EventCounts(GetParentObject())) {
MOZ_ASSERT(aWindow, "Parent window object should be provided");
CreateNavigationTimingEntry();
}
@ -239,6 +244,7 @@ void PerformanceMainThread::DispatchPendingEventTimingEntries() {
mPendingEventTimingEntries.popFirst();
entry->SetDuration(renderingTime - entry->StartTime());
IncEventCount(entry->GetName());
if (entry->Duration() >= kDefaultEventTimingMinDuration) {
QueueEntry(entry);
@ -477,6 +483,8 @@ bool PerformanceMainThread::CrossOriginIsolated() const {
return mCrossOriginIsolated;
}
EventCounts* PerformanceMainThread::EventCounts() { return mEventCounts; }
void PerformanceMainThread::GetEntries(
nsTArray<RefPtr<PerformanceEntry>>& aRetval) {
// We return an empty list when 'privacy.resistFingerprinting' is on.
@ -576,6 +584,16 @@ mozilla::PresShell* PerformanceMainThread::GetPresShell() {
return nullptr;
}
void PerformanceMainThread::IncEventCount(const nsAtom* aType) {
ErrorResult rv;
uint64_t count = EventCounts_Binding::MaplikeHelpers::Get(
mEventCounts, nsDependentAtomString(aType), rv);
MOZ_ASSERT(!rv.Failed());
EventCounts_Binding::MaplikeHelpers::Set(
mEventCounts, nsDependentAtomString(aType), ++count, rv);
MOZ_ASSERT(!rv.Failed());
}
size_t PerformanceMainThread::SizeOfEventEntries(
mozilla::MallocSizeOf aMallocSizeOf) const {
size_t eventEntries = 0;

Просмотреть файл

@ -97,6 +97,8 @@ class PerformanceMainThread final : public Performance,
static constexpr uint32_t kDefaultEventTimingDurationThreshold = 104;
static constexpr double kDefaultEventTimingMinDuration = 16.0;
class EventCounts* EventCounts() override;
protected:
~PerformanceMainThread();
@ -134,6 +136,9 @@ class PerformanceMainThread final : public Performance,
private:
bool mHasQueuedRefreshdriverObserver = false;
RefPtr<class EventCounts> mEventCounts;
void IncEventCount(const nsAtom* aType);
PresShell* GetPresShell();
};

Просмотреть файл

@ -78,6 +78,10 @@ class PerformanceWorker final : public Performance {
MOZ_CRASH("This should not be called on workders.");
}
class EventCounts* EventCounts() override {
MOZ_CRASH("This should not be called on workers");
}
bool CrossOriginIsolated() const override;
protected:

Просмотреть файл

@ -8,6 +8,7 @@ with Files("**"):
BUG_COMPONENT = ("Core", "Performance")
EXPORTS.mozilla.dom += [
"EventCounts.h",
"Performance.h",
"PerformanceEntry.h",
"PerformanceEventTiming.h",
@ -28,6 +29,7 @@ EXPORTS.mozilla.dom += [
]
UNIFIED_SOURCES += [
"EventCounts.cpp",
"Performance.cpp",
"PerformanceEntry.cpp",
"PerformanceEventTiming.cpp",

Просмотреть файл

@ -363,6 +363,8 @@ var interfaceNamesInGlobalScope = [
// IMPORTANT: Do not change this list without review from a DOM peer!
{ name: "Event", insecureContext: true },
// IMPORTANT: Do not change this list without review from a DOM peer!
{ name: "EventCounts", insecureContext: true, nightly: true },
// IMPORTANT: Do not change this list without review from a DOM peer!
{ name: "EventSource", insecureContext: true },
// IMPORTANT: Do not change this list without review from a DOM peer!
{ name: "EventTarget", insecureContext: true },

Просмотреть файл

@ -72,3 +72,10 @@ partial interface Performance {
void measure(DOMString measureName, optional DOMString startMark, optional DOMString endMark);
void clearMeasures(optional DOMString measureName);
};
[Exposed=Window]
partial interface Performance {
[Pref="dom.enable_event_timing", SameObject]
readonly attribute EventCounts eventCounts;
};

Просмотреть файл

@ -10,6 +10,12 @@
* liability, trademark and document use rules apply.
*/
[Pref="dom.enable_event_timing",
Exposed=Window]
interface EventCounts {
readonly maplike<DOMString, unsigned long long>;
};
[Pref="dom.enable_event_timing",
Exposed=Window]
interface PerformanceEventTiming : PerformanceEntry {