Bug 1852740: add tests for the `fetchpriority` attribute in Link headers. r=necko...
[gecko.git] / dom / base / LinkStyle.h
blob9f009643b9ad5d590deb94d3e29d5a13d56e222a
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/. */
6 #ifndef mozilla_dom_LinkStyle_h
7 #define mozilla_dom_LinkStyle_h
9 #include "nsINode.h"
10 #include "mozilla/Attributes.h"
11 #include "mozilla/StyleSheet.h"
12 #include "mozilla/Result.h"
13 #include "mozilla/Unused.h"
14 #include "nsTArray.h"
16 class nsIContent;
17 class nsICSSLoaderObserver;
18 class nsIPrincipal;
19 class nsIURI;
21 namespace mozilla::dom {
23 class Document;
24 class ShadowRoot;
26 // https://drafts.csswg.org/cssom/#the-linkstyle-interface
27 class LinkStyle {
28 public:
29 enum class ForceUpdate : uint8_t {
30 No,
31 Yes,
34 enum class Completed : uint8_t {
35 No,
36 Yes,
39 enum class HasAlternateRel : uint8_t {
40 No,
41 Yes,
44 enum class IsAlternate : uint8_t {
45 No,
46 Yes,
49 enum class IsInline : uint8_t {
50 No,
51 Yes,
54 enum class IsExplicitlyEnabled : uint8_t {
55 No,
56 Yes,
59 enum class MediaMatched : uint8_t {
60 Yes,
61 No,
64 struct Update {
65 private:
66 bool mWillNotify;
67 bool mIsAlternate;
68 bool mMediaMatched;
70 public:
71 Update() : mWillNotify(false), mIsAlternate(false), mMediaMatched(false) {}
73 Update(Completed aCompleted, IsAlternate aIsAlternate,
74 MediaMatched aMediaMatched)
75 : mWillNotify(aCompleted == Completed::No),
76 mIsAlternate(aIsAlternate == IsAlternate::Yes),
77 mMediaMatched(aMediaMatched == MediaMatched::Yes) {}
79 bool WillNotify() const { return mWillNotify; }
81 bool ShouldBlock() const {
82 if (!mWillNotify) {
83 return false;
86 return !mIsAlternate && mMediaMatched;
90 static LinkStyle* FromNode(nsINode& aNode) { return aNode.AsLinkStyle(); }
91 static const LinkStyle* FromNode(const nsINode& aNode) {
92 return aNode.AsLinkStyle();
95 static LinkStyle* FromNode(Element&);
96 static const LinkStyle* FromNode(const Element& aElement) {
97 return FromNode(const_cast<Element&>(aElement));
100 template <typename T>
101 static LinkStyle* FromNodeOrNull(T* aNode) {
102 return aNode ? FromNode(*aNode) : nullptr;
105 template <typename T>
106 static const LinkStyle* FromNodeOrNull(const T* aNode) {
107 return aNode ? FromNode(*aNode) : nullptr;
110 enum RelValue {
111 ePREFETCH = 0x00000001,
112 eDNS_PREFETCH = 0x00000002,
113 eSTYLESHEET = 0x00000004,
114 eNEXT = 0x00000008,
115 eALTERNATE = 0x00000010,
116 ePRECONNECT = 0x00000020,
117 // NOTE: 0x40 is unused
118 ePRELOAD = 0x00000080,
119 eMODULE_PRELOAD = 0x00000100
122 // The return value is a bitwise or of 0 or more RelValues.
123 static uint32_t ParseLinkTypes(const nsAString& aTypes);
125 void UpdateStyleSheetInternal() {
126 Unused << UpdateStyleSheetInternal(nullptr, nullptr);
129 struct MOZ_STACK_CLASS SheetInfo {
130 nsIContent* mContent;
131 // FIXME(emilio): do these really need to be strong refs?
132 nsCOMPtr<nsIURI> mURI;
134 // The principal of the scripted caller that initiated the load, if
135 // available. Otherwise null.
136 nsCOMPtr<nsIPrincipal> mTriggeringPrincipal;
137 nsCOMPtr<nsIReferrerInfo> mReferrerInfo;
138 mozilla::CORSMode mCORSMode;
139 nsString mTitle;
140 nsString mMedia;
141 nsString mIntegrity;
142 nsString mNonce;
144 bool mHasAlternateRel;
145 bool mIsInline;
146 IsExplicitlyEnabled mIsExplicitlyEnabled;
148 SheetInfo(const mozilla::dom::Document&, nsIContent*,
149 already_AddRefed<nsIURI> aURI,
150 already_AddRefed<nsIPrincipal> aTriggeringPrincipal,
151 already_AddRefed<nsIReferrerInfo> aReferrerInfo,
152 mozilla::CORSMode, const nsAString& aTitle,
153 const nsAString& aMedia, const nsAString& aIntegrity,
154 const nsAString& aNonce, HasAlternateRel, IsInline,
155 IsExplicitlyEnabled);
157 ~SheetInfo();
160 virtual nsIContent& AsContent() = 0;
161 virtual Maybe<SheetInfo> GetStyleSheetInfo() = 0;
164 * Used to make the association between a style sheet and
165 * the element that linked it to the document.
167 * @param aStyleSheet the style sheet associated with this
168 * element.
170 void SetStyleSheet(StyleSheet* aStyleSheet);
173 * Tells this element whether to update the stylesheet when the element's
174 * properties change. This is used by the parser until it has all content etc,
175 * and to guarantee that the right observer is used.
177 void DisableUpdates() { mUpdatesEnabled = false; }
178 Result<Update, nsresult> EnableUpdatesAndUpdateStyleSheet(
179 nsICSSLoaderObserver* aObserver) {
180 MOZ_ASSERT(!mUpdatesEnabled);
181 mUpdatesEnabled = true;
182 return DoUpdateStyleSheet(nullptr, nullptr, aObserver, ForceUpdate::No);
186 * Gets the charset that the element claims the style sheet is in.
187 * Can return empty string to indicate that we have no charset
188 * information.
190 * @param aCharset the charset
192 virtual void GetCharset(nsAString& aCharset);
194 // This doesn't entirely belong here since they only make sense for
195 // some types of linking elements, but it's a better place than
196 // anywhere else.
197 void SetLineNumber(uint32_t aLineNumber) { mLineNumber = aLineNumber; }
200 * Get the line number, as previously set by SetLineNumber.
202 * @return the line number of this element; or 1 if no line number
203 * was set
205 uint32_t GetLineNumber() const { return mLineNumber; }
207 // This doesn't entirely belong here since they only make sense for
208 // some types of linking elements, but it's a better place than
209 // anywhere else.
210 void SetColumnNumber(uint32_t aColumnNumber) {
211 mColumnNumber = aColumnNumber;
215 * Get the column number, as previously set by SetColumnNumber.
217 * @return the column number of this element; or 1 if no column number
218 * was set
220 uint32_t GetColumnNumber() const { return mColumnNumber; }
222 StyleSheet* GetSheet() const { return mStyleSheet; }
224 /** JS can only observe the sheet once fully loaded */
225 StyleSheet* GetSheetForBindings() const;
227 protected:
228 LinkStyle();
229 virtual ~LinkStyle();
231 // Gets a suitable title and media for SheetInfo out of an element, which
232 // needs to be `this`.
234 // NOTE(emilio): Needs nsString instead of nsAString because of
235 // CompressWhitespace.
236 static void GetTitleAndMediaForElement(const mozilla::dom::Element&,
237 nsString& aTitle, nsString& aMedia);
239 // Returns whether the type attribute specifies the text/css type for style
240 // elements.
241 static bool IsCSSMimeTypeAttributeForStyleElement(const Element&);
243 // CC methods
244 void Unlink();
245 void Traverse(nsCycleCollectionTraversalCallback& cb);
248 * @param aOldDocument should be non-null only if we're updating because we
249 * removed the node from the document.
250 * @param aOldShadowRoot should be non-null only if we're updating because we
251 * removed the node from a shadow tree.
252 * @param aForceUpdate true will force the update even if the URI has not
253 * changed. This should be used in cases when something
254 * about the content that affects the resulting sheet
255 * changed but the URI may not have changed.
257 * TODO(emilio): Should probably pass a single DocumentOrShadowRoot.
259 Result<Update, nsresult> UpdateStyleSheetInternal(
260 Document* aOldDocument, ShadowRoot* aOldShadowRoot,
261 ForceUpdate = ForceUpdate::No);
264 * @param aOldDocument should be non-null only if we're updating because we
265 * removed the node from the document.
266 * @param aOldShadowRoot The ShadowRoot that used to contain the style.
267 * Passed as a parameter because on an update, the node
268 * is removed from the tree before the sheet is removed
269 * from the ShadowRoot.
270 * @param aForceUpdate true will force the update even if the URI has not
271 * changed. This should be used in cases when something
272 * about the content that affects the resulting sheet
273 * changed but the URI may not have changed.
275 Result<Update, nsresult> DoUpdateStyleSheet(Document* aOldDocument,
276 ShadowRoot* aOldShadowRoot,
277 nsICSSLoaderObserver*,
278 ForceUpdate);
280 void BindToTree();
282 RefPtr<mozilla::StyleSheet> mStyleSheet;
283 nsCOMPtr<nsIPrincipal> mTriggeringPrincipal;
284 bool mUpdatesEnabled = true;
285 uint32_t mLineNumber = 1;
286 uint32_t mColumnNumber = 1;
289 } // namespace mozilla::dom
291 #endif // mozilla_dom_LinkStyle_h