Bug 1964426 - Move pending keydown and pointerdown logic from finalize step to ComputeInteractionId step r=sefeng

This patch doesn't change the behavior of the keydown and pointerdown logic.
But it's needed for the next patch which I will change the keydown behavior and
make it non-lazy.

Differential Revision: https://phabricator.services.mozilla.com/D247839
This commit is contained in:
Nazım Can Altınova
2025-05-06 18:45:01 +00:00
committed by canaltinova@gmail.com
parent a2cd2fae5d
commit 2abdbf6fd2
8 changed files with 76 additions and 93 deletions

View File

@@ -159,7 +159,8 @@ class Performance : public DOMEventTargetHelper {
virtual PerformanceInteractionMetrics& GetPerformanceInteractionMetrics() = 0;
virtual Maybe<uint64_t> ComputeInteractionId(const WidgetEvent* aEvent) = 0;
virtual void SetInteractionId(PerformanceEventTiming* aEventTiming,
const WidgetEvent* aEvent) = 0;
void QueueNotificationObserversTask();

View File

@@ -34,7 +34,6 @@ PerformanceEventTiming::PerformanceEventTiming(Performance* aPerformance,
const nsAString& aName,
const TimeStamp& aStartTime,
bool aIsCacelable,
Maybe<uint64_t> aInteractionId,
EventMessage aMessage)
: PerformanceEntry(aPerformance->GetParentObject(), aName, u"event"_ns),
mPerformance(aPerformance),
@@ -44,7 +43,6 @@ PerformanceEventTiming::PerformanceEventTiming(Performance* aPerformance,
aPerformance->GetDOMTiming()->TimeStampToDOMHighRes(aStartTime)),
mDuration(0),
mCancelable(aIsCacelable),
mInteractionId(aInteractionId),
mMessage(aMessage) {}
PerformanceEventTiming::PerformanceEventTiming(
@@ -132,12 +130,12 @@ PerformanceEventTiming::TryGenerateEventTiming(const EventTarget* aTarget,
const char16_t* eventName = Event::GetEventName(aEvent->mMessage);
MOZ_ASSERT(eventName,
"User defined events shouldn't be considered as event timing");
return RefPtr<PerformanceEventTiming>(
new PerformanceEventTiming(
performance, nsDependentString(eventName),
aEvent->mTimeStamp, aEvent->mFlags.mCancelable,
performance->ComputeInteractionId(aEvent), aEvent->mMessage))
.forget();
auto eventTiming =
RefPtr<PerformanceEventTiming>(new PerformanceEventTiming(
performance, nsDependentString(eventName), aEvent->mTimeStamp,
aEvent->mFlags.mCancelable, aEvent->mMessage));
performance->SetInteractionId(eventTiming, aEvent);
return eventTiming.forget();
}
return nullptr;
}
@@ -211,61 +209,6 @@ void PerformanceEventTiming::FinalizeEventTiming(const WidgetEvent* aEvent) {
mTarget = do_GetWeakReference(element);
if (!StaticPrefs::dom_performance_event_timing_enable_interactionid()) {
mPerformance->InsertEventTimingEntry(this);
return;
}
if (aEvent->mMessage == ePointerDown) {
auto& interactionMetrics = mPerformance->GetPerformanceInteractionMetrics();
// Step 8.1. Let pendingPointerDowns be relevantGlobals pending pointer
// downs.
auto& pendingPointerDowns = interactionMetrics.PendingPointerDowns();
// Step 8.2. Let pointerId be events pointerId.
uint32_t pointerId = aEvent->AsPointerEvent()->pointerId;
// Step 8.4. Set pendingPointerDowns[pointerId] to timingEntry.
pendingPointerDowns.InsertOrUpdate(pointerId, this);
} else if (aEvent->mMessage == eKeyDown) {
const WidgetKeyboardEvent* keyEvent = aEvent->AsKeyboardEvent();
// Step 9.1. If events isComposing attribute value is true:
if (keyEvent->mIsComposing) {
// Step 9.1.1. Append timingEntry to relevantGlobals entries to be
// queued.
mPerformance->InsertEventTimingEntry(this);
// Step 9.1.2. Return.
return;
}
auto& interactionMetrics = mPerformance->GetPerformanceInteractionMetrics();
// Step 9.2. Let pendingKeyDowns be relevantGlobals pending key downs.
auto& pendingKeyDowns = interactionMetrics.PendingKeyDowns();
// Step 9.3. Let code be events keyCode attribute value.
auto code = keyEvent->mKeyCode;
// Step 9.4.1 Let entry be pendingKeyDowns[code].
auto entry = pendingKeyDowns.MaybeGet(code);
// Step 9.4. If pendingKeyDowns[code] exists:
if (entry) {
// Step 9.4.2. If code is not 229:
if (code != 229) {
// Step 9.4.2.1. Increase windows user interaction value value by a
// small number chosen by the user agent.
uint64_t interactionId =
interactionMetrics.IncreaseInteractionValueAndCount();
// Step 9.4.2.2. Set entrys interactionId to windows user interaction
// value.
SetInteractionId(interactionId);
}
}
// Step 9.5. Set pendingKeyDowns[code] to timingEntry.
pendingKeyDowns.InsertOrUpdate(code, this);
}
mPerformance->InsertEventTimingEntry(this);
}
} // namespace mozilla::dom

View File

@@ -62,6 +62,10 @@ class PerformanceEventTiming final
uint64_t InteractionId() const { return mInteractionId.valueOr(0); }
bool HasKnownInteractionId() const { return mInteractionId.isSome(); }
void SetInteractionId(Maybe<uint64_t> aInteractionId) {
mInteractionId = aInteractionId;
}
void SetInteractionId(uint64_t aInteractionId) {
mInteractionId = Some(aInteractionId);
}
@@ -111,7 +115,7 @@ class PerformanceEventTiming final
private:
PerformanceEventTiming(Performance* aPerformance, const nsAString& aName,
const TimeStamp& aStartTime, bool aIsCacelable,
Maybe<uint64_t> aInteractionId, EventMessage aMessage);
EventMessage aMessage);
PerformanceEventTiming(const PerformanceEventTiming& aEventTimingEntry);

View File

@@ -5,6 +5,8 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "PerformanceInteractionMetrics.h"
#include "mozilla/EventForwards.h"
#include "mozilla/Maybe.h"
#include "mozilla/MouseEvents.h"
#include "mozilla/RandomNum.h"
#include "mozilla/TextEvents.h"
@@ -41,11 +43,11 @@ uint64_t PerformanceInteractionMetrics::IncreaseInteractionValueAndCount() {
}
// https://w3c.github.io/event-timing/#sec-computing-interactionid
uint64_t PerformanceInteractionMetrics::ComputeInteractionId(
const WidgetEvent* aEvent) {
Maybe<uint64_t> PerformanceInteractionMetrics::ComputeInteractionId(
PerformanceEventTiming* aEventTiming, const WidgetEvent* aEvent) {
// Step 1. If events isTrusted attribute value is false, return 0.
if (!aEvent->IsTrusted()) {
return 0;
return Some(0);
}
// Step 2. Let type be events type attribute value.
@@ -55,25 +57,57 @@ uint64_t PerformanceInteractionMetrics::ComputeInteractionId(
// pointercancel, pointerup, or click, return 0.
// Note: keydown and pointerdown are handled in finalize event timing.
switch (eventType) {
case eKeyDown:
case eKeyUp:
case eCompositionStart:
case eEditorInput:
case ePointerCancel:
case ePointerDown:
case ePointerUp:
case ePointerClick:
break;
default:
return 0;
return Some(0);
}
// Step 4-8. Happens in the class constructor.
if (eventType == ePointerDown) {
uint32_t pointerId = aEvent->AsPointerEvent()->pointerId;
mPendingPointerDowns.InsertOrUpdate(pointerId, aEventTiming);
// InteractionId for this will be assigned by pointerup or pointercancel
// later.
return Nothing();
}
if (eventType == eKeyDown) {
const WidgetKeyboardEvent* keyEvent = aEvent->AsKeyboardEvent();
if (keyEvent->mIsComposing) {
return Some(0);
}
auto code = keyEvent->mKeyCode;
auto entry = mPendingKeyDowns.MaybeGet(code);
if (entry) {
if (code != 229) {
uint64_t interactionId = IncreaseInteractionValueAndCount();
(*entry)->SetInteractionId(interactionId);
}
}
mPendingKeyDowns.InsertOrUpdate(code, aEventTiming);
return Nothing();
}
// Step 8. If type is keyup:
if (eventType == eKeyUp) {
// Step 8.1. If events isComposing attribute value is true, return 0.
const WidgetKeyboardEvent* keyEvent = aEvent->AsKeyboardEvent();
if (keyEvent->mIsComposing) {
return 0;
return Some(0);
}
// Step 8.2. Let code be events keyCode attribute value.
@@ -83,7 +117,7 @@ uint64_t PerformanceInteractionMetrics::ComputeInteractionId(
auto entry = mPendingKeyDowns.MaybeGet(code);
// Step 8.3. If pendingKeyDowns[code] does not exist, return 0.
if (!entry) {
return 0;
return Some(0);
}
// Step 8.5. Increase interaction count on window.
@@ -98,7 +132,7 @@ uint64_t PerformanceInteractionMetrics::ComputeInteractionId(
mLastKeydownInteractionValue = Some(interactionId);
// Step 8.10. Return interactionId.
return interactionId;
return Some(interactionId);
}
// Step 9. If type is compositionstart:
@@ -113,7 +147,7 @@ uint64_t PerformanceInteractionMetrics::ComputeInteractionId(
// Step 9.2. Clear pendingKeyDowns.
mPendingKeyDowns.Clear();
// Step 9.3. Return 0
return 0;
return Some(0);
}
// Step 10. If type is input:
@@ -121,16 +155,16 @@ uint64_t PerformanceInteractionMetrics::ComputeInteractionId(
// Step 10.1. If event is not an instance of InputEvent, return 0.
const auto* inputEvent = aEvent->AsEditorInputEvent();
if (!inputEvent) {
return 0;
return Some(0);
}
// Step 10.2. If events isComposing attribute value is false, return 0.
if (!inputEvent->mIsComposing) {
return 0;
return Some(0);
}
mLastKeydownInteractionValue = Nothing();
return IncreaseInteractionValueAndCount();
return Some(IncreaseInteractionValueAndCount());
}
// Step 11. Otherwise (type is pointercancel, pointerup, or click):
@@ -148,20 +182,20 @@ uint64_t PerformanceInteractionMetrics::ComputeInteractionId(
// -1 pointerId is a reserved value to indicate events that were generated
// by something other than a pointer device, like keydown.
// Return the interaction value of the keydown event instead.
return mLastKeydownInteractionValue.valueOr(0);
return Some(mLastKeydownInteractionValue.valueOr(0));
}
// Step 11.2.2. Let value be pointerMap[pointerId].
auto value = mPointerInteractionValueMap.MaybeGet(pointerId);
// Step 11.2.1. If pointerMap[pointerId] does not exist, return 0.
if (!value) {
return 0;
return Some(0);
}
// Step 11.2.3. Remove pointerMap[pointerId].
mPointerInteractionValueMap.Remove(pointerId);
// Step 11.2.4. Return value.
return *value;
return Some(*value);
}
// Step 11.3. Assert that type is pointerup or pointercancel.
@@ -171,7 +205,7 @@ uint64_t PerformanceInteractionMetrics::ComputeInteractionId(
auto entry = mPendingPointerDowns.MaybeGet(pointerId);
// Step 11.4. If pendingPointerDowns[pointerId] does not exist, return 0.
if (!entry) {
return 0;
return Some(0);
}
// Step 11.7. If type is pointerup:
@@ -195,10 +229,10 @@ uint64_t PerformanceInteractionMetrics::ComputeInteractionId(
// Step 11.10. If type is pointercancel, return 0.
if (eventType == ePointerCancel) {
return 0;
return Some(0);
}
return mPointerInteractionValueMap.Get(pointerId);
return Some(mPointerInteractionValueMap.Get(pointerId));
}
} // namespace mozilla::dom

View File

@@ -21,7 +21,8 @@ class PerformanceInteractionMetrics final {
PerformanceInteractionMetrics& operator=(
const PerformanceInteractionMetrics& aCopy) = delete;
uint64_t ComputeInteractionId(const WidgetEvent* aEvent);
Maybe<uint64_t> ComputeInteractionId(PerformanceEventTiming* aEventTiming,
const WidgetEvent* aEvent);
nsTHashMap<uint32_t, RefPtr<PerformanceEventTiming>>& PendingKeyDowns() {
return mPendingKeyDowns;

View File

@@ -369,19 +369,17 @@ PerformanceMainThread::GetPerformanceInteractionMetrics() {
return mInteractionMetrics;
}
Maybe<uint64_t> PerformanceMainThread::ComputeInteractionId(
const WidgetEvent* aEvent) {
void PerformanceMainThread::SetInteractionId(
PerformanceEventTiming* aEventTiming, const WidgetEvent* aEvent) {
MOZ_ASSERT(NS_IsMainThread());
if (!StaticPrefs::dom_performance_event_timing_enable_interactionid() ||
aEvent->mFlags.mOnlyChromeDispatch || !aEvent->IsTrusted()) {
return Some(0);
aEventTiming->SetInteractionId(0);
return;
}
if (aEvent->mMessage == ePointerDown || aEvent->mMessage == eKeyDown) {
return Nothing();
}
return Some(mInteractionMetrics.ComputeInteractionId(aEvent));
aEventTiming->SetInteractionId(
mInteractionMetrics.ComputeInteractionId(aEventTiming, aEvent));
}
DOMHighResTimeStamp PerformanceMainThread::GetPerformanceTimingFromString(

View File

@@ -58,7 +58,8 @@ class PerformanceMainThread final : public Performance,
PerformanceInteractionMetrics& GetPerformanceInteractionMetrics() override;
Maybe<uint64_t> ComputeInteractionId(const WidgetEvent* aEvent) override;
void SetInteractionId(PerformanceEventTiming* aEventTiming,
const WidgetEvent* aEvent) override;
void BufferLargestContentfulPaintEntryIfNeeded(LargestContentfulPaint*);

View File

@@ -82,7 +82,8 @@ class PerformanceWorker final : public Performance {
MOZ_CRASH("This should not be called on workers.");
}
Maybe<uint64_t> ComputeInteractionId(const WidgetEvent* aEvent) override {
void SetInteractionId(PerformanceEventTiming* aEventTiming,
const WidgetEvent* aEvent) override {
MOZ_CRASH("This should not be called on workers.");
}