no bug - Bumping Firefox l10n changesets r=release a=l10n-bump DONTBUILD CLOSED TREE
[gecko.git] / dom / base / LinkStyle.h
blobd62ab8f4e1fdf01e913d37f2a4c6532d6ab79ee7
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 enum class FetchPriority : uint8_t;
25 class ShadowRoot;
27 // https://drafts.csswg.org/cssom/#the-linkstyle-interface
28 class LinkStyle {
29 public:
30 enum class ForceUpdate : uint8_t {
31 No,
32 Yes,
35 enum class Completed : uint8_t {
36 No,
37 Yes,
40 enum class HasAlternateRel : uint8_t {
41 No,
42 Yes,
45 enum class IsAlternate : uint8_t {
46 No,
47 Yes,
50 enum class IsInline : uint8_t {
51 No,
52 Yes,
55 enum class IsExplicitlyEnabled : uint8_t {
56 No,
57 Yes,
60 enum class MediaMatched : uint8_t {
61 Yes,
62 No,
65 struct Update {
66 private:
67 bool mWillNotify;
68 bool mIsAlternate;
69 bool mMediaMatched;
71 public:
72 Update() : mWillNotify(false), mIsAlternate(false), mMediaMatched(false) {}
74 Update(Completed aCompleted, IsAlternate aIsAlternate,
75 MediaMatched aMediaMatched)
76 : mWillNotify(aCompleted == Completed::No),
77 mIsAlternate(aIsAlternate == IsAlternate::Yes),
78 mMediaMatched(aMediaMatched == MediaMatched::Yes) {}
80 bool WillNotify() const { return mWillNotify; }
82 bool ShouldBlock() const {
83 if (!mWillNotify) {
84 return false;
87 return !mIsAlternate && mMediaMatched;
91 static LinkStyle* FromNode(nsINode& aNode) { return aNode.AsLinkStyle(); }
92 static const LinkStyle* FromNode(const nsINode& aNode) {
93 return aNode.AsLinkStyle();
96 static LinkStyle* FromNode(Element&);
97 static const LinkStyle* FromNode(const Element& aElement) {
98 return FromNode(const_cast<Element&>(aElement));
101 template <typename T>
102 static LinkStyle* FromNodeOrNull(T* aNode) {
103 return aNode ? FromNode(*aNode) : nullptr;
106 template <typename T>
107 static const LinkStyle* FromNodeOrNull(const T* aNode) {
108 return aNode ? FromNode(*aNode) : nullptr;
111 enum RelValue {
112 ePREFETCH = 0x00000001,
113 eDNS_PREFETCH = 0x00000002,
114 eSTYLESHEET = 0x00000004,
115 eNEXT = 0x00000008,
116 eALTERNATE = 0x00000010,
117 ePRECONNECT = 0x00000020,
118 // NOTE: 0x40 is unused
119 ePRELOAD = 0x00000080,
120 eMODULE_PRELOAD = 0x00000100
123 // The return value is a bitwise or of 0 or more RelValues.
124 static uint32_t ParseLinkTypes(const nsAString& aTypes);
126 void UpdateStyleSheetInternal() {
127 Unused << UpdateStyleSheetInternal(nullptr, nullptr);
130 struct MOZ_STACK_CLASS SheetInfo {
131 nsIContent* mContent;
132 // FIXME(emilio): do these really need to be strong refs?
133 nsCOMPtr<nsIURI> mURI;
135 // The principal of the scripted caller that initiated the load, if
136 // available. Otherwise null.
137 nsCOMPtr<nsIPrincipal> mTriggeringPrincipal;
138 nsCOMPtr<nsIReferrerInfo> mReferrerInfo;
139 mozilla::CORSMode mCORSMode;
140 nsString mTitle;
141 nsString mMedia;
142 nsString mIntegrity;
143 nsString mNonce;
144 const FetchPriority mFetchPriority;
146 bool mHasAlternateRel;
147 bool mIsInline;
148 IsExplicitlyEnabled mIsExplicitlyEnabled;
150 SheetInfo(const mozilla::dom::Document&, nsIContent*,
151 already_AddRefed<nsIURI> aURI,
152 already_AddRefed<nsIPrincipal> aTriggeringPrincipal,
153 already_AddRefed<nsIReferrerInfo> aReferrerInfo,
154 mozilla::CORSMode, const nsAString& aTitle,
155 const nsAString& aMedia, const nsAString& aIntegrity,
156 const nsAString& aNonce, HasAlternateRel, IsInline,
157 IsExplicitlyEnabled, FetchPriority aFetchPriority);
159 ~SheetInfo();
162 virtual nsIContent& AsContent() = 0;
163 virtual Maybe<SheetInfo> GetStyleSheetInfo() = 0;
166 * Used to make the association between a style sheet and
167 * the element that linked it to the document.
169 * @param aStyleSheet the style sheet associated with this
170 * element.
172 void SetStyleSheet(StyleSheet* aStyleSheet);
175 * Tells this element whether to update the stylesheet when the element's
176 * properties change. This is used by the parser until it has all content etc,
177 * and to guarantee that the right observer is used.
179 void DisableUpdates() { mUpdatesEnabled = false; }
180 Result<Update, nsresult> EnableUpdatesAndUpdateStyleSheet(
181 nsICSSLoaderObserver* aObserver) {
182 MOZ_ASSERT(!mUpdatesEnabled);
183 mUpdatesEnabled = true;
184 return DoUpdateStyleSheet(nullptr, nullptr, aObserver, ForceUpdate::No);
188 * Gets the charset that the element claims the style sheet is in.
189 * Can return empty string to indicate that we have no charset
190 * information.
192 * @param aCharset the charset
194 virtual void GetCharset(nsAString& aCharset);
196 // This doesn't entirely belong here since they only make sense for
197 // some types of linking elements, but it's a better place than
198 // anywhere else.
199 void SetLineNumber(uint32_t aLineNumber) { mLineNumber = aLineNumber; }
202 * Get the line number, as previously set by SetLineNumber.
204 * @return the line number of this element; or 1 if no line number
205 * was set
207 uint32_t GetLineNumber() const { return mLineNumber; }
209 // This doesn't entirely belong here since they only make sense for
210 // some types of linking elements, but it's a better place than
211 // anywhere else.
212 void SetColumnNumber(uint32_t aColumnNumber) {
213 mColumnNumber = aColumnNumber;
217 * Get the column number, as previously set by SetColumnNumber.
219 * @return the column number of this element; or 1 if no column number
220 * was set
222 uint32_t GetColumnNumber() const { return mColumnNumber; }
224 StyleSheet* GetSheet() const { return mStyleSheet; }
226 /** JS can only observe the sheet once fully loaded */
227 StyleSheet* GetSheetForBindings() const;
229 protected:
230 LinkStyle();
231 virtual ~LinkStyle();
233 // Gets a suitable title and media for SheetInfo out of an element, which
234 // needs to be `this`.
236 // NOTE(emilio): Needs nsString instead of nsAString because of
237 // CompressWhitespace.
238 static void GetTitleAndMediaForElement(const mozilla::dom::Element&,
239 nsString& aTitle, nsString& aMedia);
241 // Returns whether the type attribute specifies the text/css type for style
242 // elements.
243 static bool IsCSSMimeTypeAttributeForStyleElement(const Element&);
245 // CC methods
246 void Unlink();
247 void Traverse(nsCycleCollectionTraversalCallback& cb);
250 * @param aOldDocument should be non-null only if we're updating because we
251 * removed the node from the document.
252 * @param aOldShadowRoot should be non-null only if we're updating because we
253 * removed the node from a shadow tree.
254 * @param aForceUpdate true will force the update even if the URI has not
255 * changed. This should be used in cases when something
256 * about the content that affects the resulting sheet
257 * changed but the URI may not have changed.
259 * TODO(emilio): Should probably pass a single DocumentOrShadowRoot.
261 Result<Update, nsresult> UpdateStyleSheetInternal(
262 Document* aOldDocument, ShadowRoot* aOldShadowRoot,
263 ForceUpdate = ForceUpdate::No);
266 * @param aOldDocument should be non-null only if we're updating because we
267 * removed the node from the document.
268 * @param aOldShadowRoot The ShadowRoot that used to contain the style.
269 * Passed as a parameter because on an update, the node
270 * is removed from the tree before the sheet is removed
271 * from the ShadowRoot.
272 * @param aForceUpdate true will force the update even if the URI has not
273 * changed. This should be used in cases when something
274 * about the content that affects the resulting sheet
275 * changed but the URI may not have changed.
277 Result<Update, nsresult> DoUpdateStyleSheet(Document* aOldDocument,
278 ShadowRoot* aOldShadowRoot,
279 nsICSSLoaderObserver*,
280 ForceUpdate);
282 void BindToTree();
284 RefPtr<mozilla::StyleSheet> mStyleSheet;
285 nsCOMPtr<nsIPrincipal> mTriggeringPrincipal;
286 bool mUpdatesEnabled = true;
287 uint32_t mLineNumber = 1;
288 uint32_t mColumnNumber = 1;
291 } // namespace mozilla::dom
293 #endif // mozilla_dom_LinkStyle_h