Bug 1892041 - Part 1: Update test262 features. r=spidermonkey-reviewers,dminor
[gecko.git] / dom / performance / LargestContentfulPaint.h
blob0eceabb1be6348e4e2d89b19952581cf7704dbba
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 #ifndef mozilla_dom_LargestContentfulPaint_h___
8 #define mozilla_dom_LargestContentfulPaint_h___
10 #include "nsCycleCollectionParticipant.h"
11 #include "mozilla/dom/Element.h"
12 #include "mozilla/dom/PerformanceEntry.h"
13 #include "mozilla/dom/PerformanceLargestContentfulPaintBinding.h"
15 #include "imgRequestProxy.h"
17 class nsTextFrame;
18 namespace mozilla::dom {
20 static constexpr nsLiteralString kLargestContentfulPaintName =
21 u"largest-contentful-paint"_ns;
23 class Performance;
24 class PerformanceMainThread;
26 struct LCPImageEntryKey {
27 LCPImageEntryKey(Element* aElement, imgRequestProxy* aImgRequestProxy)
28 : mElement(do_GetWeakReference(aElement)),
29 mImageRequestProxy(aImgRequestProxy) {
30 MOZ_ASSERT(aElement);
31 MOZ_ASSERT(aImgRequestProxy);
33 mHash = mozilla::HashGeneric(reinterpret_cast<uintptr_t>(aElement),
34 reinterpret_cast<uintptr_t>(aImgRequestProxy));
37 LCPImageEntryKey(const LCPImageEntryKey& aLCPImageEntryKey) {
38 mElement = aLCPImageEntryKey.mElement;
39 mImageRequestProxy = aLCPImageEntryKey.mImageRequestProxy;
40 mHash = aLCPImageEntryKey.mHash;
43 Element* GetElement() const {
44 nsCOMPtr<Element> element = do_QueryReferent(mElement);
45 return element;
48 imgRequestProxy* GetImgRequestProxy() const {
49 return static_cast<imgRequestProxy*>(mImageRequestProxy.get());
52 bool operator==(const LCPImageEntryKey& aOther) const {
53 imgRequestProxy* imgRequest = GetImgRequestProxy();
54 if (!imgRequest) {
55 return false;
58 imgRequestProxy* otherImgRequest = aOther.GetImgRequestProxy();
59 if (!otherImgRequest) {
60 return false;
63 Element* element = GetElement();
64 if (!element) {
65 return false;
68 Element* otherElement = aOther.GetElement();
69 if (!otherElement) {
70 return false;
73 return element == otherElement && imgRequest == otherImgRequest;
76 nsWeakPtr mElement;
78 WeakPtr<PreloaderBase> mImageRequestProxy;
80 PLDHashNumber mHash = 0;
82 ~LCPImageEntryKey() = default;
85 struct LCPTextFrameHelper final {
86 static void MaybeUnionTextFrame(nsTextFrame* aTextFrame,
87 const nsRect& aRelativeToSelfRect);
90 class ImagePendingRendering final {
91 public:
92 ImagePendingRendering(const LCPImageEntryKey& aLCPImageEntryKey,
93 const TimeStamp& aLoadTime);
95 Element* GetElement() const { return mLCPImageEntryKey.GetElement(); }
97 imgRequestProxy* GetImgRequestProxy() const {
98 return mLCPImageEntryKey.GetImgRequestProxy();
101 LCPImageEntryKey mLCPImageEntryKey;
102 TimeStamp mLoadTime;
105 class LCPEntryHashEntry : public PLDHashEntryHdr {
106 public:
107 typedef const LCPImageEntryKey& KeyType;
108 typedef const LCPImageEntryKey* KeyTypePointer;
110 explicit LCPEntryHashEntry(KeyTypePointer aKey) : mKey(*aKey) {}
111 LCPEntryHashEntry(LCPEntryHashEntry&&) = default;
113 ~LCPEntryHashEntry() = default;
115 bool KeyEquals(KeyTypePointer aKey) const { return mKey == *aKey; }
117 KeyType GetKey() const { return mKey; }
119 static KeyTypePointer KeyToPointer(KeyType& aKey) { return &aKey; }
121 static PLDHashNumber HashKey(KeyTypePointer aKey) { return aKey->mHash; }
122 enum { ALLOW_MEMMOVE = true };
124 LCPImageEntryKey mKey;
127 class LCPHelpers final {
128 public:
129 // Creates the LCP Entry for images with all information except the size of
130 // the element. The size of the image is unknown at the moment. The entry is
131 // not going to be queued in this function.
132 static void CreateLCPEntryForImage(
133 PerformanceMainThread* aPerformance, Element* aElement,
134 imgRequestProxy* aRequestProxy, const TimeStamp& aLoadTime,
135 const TimeStamp& aRenderTime, const LCPImageEntryKey& aContentIdentifier);
137 // Called when the size of the image is known.
138 static void FinalizeLCPEntryForImage(Element* aContainingBlock,
139 imgRequestProxy* aImgRequestProxy,
140 const nsRect& aTargetRectRelativeToSelf);
142 static void FinalizeLCPEntryForText(PerformanceMainThread* aPerformance,
143 const TimeStamp& aRenderTime,
144 Element* aContainingBlock,
145 const nsRect& aTargetRectRelativeToSelf,
146 const nsPresContext* aPresContext);
148 static bool IsQualifiedImageRequest(imgRequest* aRequest,
149 Element* aContainingElement);
151 private:
152 static bool CanFinalizeLCPEntry(const nsIFrame* aFrame);
155 // https://w3c.github.io/largest-contentful-paint/
156 class LargestContentfulPaint final : public PerformanceEntry {
157 public:
158 NS_DECL_ISUPPORTS_INHERITED
160 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(LargestContentfulPaint,
161 PerformanceEntry)
163 LargestContentfulPaint(PerformanceMainThread* aPerformance,
164 const TimeStamp& aRenderTime,
165 const Maybe<TimeStamp>& aLoadTime,
166 const unsigned long aSize, nsIURI* aURI,
167 Element* aElement,
168 const Maybe<const LCPImageEntryKey>& aLCPImageEntryKey,
169 bool aShouldExposeRenderTime);
171 JSObject* WrapObject(JSContext* aCx,
172 JS::Handle<JSObject*> aGivenProto) override;
174 DOMHighResTimeStamp RenderTime() const;
175 DOMHighResTimeStamp LoadTime() const;
176 DOMHighResTimeStamp StartTime() const override;
178 unsigned long Size() const { return mSize; }
179 void GetId(nsAString& aId) const {
180 if (mId) {
181 mId->ToString(aId);
184 void GetUrl(nsAString& aUrl);
186 Element* GetElement() const;
188 static Element* GetContainingBlockForTextFrame(const nsTextFrame* aTextFrame);
190 void UpdateSize(const Element* aContainingBlock,
191 const nsRect& aTargetRectRelativeToSelf,
192 const PerformanceMainThread* aPerformance, bool aIsImage);
194 void BufferEntryIfNeeded() override;
196 static void MaybeProcessImageForElementTiming(imgRequestProxy* aRequest,
197 Element* aElement);
199 void QueueEntry();
201 Maybe<LCPImageEntryKey>& GetLCPImageEntryKey() { return mLCPImageEntryKey; }
203 private:
204 ~LargestContentfulPaint() = default;
206 void ReportLCPToNavigationTimings();
208 RefPtr<PerformanceMainThread> mPerformance;
210 // This is always set but only exposed to web content if
211 // mShouldExposeRenderTime is true.
212 const TimeStamp mRenderTime;
213 const Maybe<TimeStamp> mLoadTime;
214 // This is set to false when for security reasons web content it not allowed
215 // to see the RenderTime.
216 const bool mShouldExposeRenderTime;
217 unsigned long mSize;
218 nsCOMPtr<nsIURI> mURI;
220 nsWeakPtr mElement;
221 RefPtr<nsAtom> mId;
223 Maybe<LCPImageEntryKey> mLCPImageEntryKey;
225 } // namespace mozilla::dom
226 #endif