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 #include "mozilla/dom/CSSFontFaceRule.h"
8 
9 #include "mozilla/dom/CSSFontFaceRuleBinding.h"
10 #include "mozilla/dom/CSSStyleDeclarationBinding.h"
11 #include "mozilla/ServoBindings.h"
12 #include "nsCSSProps.h"
13 
14 using namespace mozilla;
15 using namespace mozilla::dom;
16 
17 // -------------------------------------------
18 // CSSFontFaceRuleDecl and related routines
19 //
20 
21 // QueryInterface implementation for CSSFontFaceRuleDecl
22 NS_INTERFACE_MAP_BEGIN(CSSFontFaceRuleDecl)
23   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
24   NS_INTERFACE_MAP_ENTRY(nsICSSDeclaration)
25   NS_INTERFACE_MAP_ENTRY(nsISupports)
26   // We forward the cycle collection interfaces to ContainingRule(), which is
27   // never null (in fact, we're part of that object!)
28   if (aIID.Equals(NS_GET_IID(nsCycleCollectionISupports)) ||
29       aIID.Equals(NS_GET_IID(nsXPCOMCycleCollectionParticipant))) {
30     return ContainingRule()->QueryInterface(aIID, aInstancePtr);
31   } else
32 NS_INTERFACE_MAP_END
33 
NS_IMPL_ADDREF_USING_AGGREGATOR(CSSFontFaceRuleDecl,ContainingRule ())34 NS_IMPL_ADDREF_USING_AGGREGATOR(CSSFontFaceRuleDecl, ContainingRule())
35 NS_IMPL_RELEASE_USING_AGGREGATOR(CSSFontFaceRuleDecl, ContainingRule())
36 
37 // helper for string GetPropertyValue and RemovePropertyValue
38 void CSSFontFaceRuleDecl::GetPropertyValue(nsCSSFontDesc aFontDescID,
39                                            nsACString& aResult) const {
40   MOZ_ASSERT(aResult.IsEmpty());
41   Servo_FontFaceRule_GetDescriptorCssText(mRawRule, aFontDescID, &aResult);
42 }
43 
GetCssText(nsACString & aCssText)44 void CSSFontFaceRuleDecl::GetCssText(nsACString& aCssText) {
45   MOZ_ASSERT(aCssText.IsEmpty());
46   Servo_FontFaceRule_GetDeclCssText(mRawRule, &aCssText);
47 }
48 
SetCssText(const nsACString & aCssText,nsIPrincipal * aSubjectPrincipal,ErrorResult & aRv)49 void CSSFontFaceRuleDecl::SetCssText(const nsACString& aCssText,
50                                      nsIPrincipal* aSubjectPrincipal,
51                                      ErrorResult& aRv) {
52   if (ContainingRule()->IsReadOnly()) {
53     return;
54   }
55   // bug 443978
56   aRv.ThrowNotSupportedError(
57       "Can't set cssText on CSSFontFaceRule declarations");
58 }
59 
60 NS_IMETHODIMP
GetPropertyValue(const nsACString & aPropName,nsACString & aResult)61 CSSFontFaceRuleDecl::GetPropertyValue(const nsACString& aPropName,
62                                       nsACString& aResult) {
63   aResult.Truncate();
64   nsCSSFontDesc descID = nsCSSProps::LookupFontDesc(aPropName);
65   if (descID != eCSSFontDesc_UNKNOWN) {
66     GetPropertyValue(descID, aResult);
67   }
68   return NS_OK;
69 }
70 
RemoveProperty(const nsACString & aPropName,nsACString & aResult,ErrorResult & aRv)71 void CSSFontFaceRuleDecl::RemoveProperty(const nsACString& aPropName,
72                                          nsACString& aResult,
73                                          ErrorResult& aRv) {
74   nsCSSFontDesc descID = nsCSSProps::LookupFontDesc(aPropName);
75   NS_ASSERTION(descID >= eCSSFontDesc_UNKNOWN && descID < eCSSFontDesc_COUNT,
76                "LookupFontDesc returned value out of range");
77 
78   if (ContainingRule()->IsReadOnly()) {
79     return;
80   }
81 
82   aResult.Truncate();
83   if (descID != eCSSFontDesc_UNKNOWN) {
84     GetPropertyValue(descID, aResult);
85     Servo_FontFaceRule_ResetDescriptor(mRawRule, descID);
86   }
87 }
88 
GetPropertyPriority(const nsACString & aPropName,nsACString & aResult)89 void CSSFontFaceRuleDecl::GetPropertyPriority(const nsACString& aPropName,
90                                               nsACString& aResult) {
91   // font descriptors do not have priorities at present
92   aResult.Truncate();
93 }
94 
SetProperty(const nsACString & aPropName,const nsACString & aValue,const nsACString & aPriority,nsIPrincipal * aSubjectPrincipal,ErrorResult & aRv)95 void CSSFontFaceRuleDecl::SetProperty(const nsACString& aPropName,
96                                       const nsACString& aValue,
97                                       const nsACString& aPriority,
98                                       nsIPrincipal* aSubjectPrincipal,
99                                       ErrorResult& aRv) {
100   // FIXME(heycam): If we are changing unicode-range, then a FontFace object
101   // representing this rule must have its mUnicodeRange value invalidated.
102 
103   if (ContainingRule()->IsReadOnly()) {
104     return;
105   }
106 
107   // bug 443978
108   aRv.ThrowNotSupportedError(
109       "Can't set properties on CSSFontFaceRule declarations");
110 }
111 
Length()112 uint32_t CSSFontFaceRuleDecl::Length() {
113   return Servo_FontFaceRule_Length(mRawRule);
114 }
115 
IndexedGetter(uint32_t aIndex,bool & aFound,nsACString & aResult)116 void CSSFontFaceRuleDecl::IndexedGetter(uint32_t aIndex, bool& aFound,
117                                         nsACString& aResult) {
118   nsCSSFontDesc id = Servo_FontFaceRule_IndexGetter(mRawRule, aIndex);
119   if (id != eCSSFontDesc_UNKNOWN) {
120     aFound = true;
121     aResult.Assign(nsCSSProps::GetStringValue(id));
122   } else {
123     aFound = false;
124   }
125 }
126 
GetParentRule()127 css::Rule* CSSFontFaceRuleDecl::GetParentRule() { return ContainingRule(); }
128 
GetAssociatedNode() const129 nsINode* CSSFontFaceRuleDecl::GetAssociatedNode() const {
130   return ContainingRule()->GetAssociatedDocumentOrShadowRoot();
131 }
132 
GetParentObject() const133 nsISupports* CSSFontFaceRuleDecl::GetParentObject() const {
134   return ContainingRule()->GetParentObject();
135 }
136 
WrapObject(JSContext * cx,JS::Handle<JSObject * > aGivenProto)137 JSObject* CSSFontFaceRuleDecl::WrapObject(JSContext* cx,
138                                           JS::Handle<JSObject*> aGivenProto) {
139   // If this changes to use a different type, remove the 'concrete'
140   // annotation from CSSStyleDeclaration.
141   return CSSStyleDeclaration_Binding::Wrap(cx, this, aGivenProto);
142 }
143 
144 // -------------------------------------------
145 // CSSFontFaceRule
146 //
147 
148 NS_IMPL_CYCLE_COLLECTION_CLASS(CSSFontFaceRule)
149 
150 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(CSSFontFaceRule,
151                                                mozilla::css::Rule)
152   // Keep this in sync with IsCCLeaf.
153 
154   // Trace the wrapper for our declaration.  This just expands out
155   // NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER which we can't use
156   // directly because the wrapper is on the declaration, not on us.
157   tmp->mDecl.TraceWrapper(aCallbacks, aClosure);
158 NS_IMPL_CYCLE_COLLECTION_TRACE_END
159 
160 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(CSSFontFaceRule)
161   // Keep this in sync with IsCCLeaf.
162 
163   // Unlink the wrapper for our declaration.
164   //
165   // Note that this has to happen before unlinking css::Rule.
166   tmp->UnlinkDeclarationWrapper(tmp->mDecl);
167 NS_IMPL_CYCLE_COLLECTION_UNLINK_END_INHERITED(mozilla::css::Rule)
168 
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(CSSFontFaceRule,mozilla::css::Rule)169 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(CSSFontFaceRule,
170                                                   mozilla::css::Rule)
171   // Keep this in sync with IsCCLeaf.
172 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
173 
174 bool CSSFontFaceRule::IsCCLeaf() const {
175   if (!Rule::IsCCLeaf()) {
176     return false;
177   }
178 
179   return !mDecl.PreservingWrapper();
180 }
181 
NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED_0(CSSFontFaceRule,mozilla::css::Rule)182 NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED_0(CSSFontFaceRule,
183                                                mozilla::css::Rule)
184 
185 #ifdef DEBUG
186 void CSSFontFaceRule::List(FILE* out, int32_t aIndent) const {
187   nsAutoCString str;
188   for (int32_t i = 0; i < aIndent; i++) {
189     str.AppendLiteral("  ");
190   }
191   Servo_FontFaceRule_Debug(Raw(), &str);
192   fprintf_stderr(out, "%s\n", str.get());
193 }
194 #endif
195 
Type() const196 uint16_t CSSFontFaceRule::Type() const {
197   return CSSRule_Binding::FONT_FACE_RULE;
198 }
199 
GetCssText(nsACString & aCssText) const200 void CSSFontFaceRule::GetCssText(nsACString& aCssText) const {
201   aCssText.Truncate();
202   Servo_FontFaceRule_GetCssText(Raw(), &aCssText);
203 }
204 
Style()205 nsICSSDeclaration* CSSFontFaceRule::Style() { return &mDecl; }
206 
207 /* virtual */
SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const208 size_t CSSFontFaceRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const {
209   return aMallocSizeOf(this);
210 }
211 
212 /* virtual */
WrapObject(JSContext * aCx,JS::Handle<JSObject * > aGivenProto)213 JSObject* CSSFontFaceRule::WrapObject(JSContext* aCx,
214                                       JS::Handle<JSObject*> aGivenProto) {
215   return CSSFontFaceRule_Binding::Wrap(aCx, this, aGivenProto);
216 }
217