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 
7 #ifndef mozilla_ServoStyleSheet_h
8 #define mozilla_ServoStyleSheet_h
9 
10 #include "mozilla/dom/SRIMetadata.h"
11 #include "mozilla/MozPromise.h"
12 #include "mozilla/RefPtr.h"
13 #include "mozilla/ServoBindingTypes.h"
14 #include "mozilla/StyleSheet.h"
15 #include "mozilla/StyleSheetInfo.h"
16 #include "mozilla/URLExtraData.h"
17 #include "nsCompatibility.h"
18 #include "nsStringFwd.h"
19 
20 namespace mozilla {
21 
22 class ServoCSSRuleList;
23 typedef MozPromise</* Dummy */ bool,
24                    /* Dummy */ bool,
25                    /* IsExclusive = */ true>
26     StyleSheetParsePromise;
27 
28 namespace css {
29 class Loader;
30 class LoaderReusableStyleSheets;
31 class SheetLoadData;
32 }  // namespace css
33 
34 // -------------------------------
35 // Servo Style Sheet Inner Data Container
36 //
37 
38 struct ServoStyleSheetInner final : public StyleSheetInfo {
39   ServoStyleSheetInner(CORSMode aCORSMode, ReferrerPolicy aReferrerPolicy,
40                        const dom::SRIMetadata& aIntegrity,
41                        css::SheetParsingMode aParsingMode);
42   ServoStyleSheetInner(ServoStyleSheetInner& aCopy,
43                        ServoStyleSheet* aPrimarySheet);
44   ~ServoStyleSheetInner();
45 
46   StyleSheetInfo* CloneFor(StyleSheet* aPrimarySheet) override;
47 
48   size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const;
49 
50   RefPtr<const RawServoStyleSheetContents> mContents;
51 
52   // XXX StyleSheetInfo already has mSheetURI, mBaseURI, and mPrincipal.
53   // Can we somehow replace them with URLExtraData directly? The issue
54   // is currently URLExtraData is immutable, but URIs in StyleSheetInfo
55   // seems to be mutable, so we probably cannot set them altogether.
56   // Also, this is mostly a duplicate reference of the same url data
57   // inside RawServoStyleSheet. We may want to just use that instead.
58   RefPtr<URLExtraData> mURLData;
59 };
60 
61 /**
62  * CSS style sheet object that is a wrapper for a Servo Stylesheet.
63  */
64 
65 // CID for the ServoStyleSheet class
66 // a6f31472-ab69-4beb-860f-c221431ead77
67 #define NS_SERVO_STYLE_SHEET_IMPL_CID                \
68   {                                                  \
69     0xa6f31472, 0xab69, 0x4beb, {                    \
70       0x86, 0x0f, 0xc2, 0x21, 0x43, 0x1e, 0xad, 0x77 \
71     }                                                \
72   }
73 
74 class ServoStyleSheet : public StyleSheet {
75  public:
76   ServoStyleSheet(css::SheetParsingMode aParsingMode, CORSMode aCORSMode,
77                   net::ReferrerPolicy aReferrerPolicy,
78                   const dom::SRIMetadata& aIntegrity);
79 
80   already_AddRefed<ServoStyleSheet> CreateEmptyChildSheet(
81       already_AddRefed<dom::MediaList> aMediaList) const;
82 
83   NS_DECL_ISUPPORTS_INHERITED
84   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ServoStyleSheet, StyleSheet)
85 
86   NS_DECLARE_STATIC_IID_ACCESSOR(NS_SERVO_STYLE_SHEET_IMPL_CID)
87 
88   bool HasRules() const;
89 
90   // Parses a stylesheet. The aLoadData argument corresponds to the
91   // SheetLoadData for this stylesheet. It may be null in some cases.
92   RefPtr<StyleSheetParsePromise> ParseSheet(
93       css::Loader* aLoader, Span<const uint8_t> aInput, nsIURI* aSheetURI,
94       nsIURI* aBaseURI, nsIPrincipal* aSheetPrincipal,
95       css::SheetLoadData* aLoadData, uint32_t aLineNumber,
96       nsCompatibility aCompatMode,
97       css::LoaderReusableStyleSheets* aReusableSheets = nullptr);
98 
99   // Similar to the above, but guarantees that parsing will be performed
100   // synchronously.
101   void ParseSheetSync(
102       css::Loader* aLoader, Span<const uint8_t> aInput, nsIURI* aSheetURI,
103       nsIURI* aBaseURI, nsIPrincipal* aSheetPrincipal,
104       css::SheetLoadData* aLoadData, uint32_t aLineNumber,
105       nsCompatibility aCompatMode,
106       css::LoaderReusableStyleSheets* aReusableSheets = nullptr);
107 
108   nsresult ReparseSheet(const nsAString& aInput);
109 
RawContents()110   const RawServoStyleSheetContents* RawContents() const {
111     return Inner()->mContents;
112   }
113 
SetContentsForImport(const RawServoStyleSheetContents * aContents)114   void SetContentsForImport(const RawServoStyleSheetContents* aContents) {
115     MOZ_ASSERT(!Inner()->mContents);
116     Inner()->mContents = aContents;
117   }
118 
URLData()119   URLExtraData* URLData() const { return Inner()->mURLData; }
120 
DidDirty()121   void DidDirty() override {}
122 
123   already_AddRefed<StyleSheet> Clone(StyleSheet* aCloneParent,
124                                      dom::CSSImportRule* aCloneOwnerRule,
125                                      nsIDocument* aCloneDocument,
126                                      nsINode* aCloneOwningNode) const final;
127 
128   // nsICSSLoaderObserver interface
129   NS_IMETHOD StyleSheetLoaded(StyleSheet* aSheet, bool aWasAlternate,
130                               nsresult aStatus) final;
131 
132   // Internal GetCssRules methods which do not have security check and
133   // completeness check.
134   ServoCSSRuleList* GetCssRulesInternal();
135 
136   // Returns the stylesheet's Servo origin as an OriginFlags value.
137   OriginFlags GetOrigin();
138 
139  protected:
140   virtual ~ServoStyleSheet();
141 
142   void LastRelease();
143 
Inner()144   ServoStyleSheetInner* Inner() const {
145     return static_cast<ServoStyleSheetInner*>(mInner);
146   }
147 
148   // Internal methods which do not have security check and completeness check.
149   uint32_t InsertRuleInternal(const nsAString& aRule, uint32_t aIndex,
150                               ErrorResult& aRv);
151   void DeleteRuleInternal(uint32_t aIndex, ErrorResult& aRv);
152   nsresult InsertRuleIntoGroupInternal(const nsAString& aRule,
153                                        css::GroupRule* aGroup, uint32_t aIndex);
154 
EnabledStateChangedInternal()155   void EnabledStateChangedInternal() {}
156 
157   size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override;
158 
159  private:
160   ServoStyleSheet(const ServoStyleSheet& aCopy, ServoStyleSheet* aParentToUse,
161                   dom::CSSImportRule* aOwnerRuleToUse,
162                   nsIDocument* aDocumentToUse, nsINode* aOwningNodeToUse);
163 
164   // Common tail routine for the synchronous and asynchronous parsing paths.
165   void FinishParse();
166 
167   void DropRuleList();
168 
169   // Take the recently cloned sheets from the `@import` rules, and reparent them
170   // correctly to `aPrimarySheet`.
171   void BuildChildListAfterInnerClone();
172 
173   RefPtr<ServoCSSRuleList> mRuleList;
174 
175   MozPromiseHolder<StyleSheetParsePromise> mParsePromise;
176 
177   friend class StyleSheet;
178 };
179 
180 NS_DEFINE_STATIC_IID_ACCESSOR(ServoStyleSheet, NS_SERVO_STYLE_SHEET_IMPL_CID)
181 
182 }  // namespace mozilla
183 
184 #endif  // mozilla_ServoStyleSheet_h
185