1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3  * License, v. 2.0. If a copy of the MPL was not distributed with this
4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 
6 /* base class for DOM objects for element.style and cssStyleRule.style */
7 
8 #ifndef nsDOMCSSDeclaration_h___
9 #define nsDOMCSSDeclaration_h___
10 
11 #include "nsICSSDeclaration.h"
12 
13 #include "mozilla/Attributes.h"
14 #include "nsIURI.h"
15 #include "nsCOMPtr.h"
16 
17 class nsIPrincipal;
18 class nsIDocument;
19 struct JSContext;
20 class JSObject;
21 
22 namespace mozilla {
23 class DeclarationBlock;
24 namespace css {
25 class Loader;
26 class Rule;
27 } // namespace css
28 } // namespace mozilla
29 
30 class nsDOMCSSDeclaration : public nsICSSDeclaration
31 {
32 public:
33   // Only implement QueryInterface; subclasses have the responsibility
34   // of implementing AddRef/Release.
35   NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) override;
36 
37   // Declare addref and release so they can be called on us, but don't
38   // implement them.  Our subclasses must handle their own
39   // refcounting.
40   NS_IMETHOD_(MozExternalRefCountType) AddRef() override = 0;
41   NS_IMETHOD_(MozExternalRefCountType) Release() override = 0;
42 
43   NS_DECL_NSICSSDECLARATION
44   using nsICSSDeclaration::GetLength;
45 
46   // Require subclasses to implement |GetParentRule|.
47   //NS_DECL_NSIDOMCSSSTYLEDECLARATION
48   NS_IMETHOD GetCssText(nsAString & aCssText) override;
49   NS_IMETHOD SetCssText(const nsAString & aCssText) override;
50   NS_IMETHOD GetPropertyValue(const nsAString & propertyName,
51                               nsAString & _retval) override;
52   virtual already_AddRefed<mozilla::dom::CSSValue>
53     GetPropertyCSSValue(const nsAString & propertyName,
54                         mozilla::ErrorResult& aRv) override;
55   using nsICSSDeclaration::GetPropertyCSSValue;
56   NS_IMETHOD RemoveProperty(const nsAString & propertyName,
57                             nsAString & _retval) override;
58   NS_IMETHOD GetPropertyPriority(const nsAString & propertyName,
59                                  nsAString & _retval) override;
60   NS_IMETHOD SetProperty(const nsAString & propertyName,
61                          const nsAString & value, const nsAString & priority) override;
62   NS_IMETHOD GetLength(uint32_t *aLength) override;
63   NS_IMETHOD GetParentRule(nsIDOMCSSRule * *aParentRule) override = 0;
64 
65   // WebIDL interface for CSS2Properties
66 #define CSS_PROP_PUBLIC_OR_PRIVATE(publicname_, privatename_) publicname_
67 #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_,          \
68                  kwtable_, stylestruct_, stylestructoffset_, animtype_)      \
69   void                                                                       \
70   Get##method_(nsAString& aValue, mozilla::ErrorResult& rv)                  \
71   {                                                                          \
72     rv = GetPropertyValue(eCSSProperty_##id_, aValue);                       \
73   }                                                                          \
74                                                                              \
75   void                                                                       \
76   Set##method_(const nsAString& aValue, mozilla::ErrorResult& rv)            \
77   {                                                                          \
78     rv = SetPropertyValue(eCSSProperty_##id_, aValue);                       \
79   }
80 
81 #define CSS_PROP_LIST_EXCLUDE_INTERNAL
82 #define CSS_PROP_LIST_INCLUDE_LOGICAL
83 #define CSS_PROP_SHORTHAND(name_, id_, method_, flags_, pref_)  \
84   CSS_PROP(name_, id_, method_, flags_, pref_, X, X, X, X, X)
85 #include "nsCSSPropList.h"
86 
87 #define CSS_PROP_ALIAS(aliasname_, propid_, aliasmethod_, pref_)  \
88   CSS_PROP(X, propid_, aliasmethod_, X, pref_, X, X, X, X, X)
89 #include "nsCSSPropAliasList.h"
90 #undef CSS_PROP_ALIAS
91 
92 #undef CSS_PROP_SHORTHAND
93 #undef CSS_PROP_LIST_INCLUDE_LOGICAL
94 #undef CSS_PROP_LIST_EXCLUDE_INTERNAL
95 #undef CSS_PROP
96 #undef CSS_PROP_PUBLIC_OR_PRIVATE
97 
98   virtual void IndexedGetter(uint32_t aIndex, bool& aFound, nsAString& aPropName) override;
99 
100   virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
101 
102 protected:
103   // The reason for calling GetCSSDeclaration.
104   enum Operation {
105     // We are calling GetCSSDeclaration so that we can read from it.  Does not
106     // allocate a new declaration if we don't have one yet; returns nullptr in
107     // this case.
108     eOperation_Read,
109 
110     // We are calling GetCSSDeclaration so that we can set a property on it
111     // or re-parse the whole declaration.  Allocates a new declaration if we
112     // don't have one yet and calls AttributeWillChange.  A nullptr return value
113     // indicates an error allocating the declaration.
114     eOperation_Modify,
115 
116     // We are calling GetCSSDeclaration so that we can remove a property from
117     // it.  Does not allocates a new declaration if we don't have one yet;
118     // returns nullptr in this case.  If we do have a declaration, calls
119     // AttributeWillChange.
120     eOperation_RemoveProperty
121   };
122   virtual mozilla::DeclarationBlock* GetCSSDeclaration(Operation aOperation) = 0;
123   virtual nsresult SetCSSDeclaration(mozilla::DeclarationBlock* aDecl) = 0;
124   // Document that we must call BeginUpdate/EndUpdate on around the
125   // calls to SetCSSDeclaration and the style rule mutation that leads
126   // to it.
127   virtual nsIDocument* DocToUpdate() = 0;
128 
129   // Information neded to parse a declaration.  We need the mSheetURI
130   // for error reporting, mBaseURI to resolve relative URIs,
131   // mPrincipal for subresource loads, and mCSSLoader for determining
132   // whether we're in quirks mode.  mBaseURI needs to be a strong
133   // pointer because of xml:base possibly creating base URIs on the
134   // fly.  This is why we don't use CSSParsingEnvironment as a return
135   // value, to avoid multiple-refcounting of mBaseURI.
136   struct CSSParsingEnvironment {
137     nsIURI* MOZ_UNSAFE_REF("user of CSSParsingEnviroment must hold an owning "
138                            "reference; reference counting here has unacceptable "
139                            "performance overhead (see bug 649163)") mSheetURI;
140     nsCOMPtr<nsIURI> mBaseURI;
141     nsIPrincipal* MOZ_UNSAFE_REF("user of CSSParsingEnviroment must hold an owning "
142                                  "reference; reference counting here has unacceptable "
143                                  "performance overhead (see bug 649163)") mPrincipal;
144     mozilla::css::Loader* MOZ_UNSAFE_REF("user of CSSParsingEnviroment must hold an owning "
145                                          "reference; reference counting here has unacceptable "
146                                          "performance overhead (see bug 649163)") mCSSLoader;
147   };
148 
149   // On failure, mPrincipal should be set to null in aCSSParseEnv.
150   // If mPrincipal is null, the other members may not be set to
151   // anything meaningful.
152   virtual void GetCSSParsingEnvironment(CSSParsingEnvironment& aCSSParseEnv) = 0;
153 
154   // An implementation for GetCSSParsingEnvironment for callers wrapping
155   // an css::Rule.
156   static void GetCSSParsingEnvironmentForRule(mozilla::css::Rule* aRule,
157                                               CSSParsingEnvironment& aCSSParseEnv);
158 
159   nsresult ParsePropertyValue(const nsCSSPropertyID aPropID,
160                               const nsAString& aPropValue,
161                               bool aIsImportant);
162 
163   nsresult ParseCustomPropertyValue(const nsAString& aPropertyName,
164                                     const nsAString& aPropValue,
165                                     bool aIsImportant);
166 
167   nsresult RemovePropertyInternal(nsCSSPropertyID aPropID);
168   nsresult RemovePropertyInternal(const nsAString& aProperty);
169 
170 protected:
171   virtual ~nsDOMCSSDeclaration();
172 };
173 
174 #endif // nsDOMCSSDeclaration_h___
175