diff --git a/dom/performance/Performance.h b/dom/performance/Performance.h index 716e5c6f8e4e..be0c20f37d6d 100644 --- a/dom/performance/Performance.h +++ b/dom/performance/Performance.h @@ -159,7 +159,8 @@ class Performance : public DOMEventTargetHelper { virtual PerformanceInteractionMetrics& GetPerformanceInteractionMetrics() = 0; - virtual Maybe ComputeInteractionId(const WidgetEvent* aEvent) = 0; + virtual void SetInteractionId(PerformanceEventTiming* aEventTiming, + const WidgetEvent* aEvent) = 0; void QueueNotificationObserversTask(); diff --git a/dom/performance/PerformanceEventTiming.cpp b/dom/performance/PerformanceEventTiming.cpp index 355156a1235b..53e637c12d62 100644 --- a/dom/performance/PerformanceEventTiming.cpp +++ b/dom/performance/PerformanceEventTiming.cpp @@ -34,7 +34,6 @@ PerformanceEventTiming::PerformanceEventTiming(Performance* aPerformance, const nsAString& aName, const TimeStamp& aStartTime, bool aIsCacelable, - Maybe 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( - new PerformanceEventTiming( - performance, nsDependentString(eventName), - aEvent->mTimeStamp, aEvent->mFlags.mCancelable, - performance->ComputeInteractionId(aEvent), aEvent->mMessage)) - .forget(); + auto eventTiming = + RefPtr(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 relevantGlobal’s pending pointer - // downs. - auto& pendingPointerDowns = interactionMetrics.PendingPointerDowns(); - - // Step 8.2. Let pointerId be event’s 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 event’s isComposing attribute value is true: - if (keyEvent->mIsComposing) { - // Step 9.1.1. Append timingEntry to relevantGlobal’s entries to be - // queued. - mPerformance->InsertEventTimingEntry(this); - // Step 9.1.2. Return. - return; - } - - auto& interactionMetrics = mPerformance->GetPerformanceInteractionMetrics(); - - // Step 9.2. Let pendingKeyDowns be relevantGlobal’s pending key downs. - auto& pendingKeyDowns = interactionMetrics.PendingKeyDowns(); - // Step 9.3. Let code be event’s 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 window’s user interaction value value by a - // small number chosen by the user agent. - uint64_t interactionId = - interactionMetrics.IncreaseInteractionValueAndCount(); - // Step 9.4.2.2. Set entry’s interactionId to window’s user interaction - // value. - SetInteractionId(interactionId); - } - } - - // Step 9.5. Set pendingKeyDowns[code] to timingEntry. - pendingKeyDowns.InsertOrUpdate(code, this); - } - mPerformance->InsertEventTimingEntry(this); } } // namespace mozilla::dom diff --git a/dom/performance/PerformanceEventTiming.h b/dom/performance/PerformanceEventTiming.h index 8c4295fe6490..8f93809259e4 100644 --- a/dom/performance/PerformanceEventTiming.h +++ b/dom/performance/PerformanceEventTiming.h @@ -62,6 +62,10 @@ class PerformanceEventTiming final uint64_t InteractionId() const { return mInteractionId.valueOr(0); } bool HasKnownInteractionId() const { return mInteractionId.isSome(); } + void SetInteractionId(Maybe 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 aInteractionId, EventMessage aMessage); + EventMessage aMessage); PerformanceEventTiming(const PerformanceEventTiming& aEventTimingEntry); diff --git a/dom/performance/PerformanceInteractionMetrics.cpp b/dom/performance/PerformanceInteractionMetrics.cpp index 7597c62daf5c..e82605d63ae0 100644 --- a/dom/performance/PerformanceInteractionMetrics.cpp +++ b/dom/performance/PerformanceInteractionMetrics.cpp @@ -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 PerformanceInteractionMetrics::ComputeInteractionId( + PerformanceEventTiming* aEventTiming, const WidgetEvent* aEvent) { // Step 1. If event’s isTrusted attribute value is false, return 0. if (!aEvent->IsTrusted()) { - return 0; + return Some(0); } // Step 2. Let type be event’s 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 event’s 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 event’s 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 event’s 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 diff --git a/dom/performance/PerformanceInteractionMetrics.h b/dom/performance/PerformanceInteractionMetrics.h index 290bcceb5998..4caebccb3c9f 100644 --- a/dom/performance/PerformanceInteractionMetrics.h +++ b/dom/performance/PerformanceInteractionMetrics.h @@ -21,7 +21,8 @@ class PerformanceInteractionMetrics final { PerformanceInteractionMetrics& operator=( const PerformanceInteractionMetrics& aCopy) = delete; - uint64_t ComputeInteractionId(const WidgetEvent* aEvent); + Maybe ComputeInteractionId(PerformanceEventTiming* aEventTiming, + const WidgetEvent* aEvent); nsTHashMap>& PendingKeyDowns() { return mPendingKeyDowns; diff --git a/dom/performance/PerformanceMainThread.cpp b/dom/performance/PerformanceMainThread.cpp index 3bc95d747a18..411ea803ee8f 100644 --- a/dom/performance/PerformanceMainThread.cpp +++ b/dom/performance/PerformanceMainThread.cpp @@ -369,19 +369,17 @@ PerformanceMainThread::GetPerformanceInteractionMetrics() { return mInteractionMetrics; } -Maybe 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( diff --git a/dom/performance/PerformanceMainThread.h b/dom/performance/PerformanceMainThread.h index 781ad7842b99..006a32a87215 100644 --- a/dom/performance/PerformanceMainThread.h +++ b/dom/performance/PerformanceMainThread.h @@ -58,7 +58,8 @@ class PerformanceMainThread final : public Performance, PerformanceInteractionMetrics& GetPerformanceInteractionMetrics() override; - Maybe ComputeInteractionId(const WidgetEvent* aEvent) override; + void SetInteractionId(PerformanceEventTiming* aEventTiming, + const WidgetEvent* aEvent) override; void BufferLargestContentfulPaintEntryIfNeeded(LargestContentfulPaint*); diff --git a/dom/performance/PerformanceWorker.h b/dom/performance/PerformanceWorker.h index d0c9c5393610..aedb30deb227 100644 --- a/dom/performance/PerformanceWorker.h +++ b/dom/performance/PerformanceWorker.h @@ -82,7 +82,8 @@ class PerformanceWorker final : public Performance { MOZ_CRASH("This should not be called on workers."); } - Maybe ComputeInteractionId(const WidgetEvent* aEvent) override { + void SetInteractionId(PerformanceEventTiming* aEventTiming, + const WidgetEvent* aEvent) override { MOZ_CRASH("This should not be called on workers."); }