Bug 1892041 - Part 1: Update test262 features. r=spidermonkey-reviewers,dminor
[gecko.git] / dom / performance / PerformanceEventTiming.cpp
blob7a893293629caa8ba0c85dca239b2d1688fd676d
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "PerformanceEventTiming.h"
8 #include "PerformanceMainThread.h"
9 #include "mozilla/StaticPrefs_dom.h"
10 #include "mozilla/dom/PerformanceEventTimingBinding.h"
11 #include "mozilla/dom/Document.h"
12 #include "mozilla/dom/Performance.h"
13 #include "mozilla/dom/Event.h"
14 #include "nsContentUtils.h"
15 #include "nsIDocShell.h"
16 #include <algorithm>
18 namespace mozilla::dom {
20 NS_IMPL_CYCLE_COLLECTION_INHERITED(PerformanceEventTiming, PerformanceEntry,
21 mPerformance, mTarget)
23 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(PerformanceEventTiming)
24 NS_INTERFACE_MAP_END_INHERITING(PerformanceEntry)
26 NS_IMPL_ADDREF_INHERITED(PerformanceEventTiming, PerformanceEntry)
27 NS_IMPL_RELEASE_INHERITED(PerformanceEventTiming, PerformanceEntry)
29 PerformanceEventTiming::PerformanceEventTiming(Performance* aPerformance,
30 const nsAString& aName,
31 const TimeStamp& aStartTime,
32 bool aIsCacelable,
33 EventMessage aMessage)
34 : PerformanceEntry(aPerformance->GetParentObject(), aName, u"event"_ns),
35 mPerformance(aPerformance),
36 mProcessingStart(aPerformance->NowUnclamped()),
37 mProcessingEnd(0),
38 mStartTime(
39 aPerformance->GetDOMTiming()->TimeStampToDOMHighRes(aStartTime)),
40 mDuration(0),
41 mCancelable(aIsCacelable),
42 mMessage(aMessage) {}
44 PerformanceEventTiming::PerformanceEventTiming(
45 const PerformanceEventTiming& aEventTimingEntry)
46 : PerformanceEntry(aEventTimingEntry.mPerformance->GetParentObject(),
47 nsDependentAtomString(aEventTimingEntry.GetName()),
48 nsDependentAtomString(aEventTimingEntry.GetEntryType())),
49 mPerformance(aEventTimingEntry.mPerformance),
50 mProcessingStart(aEventTimingEntry.mProcessingStart),
51 mProcessingEnd(aEventTimingEntry.mProcessingEnd),
52 mTarget(aEventTimingEntry.mTarget),
53 mStartTime(aEventTimingEntry.mStartTime),
54 mDuration(aEventTimingEntry.mDuration),
55 mCancelable(aEventTimingEntry.mCancelable),
56 mMessage(aEventTimingEntry.mMessage) {}
58 JSObject* PerformanceEventTiming::WrapObject(
59 JSContext* cx, JS::Handle<JSObject*> aGivenProto) {
60 return PerformanceEventTiming_Binding::Wrap(cx, this, aGivenProto);
63 already_AddRefed<PerformanceEventTiming>
64 PerformanceEventTiming::TryGenerateEventTiming(const EventTarget* aTarget,
65 const WidgetEvent* aEvent) {
66 MOZ_ASSERT(NS_IsMainThread());
67 if (!StaticPrefs::dom_enable_event_timing() ||
68 aEvent->mFlags.mOnlyChromeDispatch) {
69 return nullptr;
72 if (!aEvent->IsTrusted()) {
73 return nullptr;
76 switch (aEvent->mMessage) {
77 case eMouseAuxClick:
78 case eMouseClick:
79 case eContextMenu:
80 case eMouseDoubleClick:
81 case eMouseDown:
82 case eMouseEnter:
83 case eMouseLeave:
84 case eMouseOut:
85 case eMouseOver:
86 case eMouseUp:
87 case ePointerOver:
88 case ePointerEnter:
89 case ePointerDown:
90 case ePointerUp:
91 case ePointerCancel:
92 case ePointerOut:
93 case ePointerLeave:
94 case ePointerGotCapture:
95 case ePointerLostCapture:
96 case eTouchStart:
97 case eTouchEnd:
98 case eTouchCancel:
99 case eKeyDown:
100 case eKeyPress:
101 case eKeyUp:
102 case eEditorBeforeInput:
103 case eEditorInput:
104 case eCompositionStart:
105 case eCompositionUpdate:
106 case eCompositionEnd:
107 case eDragStart:
108 case eDragEnd:
109 case eDragEnter:
110 case eDragLeave:
111 case eDragOver:
112 case eDrop:
113 break;
114 default:
115 return nullptr;
118 nsCOMPtr<nsPIDOMWindowInner> innerWindow =
119 do_QueryInterface(aTarget->GetOwnerGlobal());
120 if (!innerWindow) {
121 return nullptr;
124 if (Performance* performance = innerWindow->GetPerformance()) {
125 const char16_t* eventName = Event::GetEventName(aEvent->mMessage);
126 MOZ_ASSERT(eventName,
127 "User defined events shouldn't be considered as event timing");
128 return RefPtr<PerformanceEventTiming>(
129 new PerformanceEventTiming(
130 performance, nsDependentString(eventName),
131 aEvent->mTimeStamp, aEvent->mFlags.mCancelable,
132 aEvent->mMessage))
133 .forget();
135 return nullptr;
138 bool PerformanceEventTiming::ShouldAddEntryToBuffer(double aDuration) const {
139 if (GetEntryType() == nsGkAtoms::firstInput) {
140 return true;
142 MOZ_ASSERT(GetEntryType() == nsGkAtoms::event);
143 return RawDuration() >= aDuration;
146 bool PerformanceEventTiming::ShouldAddEntryToObserverBuffer(
147 PerformanceObserverInit& aOption) const {
148 if (!PerformanceEntry::ShouldAddEntryToObserverBuffer(aOption)) {
149 return false;
152 const double minDuration =
153 aOption.mDurationThreshold.WasPassed()
154 ? std::max(aOption.mDurationThreshold.Value(),
155 PerformanceMainThread::kDefaultEventTimingMinDuration)
156 : PerformanceMainThread::kDefaultEventTimingDurationThreshold;
158 return ShouldAddEntryToBuffer(minDuration);
161 void PerformanceEventTiming::BufferEntryIfNeeded() {
162 if (ShouldAddEntryToBuffer(
163 PerformanceMainThread::kDefaultEventTimingDurationThreshold)) {
164 if (GetEntryType() != nsGkAtoms::firstInput) {
165 MOZ_ASSERT(GetEntryType() == nsGkAtoms::event);
166 mPerformance->BufferEventTimingEntryIfNeeded(this);
171 nsINode* PerformanceEventTiming::GetTarget() const {
172 nsCOMPtr<Element> element = do_QueryReferent(mTarget);
173 if (!element) {
174 return nullptr;
177 nsCOMPtr<nsPIDOMWindowInner> global =
178 do_QueryInterface(element->GetOwnerGlobal());
179 if (!global) {
180 return nullptr;
182 return nsContentUtils::GetAnElementForTiming(element, global->GetExtantDoc(),
183 mPerformance->GetParentObject());
186 void PerformanceEventTiming::FinalizeEventTiming(EventTarget* aTarget) {
187 if (!aTarget) {
188 return;
190 nsCOMPtr<nsPIDOMWindowInner> global =
191 do_QueryInterface(aTarget->GetOwnerGlobal());
192 if (!global) {
193 return;
196 mProcessingEnd = mPerformance->NowUnclamped();
198 Element* element = Element::FromEventTarget(aTarget);
199 if (!element || element->ChromeOnlyAccess()) {
200 return;
203 mTarget = do_GetWeakReference(element);
205 mPerformance->InsertEventTimingEntry(this);
207 } // namespace mozilla::dom