1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/layout/style/nsCSSRules.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,3062 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +/* rules in a CSS stylesheet other than style rules (e.g., @import rules) */ 1.10 + 1.11 +#include "mozilla/Attributes.h" 1.12 + 1.13 +#include "nsCSSRules.h" 1.14 +#include "nsCSSValue.h" 1.15 +#include "mozilla/MemoryReporting.h" 1.16 +#include "mozilla/css/ImportRule.h" 1.17 +#include "mozilla/css/NameSpaceRule.h" 1.18 + 1.19 +#include "nsString.h" 1.20 +#include "nsIAtom.h" 1.21 + 1.22 +#include "nsCSSProps.h" 1.23 +#include "nsCSSStyleSheet.h" 1.24 + 1.25 +#include "nsCOMPtr.h" 1.26 +#include "nsIDOMCSSStyleSheet.h" 1.27 +#include "nsIMediaList.h" 1.28 +#include "nsICSSRuleList.h" 1.29 +#include "nsIDocument.h" 1.30 +#include "nsPresContext.h" 1.31 + 1.32 +#include "nsContentUtils.h" 1.33 +#include "nsError.h" 1.34 +#include "nsStyleUtil.h" 1.35 +#include "mozilla/css/Declaration.h" 1.36 +#include "nsCSSParser.h" 1.37 +#include "nsPrintfCString.h" 1.38 +#include "nsDOMClassInfoID.h" 1.39 +#include "mozilla/dom/CSSStyleDeclarationBinding.h" 1.40 +#include "StyleRule.h" 1.41 +#include "nsFont.h" 1.42 +#include "nsIURI.h" 1.43 +#include "mozAutoDocUpdate.h" 1.44 + 1.45 +using namespace mozilla; 1.46 + 1.47 +#define IMPL_STYLE_RULE_INHERIT_GET_DOM_RULE_WEAK(class_, super_) \ 1.48 + /* virtual */ nsIDOMCSSRule* class_::GetDOMRule() \ 1.49 + { return this; } \ 1.50 + /* virtual */ nsIDOMCSSRule* class_::GetExistingDOMRule() \ 1.51 + { return this; } 1.52 +#define IMPL_STYLE_RULE_INHERIT_MAP_RULE_INFO_INTO(class_, super_) \ 1.53 +/* virtual */ void class_::MapRuleInfoInto(nsRuleData* aRuleData) \ 1.54 + { NS_ABORT_IF_FALSE(false, "should not be called"); } 1.55 + 1.56 +#define IMPL_STYLE_RULE_INHERIT(class_, super_) \ 1.57 +IMPL_STYLE_RULE_INHERIT_GET_DOM_RULE_WEAK(class_, super_) \ 1.58 +IMPL_STYLE_RULE_INHERIT_MAP_RULE_INFO_INTO(class_, super_) 1.59 + 1.60 +// base class for all rule types in a CSS style sheet 1.61 + 1.62 +namespace mozilla { 1.63 +namespace css { 1.64 + 1.65 +nsCSSStyleSheet* 1.66 +Rule::GetStyleSheet() const 1.67 +{ 1.68 + if (!(mSheet & 0x1)) { 1.69 + return reinterpret_cast<nsCSSStyleSheet*>(mSheet); 1.70 + } 1.71 + 1.72 + return nullptr; 1.73 +} 1.74 + 1.75 +nsHTMLCSSStyleSheet* 1.76 +Rule::GetHTMLCSSStyleSheet() const 1.77 +{ 1.78 + if (mSheet & 0x1) { 1.79 + return reinterpret_cast<nsHTMLCSSStyleSheet*>(mSheet & ~uintptr_t(0x1)); 1.80 + } 1.81 + 1.82 + return nullptr; 1.83 +} 1.84 + 1.85 +/* virtual */ void 1.86 +Rule::SetStyleSheet(nsCSSStyleSheet* aSheet) 1.87 +{ 1.88 + // We don't reference count this up reference. The style sheet 1.89 + // will tell us when it's going away or when we're detached from 1.90 + // it. 1.91 + mSheet = reinterpret_cast<uintptr_t>(aSheet); 1.92 +} 1.93 + 1.94 +void 1.95 +Rule::SetHTMLCSSStyleSheet(nsHTMLCSSStyleSheet* aSheet) 1.96 +{ 1.97 + // We don't reference count this up reference. The style sheet 1.98 + // will tell us when it's going away or when we're detached from 1.99 + // it. 1.100 + mSheet = reinterpret_cast<uintptr_t>(aSheet); 1.101 + mSheet |= 0x1; 1.102 +} 1.103 + 1.104 +nsresult 1.105 +Rule::GetParentRule(nsIDOMCSSRule** aParentRule) 1.106 +{ 1.107 + if (mParentRule) { 1.108 + NS_IF_ADDREF(*aParentRule = mParentRule->GetDOMRule()); 1.109 + } else { 1.110 + *aParentRule = nullptr; 1.111 + } 1.112 + return NS_OK; 1.113 +} 1.114 + 1.115 +nsresult 1.116 +Rule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet) 1.117 +{ 1.118 + NS_ENSURE_ARG_POINTER(aSheet); 1.119 + 1.120 + NS_IF_ADDREF(*aSheet = GetStyleSheet()); 1.121 + return NS_OK; 1.122 +} 1.123 + 1.124 +size_t 1.125 +Rule::SizeOfCOMArrayElementIncludingThis(css::Rule* aElement, 1.126 + MallocSizeOf aMallocSizeOf, 1.127 + void* aData) 1.128 +{ 1.129 + return aElement->SizeOfIncludingThis(aMallocSizeOf); 1.130 +} 1.131 + 1.132 +// ------------------------------- 1.133 +// Style Rule List for group rules 1.134 +// 1.135 + 1.136 +class GroupRuleRuleList MOZ_FINAL : public nsICSSRuleList 1.137 +{ 1.138 +public: 1.139 + GroupRuleRuleList(GroupRule *aGroupRule); 1.140 + 1.141 + NS_DECL_ISUPPORTS 1.142 + 1.143 + virtual nsIDOMCSSRule* 1.144 + IndexedGetter(uint32_t aIndex, bool& aFound) MOZ_OVERRIDE; 1.145 + virtual uint32_t 1.146 + Length() MOZ_OVERRIDE; 1.147 + 1.148 + void DropReference() { mGroupRule = nullptr; } 1.149 + 1.150 +private: 1.151 + ~GroupRuleRuleList(); 1.152 + 1.153 +private: 1.154 + GroupRule* mGroupRule; 1.155 +}; 1.156 + 1.157 +GroupRuleRuleList::GroupRuleRuleList(GroupRule *aGroupRule) 1.158 +{ 1.159 + // Not reference counted to avoid circular references. 1.160 + // The rule will tell us when its going away. 1.161 + mGroupRule = aGroupRule; 1.162 +} 1.163 + 1.164 +GroupRuleRuleList::~GroupRuleRuleList() 1.165 +{ 1.166 +} 1.167 + 1.168 +// QueryInterface implementation for GroupRuleRuleList 1.169 +NS_INTERFACE_MAP_BEGIN(GroupRuleRuleList) 1.170 + NS_INTERFACE_MAP_ENTRY(nsICSSRuleList) 1.171 + NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRuleList) 1.172 + NS_INTERFACE_MAP_ENTRY(nsISupports) 1.173 + NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSRuleList) 1.174 +NS_INTERFACE_MAP_END 1.175 + 1.176 + 1.177 +NS_IMPL_ADDREF(GroupRuleRuleList) 1.178 +NS_IMPL_RELEASE(GroupRuleRuleList) 1.179 + 1.180 +uint32_t 1.181 +GroupRuleRuleList::Length() 1.182 +{ 1.183 + if (!mGroupRule) { 1.184 + return 0; 1.185 + } 1.186 + 1.187 + return SafeCast<uint32_t>(mGroupRule->StyleRuleCount()); 1.188 +} 1.189 + 1.190 +nsIDOMCSSRule* 1.191 +GroupRuleRuleList::IndexedGetter(uint32_t aIndex, bool& aFound) 1.192 +{ 1.193 + aFound = false; 1.194 + 1.195 + if (mGroupRule) { 1.196 + nsRefPtr<Rule> rule = mGroupRule->GetStyleRuleAt(aIndex); 1.197 + if (rule) { 1.198 + aFound = true; 1.199 + return rule->GetDOMRule(); 1.200 + } 1.201 + } 1.202 + 1.203 + return nullptr; 1.204 +} 1.205 + 1.206 +} // namespace css 1.207 +} // namespace mozilla 1.208 + 1.209 +// ------------------------------------------- 1.210 +// CharsetRule 1.211 +// 1.212 + 1.213 +// Must be outside namespace 1.214 +DOMCI_DATA(CSSCharsetRule, css::CharsetRule) 1.215 + 1.216 +namespace mozilla { 1.217 +namespace css { 1.218 + 1.219 +CharsetRule::CharsetRule(const nsAString& aEncoding) 1.220 + : Rule(), 1.221 + mEncoding(aEncoding) 1.222 +{ 1.223 +} 1.224 + 1.225 +CharsetRule::CharsetRule(const CharsetRule& aCopy) 1.226 + : Rule(aCopy), 1.227 + mEncoding(aCopy.mEncoding) 1.228 +{ 1.229 +} 1.230 + 1.231 +NS_IMPL_ADDREF(CharsetRule) 1.232 +NS_IMPL_RELEASE(CharsetRule) 1.233 + 1.234 +// QueryInterface implementation for CharsetRule 1.235 +NS_INTERFACE_MAP_BEGIN(CharsetRule) 1.236 + NS_INTERFACE_MAP_ENTRY(nsIStyleRule) 1.237 + NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule) 1.238 + NS_INTERFACE_MAP_ENTRY(nsIDOMCSSCharsetRule) 1.239 + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStyleRule) 1.240 + NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSCharsetRule) 1.241 +NS_INTERFACE_MAP_END 1.242 + 1.243 +IMPL_STYLE_RULE_INHERIT(CharsetRule, Rule) 1.244 + 1.245 +#ifdef DEBUG 1.246 +/* virtual */ void 1.247 +CharsetRule::List(FILE* out, int32_t aIndent) const 1.248 +{ 1.249 + // Indent 1.250 + for (int32_t indent = aIndent; --indent >= 0; ) fputs(" ", out); 1.251 + 1.252 + fputs("@charset \"", out); 1.253 + fputs(NS_LossyConvertUTF16toASCII(mEncoding).get(), out); 1.254 + fputs("\"\n", out); 1.255 +} 1.256 +#endif 1.257 + 1.258 +/* virtual */ int32_t 1.259 +CharsetRule::GetType() const 1.260 +{ 1.261 + return Rule::CHARSET_RULE; 1.262 +} 1.263 + 1.264 +/* virtual */ already_AddRefed<Rule> 1.265 +CharsetRule::Clone() const 1.266 +{ 1.267 + nsRefPtr<Rule> clone = new CharsetRule(*this); 1.268 + return clone.forget(); 1.269 +} 1.270 + 1.271 +NS_IMETHODIMP 1.272 +CharsetRule::GetEncoding(nsAString& aEncoding) 1.273 +{ 1.274 + aEncoding = mEncoding; 1.275 + return NS_OK; 1.276 +} 1.277 + 1.278 +NS_IMETHODIMP 1.279 +CharsetRule::SetEncoding(const nsAString& aEncoding) 1.280 +{ 1.281 + mEncoding = aEncoding; 1.282 + return NS_OK; 1.283 +} 1.284 + 1.285 +NS_IMETHODIMP 1.286 +CharsetRule::GetType(uint16_t* aType) 1.287 +{ 1.288 + *aType = nsIDOMCSSRule::CHARSET_RULE; 1.289 + return NS_OK; 1.290 +} 1.291 + 1.292 +NS_IMETHODIMP 1.293 +CharsetRule::GetCssText(nsAString& aCssText) 1.294 +{ 1.295 + aCssText.AssignLiteral("@charset \""); 1.296 + aCssText.Append(mEncoding); 1.297 + aCssText.AppendLiteral("\";"); 1.298 + return NS_OK; 1.299 +} 1.300 + 1.301 +NS_IMETHODIMP 1.302 +CharsetRule::SetCssText(const nsAString& aCssText) 1.303 +{ 1.304 + return NS_ERROR_NOT_IMPLEMENTED; 1.305 +} 1.306 + 1.307 +NS_IMETHODIMP 1.308 +CharsetRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet) 1.309 +{ 1.310 + return Rule::GetParentStyleSheet(aSheet); 1.311 +} 1.312 + 1.313 +NS_IMETHODIMP 1.314 +CharsetRule::GetParentRule(nsIDOMCSSRule** aParentRule) 1.315 +{ 1.316 + return Rule::GetParentRule(aParentRule); 1.317 +} 1.318 + 1.319 +/* virtual */ size_t 1.320 +CharsetRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const 1.321 +{ 1.322 + return aMallocSizeOf(this); 1.323 + 1.324 + // Measurement of the following members may be added later if DMD finds it is 1.325 + // worthwhile: 1.326 + // - mEncoding 1.327 +} 1.328 + 1.329 +// ------------------------------------------- 1.330 +// ImportRule 1.331 +// 1.332 + 1.333 +ImportRule::ImportRule(nsMediaList* aMedia, const nsString& aURLSpec) 1.334 + : Rule() 1.335 + , mURLSpec(aURLSpec) 1.336 + , mMedia(aMedia) 1.337 +{ 1.338 + // XXXbz This is really silly.... the mMedia here will be replaced 1.339 + // with itself if we manage to load a sheet. Which should really 1.340 + // never fail nowadays, in sane cases. 1.341 +} 1.342 + 1.343 +ImportRule::ImportRule(const ImportRule& aCopy) 1.344 + : Rule(aCopy), 1.345 + mURLSpec(aCopy.mURLSpec) 1.346 +{ 1.347 + // Whether or not an @import rule has a null sheet is a permanent 1.348 + // property of that @import rule, since it is null only if the target 1.349 + // sheet failed security checks. 1.350 + if (aCopy.mChildSheet) { 1.351 + nsRefPtr<nsCSSStyleSheet> sheet = 1.352 + aCopy.mChildSheet->Clone(nullptr, this, nullptr, nullptr); 1.353 + SetSheet(sheet); 1.354 + // SetSheet sets mMedia appropriately 1.355 + } 1.356 +} 1.357 + 1.358 +ImportRule::~ImportRule() 1.359 +{ 1.360 + if (mChildSheet) { 1.361 + mChildSheet->SetOwnerRule(nullptr); 1.362 + } 1.363 +} 1.364 + 1.365 +NS_IMPL_ADDREF(ImportRule) 1.366 +NS_IMPL_RELEASE(ImportRule) 1.367 + 1.368 +// QueryInterface implementation for ImportRule 1.369 +NS_INTERFACE_MAP_BEGIN(ImportRule) 1.370 + NS_INTERFACE_MAP_ENTRY(nsIStyleRule) 1.371 + NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule) 1.372 + NS_INTERFACE_MAP_ENTRY(nsIDOMCSSImportRule) 1.373 + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStyleRule) 1.374 + NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSImportRule) 1.375 +NS_INTERFACE_MAP_END 1.376 + 1.377 +IMPL_STYLE_RULE_INHERIT(ImportRule, Rule) 1.378 + 1.379 +#ifdef DEBUG 1.380 +/* virtual */ void 1.381 +ImportRule::List(FILE* out, int32_t aIndent) const 1.382 +{ 1.383 + // Indent 1.384 + for (int32_t indent = aIndent; --indent >= 0; ) fputs(" ", out); 1.385 + 1.386 + fputs("@import \"", out); 1.387 + fputs(NS_LossyConvertUTF16toASCII(mURLSpec).get(), out); 1.388 + fputs("\" ", out); 1.389 + 1.390 + nsAutoString mediaText; 1.391 + mMedia->GetText(mediaText); 1.392 + fputs(NS_LossyConvertUTF16toASCII(mediaText).get(), out); 1.393 + fputs("\n", out); 1.394 +} 1.395 +#endif 1.396 + 1.397 +/* virtual */ int32_t 1.398 +ImportRule::GetType() const 1.399 +{ 1.400 + return Rule::IMPORT_RULE; 1.401 +} 1.402 + 1.403 +/* virtual */ already_AddRefed<Rule> 1.404 +ImportRule::Clone() const 1.405 +{ 1.406 + nsRefPtr<Rule> clone = new ImportRule(*this); 1.407 + return clone.forget(); 1.408 +} 1.409 + 1.410 +void 1.411 +ImportRule::SetSheet(nsCSSStyleSheet* aSheet) 1.412 +{ 1.413 + NS_PRECONDITION(aSheet, "null arg"); 1.414 + 1.415 + // set the new sheet 1.416 + mChildSheet = aSheet; 1.417 + aSheet->SetOwnerRule(this); 1.418 + 1.419 + // set our medialist to be the same as the sheet's medialist 1.420 + mMedia = mChildSheet->Media(); 1.421 +} 1.422 + 1.423 +NS_IMETHODIMP 1.424 +ImportRule::GetType(uint16_t* aType) 1.425 +{ 1.426 + NS_ENSURE_ARG_POINTER(aType); 1.427 + *aType = nsIDOMCSSRule::IMPORT_RULE; 1.428 + return NS_OK; 1.429 +} 1.430 + 1.431 +NS_IMETHODIMP 1.432 +ImportRule::GetCssText(nsAString& aCssText) 1.433 +{ 1.434 + aCssText.AssignLiteral("@import url("); 1.435 + nsStyleUtil::AppendEscapedCSSString(mURLSpec, aCssText); 1.436 + aCssText.Append(NS_LITERAL_STRING(")")); 1.437 + if (mMedia) { 1.438 + nsAutoString mediaText; 1.439 + mMedia->GetText(mediaText); 1.440 + if (!mediaText.IsEmpty()) { 1.441 + aCssText.AppendLiteral(" "); 1.442 + aCssText.Append(mediaText); 1.443 + } 1.444 + } 1.445 + aCssText.AppendLiteral(";"); 1.446 + return NS_OK; 1.447 +} 1.448 + 1.449 +NS_IMETHODIMP 1.450 +ImportRule::SetCssText(const nsAString& aCssText) 1.451 +{ 1.452 + return NS_ERROR_NOT_IMPLEMENTED; 1.453 +} 1.454 + 1.455 +NS_IMETHODIMP 1.456 +ImportRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet) 1.457 +{ 1.458 + return Rule::GetParentStyleSheet(aSheet); 1.459 +} 1.460 + 1.461 +NS_IMETHODIMP 1.462 +ImportRule::GetParentRule(nsIDOMCSSRule** aParentRule) 1.463 +{ 1.464 + return Rule::GetParentRule(aParentRule); 1.465 +} 1.466 + 1.467 +NS_IMETHODIMP 1.468 +ImportRule::GetHref(nsAString & aHref) 1.469 +{ 1.470 + aHref = mURLSpec; 1.471 + return NS_OK; 1.472 +} 1.473 + 1.474 +NS_IMETHODIMP 1.475 +ImportRule::GetMedia(nsIDOMMediaList * *aMedia) 1.476 +{ 1.477 + NS_ENSURE_ARG_POINTER(aMedia); 1.478 + 1.479 + NS_IF_ADDREF(*aMedia = mMedia); 1.480 + return NS_OK; 1.481 +} 1.482 + 1.483 +NS_IMETHODIMP 1.484 +ImportRule::GetStyleSheet(nsIDOMCSSStyleSheet * *aStyleSheet) 1.485 +{ 1.486 + NS_ENSURE_ARG_POINTER(aStyleSheet); 1.487 + 1.488 + NS_IF_ADDREF(*aStyleSheet = mChildSheet); 1.489 + return NS_OK; 1.490 +} 1.491 + 1.492 +/* virtual */ size_t 1.493 +ImportRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const 1.494 +{ 1.495 + return aMallocSizeOf(this); 1.496 + 1.497 + // Measurement of the following members may be added later if DMD finds it is 1.498 + // worthwhile: 1.499 + // - mURLSpec 1.500 + // 1.501 + // The following members are not measured: 1.502 + // - mMedia, because it is measured via nsCSSStyleSheet::mMedia 1.503 + // - mChildSheet, because it is measured via nsCSSStyleSheetInner::mSheets 1.504 +} 1.505 + 1.506 +} // namespace css 1.507 +} // namespace mozilla 1.508 + 1.509 +// must be outside the namespace 1.510 +DOMCI_DATA(CSSImportRule, css::ImportRule) 1.511 + 1.512 +namespace mozilla { 1.513 +namespace css { 1.514 + 1.515 +GroupRule::GroupRule() 1.516 + : Rule() 1.517 +{ 1.518 +} 1.519 + 1.520 +static bool 1.521 +SetParentRuleReference(Rule* aRule, void* aParentRule) 1.522 +{ 1.523 + GroupRule* parentRule = static_cast<GroupRule*>(aParentRule); 1.524 + aRule->SetParentRule(parentRule); 1.525 + return true; 1.526 +} 1.527 + 1.528 +GroupRule::GroupRule(const GroupRule& aCopy) 1.529 + : Rule(aCopy) 1.530 +{ 1.531 + const_cast<GroupRule&>(aCopy).mRules.EnumerateForwards(GroupRule::CloneRuleInto, &mRules); 1.532 + mRules.EnumerateForwards(SetParentRuleReference, this); 1.533 +} 1.534 + 1.535 +GroupRule::~GroupRule() 1.536 +{ 1.537 + NS_ABORT_IF_FALSE(!mSheet, "SetStyleSheet should have been called"); 1.538 + mRules.EnumerateForwards(SetParentRuleReference, nullptr); 1.539 + if (mRuleCollection) { 1.540 + mRuleCollection->DropReference(); 1.541 + } 1.542 +} 1.543 + 1.544 +NS_IMPL_CYCLE_COLLECTING_ADDREF(GroupRule) 1.545 +NS_IMPL_CYCLE_COLLECTING_RELEASE(GroupRule) 1.546 + 1.547 +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(GroupRule) 1.548 +NS_INTERFACE_MAP_END 1.549 + 1.550 +IMPL_STYLE_RULE_INHERIT_MAP_RULE_INFO_INTO(GroupRule, Rule) 1.551 + 1.552 +static bool 1.553 +SetStyleSheetReference(Rule* aRule, void* aSheet) 1.554 +{ 1.555 + nsCSSStyleSheet* sheet = (nsCSSStyleSheet*)aSheet; 1.556 + aRule->SetStyleSheet(sheet); 1.557 + return true; 1.558 +} 1.559 + 1.560 +NS_IMPL_CYCLE_COLLECTION_CLASS(GroupRule) 1.561 + 1.562 +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(GroupRule) 1.563 + tmp->mRules.EnumerateForwards(SetParentRuleReference, nullptr); 1.564 + // If tmp does not have a stylesheet, neither do its descendants. In that 1.565 + // case, don't try to null out their stylesheet, to avoid O(N^2) behavior in 1.566 + // depth of group rule nesting. But if tmp _does_ have a stylesheet (which 1.567 + // can happen if it gets unlinked earlier than its owning stylesheet), then we 1.568 + // need to null out the stylesheet pointer on descendants now, before we clear 1.569 + // tmp->mRules. 1.570 + if (tmp->GetStyleSheet()) { 1.571 + tmp->mRules.EnumerateForwards(SetStyleSheetReference, nullptr); 1.572 + } 1.573 + tmp->mRules.Clear(); 1.574 + if (tmp->mRuleCollection) { 1.575 + tmp->mRuleCollection->DropReference(); 1.576 + tmp->mRuleCollection = nullptr; 1.577 + } 1.578 +NS_IMPL_CYCLE_COLLECTION_UNLINK_END 1.579 + 1.580 +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(GroupRule) 1.581 + const nsCOMArray<Rule>& rules = tmp->mRules; 1.582 + for (int32_t i = 0, count = rules.Count(); i < count; ++i) { 1.583 + NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mRules[i]"); 1.584 + cb.NoteXPCOMChild(rules[i]->GetExistingDOMRule()); 1.585 + } 1.586 + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRuleCollection) 1.587 +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END 1.588 + 1.589 +/* virtual */ void 1.590 +GroupRule::SetStyleSheet(nsCSSStyleSheet* aSheet) 1.591 +{ 1.592 + // Don't set the sheet on the kids if it's already the same as the sheet we 1.593 + // already have. This is needed to avoid O(N^2) behavior in group nesting 1.594 + // depth when seting the sheet to null during unlink, if we happen to unlin in 1.595 + // order from most nested rule up to least nested rule. 1.596 + if (aSheet != GetStyleSheet()) { 1.597 + mRules.EnumerateForwards(SetStyleSheetReference, aSheet); 1.598 + Rule::SetStyleSheet(aSheet); 1.599 + } 1.600 +} 1.601 + 1.602 +#ifdef DEBUG 1.603 +/* virtual */ void 1.604 +GroupRule::List(FILE* out, int32_t aIndent) const 1.605 +{ 1.606 + fputs(" {\n", out); 1.607 + 1.608 + for (int32_t index = 0, count = mRules.Count(); index < count; ++index) { 1.609 + mRules.ObjectAt(index)->List(out, aIndent + 1); 1.610 + } 1.611 + 1.612 + for (int32_t indent = aIndent; --indent >= 0; ) fputs(" ", out); 1.613 + fputs("}\n", out); 1.614 +} 1.615 +#endif 1.616 + 1.617 +void 1.618 +GroupRule::AppendStyleRule(Rule* aRule) 1.619 +{ 1.620 + mRules.AppendObject(aRule); 1.621 + nsCSSStyleSheet* sheet = GetStyleSheet(); 1.622 + aRule->SetStyleSheet(sheet); 1.623 + aRule->SetParentRule(this); 1.624 + if (sheet) { 1.625 + sheet->SetModifiedByChildRule(); 1.626 + } 1.627 +} 1.628 + 1.629 +Rule* 1.630 +GroupRule::GetStyleRuleAt(int32_t aIndex) const 1.631 +{ 1.632 + return mRules.SafeObjectAt(aIndex); 1.633 +} 1.634 + 1.635 +bool 1.636 +GroupRule::EnumerateRulesForwards(RuleEnumFunc aFunc, void * aData) const 1.637 +{ 1.638 + return 1.639 + const_cast<GroupRule*>(this)->mRules.EnumerateForwards(aFunc, aData); 1.640 +} 1.641 + 1.642 +/* 1.643 + * The next two methods (DeleteStyleRuleAt and InsertStyleRuleAt) 1.644 + * should never be called unless you have first called WillDirty() on 1.645 + * the parents stylesheet. After they are called, DidDirty() needs to 1.646 + * be called on the sheet 1.647 + */ 1.648 +nsresult 1.649 +GroupRule::DeleteStyleRuleAt(uint32_t aIndex) 1.650 +{ 1.651 + Rule* rule = mRules.SafeObjectAt(aIndex); 1.652 + if (rule) { 1.653 + rule->SetStyleSheet(nullptr); 1.654 + rule->SetParentRule(nullptr); 1.655 + } 1.656 + return mRules.RemoveObjectAt(aIndex) ? NS_OK : NS_ERROR_ILLEGAL_VALUE; 1.657 +} 1.658 + 1.659 +nsresult 1.660 +GroupRule::InsertStyleRuleAt(uint32_t aIndex, Rule* aRule) 1.661 +{ 1.662 + aRule->SetStyleSheet(GetStyleSheet()); 1.663 + aRule->SetParentRule(this); 1.664 + if (! mRules.InsertObjectAt(aRule, aIndex)) { 1.665 + return NS_ERROR_FAILURE; 1.666 + } 1.667 + return NS_OK; 1.668 +} 1.669 + 1.670 +nsresult 1.671 +GroupRule::ReplaceStyleRule(Rule* aOld, Rule* aNew) 1.672 +{ 1.673 + int32_t index = mRules.IndexOf(aOld); 1.674 + NS_ENSURE_TRUE(index != -1, NS_ERROR_UNEXPECTED); 1.675 + mRules.ReplaceObjectAt(aNew, index); 1.676 + aNew->SetStyleSheet(GetStyleSheet()); 1.677 + aNew->SetParentRule(this); 1.678 + aOld->SetStyleSheet(nullptr); 1.679 + aOld->SetParentRule(nullptr); 1.680 + return NS_OK; 1.681 +} 1.682 + 1.683 +void 1.684 +GroupRule::AppendRulesToCssText(nsAString& aCssText) 1.685 +{ 1.686 + aCssText.AppendLiteral(" {\n"); 1.687 + 1.688 + // get all the rules 1.689 + for (int32_t index = 0, count = mRules.Count(); index < count; ++index) { 1.690 + Rule* rule = mRules.ObjectAt(index); 1.691 + nsIDOMCSSRule* domRule = rule->GetDOMRule(); 1.692 + if (domRule) { 1.693 + nsAutoString cssText; 1.694 + domRule->GetCssText(cssText); 1.695 + aCssText.Append(NS_LITERAL_STRING(" ") + 1.696 + cssText + 1.697 + NS_LITERAL_STRING("\n")); 1.698 + } 1.699 + } 1.700 + 1.701 + aCssText.AppendLiteral("}"); 1.702 +} 1.703 + 1.704 +// nsIDOMCSSMediaRule or nsIDOMCSSMozDocumentRule methods 1.705 +nsresult 1.706 +GroupRule::GetCssRules(nsIDOMCSSRuleList* *aRuleList) 1.707 +{ 1.708 + if (!mRuleCollection) { 1.709 + mRuleCollection = new css::GroupRuleRuleList(this); 1.710 + } 1.711 + 1.712 + NS_ADDREF(*aRuleList = mRuleCollection); 1.713 + return NS_OK; 1.714 +} 1.715 + 1.716 +nsresult 1.717 +GroupRule::InsertRule(const nsAString & aRule, uint32_t aIndex, uint32_t* _retval) 1.718 +{ 1.719 + nsCSSStyleSheet* sheet = GetStyleSheet(); 1.720 + NS_ENSURE_TRUE(sheet, NS_ERROR_FAILURE); 1.721 + 1.722 + if (aIndex > uint32_t(mRules.Count())) 1.723 + return NS_ERROR_DOM_INDEX_SIZE_ERR; 1.724 + 1.725 + NS_ASSERTION(uint32_t(mRules.Count()) <= INT32_MAX, 1.726 + "Too many style rules!"); 1.727 + 1.728 + return sheet->InsertRuleIntoGroup(aRule, this, aIndex, _retval); 1.729 +} 1.730 + 1.731 +nsresult 1.732 +GroupRule::DeleteRule(uint32_t aIndex) 1.733 +{ 1.734 + nsCSSStyleSheet* sheet = GetStyleSheet(); 1.735 + NS_ENSURE_TRUE(sheet, NS_ERROR_FAILURE); 1.736 + 1.737 + if (aIndex >= uint32_t(mRules.Count())) 1.738 + return NS_ERROR_DOM_INDEX_SIZE_ERR; 1.739 + 1.740 + NS_ASSERTION(uint32_t(mRules.Count()) <= INT32_MAX, 1.741 + "Too many style rules!"); 1.742 + 1.743 + return sheet->DeleteRuleFromGroup(this, aIndex); 1.744 +} 1.745 + 1.746 +/* virtual */ size_t 1.747 +GroupRule::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const 1.748 +{ 1.749 + return mRules.SizeOfExcludingThis(Rule::SizeOfCOMArrayElementIncludingThis, 1.750 + aMallocSizeOf); 1.751 + 1.752 + // Measurement of the following members may be added later if DMD finds it is 1.753 + // worthwhile: 1.754 + // - mRuleCollection 1.755 +} 1.756 + 1.757 + 1.758 +// ------------------------------------------- 1.759 +// nsICSSMediaRule 1.760 +// 1.761 +MediaRule::MediaRule() 1.762 +{ 1.763 +} 1.764 + 1.765 +MediaRule::MediaRule(const MediaRule& aCopy) 1.766 + : GroupRule(aCopy) 1.767 +{ 1.768 + if (aCopy.mMedia) { 1.769 + mMedia = aCopy.mMedia->Clone(); 1.770 + // XXXldb This doesn't really make sense. 1.771 + mMedia->SetStyleSheet(aCopy.GetStyleSheet()); 1.772 + } 1.773 +} 1.774 + 1.775 +MediaRule::~MediaRule() 1.776 +{ 1.777 + if (mMedia) { 1.778 + mMedia->SetStyleSheet(nullptr); 1.779 + } 1.780 +} 1.781 + 1.782 +NS_IMPL_ADDREF_INHERITED(MediaRule, GroupRule) 1.783 +NS_IMPL_RELEASE_INHERITED(MediaRule, GroupRule) 1.784 + 1.785 +// QueryInterface implementation for MediaRule 1.786 +NS_INTERFACE_MAP_BEGIN(MediaRule) 1.787 + NS_INTERFACE_MAP_ENTRY(nsIStyleRule) 1.788 + NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule) 1.789 + NS_INTERFACE_MAP_ENTRY(nsIDOMCSSGroupingRule) 1.790 + NS_INTERFACE_MAP_ENTRY(nsIDOMCSSConditionRule) 1.791 + NS_INTERFACE_MAP_ENTRY(nsIDOMCSSMediaRule) 1.792 + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStyleRule) 1.793 + NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSMediaRule) 1.794 +NS_INTERFACE_MAP_END_INHERITING(GroupRule) 1.795 + 1.796 +/* virtual */ void 1.797 +MediaRule::SetStyleSheet(nsCSSStyleSheet* aSheet) 1.798 +{ 1.799 + if (mMedia) { 1.800 + // Set to null so it knows it's leaving one sheet and joining another. 1.801 + mMedia->SetStyleSheet(nullptr); 1.802 + mMedia->SetStyleSheet(aSheet); 1.803 + } 1.804 + 1.805 + GroupRule::SetStyleSheet(aSheet); 1.806 +} 1.807 + 1.808 +#ifdef DEBUG 1.809 +/* virtual */ void 1.810 +MediaRule::List(FILE* out, int32_t aIndent) const 1.811 +{ 1.812 + for (int32_t indent = aIndent; --indent >= 0; ) fputs(" ", out); 1.813 + 1.814 + nsAutoString buffer; 1.815 + 1.816 + fputs("@media ", out); 1.817 + 1.818 + if (mMedia) { 1.819 + nsAutoString mediaText; 1.820 + mMedia->GetText(mediaText); 1.821 + fputs(NS_LossyConvertUTF16toASCII(mediaText).get(), out); 1.822 + } 1.823 + 1.824 + GroupRule::List(out, aIndent); 1.825 +} 1.826 +#endif 1.827 + 1.828 +/* virtual */ int32_t 1.829 +MediaRule::GetType() const 1.830 +{ 1.831 + return Rule::MEDIA_RULE; 1.832 +} 1.833 + 1.834 +/* virtual */ already_AddRefed<Rule> 1.835 +MediaRule::Clone() const 1.836 +{ 1.837 + nsRefPtr<Rule> clone = new MediaRule(*this); 1.838 + return clone.forget(); 1.839 +} 1.840 + 1.841 +nsresult 1.842 +MediaRule::SetMedia(nsMediaList* aMedia) 1.843 +{ 1.844 + mMedia = aMedia; 1.845 + if (aMedia) 1.846 + mMedia->SetStyleSheet(GetStyleSheet()); 1.847 + return NS_OK; 1.848 +} 1.849 + 1.850 +// nsIDOMCSSRule methods 1.851 +NS_IMETHODIMP 1.852 +MediaRule::GetType(uint16_t* aType) 1.853 +{ 1.854 + *aType = nsIDOMCSSRule::MEDIA_RULE; 1.855 + return NS_OK; 1.856 +} 1.857 + 1.858 +NS_IMETHODIMP 1.859 +MediaRule::GetCssText(nsAString& aCssText) 1.860 +{ 1.861 + aCssText.AssignLiteral("@media "); 1.862 + AppendConditionText(aCssText); 1.863 + GroupRule::AppendRulesToCssText(aCssText); 1.864 + return NS_OK; 1.865 +} 1.866 + 1.867 +NS_IMETHODIMP 1.868 +MediaRule::SetCssText(const nsAString& aCssText) 1.869 +{ 1.870 + return NS_ERROR_NOT_IMPLEMENTED; 1.871 +} 1.872 + 1.873 +NS_IMETHODIMP 1.874 +MediaRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet) 1.875 +{ 1.876 + return GroupRule::GetParentStyleSheet(aSheet); 1.877 +} 1.878 + 1.879 +NS_IMETHODIMP 1.880 +MediaRule::GetParentRule(nsIDOMCSSRule** aParentRule) 1.881 +{ 1.882 + return GroupRule::GetParentRule(aParentRule); 1.883 +} 1.884 + 1.885 +// nsIDOMCSSGroupingRule methods 1.886 +NS_IMETHODIMP 1.887 +MediaRule::GetCssRules(nsIDOMCSSRuleList* *aRuleList) 1.888 +{ 1.889 + return GroupRule::GetCssRules(aRuleList); 1.890 +} 1.891 + 1.892 +NS_IMETHODIMP 1.893 +MediaRule::InsertRule(const nsAString & aRule, uint32_t aIndex, uint32_t* _retval) 1.894 +{ 1.895 + return GroupRule::InsertRule(aRule, aIndex, _retval); 1.896 +} 1.897 + 1.898 +NS_IMETHODIMP 1.899 +MediaRule::DeleteRule(uint32_t aIndex) 1.900 +{ 1.901 + return GroupRule::DeleteRule(aIndex); 1.902 +} 1.903 + 1.904 +// nsIDOMCSSConditionRule methods 1.905 +NS_IMETHODIMP 1.906 +MediaRule::GetConditionText(nsAString& aConditionText) 1.907 +{ 1.908 + aConditionText.Truncate(0); 1.909 + AppendConditionText(aConditionText); 1.910 + return NS_OK; 1.911 +} 1.912 + 1.913 +NS_IMETHODIMP 1.914 +MediaRule::SetConditionText(const nsAString& aConditionText) 1.915 +{ 1.916 + if (!mMedia) { 1.917 + nsRefPtr<nsMediaList> media = new nsMediaList(); 1.918 + media->SetStyleSheet(GetStyleSheet()); 1.919 + nsresult rv = media->SetMediaText(aConditionText); 1.920 + if (NS_SUCCEEDED(rv)) { 1.921 + mMedia = media; 1.922 + } 1.923 + return rv; 1.924 + } 1.925 + 1.926 + return mMedia->SetMediaText(aConditionText); 1.927 +} 1.928 + 1.929 +// nsIDOMCSSMediaRule methods 1.930 +NS_IMETHODIMP 1.931 +MediaRule::GetMedia(nsIDOMMediaList* *aMedia) 1.932 +{ 1.933 + NS_ENSURE_ARG_POINTER(aMedia); 1.934 + NS_IF_ADDREF(*aMedia = mMedia); 1.935 + return NS_OK; 1.936 +} 1.937 + 1.938 +// GroupRule interface 1.939 +/* virtual */ bool 1.940 +MediaRule::UseForPresentation(nsPresContext* aPresContext, 1.941 + nsMediaQueryResultCacheKey& aKey) 1.942 +{ 1.943 + if (mMedia) { 1.944 + return mMedia->Matches(aPresContext, &aKey); 1.945 + } 1.946 + return true; 1.947 +} 1.948 + 1.949 +/* virtual */ size_t 1.950 +MediaRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const 1.951 +{ 1.952 + size_t n = aMallocSizeOf(this); 1.953 + n += GroupRule::SizeOfExcludingThis(aMallocSizeOf); 1.954 + 1.955 + // Measurement of the following members may be added later if DMD finds it is 1.956 + // worthwhile: 1.957 + // - mMedia 1.958 + 1.959 + return n; 1.960 +} 1.961 + 1.962 +void 1.963 +MediaRule::AppendConditionText(nsAString& aOutput) 1.964 +{ 1.965 + if (mMedia) { 1.966 + nsAutoString mediaText; 1.967 + mMedia->GetText(mediaText); 1.968 + aOutput.Append(mediaText); 1.969 + } 1.970 +} 1.971 + 1.972 +} // namespace css 1.973 +} // namespace mozilla 1.974 + 1.975 +// Must be outside namespace 1.976 +DOMCI_DATA(CSSMediaRule, css::MediaRule) 1.977 + 1.978 +namespace mozilla { 1.979 +namespace css { 1.980 + 1.981 +DocumentRule::DocumentRule() 1.982 +{ 1.983 +} 1.984 + 1.985 +DocumentRule::DocumentRule(const DocumentRule& aCopy) 1.986 + : GroupRule(aCopy) 1.987 + , mURLs(new URL(*aCopy.mURLs)) 1.988 +{ 1.989 +} 1.990 + 1.991 +DocumentRule::~DocumentRule() 1.992 +{ 1.993 +} 1.994 + 1.995 +NS_IMPL_ADDREF_INHERITED(DocumentRule, GroupRule) 1.996 +NS_IMPL_RELEASE_INHERITED(DocumentRule, GroupRule) 1.997 + 1.998 +// QueryInterface implementation for DocumentRule 1.999 +NS_INTERFACE_MAP_BEGIN(DocumentRule) 1.1000 + NS_INTERFACE_MAP_ENTRY(nsIStyleRule) 1.1001 + NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule) 1.1002 + NS_INTERFACE_MAP_ENTRY(nsIDOMCSSGroupingRule) 1.1003 + NS_INTERFACE_MAP_ENTRY(nsIDOMCSSConditionRule) 1.1004 + NS_INTERFACE_MAP_ENTRY(nsIDOMCSSMozDocumentRule) 1.1005 + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStyleRule) 1.1006 + NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSMozDocumentRule) 1.1007 +NS_INTERFACE_MAP_END_INHERITING(GroupRule) 1.1008 + 1.1009 +#ifdef DEBUG 1.1010 +/* virtual */ void 1.1011 +DocumentRule::List(FILE* out, int32_t aIndent) const 1.1012 +{ 1.1013 + for (int32_t indent = aIndent; --indent >= 0; ) fputs(" ", out); 1.1014 + 1.1015 + nsAutoCString str; 1.1016 + str.AssignLiteral("@-moz-document "); 1.1017 + for (URL *url = mURLs; url; url = url->next) { 1.1018 + switch (url->func) { 1.1019 + case eURL: 1.1020 + str.AppendLiteral("url(\""); 1.1021 + break; 1.1022 + case eURLPrefix: 1.1023 + str.AppendLiteral("url-prefix(\""); 1.1024 + break; 1.1025 + case eDomain: 1.1026 + str.AppendLiteral("domain(\""); 1.1027 + break; 1.1028 + case eRegExp: 1.1029 + str.AppendLiteral("regexp(\""); 1.1030 + break; 1.1031 + } 1.1032 + nsAutoCString escapedURL(url->url); 1.1033 + escapedURL.ReplaceSubstring("\"", "\\\""); // escape quotes 1.1034 + str.Append(escapedURL); 1.1035 + str.AppendLiteral("\"), "); 1.1036 + } 1.1037 + str.Cut(str.Length() - 2, 1); // remove last , 1.1038 + fputs(str.get(), out); 1.1039 + 1.1040 + GroupRule::List(out, aIndent); 1.1041 +} 1.1042 +#endif 1.1043 + 1.1044 +/* virtual */ int32_t 1.1045 +DocumentRule::GetType() const 1.1046 +{ 1.1047 + return Rule::DOCUMENT_RULE; 1.1048 +} 1.1049 + 1.1050 +/* virtual */ already_AddRefed<Rule> 1.1051 +DocumentRule::Clone() const 1.1052 +{ 1.1053 + nsRefPtr<Rule> clone = new DocumentRule(*this); 1.1054 + return clone.forget(); 1.1055 +} 1.1056 + 1.1057 +// nsIDOMCSSRule methods 1.1058 +NS_IMETHODIMP 1.1059 +DocumentRule::GetType(uint16_t* aType) 1.1060 +{ 1.1061 + // XXX What should really happen here? 1.1062 + *aType = nsIDOMCSSRule::UNKNOWN_RULE; 1.1063 + return NS_OK; 1.1064 +} 1.1065 + 1.1066 +NS_IMETHODIMP 1.1067 +DocumentRule::GetCssText(nsAString& aCssText) 1.1068 +{ 1.1069 + aCssText.AssignLiteral("@-moz-document "); 1.1070 + AppendConditionText(aCssText); 1.1071 + GroupRule::AppendRulesToCssText(aCssText); 1.1072 + return NS_OK; 1.1073 +} 1.1074 + 1.1075 +NS_IMETHODIMP 1.1076 +DocumentRule::SetCssText(const nsAString& aCssText) 1.1077 +{ 1.1078 + return NS_ERROR_NOT_IMPLEMENTED; 1.1079 +} 1.1080 + 1.1081 +NS_IMETHODIMP 1.1082 +DocumentRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet) 1.1083 +{ 1.1084 + return GroupRule::GetParentStyleSheet(aSheet); 1.1085 +} 1.1086 + 1.1087 +NS_IMETHODIMP 1.1088 +DocumentRule::GetParentRule(nsIDOMCSSRule** aParentRule) 1.1089 +{ 1.1090 + return GroupRule::GetParentRule(aParentRule); 1.1091 +} 1.1092 + 1.1093 +// nsIDOMCSSGroupingRule methods 1.1094 +NS_IMETHODIMP 1.1095 +DocumentRule::GetCssRules(nsIDOMCSSRuleList* *aRuleList) 1.1096 +{ 1.1097 + return GroupRule::GetCssRules(aRuleList); 1.1098 +} 1.1099 + 1.1100 +NS_IMETHODIMP 1.1101 +DocumentRule::InsertRule(const nsAString & aRule, uint32_t aIndex, uint32_t* _retval) 1.1102 +{ 1.1103 + return GroupRule::InsertRule(aRule, aIndex, _retval); 1.1104 +} 1.1105 + 1.1106 +NS_IMETHODIMP 1.1107 +DocumentRule::DeleteRule(uint32_t aIndex) 1.1108 +{ 1.1109 + return GroupRule::DeleteRule(aIndex); 1.1110 +} 1.1111 + 1.1112 +// nsIDOMCSSConditionRule methods 1.1113 +NS_IMETHODIMP 1.1114 +DocumentRule::GetConditionText(nsAString& aConditionText) 1.1115 +{ 1.1116 + aConditionText.Truncate(0); 1.1117 + AppendConditionText(aConditionText); 1.1118 + return NS_OK; 1.1119 +} 1.1120 + 1.1121 +NS_IMETHODIMP 1.1122 +DocumentRule::SetConditionText(const nsAString& aConditionText) 1.1123 +{ 1.1124 + return NS_ERROR_NOT_IMPLEMENTED; 1.1125 +} 1.1126 + 1.1127 +// GroupRule interface 1.1128 +/* virtual */ bool 1.1129 +DocumentRule::UseForPresentation(nsPresContext* aPresContext, 1.1130 + nsMediaQueryResultCacheKey& aKey) 1.1131 +{ 1.1132 + nsIDocument *doc = aPresContext->Document(); 1.1133 + nsIURI *docURI = doc->GetDocumentURI(); 1.1134 + nsAutoCString docURISpec; 1.1135 + if (docURI) 1.1136 + docURI->GetSpec(docURISpec); 1.1137 + 1.1138 + for (URL *url = mURLs; url; url = url->next) { 1.1139 + switch (url->func) { 1.1140 + case eURL: { 1.1141 + if (docURISpec == url->url) 1.1142 + return true; 1.1143 + } break; 1.1144 + case eURLPrefix: { 1.1145 + if (StringBeginsWith(docURISpec, url->url)) 1.1146 + return true; 1.1147 + } break; 1.1148 + case eDomain: { 1.1149 + nsAutoCString host; 1.1150 + if (docURI) 1.1151 + docURI->GetHost(host); 1.1152 + int32_t lenDiff = host.Length() - url->url.Length(); 1.1153 + if (lenDiff == 0) { 1.1154 + if (host == url->url) 1.1155 + return true; 1.1156 + } else { 1.1157 + if (StringEndsWith(host, url->url) && 1.1158 + host.CharAt(lenDiff - 1) == '.') 1.1159 + return true; 1.1160 + } 1.1161 + } break; 1.1162 + case eRegExp: { 1.1163 + NS_ConvertUTF8toUTF16 spec(docURISpec); 1.1164 + NS_ConvertUTF8toUTF16 regex(url->url); 1.1165 + if (nsContentUtils::IsPatternMatching(spec, regex, doc)) { 1.1166 + return true; 1.1167 + } 1.1168 + } break; 1.1169 + } 1.1170 + } 1.1171 + 1.1172 + return false; 1.1173 +} 1.1174 + 1.1175 +DocumentRule::URL::~URL() 1.1176 +{ 1.1177 + NS_CSS_DELETE_LIST_MEMBER(DocumentRule::URL, this, next); 1.1178 +} 1.1179 + 1.1180 +/* virtual */ size_t 1.1181 +DocumentRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const 1.1182 +{ 1.1183 + size_t n = aMallocSizeOf(this); 1.1184 + n += GroupRule::SizeOfExcludingThis(aMallocSizeOf); 1.1185 + 1.1186 + // Measurement of the following members may be added later if DMD finds it is 1.1187 + // worthwhile: 1.1188 + // - mURLs 1.1189 + 1.1190 + return n; 1.1191 +} 1.1192 + 1.1193 +void 1.1194 +DocumentRule::AppendConditionText(nsAString& aCssText) 1.1195 +{ 1.1196 + for (URL *url = mURLs; url; url = url->next) { 1.1197 + switch (url->func) { 1.1198 + case eURL: 1.1199 + aCssText.AppendLiteral("url("); 1.1200 + break; 1.1201 + case eURLPrefix: 1.1202 + aCssText.AppendLiteral("url-prefix("); 1.1203 + break; 1.1204 + case eDomain: 1.1205 + aCssText.AppendLiteral("domain("); 1.1206 + break; 1.1207 + case eRegExp: 1.1208 + aCssText.AppendLiteral("regexp("); 1.1209 + break; 1.1210 + } 1.1211 + nsStyleUtil::AppendEscapedCSSString(NS_ConvertUTF8toUTF16(url->url), 1.1212 + aCssText); 1.1213 + aCssText.AppendLiteral("), "); 1.1214 + } 1.1215 + aCssText.Truncate(aCssText.Length() - 2); // remove last ", " 1.1216 +} 1.1217 + 1.1218 +} // namespace css 1.1219 +} // namespace mozilla 1.1220 + 1.1221 +// Must be outside namespace 1.1222 +DOMCI_DATA(CSSMozDocumentRule, css::DocumentRule) 1.1223 + 1.1224 +// ------------------------------------------- 1.1225 +// NameSpaceRule 1.1226 +// 1.1227 + 1.1228 +namespace mozilla { 1.1229 +namespace css { 1.1230 + 1.1231 +NameSpaceRule::NameSpaceRule(nsIAtom* aPrefix, const nsString& aURLSpec) 1.1232 + : Rule(), 1.1233 + mPrefix(aPrefix), 1.1234 + mURLSpec(aURLSpec) 1.1235 +{ 1.1236 +} 1.1237 + 1.1238 +NameSpaceRule::NameSpaceRule(const NameSpaceRule& aCopy) 1.1239 + : Rule(aCopy), 1.1240 + mPrefix(aCopy.mPrefix), 1.1241 + mURLSpec(aCopy.mURLSpec) 1.1242 +{ 1.1243 +} 1.1244 + 1.1245 +NameSpaceRule::~NameSpaceRule() 1.1246 +{ 1.1247 +} 1.1248 + 1.1249 +NS_IMPL_ADDREF(NameSpaceRule) 1.1250 +NS_IMPL_RELEASE(NameSpaceRule) 1.1251 + 1.1252 +// QueryInterface implementation for NameSpaceRule 1.1253 +NS_INTERFACE_MAP_BEGIN(NameSpaceRule) 1.1254 + if (aIID.Equals(NS_GET_IID(css::NameSpaceRule))) { 1.1255 + *aInstancePtr = this; 1.1256 + NS_ADDREF_THIS(); 1.1257 + return NS_OK; 1.1258 + } 1.1259 + else 1.1260 + NS_INTERFACE_MAP_ENTRY(nsIStyleRule) 1.1261 + NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule) 1.1262 + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStyleRule) 1.1263 + NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSNameSpaceRule) 1.1264 +NS_INTERFACE_MAP_END 1.1265 + 1.1266 +IMPL_STYLE_RULE_INHERIT(NameSpaceRule, Rule) 1.1267 + 1.1268 +#ifdef DEBUG 1.1269 +/* virtual */ void 1.1270 +NameSpaceRule::List(FILE* out, int32_t aIndent) const 1.1271 +{ 1.1272 + for (int32_t indent = aIndent; --indent >= 0; ) fputs(" ", out); 1.1273 + 1.1274 + nsAutoString buffer; 1.1275 + 1.1276 + fputs("@namespace ", out); 1.1277 + 1.1278 + if (mPrefix) { 1.1279 + mPrefix->ToString(buffer); 1.1280 + fputs(NS_LossyConvertUTF16toASCII(buffer).get(), out); 1.1281 + fputs(" ", out); 1.1282 + } 1.1283 + 1.1284 + fputs("url(", out); 1.1285 + fputs(NS_LossyConvertUTF16toASCII(mURLSpec).get(), out); 1.1286 + fputs(")\n", out); 1.1287 +} 1.1288 +#endif 1.1289 + 1.1290 +/* virtual */ int32_t 1.1291 +NameSpaceRule::GetType() const 1.1292 +{ 1.1293 + return Rule::NAMESPACE_RULE; 1.1294 +} 1.1295 + 1.1296 +/* virtual */ already_AddRefed<Rule> 1.1297 +NameSpaceRule::Clone() const 1.1298 +{ 1.1299 + nsRefPtr<Rule> clone = new NameSpaceRule(*this); 1.1300 + return clone.forget(); 1.1301 +} 1.1302 + 1.1303 +NS_IMETHODIMP 1.1304 +NameSpaceRule::GetType(uint16_t* aType) 1.1305 +{ 1.1306 + *aType = nsIDOMCSSRule::NAMESPACE_RULE; 1.1307 + return NS_OK; 1.1308 +} 1.1309 + 1.1310 +NS_IMETHODIMP 1.1311 +NameSpaceRule::GetCssText(nsAString& aCssText) 1.1312 +{ 1.1313 + aCssText.AssignLiteral("@namespace "); 1.1314 + if (mPrefix) { 1.1315 + aCssText.Append(nsDependentAtomString(mPrefix) + NS_LITERAL_STRING(" ")); 1.1316 + } 1.1317 + aCssText.AppendLiteral("url("); 1.1318 + nsStyleUtil::AppendEscapedCSSString(mURLSpec, aCssText); 1.1319 + aCssText.Append(NS_LITERAL_STRING(");")); 1.1320 + return NS_OK; 1.1321 +} 1.1322 + 1.1323 +NS_IMETHODIMP 1.1324 +NameSpaceRule::SetCssText(const nsAString& aCssText) 1.1325 +{ 1.1326 + return NS_ERROR_NOT_IMPLEMENTED; 1.1327 +} 1.1328 + 1.1329 +NS_IMETHODIMP 1.1330 +NameSpaceRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet) 1.1331 +{ 1.1332 + return Rule::GetParentStyleSheet(aSheet); 1.1333 +} 1.1334 + 1.1335 +NS_IMETHODIMP 1.1336 +NameSpaceRule::GetParentRule(nsIDOMCSSRule** aParentRule) 1.1337 +{ 1.1338 + return Rule::GetParentRule(aParentRule); 1.1339 +} 1.1340 + 1.1341 +/* virtual */ size_t 1.1342 +NameSpaceRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const 1.1343 +{ 1.1344 + return aMallocSizeOf(this); 1.1345 + 1.1346 + // Measurement of the following members may be added later if DMD finds it is 1.1347 + // worthwhile: 1.1348 + // - mPrefix 1.1349 + // - mURLSpec 1.1350 +} 1.1351 + 1.1352 + 1.1353 +} // namespace css 1.1354 +} // namespace mozilla 1.1355 + 1.1356 +// Must be outside namespace 1.1357 +DOMCI_DATA(CSSNameSpaceRule, css::NameSpaceRule) 1.1358 + 1.1359 +// ------------------------------------------- 1.1360 +// nsCSSFontFaceStyleDecl and related routines 1.1361 +// 1.1362 + 1.1363 +// A src: descriptor is represented as an array value; each entry in 1.1364 +// the array can be eCSSUnit_URL, eCSSUnit_Local_Font, or 1.1365 +// eCSSUnit_Font_Format. Blocks of eCSSUnit_Font_Format may appear 1.1366 +// only after one of the first two. (css3-fonts only contemplates 1.1367 +// annotating URLs with formats, but we handle the general case.) 1.1368 +static void 1.1369 +AppendSerializedFontSrc(const nsCSSValue& src, nsAString & aResult) 1.1370 +{ 1.1371 + NS_PRECONDITION(src.GetUnit() == eCSSUnit_Array, 1.1372 + "improper value unit for src:"); 1.1373 + 1.1374 + const nsCSSValue::Array& sources = *src.GetArrayValue(); 1.1375 + size_t i = 0; 1.1376 + 1.1377 + while (i < sources.Count()) { 1.1378 + nsAutoString formats; 1.1379 + 1.1380 + if (sources[i].GetUnit() == eCSSUnit_URL) { 1.1381 + aResult.AppendLiteral("url("); 1.1382 + nsDependentString url(sources[i].GetOriginalURLValue()); 1.1383 + nsStyleUtil::AppendEscapedCSSString(url, aResult); 1.1384 + aResult.AppendLiteral(")"); 1.1385 + } else if (sources[i].GetUnit() == eCSSUnit_Local_Font) { 1.1386 + aResult.AppendLiteral("local("); 1.1387 + nsDependentString local(sources[i].GetStringBufferValue()); 1.1388 + nsStyleUtil::AppendEscapedCSSString(local, aResult); 1.1389 + aResult.AppendLiteral(")"); 1.1390 + } else { 1.1391 + NS_NOTREACHED("entry in src: descriptor with improper unit"); 1.1392 + i++; 1.1393 + continue; 1.1394 + } 1.1395 + 1.1396 + i++; 1.1397 + formats.Truncate(); 1.1398 + while (i < sources.Count() && 1.1399 + sources[i].GetUnit() == eCSSUnit_Font_Format) { 1.1400 + formats.Append('"'); 1.1401 + formats.Append(sources[i].GetStringBufferValue()); 1.1402 + formats.AppendLiteral("\", "); 1.1403 + i++; 1.1404 + } 1.1405 + if (formats.Length() > 0) { 1.1406 + formats.Truncate(formats.Length() - 2); // remove the last comma 1.1407 + aResult.AppendLiteral(" format("); 1.1408 + aResult.Append(formats); 1.1409 + aResult.Append(')'); 1.1410 + } 1.1411 + aResult.AppendLiteral(", "); 1.1412 + } 1.1413 + aResult.Truncate(aResult.Length() - 2); // remove the last comma-space 1.1414 +} 1.1415 + 1.1416 +// print all characters with at least four hex digits 1.1417 +static void 1.1418 +AppendSerializedUnicodePoint(uint32_t aCode, nsACString &aBuf) 1.1419 +{ 1.1420 + aBuf.Append(nsPrintfCString("%04X", aCode)); 1.1421 +} 1.1422 + 1.1423 +// A unicode-range: descriptor is represented as an array of integers, 1.1424 +// to be interpreted as a sequence of pairs: min max min max ... 1.1425 +// It is in source order. (Possibly it should be sorted and overlaps 1.1426 +// consolidated, but right now we don't do that.) 1.1427 +static void 1.1428 +AppendSerializedUnicodeRange(nsCSSValue const & aValue, 1.1429 + nsAString & aResult) 1.1430 +{ 1.1431 + NS_PRECONDITION(aValue.GetUnit() == eCSSUnit_Null || 1.1432 + aValue.GetUnit() == eCSSUnit_Array, 1.1433 + "improper value unit for unicode-range:"); 1.1434 + aResult.Truncate(); 1.1435 + if (aValue.GetUnit() != eCSSUnit_Array) 1.1436 + return; 1.1437 + 1.1438 + nsCSSValue::Array const & sources = *aValue.GetArrayValue(); 1.1439 + nsAutoCString buf; 1.1440 + 1.1441 + NS_ABORT_IF_FALSE(sources.Count() % 2 == 0, 1.1442 + "odd number of entries in a unicode-range: array"); 1.1443 + 1.1444 + for (uint32_t i = 0; i < sources.Count(); i += 2) { 1.1445 + uint32_t min = sources[i].GetIntValue(); 1.1446 + uint32_t max = sources[i+1].GetIntValue(); 1.1447 + 1.1448 + // We don't try to replicate the U+XX?? notation. 1.1449 + buf.AppendLiteral("U+"); 1.1450 + AppendSerializedUnicodePoint(min, buf); 1.1451 + 1.1452 + if (min != max) { 1.1453 + buf.Append('-'); 1.1454 + AppendSerializedUnicodePoint(max, buf); 1.1455 + } 1.1456 + buf.AppendLiteral(", "); 1.1457 + } 1.1458 + buf.Truncate(buf.Length() - 2); // remove the last comma-space 1.1459 + CopyASCIItoUTF16(buf, aResult); 1.1460 +} 1.1461 + 1.1462 +// Mapping from nsCSSFontDesc codes to nsCSSFontFaceStyleDecl fields. 1.1463 +nsCSSValue nsCSSFontFaceStyleDecl::* const 1.1464 +nsCSSFontFaceStyleDecl::Fields[] = { 1.1465 +#define CSS_FONT_DESC(name_, method_) &nsCSSFontFaceStyleDecl::m##method_, 1.1466 +#include "nsCSSFontDescList.h" 1.1467 +#undef CSS_FONT_DESC 1.1468 +}; 1.1469 + 1.1470 +// QueryInterface implementation for nsCSSFontFaceStyleDecl 1.1471 +NS_INTERFACE_MAP_BEGIN(nsCSSFontFaceStyleDecl) 1.1472 + NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY 1.1473 + NS_INTERFACE_MAP_ENTRY(nsIDOMCSSStyleDeclaration) 1.1474 + NS_INTERFACE_MAP_ENTRY(nsICSSDeclaration) 1.1475 + NS_INTERFACE_MAP_ENTRY(nsISupports) 1.1476 + // We forward the cycle collection interfaces to ContainingRule(), which is 1.1477 + // never null (in fact, we're part of that object!) 1.1478 + if (aIID.Equals(NS_GET_IID(nsCycleCollectionISupports)) || 1.1479 + aIID.Equals(NS_GET_IID(nsXPCOMCycleCollectionParticipant))) { 1.1480 + return ContainingRule()->QueryInterface(aIID, aInstancePtr); 1.1481 + } 1.1482 + else 1.1483 +NS_INTERFACE_MAP_END 1.1484 + 1.1485 +NS_IMPL_ADDREF_USING_AGGREGATOR(nsCSSFontFaceStyleDecl, ContainingRule()) 1.1486 +NS_IMPL_RELEASE_USING_AGGREGATOR(nsCSSFontFaceStyleDecl, ContainingRule()) 1.1487 + 1.1488 +// helper for string GetPropertyValue and RemovePropertyValue 1.1489 +nsresult 1.1490 +nsCSSFontFaceStyleDecl::GetPropertyValue(nsCSSFontDesc aFontDescID, 1.1491 + nsAString & aResult) const 1.1492 +{ 1.1493 + NS_ENSURE_ARG_RANGE(aFontDescID, eCSSFontDesc_UNKNOWN, 1.1494 + eCSSFontDesc_COUNT - 1); 1.1495 + 1.1496 + aResult.Truncate(); 1.1497 + if (aFontDescID == eCSSFontDesc_UNKNOWN) 1.1498 + return NS_OK; 1.1499 + 1.1500 + const nsCSSValue& val = this->*nsCSSFontFaceStyleDecl::Fields[aFontDescID]; 1.1501 + 1.1502 + if (val.GetUnit() == eCSSUnit_Null) { 1.1503 + // Avoid having to check no-value in the Family and Src cases below. 1.1504 + return NS_OK; 1.1505 + } 1.1506 + 1.1507 + switch (aFontDescID) { 1.1508 + case eCSSFontDesc_Family: { 1.1509 + // we don't use nsCSSValue::AppendToString here because it doesn't 1.1510 + // canonicalize the way we want, and anyway it's overkill when 1.1511 + // we know we have eCSSUnit_String 1.1512 + NS_ASSERTION(val.GetUnit() == eCSSUnit_String, "unexpected unit"); 1.1513 + nsDependentString family(val.GetStringBufferValue()); 1.1514 + nsStyleUtil::AppendEscapedCSSString(family, aResult); 1.1515 + return NS_OK; 1.1516 + } 1.1517 + 1.1518 + case eCSSFontDesc_Style: 1.1519 + val.AppendToString(eCSSProperty_font_style, aResult, 1.1520 + nsCSSValue::eNormalized); 1.1521 + return NS_OK; 1.1522 + 1.1523 + case eCSSFontDesc_Weight: 1.1524 + val.AppendToString(eCSSProperty_font_weight, aResult, 1.1525 + nsCSSValue::eNormalized); 1.1526 + return NS_OK; 1.1527 + 1.1528 + case eCSSFontDesc_Stretch: 1.1529 + val.AppendToString(eCSSProperty_font_stretch, aResult, 1.1530 + nsCSSValue::eNormalized); 1.1531 + return NS_OK; 1.1532 + 1.1533 + case eCSSFontDesc_FontFeatureSettings: 1.1534 + nsStyleUtil::AppendFontFeatureSettings(val, aResult); 1.1535 + return NS_OK; 1.1536 + 1.1537 + case eCSSFontDesc_FontLanguageOverride: 1.1538 + val.AppendToString(eCSSProperty_font_language_override, aResult, 1.1539 + nsCSSValue::eNormalized); 1.1540 + return NS_OK; 1.1541 + 1.1542 + case eCSSFontDesc_Src: 1.1543 + AppendSerializedFontSrc(val, aResult); 1.1544 + return NS_OK; 1.1545 + 1.1546 + case eCSSFontDesc_UnicodeRange: 1.1547 + AppendSerializedUnicodeRange(val, aResult); 1.1548 + return NS_OK; 1.1549 + 1.1550 + case eCSSFontDesc_UNKNOWN: 1.1551 + case eCSSFontDesc_COUNT: 1.1552 + ; 1.1553 + } 1.1554 + NS_NOTREACHED("nsCSSFontFaceStyleDecl::GetPropertyValue: " 1.1555 + "out-of-range value got to the switch"); 1.1556 + return NS_ERROR_INVALID_ARG; 1.1557 +} 1.1558 + 1.1559 + 1.1560 +// attribute DOMString cssText; 1.1561 +NS_IMETHODIMP 1.1562 +nsCSSFontFaceStyleDecl::GetCssText(nsAString & aCssText) 1.1563 +{ 1.1564 + nsAutoString descStr; 1.1565 + 1.1566 + aCssText.Truncate(); 1.1567 + for (nsCSSFontDesc id = nsCSSFontDesc(eCSSFontDesc_UNKNOWN + 1); 1.1568 + id < eCSSFontDesc_COUNT; 1.1569 + id = nsCSSFontDesc(id + 1)) { 1.1570 + if ((this->*nsCSSFontFaceStyleDecl::Fields[id]).GetUnit() 1.1571 + != eCSSUnit_Null && 1.1572 + NS_SUCCEEDED(GetPropertyValue(id, descStr))) { 1.1573 + NS_ASSERTION(descStr.Length() > 0, 1.1574 + "GetCssText: non-null unit, empty property value"); 1.1575 + aCssText.AppendLiteral(" "); 1.1576 + aCssText.AppendASCII(nsCSSProps::GetStringValue(id).get()); 1.1577 + aCssText.AppendLiteral(": "); 1.1578 + aCssText.Append(descStr); 1.1579 + aCssText.AppendLiteral(";\n"); 1.1580 + } 1.1581 + } 1.1582 + return NS_OK; 1.1583 +} 1.1584 + 1.1585 +NS_IMETHODIMP 1.1586 +nsCSSFontFaceStyleDecl::SetCssText(const nsAString & aCssText) 1.1587 +{ 1.1588 + return NS_ERROR_NOT_IMPLEMENTED; // bug 443978 1.1589 +} 1.1590 + 1.1591 +// DOMString getPropertyValue (in DOMString propertyName); 1.1592 +NS_IMETHODIMP 1.1593 +nsCSSFontFaceStyleDecl::GetPropertyValue(const nsAString & propertyName, 1.1594 + nsAString & aResult) 1.1595 +{ 1.1596 + return GetPropertyValue(nsCSSProps::LookupFontDesc(propertyName), aResult); 1.1597 +} 1.1598 + 1.1599 +NS_IMETHODIMP 1.1600 +nsCSSFontFaceStyleDecl::GetAuthoredPropertyValue(const nsAString& propertyName, 1.1601 + nsAString& aResult) 1.1602 +{ 1.1603 + // We don't return any authored property values different from 1.1604 + // GetPropertyValue, currently. 1.1605 + return GetPropertyValue(nsCSSProps::LookupFontDesc(propertyName), aResult); 1.1606 +} 1.1607 + 1.1608 +// nsIDOMCSSValue getPropertyCSSValue (in DOMString propertyName); 1.1609 +already_AddRefed<dom::CSSValue> 1.1610 +nsCSSFontFaceStyleDecl::GetPropertyCSSValue(const nsAString & propertyName, 1.1611 + ErrorResult& aRv) 1.1612 +{ 1.1613 + // ??? nsDOMCSSDeclaration returns null/NS_OK, but that seems wrong. 1.1614 + aRv.Throw(NS_ERROR_NOT_IMPLEMENTED); 1.1615 + return nullptr; 1.1616 +} 1.1617 + 1.1618 +// DOMString removeProperty (in DOMString propertyName) raises (DOMException); 1.1619 +NS_IMETHODIMP 1.1620 +nsCSSFontFaceStyleDecl::RemoveProperty(const nsAString & propertyName, 1.1621 + nsAString & aResult) 1.1622 +{ 1.1623 + nsCSSFontDesc descID = nsCSSProps::LookupFontDesc(propertyName); 1.1624 + NS_ASSERTION(descID >= eCSSFontDesc_UNKNOWN && 1.1625 + descID < eCSSFontDesc_COUNT, 1.1626 + "LookupFontDesc returned value out of range"); 1.1627 + 1.1628 + if (descID == eCSSFontDesc_UNKNOWN) { 1.1629 + aResult.Truncate(); 1.1630 + } else { 1.1631 + nsresult rv = GetPropertyValue(descID, aResult); 1.1632 + NS_ENSURE_SUCCESS(rv, rv); 1.1633 + (this->*nsCSSFontFaceStyleDecl::Fields[descID]).Reset(); 1.1634 + } 1.1635 + return NS_OK; 1.1636 +} 1.1637 + 1.1638 +// DOMString getPropertyPriority (in DOMString propertyName); 1.1639 +NS_IMETHODIMP 1.1640 +nsCSSFontFaceStyleDecl::GetPropertyPriority(const nsAString & propertyName, 1.1641 + nsAString & aResult) 1.1642 +{ 1.1643 + // font descriptors do not have priorities at present 1.1644 + aResult.Truncate(); 1.1645 + return NS_OK; 1.1646 +} 1.1647 + 1.1648 +// void setProperty (in DOMString propertyName, in DOMString value, 1.1649 +// in DOMString priority) raises (DOMException); 1.1650 +NS_IMETHODIMP 1.1651 +nsCSSFontFaceStyleDecl::SetProperty(const nsAString & propertyName, 1.1652 + const nsAString & value, 1.1653 + const nsAString & priority) 1.1654 +{ 1.1655 + return NS_ERROR_NOT_IMPLEMENTED; // bug 443978 1.1656 +} 1.1657 + 1.1658 +// readonly attribute unsigned long length; 1.1659 +NS_IMETHODIMP 1.1660 +nsCSSFontFaceStyleDecl::GetLength(uint32_t *aLength) 1.1661 +{ 1.1662 + uint32_t len = 0; 1.1663 + for (nsCSSFontDesc id = nsCSSFontDesc(eCSSFontDesc_UNKNOWN + 1); 1.1664 + id < eCSSFontDesc_COUNT; 1.1665 + id = nsCSSFontDesc(id + 1)) 1.1666 + if ((this->*nsCSSFontFaceStyleDecl::Fields[id]).GetUnit() != eCSSUnit_Null) 1.1667 + len++; 1.1668 + 1.1669 + *aLength = len; 1.1670 + return NS_OK; 1.1671 +} 1.1672 + 1.1673 +// DOMString item (in unsigned long index); 1.1674 +NS_IMETHODIMP 1.1675 +nsCSSFontFaceStyleDecl::Item(uint32_t aIndex, nsAString& aReturn) 1.1676 +{ 1.1677 + bool found; 1.1678 + IndexedGetter(aIndex, found, aReturn); 1.1679 + if (!found) { 1.1680 + aReturn.Truncate(); 1.1681 + } 1.1682 + return NS_OK; 1.1683 +} 1.1684 + 1.1685 +void 1.1686 +nsCSSFontFaceStyleDecl::IndexedGetter(uint32_t index, bool& aFound, nsAString & aResult) 1.1687 +{ 1.1688 + int32_t nset = -1; 1.1689 + for (nsCSSFontDesc id = nsCSSFontDesc(eCSSFontDesc_UNKNOWN + 1); 1.1690 + id < eCSSFontDesc_COUNT; 1.1691 + id = nsCSSFontDesc(id + 1)) { 1.1692 + if ((this->*nsCSSFontFaceStyleDecl::Fields[id]).GetUnit() 1.1693 + != eCSSUnit_Null) { 1.1694 + nset++; 1.1695 + if (nset == int32_t(index)) { 1.1696 + aFound = true; 1.1697 + aResult.AssignASCII(nsCSSProps::GetStringValue(id).get()); 1.1698 + return; 1.1699 + } 1.1700 + } 1.1701 + } 1.1702 + aFound = false; 1.1703 +} 1.1704 + 1.1705 +// readonly attribute nsIDOMCSSRule parentRule; 1.1706 +NS_IMETHODIMP 1.1707 +nsCSSFontFaceStyleDecl::GetParentRule(nsIDOMCSSRule** aParentRule) 1.1708 +{ 1.1709 + NS_IF_ADDREF(*aParentRule = ContainingRule()->GetDOMRule()); 1.1710 + return NS_OK; 1.1711 +} 1.1712 + 1.1713 +NS_IMETHODIMP 1.1714 +nsCSSFontFaceStyleDecl::GetPropertyValue(const nsCSSProperty aPropID, 1.1715 + nsAString& aValue) 1.1716 +{ 1.1717 + return 1.1718 + GetPropertyValue(NS_ConvertUTF8toUTF16(nsCSSProps::GetStringValue(aPropID)), 1.1719 + aValue); 1.1720 +} 1.1721 + 1.1722 +NS_IMETHODIMP 1.1723 +nsCSSFontFaceStyleDecl::SetPropertyValue(const nsCSSProperty aPropID, 1.1724 + const nsAString& aValue) 1.1725 +{ 1.1726 + return SetProperty(NS_ConvertUTF8toUTF16(nsCSSProps::GetStringValue(aPropID)), 1.1727 + aValue, EmptyString()); 1.1728 +} 1.1729 + 1.1730 +nsINode* 1.1731 +nsCSSFontFaceStyleDecl::GetParentObject() 1.1732 +{ 1.1733 + return ContainingRule()->GetDocument(); 1.1734 +} 1.1735 + 1.1736 +JSObject* 1.1737 +nsCSSFontFaceStyleDecl::WrapObject(JSContext *cx) 1.1738 +{ 1.1739 + return mozilla::dom::CSSStyleDeclarationBinding::Wrap(cx, this); 1.1740 +} 1.1741 + 1.1742 +// ------------------------------------------- 1.1743 +// nsCSSFontFaceRule 1.1744 +// 1.1745 + 1.1746 +/* virtual */ already_AddRefed<css::Rule> 1.1747 +nsCSSFontFaceRule::Clone() const 1.1748 +{ 1.1749 + nsRefPtr<css::Rule> clone = new nsCSSFontFaceRule(*this); 1.1750 + return clone.forget(); 1.1751 +} 1.1752 + 1.1753 +NS_IMPL_CYCLE_COLLECTING_ADDREF(nsCSSFontFaceRule) 1.1754 +NS_IMPL_CYCLE_COLLECTING_RELEASE(nsCSSFontFaceRule) 1.1755 + 1.1756 +NS_IMPL_CYCLE_COLLECTION_CLASS(nsCSSFontFaceRule) 1.1757 + 1.1758 +NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsCSSFontFaceRule) 1.1759 + // Trace the wrapper for our declaration. This just expands out 1.1760 + // NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER which we can't use 1.1761 + // directly because the wrapper is on the declaration, not on us. 1.1762 + tmp->mDecl.TraceWrapper(aCallbacks, aClosure); 1.1763 +NS_IMPL_CYCLE_COLLECTION_TRACE_END 1.1764 + 1.1765 +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsCSSFontFaceRule) 1.1766 + // Unlink the wrapper for our declaraton. This just expands out 1.1767 + // NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER which we can't use 1.1768 + // directly because the wrapper is on the declaration, not on us. 1.1769 + tmp->mDecl.ReleaseWrapper(static_cast<nsISupports*>(p)); 1.1770 +NS_IMPL_CYCLE_COLLECTION_UNLINK_END 1.1771 + 1.1772 +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsCSSFontFaceRule) 1.1773 + // Just NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS here: that will call 1.1774 + // into our Trace hook, where we do the right thing with declarations 1.1775 + // already. 1.1776 + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS 1.1777 +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END 1.1778 + 1.1779 +DOMCI_DATA(CSSFontFaceRule, nsCSSFontFaceRule) 1.1780 + 1.1781 +// QueryInterface implementation for nsCSSFontFaceRule 1.1782 +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsCSSFontFaceRule) 1.1783 + NS_INTERFACE_MAP_ENTRY(nsIStyleRule) 1.1784 + NS_INTERFACE_MAP_ENTRY(nsIDOMCSSFontFaceRule) 1.1785 + NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule) 1.1786 + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStyleRule) 1.1787 + NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSFontFaceRule) 1.1788 +NS_INTERFACE_MAP_END 1.1789 + 1.1790 +IMPL_STYLE_RULE_INHERIT(nsCSSFontFaceRule, Rule) 1.1791 + 1.1792 +#ifdef DEBUG 1.1793 +void 1.1794 +nsCSSFontFaceRule::List(FILE* out, int32_t aIndent) const 1.1795 +{ 1.1796 + nsCString baseInd, descInd; 1.1797 + for (int32_t indent = aIndent; --indent >= 0; ) { 1.1798 + baseInd.AppendLiteral(" "); 1.1799 + descInd.AppendLiteral(" "); 1.1800 + } 1.1801 + descInd.AppendLiteral(" "); 1.1802 + 1.1803 + nsString descStr; 1.1804 + 1.1805 + fprintf(out, "%s@font-face {\n", baseInd.get()); 1.1806 + for (nsCSSFontDesc id = nsCSSFontDesc(eCSSFontDesc_UNKNOWN + 1); 1.1807 + id < eCSSFontDesc_COUNT; 1.1808 + id = nsCSSFontDesc(id + 1)) 1.1809 + if ((mDecl.*nsCSSFontFaceStyleDecl::Fields[id]).GetUnit() 1.1810 + != eCSSUnit_Null) { 1.1811 + if (NS_FAILED(mDecl.GetPropertyValue(id, descStr))) 1.1812 + descStr.AssignLiteral("#<serialization error>"); 1.1813 + else if (descStr.Length() == 0) 1.1814 + descStr.AssignLiteral("#<serialization missing>"); 1.1815 + fprintf(out, "%s%s: %s\n", 1.1816 + descInd.get(), nsCSSProps::GetStringValue(id).get(), 1.1817 + NS_ConvertUTF16toUTF8(descStr).get()); 1.1818 + } 1.1819 + fprintf(out, "%s}\n", baseInd.get()); 1.1820 +} 1.1821 +#endif 1.1822 + 1.1823 +/* virtual */ int32_t 1.1824 +nsCSSFontFaceRule::GetType() const 1.1825 +{ 1.1826 + return Rule::FONT_FACE_RULE; 1.1827 +} 1.1828 + 1.1829 +NS_IMETHODIMP 1.1830 +nsCSSFontFaceRule::GetType(uint16_t* aType) 1.1831 +{ 1.1832 + *aType = nsIDOMCSSRule::FONT_FACE_RULE; 1.1833 + return NS_OK; 1.1834 +} 1.1835 + 1.1836 +NS_IMETHODIMP 1.1837 +nsCSSFontFaceRule::GetCssText(nsAString& aCssText) 1.1838 +{ 1.1839 + nsAutoString propText; 1.1840 + mDecl.GetCssText(propText); 1.1841 + 1.1842 + aCssText.AssignLiteral("@font-face {\n"); 1.1843 + aCssText.Append(propText); 1.1844 + aCssText.Append('}'); 1.1845 + return NS_OK; 1.1846 +} 1.1847 + 1.1848 +NS_IMETHODIMP 1.1849 +nsCSSFontFaceRule::SetCssText(const nsAString& aCssText) 1.1850 +{ 1.1851 + return NS_ERROR_NOT_IMPLEMENTED; // bug 443978 1.1852 +} 1.1853 + 1.1854 +NS_IMETHODIMP 1.1855 +nsCSSFontFaceRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet) 1.1856 +{ 1.1857 + return Rule::GetParentStyleSheet(aSheet); 1.1858 +} 1.1859 + 1.1860 +NS_IMETHODIMP 1.1861 +nsCSSFontFaceRule::GetParentRule(nsIDOMCSSRule** aParentRule) 1.1862 +{ 1.1863 + return Rule::GetParentRule(aParentRule); 1.1864 +} 1.1865 + 1.1866 +NS_IMETHODIMP 1.1867 +nsCSSFontFaceRule::GetStyle(nsIDOMCSSStyleDeclaration** aStyle) 1.1868 +{ 1.1869 + NS_IF_ADDREF(*aStyle = &mDecl); 1.1870 + return NS_OK; 1.1871 +} 1.1872 + 1.1873 +// Arguably these should forward to nsCSSFontFaceStyleDecl methods. 1.1874 +void 1.1875 +nsCSSFontFaceRule::SetDesc(nsCSSFontDesc aDescID, nsCSSValue const & aValue) 1.1876 +{ 1.1877 + NS_PRECONDITION(aDescID > eCSSFontDesc_UNKNOWN && 1.1878 + aDescID < eCSSFontDesc_COUNT, 1.1879 + "aDescID out of range in nsCSSFontFaceRule::SetDesc"); 1.1880 + 1.1881 + // FIXME: handle dynamic changes 1.1882 + 1.1883 + mDecl.*nsCSSFontFaceStyleDecl::Fields[aDescID] = aValue; 1.1884 +} 1.1885 + 1.1886 +void 1.1887 +nsCSSFontFaceRule::GetDesc(nsCSSFontDesc aDescID, nsCSSValue & aValue) 1.1888 +{ 1.1889 + NS_PRECONDITION(aDescID > eCSSFontDesc_UNKNOWN && 1.1890 + aDescID < eCSSFontDesc_COUNT, 1.1891 + "aDescID out of range in nsCSSFontFaceRule::GetDesc"); 1.1892 + 1.1893 + aValue = mDecl.*nsCSSFontFaceStyleDecl::Fields[aDescID]; 1.1894 +} 1.1895 + 1.1896 +/* virtual */ size_t 1.1897 +nsCSSFontFaceRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const 1.1898 +{ 1.1899 + return aMallocSizeOf(this); 1.1900 + 1.1901 + // Measurement of the following members may be added later if DMD finds it is 1.1902 + // worthwhile: 1.1903 + // - mDecl 1.1904 +} 1.1905 + 1.1906 + 1.1907 +// ----------------------------------- 1.1908 +// nsCSSFontFeatureValuesRule 1.1909 +// 1.1910 + 1.1911 +/* virtual */ already_AddRefed<css::Rule> 1.1912 +nsCSSFontFeatureValuesRule::Clone() const 1.1913 +{ 1.1914 + nsRefPtr<css::Rule> clone = new nsCSSFontFeatureValuesRule(*this); 1.1915 + return clone.forget(); 1.1916 +} 1.1917 + 1.1918 +NS_IMPL_ADDREF(nsCSSFontFeatureValuesRule) 1.1919 +NS_IMPL_RELEASE(nsCSSFontFeatureValuesRule) 1.1920 + 1.1921 +DOMCI_DATA(CSSFontFeatureValuesRule, nsCSSFontFeatureValuesRule) 1.1922 + 1.1923 +// QueryInterface implementation for nsCSSFontFeatureValuesRule 1.1924 +NS_INTERFACE_MAP_BEGIN(nsCSSFontFeatureValuesRule) 1.1925 + NS_INTERFACE_MAP_ENTRY(nsIStyleRule) 1.1926 + NS_INTERFACE_MAP_ENTRY(nsIDOMCSSFontFeatureValuesRule) 1.1927 + NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule) 1.1928 + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStyleRule) 1.1929 + NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSFontFeatureValuesRule) 1.1930 +NS_INTERFACE_MAP_END 1.1931 + 1.1932 +IMPL_STYLE_RULE_INHERIT(nsCSSFontFeatureValuesRule, Rule) 1.1933 + 1.1934 +static void 1.1935 +FamilyListToString(const nsTArray<nsString>& aFamilyList, nsAString& aOutStr) 1.1936 +{ 1.1937 + uint32_t i, n = aFamilyList.Length(); 1.1938 + 1.1939 + for (i = 0; i < n; i++) { 1.1940 + nsStyleUtil::AppendEscapedCSSString(aFamilyList[i], aOutStr); 1.1941 + if (i != n - 1) { 1.1942 + aOutStr.AppendLiteral(", "); 1.1943 + } 1.1944 + } 1.1945 +} 1.1946 + 1.1947 +static void 1.1948 +FeatureValuesToString( 1.1949 + const nsTArray<gfxFontFeatureValueSet::FeatureValues>& aFeatureValues, 1.1950 + nsAString& aOutStr) 1.1951 +{ 1.1952 + uint32_t i, n; 1.1953 + 1.1954 + // append values 1.1955 + n = aFeatureValues.Length(); 1.1956 + for (i = 0; i < n; i++) { 1.1957 + const gfxFontFeatureValueSet::FeatureValues& fv = aFeatureValues[i]; 1.1958 + 1.1959 + // @alternate 1.1960 + aOutStr.AppendLiteral(" @"); 1.1961 + nsAutoString functAlt; 1.1962 + nsStyleUtil::GetFunctionalAlternatesName(fv.alternate, functAlt); 1.1963 + aOutStr.Append(functAlt); 1.1964 + aOutStr.AppendLiteral(" {"); 1.1965 + 1.1966 + // for each ident-values tuple 1.1967 + uint32_t j, numValues = fv.valuelist.Length(); 1.1968 + for (j = 0; j < numValues; j++) { 1.1969 + aOutStr.AppendLiteral(" "); 1.1970 + const gfxFontFeatureValueSet::ValueList& vlist = fv.valuelist[j]; 1.1971 + nsStyleUtil::AppendEscapedCSSIdent(vlist.name, aOutStr); 1.1972 + aOutStr.AppendLiteral(":"); 1.1973 + 1.1974 + uint32_t k, numSelectors = vlist.featureSelectors.Length(); 1.1975 + for (k = 0; k < numSelectors; k++) { 1.1976 + aOutStr.AppendLiteral(" "); 1.1977 + aOutStr.AppendInt(vlist.featureSelectors[k]); 1.1978 + } 1.1979 + 1.1980 + aOutStr.AppendLiteral(";"); 1.1981 + } 1.1982 + aOutStr.AppendLiteral(" }\n"); 1.1983 + } 1.1984 +} 1.1985 + 1.1986 +static void 1.1987 +FontFeatureValuesRuleToString( 1.1988 + const nsTArray<nsString>& aFamilyList, 1.1989 + const nsTArray<gfxFontFeatureValueSet::FeatureValues>& aFeatureValues, 1.1990 + nsAString& aOutStr) 1.1991 +{ 1.1992 + aOutStr.AssignLiteral("@font-feature-values "); 1.1993 + nsAutoString familyListStr, valueTextStr; 1.1994 + FamilyListToString(aFamilyList, familyListStr); 1.1995 + aOutStr.Append(familyListStr); 1.1996 + aOutStr.AppendLiteral(" {\n"); 1.1997 + FeatureValuesToString(aFeatureValues, valueTextStr); 1.1998 + aOutStr.Append(valueTextStr); 1.1999 + aOutStr.AppendLiteral("}"); 1.2000 +} 1.2001 + 1.2002 +#ifdef DEBUG 1.2003 +void 1.2004 +nsCSSFontFeatureValuesRule::List(FILE* out, int32_t aIndent) const 1.2005 +{ 1.2006 + nsAutoString text; 1.2007 + FontFeatureValuesRuleToString(mFamilyList, mFeatureValues, text); 1.2008 + NS_ConvertUTF16toUTF8 utf8(text); 1.2009 + 1.2010 + // replace newlines with newlines plus indent spaces 1.2011 + char* indent = new char[(aIndent + 1) * 2]; 1.2012 + int32_t i; 1.2013 + for (i = 1; i < (aIndent + 1) * 2 - 1; i++) { 1.2014 + indent[i] = 0x20; 1.2015 + } 1.2016 + indent[0] = 0xa; 1.2017 + indent[aIndent * 2 + 1] = 0; 1.2018 + utf8.ReplaceSubstring("\n", indent); 1.2019 + delete [] indent; 1.2020 + 1.2021 + for (i = aIndent; --i >= 0; ) fputs(" ", out); 1.2022 + fprintf(out, "%s\n", utf8.get()); 1.2023 +} 1.2024 +#endif 1.2025 + 1.2026 +/* virtual */ int32_t 1.2027 +nsCSSFontFeatureValuesRule::GetType() const 1.2028 +{ 1.2029 + return Rule::FONT_FEATURE_VALUES_RULE; 1.2030 +} 1.2031 + 1.2032 +NS_IMETHODIMP 1.2033 +nsCSSFontFeatureValuesRule::GetType(uint16_t* aType) 1.2034 +{ 1.2035 + *aType = nsIDOMCSSRule::FONT_FEATURE_VALUES_RULE; 1.2036 + return NS_OK; 1.2037 +} 1.2038 + 1.2039 +NS_IMETHODIMP 1.2040 +nsCSSFontFeatureValuesRule::GetCssText(nsAString& aCssText) 1.2041 +{ 1.2042 + FontFeatureValuesRuleToString(mFamilyList, mFeatureValues, aCssText); 1.2043 + return NS_OK; 1.2044 +} 1.2045 + 1.2046 +NS_IMETHODIMP 1.2047 +nsCSSFontFeatureValuesRule::SetCssText(const nsAString& aCssText) 1.2048 +{ 1.2049 + // FIXME: implement??? 1.2050 + return NS_ERROR_NOT_IMPLEMENTED; 1.2051 +} 1.2052 + 1.2053 +NS_IMETHODIMP 1.2054 +nsCSSFontFeatureValuesRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet) 1.2055 +{ 1.2056 + return Rule::GetParentStyleSheet(aSheet); 1.2057 +} 1.2058 + 1.2059 +NS_IMETHODIMP 1.2060 +nsCSSFontFeatureValuesRule::GetParentRule(nsIDOMCSSRule** aParentRule) 1.2061 +{ 1.2062 + return Rule::GetParentRule(aParentRule); 1.2063 +} 1.2064 + 1.2065 +NS_IMETHODIMP 1.2066 +nsCSSFontFeatureValuesRule::GetFontFamily(nsAString& aFontFamily) 1.2067 +{ 1.2068 + FamilyListToString(mFamilyList, aFontFamily); 1.2069 + return NS_OK; 1.2070 +} 1.2071 + 1.2072 +NS_IMETHODIMP 1.2073 +nsCSSFontFeatureValuesRule::SetFontFamily(const nsAString& aFontFamily) 1.2074 +{ 1.2075 + return NS_ERROR_NOT_IMPLEMENTED; 1.2076 +} 1.2077 + 1.2078 +NS_IMETHODIMP 1.2079 +nsCSSFontFeatureValuesRule::GetValueText(nsAString& aValueText) 1.2080 +{ 1.2081 + FeatureValuesToString(mFeatureValues, aValueText); 1.2082 + return NS_OK; 1.2083 +} 1.2084 + 1.2085 +NS_IMETHODIMP 1.2086 +nsCSSFontFeatureValuesRule::SetValueText(const nsAString& aValueText) 1.2087 +{ 1.2088 + return NS_ERROR_NOT_IMPLEMENTED; 1.2089 +} 1.2090 + 1.2091 +struct MakeFamilyArray { 1.2092 + MakeFamilyArray(nsTArray<nsString>& aFamilyArray) 1.2093 + : familyArray(aFamilyArray), hasGeneric(false) 1.2094 + {} 1.2095 + 1.2096 + static bool 1.2097 + AddFamily(const nsString& aFamily, bool aGeneric, void* aData) 1.2098 + { 1.2099 + MakeFamilyArray *familyArr = reinterpret_cast<MakeFamilyArray*> (aData); 1.2100 + if (!aGeneric && !aFamily.IsEmpty()) { 1.2101 + familyArr->familyArray.AppendElement(aFamily); 1.2102 + } 1.2103 + if (aGeneric) { 1.2104 + familyArr->hasGeneric = true; 1.2105 + } 1.2106 + return true; 1.2107 + } 1.2108 + 1.2109 + nsTArray<nsString>& familyArray; 1.2110 + bool hasGeneric; 1.2111 +}; 1.2112 + 1.2113 +void 1.2114 +nsCSSFontFeatureValuesRule::SetFamilyList(const nsAString& aFamilyList, 1.2115 + bool& aContainsGeneric) 1.2116 +{ 1.2117 + nsFont font(aFamilyList, 0, 0, 0, 0, 0, 0); 1.2118 + MakeFamilyArray families(mFamilyList); 1.2119 + font.EnumerateFamilies(MakeFamilyArray::AddFamily, (void*) &families); 1.2120 + aContainsGeneric = families.hasGeneric; 1.2121 +} 1.2122 + 1.2123 +void 1.2124 +nsCSSFontFeatureValuesRule::AddValueList(int32_t aVariantAlternate, 1.2125 + nsTArray<gfxFontFeatureValueSet::ValueList>& aValueList) 1.2126 +{ 1.2127 + uint32_t i, len = mFeatureValues.Length(); 1.2128 + bool foundAlternate = false; 1.2129 + 1.2130 + // add to an existing list for a given property value 1.2131 + for (i = 0; i < len; i++) { 1.2132 + gfxFontFeatureValueSet::FeatureValues& f = mFeatureValues.ElementAt(i); 1.2133 + 1.2134 + if (f.alternate == uint32_t(aVariantAlternate)) { 1.2135 + f.valuelist.AppendElements(aValueList); 1.2136 + foundAlternate = true; 1.2137 + break; 1.2138 + } 1.2139 + } 1.2140 + 1.2141 + // create a new list for a given property value 1.2142 + if (!foundAlternate) { 1.2143 + gfxFontFeatureValueSet::FeatureValues &f = *mFeatureValues.AppendElement(); 1.2144 + f.alternate = aVariantAlternate; 1.2145 + f.valuelist.AppendElements(aValueList); 1.2146 + } 1.2147 +} 1.2148 + 1.2149 +size_t 1.2150 +nsCSSFontFeatureValuesRule::SizeOfIncludingThis( 1.2151 + MallocSizeOf aMallocSizeOf) const 1.2152 +{ 1.2153 + return aMallocSizeOf(this); 1.2154 +} 1.2155 + 1.2156 +// ------------------------------------------- 1.2157 +// nsCSSKeyframeStyleDeclaration 1.2158 +// 1.2159 + 1.2160 +nsCSSKeyframeStyleDeclaration::nsCSSKeyframeStyleDeclaration(nsCSSKeyframeRule *aRule) 1.2161 + : mRule(aRule) 1.2162 +{ 1.2163 +} 1.2164 + 1.2165 +nsCSSKeyframeStyleDeclaration::~nsCSSKeyframeStyleDeclaration() 1.2166 +{ 1.2167 + NS_ASSERTION(!mRule, "DropReference not called."); 1.2168 +} 1.2169 + 1.2170 +NS_IMPL_CYCLE_COLLECTING_ADDREF(nsCSSKeyframeStyleDeclaration) 1.2171 +NS_IMPL_CYCLE_COLLECTING_RELEASE(nsCSSKeyframeStyleDeclaration) 1.2172 + 1.2173 +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(nsCSSKeyframeStyleDeclaration) 1.2174 + 1.2175 +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsCSSKeyframeStyleDeclaration) 1.2176 + NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY 1.2177 +NS_INTERFACE_MAP_END_INHERITING(nsDOMCSSDeclaration) 1.2178 + 1.2179 +css::Declaration* 1.2180 +nsCSSKeyframeStyleDeclaration::GetCSSDeclaration(bool aAllocate) 1.2181 +{ 1.2182 + if (mRule) { 1.2183 + return mRule->Declaration(); 1.2184 + } else { 1.2185 + return nullptr; 1.2186 + } 1.2187 +} 1.2188 + 1.2189 +void 1.2190 +nsCSSKeyframeStyleDeclaration::GetCSSParsingEnvironment(CSSParsingEnvironment& aCSSParseEnv) 1.2191 +{ 1.2192 + GetCSSParsingEnvironmentForRule(mRule, aCSSParseEnv); 1.2193 +} 1.2194 + 1.2195 +NS_IMETHODIMP 1.2196 +nsCSSKeyframeStyleDeclaration::GetParentRule(nsIDOMCSSRule **aParent) 1.2197 +{ 1.2198 + NS_ENSURE_ARG_POINTER(aParent); 1.2199 + 1.2200 + NS_IF_ADDREF(*aParent = mRule); 1.2201 + return NS_OK; 1.2202 +} 1.2203 + 1.2204 +nsresult 1.2205 +nsCSSKeyframeStyleDeclaration::SetCSSDeclaration(css::Declaration* aDecl) 1.2206 +{ 1.2207 + NS_ABORT_IF_FALSE(aDecl, "must be non-null"); 1.2208 + mRule->ChangeDeclaration(aDecl); 1.2209 + return NS_OK; 1.2210 +} 1.2211 + 1.2212 +nsIDocument* 1.2213 +nsCSSKeyframeStyleDeclaration::DocToUpdate() 1.2214 +{ 1.2215 + return nullptr; 1.2216 +} 1.2217 + 1.2218 +nsINode* 1.2219 +nsCSSKeyframeStyleDeclaration::GetParentObject() 1.2220 +{ 1.2221 + return mRule ? mRule->GetDocument() : nullptr; 1.2222 +} 1.2223 + 1.2224 +// ------------------------------------------- 1.2225 +// nsCSSKeyframeRule 1.2226 +// 1.2227 + 1.2228 +nsCSSKeyframeRule::nsCSSKeyframeRule(const nsCSSKeyframeRule& aCopy) 1.2229 + // copy everything except our reference count and mDOMDeclaration 1.2230 + : Rule(aCopy) 1.2231 + , mKeys(aCopy.mKeys) 1.2232 + , mDeclaration(new css::Declaration(*aCopy.mDeclaration)) 1.2233 +{ 1.2234 +} 1.2235 + 1.2236 +nsCSSKeyframeRule::~nsCSSKeyframeRule() 1.2237 +{ 1.2238 + if (mDOMDeclaration) { 1.2239 + mDOMDeclaration->DropReference(); 1.2240 + } 1.2241 +} 1.2242 + 1.2243 +/* virtual */ already_AddRefed<css::Rule> 1.2244 +nsCSSKeyframeRule::Clone() const 1.2245 +{ 1.2246 + nsRefPtr<css::Rule> clone = new nsCSSKeyframeRule(*this); 1.2247 + return clone.forget(); 1.2248 +} 1.2249 + 1.2250 +NS_IMPL_CYCLE_COLLECTING_ADDREF(nsCSSKeyframeRule) 1.2251 +NS_IMPL_CYCLE_COLLECTING_RELEASE(nsCSSKeyframeRule) 1.2252 + 1.2253 +NS_IMPL_CYCLE_COLLECTION_CLASS(nsCSSKeyframeRule) 1.2254 + 1.2255 +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsCSSKeyframeRule) 1.2256 + if (tmp->mDOMDeclaration) { 1.2257 + tmp->mDOMDeclaration->DropReference(); 1.2258 + tmp->mDOMDeclaration = nullptr; 1.2259 + } 1.2260 +NS_IMPL_CYCLE_COLLECTION_UNLINK_END 1.2261 +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsCSSKeyframeRule) 1.2262 + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDOMDeclaration) 1.2263 +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END 1.2264 + 1.2265 +DOMCI_DATA(MozCSSKeyframeRule, nsCSSKeyframeRule) 1.2266 + 1.2267 +// QueryInterface implementation for nsCSSKeyframeRule 1.2268 +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsCSSKeyframeRule) 1.2269 + NS_INTERFACE_MAP_ENTRY(nsIStyleRule) 1.2270 + NS_INTERFACE_MAP_ENTRY(nsIDOMMozCSSKeyframeRule) 1.2271 + NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule) 1.2272 + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStyleRule) 1.2273 + NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MozCSSKeyframeRule) 1.2274 +NS_INTERFACE_MAP_END 1.2275 + 1.2276 +IMPL_STYLE_RULE_INHERIT_GET_DOM_RULE_WEAK(nsCSSKeyframeRule, Rule) 1.2277 + 1.2278 +/* virtual */ void 1.2279 +nsCSSKeyframeRule::MapRuleInfoInto(nsRuleData* aRuleData) 1.2280 +{ 1.2281 + // We need to implement MapRuleInfoInto because the animation manager 1.2282 + // constructs a rule node pointing to us in order to compute the 1.2283 + // styles it needs to animate. 1.2284 + 1.2285 + // The spec says that !important declarations should just be ignored 1.2286 + NS_ASSERTION(!mDeclaration->HasImportantData(), 1.2287 + "Keyframe rules has !important data"); 1.2288 + 1.2289 + mDeclaration->MapNormalRuleInfoInto(aRuleData); 1.2290 +} 1.2291 + 1.2292 +#ifdef DEBUG 1.2293 +void 1.2294 +nsCSSKeyframeRule::List(FILE* out, int32_t aIndent) const 1.2295 +{ 1.2296 + for (int32_t index = aIndent; --index >= 0; ) fputs(" ", out); 1.2297 + 1.2298 + nsAutoString tmp; 1.2299 + DoGetKeyText(tmp); 1.2300 + fputs(NS_ConvertUTF16toUTF8(tmp).get(), out); 1.2301 + fputs(" ", out); 1.2302 + mDeclaration->List(out, aIndent); 1.2303 + fputs("\n", out); 1.2304 +} 1.2305 +#endif 1.2306 + 1.2307 +/* virtual */ int32_t 1.2308 +nsCSSKeyframeRule::GetType() const 1.2309 +{ 1.2310 + return Rule::KEYFRAME_RULE; 1.2311 +} 1.2312 + 1.2313 +NS_IMETHODIMP 1.2314 +nsCSSKeyframeRule::GetType(uint16_t* aType) 1.2315 +{ 1.2316 + *aType = nsIDOMCSSRule::KEYFRAME_RULE; 1.2317 + return NS_OK; 1.2318 +} 1.2319 + 1.2320 +NS_IMETHODIMP 1.2321 +nsCSSKeyframeRule::GetCssText(nsAString& aCssText) 1.2322 +{ 1.2323 + DoGetKeyText(aCssText); 1.2324 + aCssText.AppendLiteral(" { "); 1.2325 + nsAutoString tmp; 1.2326 + mDeclaration->ToString(tmp); 1.2327 + aCssText.Append(tmp); 1.2328 + aCssText.AppendLiteral(" }"); 1.2329 + return NS_OK; 1.2330 +} 1.2331 + 1.2332 +NS_IMETHODIMP 1.2333 +nsCSSKeyframeRule::SetCssText(const nsAString& aCssText) 1.2334 +{ 1.2335 + // FIXME: implement??? 1.2336 + return NS_ERROR_NOT_IMPLEMENTED; 1.2337 +} 1.2338 + 1.2339 +NS_IMETHODIMP 1.2340 +nsCSSKeyframeRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet) 1.2341 +{ 1.2342 + return Rule::GetParentStyleSheet(aSheet); 1.2343 +} 1.2344 + 1.2345 +NS_IMETHODIMP 1.2346 +nsCSSKeyframeRule::GetParentRule(nsIDOMCSSRule** aParentRule) 1.2347 +{ 1.2348 + return Rule::GetParentRule(aParentRule); 1.2349 +} 1.2350 + 1.2351 +NS_IMETHODIMP 1.2352 +nsCSSKeyframeRule::GetKeyText(nsAString& aKeyText) 1.2353 +{ 1.2354 + DoGetKeyText(aKeyText); 1.2355 + return NS_OK; 1.2356 +} 1.2357 + 1.2358 +void 1.2359 +nsCSSKeyframeRule::DoGetKeyText(nsAString& aKeyText) const 1.2360 +{ 1.2361 + aKeyText.Truncate(); 1.2362 + uint32_t i = 0, i_end = mKeys.Length(); 1.2363 + NS_ABORT_IF_FALSE(i_end != 0, "must have some keys"); 1.2364 + for (;;) { 1.2365 + aKeyText.AppendFloat(mKeys[i] * 100.0f); 1.2366 + aKeyText.Append(char16_t('%')); 1.2367 + if (++i == i_end) { 1.2368 + break; 1.2369 + } 1.2370 + aKeyText.AppendLiteral(", "); 1.2371 + } 1.2372 +} 1.2373 + 1.2374 +NS_IMETHODIMP 1.2375 +nsCSSKeyframeRule::SetKeyText(const nsAString& aKeyText) 1.2376 +{ 1.2377 + nsCSSParser parser; 1.2378 + 1.2379 + InfallibleTArray<float> newSelectors; 1.2380 + // FIXME: pass filename and line number 1.2381 + if (!parser.ParseKeyframeSelectorString(aKeyText, nullptr, 0, newSelectors)) { 1.2382 + // for now, we don't do anything if the parse fails 1.2383 + return NS_OK; 1.2384 + } 1.2385 + 1.2386 + nsIDocument* doc = GetDocument(); 1.2387 + MOZ_AUTO_DOC_UPDATE(doc, UPDATE_STYLE, true); 1.2388 + 1.2389 + newSelectors.SwapElements(mKeys); 1.2390 + 1.2391 + nsCSSStyleSheet* sheet = GetStyleSheet(); 1.2392 + if (sheet) { 1.2393 + sheet->SetModifiedByChildRule(); 1.2394 + 1.2395 + if (doc) { 1.2396 + doc->StyleRuleChanged(sheet, this, this); 1.2397 + } 1.2398 + } 1.2399 + 1.2400 + return NS_OK; 1.2401 +} 1.2402 + 1.2403 +NS_IMETHODIMP 1.2404 +nsCSSKeyframeRule::GetStyle(nsIDOMCSSStyleDeclaration** aStyle) 1.2405 +{ 1.2406 + if (!mDOMDeclaration) { 1.2407 + mDOMDeclaration = new nsCSSKeyframeStyleDeclaration(this); 1.2408 + } 1.2409 + NS_ADDREF(*aStyle = mDOMDeclaration); 1.2410 + return NS_OK; 1.2411 +} 1.2412 + 1.2413 +void 1.2414 +nsCSSKeyframeRule::ChangeDeclaration(css::Declaration* aDeclaration) 1.2415 +{ 1.2416 + // Our caller already did a BeginUpdate/EndUpdate, but with 1.2417 + // UPDATE_CONTENT, and we need UPDATE_STYLE to trigger work in 1.2418 + // PresShell::EndUpdate. 1.2419 + nsIDocument* doc = GetDocument(); 1.2420 + MOZ_AUTO_DOC_UPDATE(doc, UPDATE_STYLE, true); 1.2421 + 1.2422 + // Be careful to not assign to an nsAutoPtr if we would be assigning 1.2423 + // the thing it already holds. 1.2424 + if (aDeclaration != mDeclaration) { 1.2425 + mDeclaration = aDeclaration; 1.2426 + } 1.2427 + 1.2428 + nsCSSStyleSheet* sheet = GetStyleSheet(); 1.2429 + if (sheet) { 1.2430 + sheet->SetModifiedByChildRule(); 1.2431 + 1.2432 + if (doc) { 1.2433 + doc->StyleRuleChanged(sheet, this, this); 1.2434 + } 1.2435 + } 1.2436 +} 1.2437 + 1.2438 +/* virtual */ size_t 1.2439 +nsCSSKeyframeRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const 1.2440 +{ 1.2441 + return aMallocSizeOf(this); 1.2442 + 1.2443 + // Measurement of the following members may be added later if DMD finds it is 1.2444 + // worthwhile: 1.2445 + // - mKeys 1.2446 + // - mDeclaration 1.2447 + // - mDOMDeclaration 1.2448 +} 1.2449 + 1.2450 + 1.2451 +// ------------------------------------------- 1.2452 +// nsCSSKeyframesRule 1.2453 +// 1.2454 + 1.2455 +nsCSSKeyframesRule::nsCSSKeyframesRule(const nsCSSKeyframesRule& aCopy) 1.2456 + // copy everything except our reference count. GroupRule's copy 1.2457 + // constructor also doesn't copy the lazily-constructed 1.2458 + // mRuleCollection. 1.2459 + : GroupRule(aCopy), 1.2460 + mName(aCopy.mName) 1.2461 +{ 1.2462 +} 1.2463 + 1.2464 +nsCSSKeyframesRule::~nsCSSKeyframesRule() 1.2465 +{ 1.2466 +} 1.2467 + 1.2468 +/* virtual */ already_AddRefed<css::Rule> 1.2469 +nsCSSKeyframesRule::Clone() const 1.2470 +{ 1.2471 + nsRefPtr<css::Rule> clone = new nsCSSKeyframesRule(*this); 1.2472 + return clone.forget(); 1.2473 +} 1.2474 + 1.2475 +NS_IMPL_ADDREF_INHERITED(nsCSSKeyframesRule, css::GroupRule) 1.2476 +NS_IMPL_RELEASE_INHERITED(nsCSSKeyframesRule, css::GroupRule) 1.2477 + 1.2478 +DOMCI_DATA(MozCSSKeyframesRule, nsCSSKeyframesRule) 1.2479 + 1.2480 +// QueryInterface implementation for nsCSSKeyframesRule 1.2481 +NS_INTERFACE_MAP_BEGIN(nsCSSKeyframesRule) 1.2482 + NS_INTERFACE_MAP_ENTRY(nsIStyleRule) 1.2483 + NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule) 1.2484 + NS_INTERFACE_MAP_ENTRY(nsIDOMMozCSSKeyframesRule) 1.2485 + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStyleRule) 1.2486 + NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MozCSSKeyframesRule) 1.2487 +NS_INTERFACE_MAP_END_INHERITING(GroupRule) 1.2488 + 1.2489 +#ifdef DEBUG 1.2490 +void 1.2491 +nsCSSKeyframesRule::List(FILE* out, int32_t aIndent) const 1.2492 +{ 1.2493 + for (int32_t indent = aIndent; --indent >= 0; ) fputs(" ", out); 1.2494 + 1.2495 + fprintf(out, "@keyframes %s", NS_ConvertUTF16toUTF8(mName).get()); 1.2496 + GroupRule::List(out, aIndent); 1.2497 +} 1.2498 +#endif 1.2499 + 1.2500 +/* virtual */ int32_t 1.2501 +nsCSSKeyframesRule::GetType() const 1.2502 +{ 1.2503 + return Rule::KEYFRAMES_RULE; 1.2504 +} 1.2505 + 1.2506 +NS_IMETHODIMP 1.2507 +nsCSSKeyframesRule::GetType(uint16_t* aType) 1.2508 +{ 1.2509 + *aType = nsIDOMCSSRule::KEYFRAMES_RULE; 1.2510 + return NS_OK; 1.2511 +} 1.2512 + 1.2513 +NS_IMETHODIMP 1.2514 +nsCSSKeyframesRule::GetCssText(nsAString& aCssText) 1.2515 +{ 1.2516 + aCssText.AssignLiteral("@keyframes "); 1.2517 + aCssText.Append(mName); 1.2518 + aCssText.AppendLiteral(" {\n"); 1.2519 + nsAutoString tmp; 1.2520 + for (uint32_t i = 0, i_end = mRules.Count(); i != i_end; ++i) { 1.2521 + static_cast<nsCSSKeyframeRule*>(mRules[i])->GetCssText(tmp); 1.2522 + aCssText.Append(tmp); 1.2523 + aCssText.AppendLiteral("\n"); 1.2524 + } 1.2525 + aCssText.AppendLiteral("}"); 1.2526 + return NS_OK; 1.2527 +} 1.2528 + 1.2529 +NS_IMETHODIMP 1.2530 +nsCSSKeyframesRule::SetCssText(const nsAString& aCssText) 1.2531 +{ 1.2532 + // FIXME: implement??? 1.2533 + return NS_ERROR_NOT_IMPLEMENTED; 1.2534 +} 1.2535 + 1.2536 +NS_IMETHODIMP 1.2537 +nsCSSKeyframesRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet) 1.2538 +{ 1.2539 + return GroupRule::GetParentStyleSheet(aSheet); 1.2540 +} 1.2541 + 1.2542 +NS_IMETHODIMP 1.2543 +nsCSSKeyframesRule::GetParentRule(nsIDOMCSSRule** aParentRule) 1.2544 +{ 1.2545 + return GroupRule::GetParentRule(aParentRule); 1.2546 +} 1.2547 + 1.2548 +NS_IMETHODIMP 1.2549 +nsCSSKeyframesRule::GetName(nsAString& aName) 1.2550 +{ 1.2551 + aName = mName; 1.2552 + return NS_OK; 1.2553 +} 1.2554 + 1.2555 +NS_IMETHODIMP 1.2556 +nsCSSKeyframesRule::SetName(const nsAString& aName) 1.2557 +{ 1.2558 + if (mName == aName) { 1.2559 + return NS_OK; 1.2560 + } 1.2561 + 1.2562 + nsIDocument* doc = GetDocument(); 1.2563 + MOZ_AUTO_DOC_UPDATE(doc, UPDATE_STYLE, true); 1.2564 + 1.2565 + mName = aName; 1.2566 + 1.2567 + nsCSSStyleSheet* sheet = GetStyleSheet(); 1.2568 + if (sheet) { 1.2569 + sheet->SetModifiedByChildRule(); 1.2570 + 1.2571 + if (doc) { 1.2572 + doc->StyleRuleChanged(sheet, this, this); 1.2573 + } 1.2574 + } 1.2575 + 1.2576 + return NS_OK; 1.2577 +} 1.2578 + 1.2579 +NS_IMETHODIMP 1.2580 +nsCSSKeyframesRule::GetCssRules(nsIDOMCSSRuleList* *aRuleList) 1.2581 +{ 1.2582 + return GroupRule::GetCssRules(aRuleList); 1.2583 +} 1.2584 + 1.2585 +NS_IMETHODIMP 1.2586 +nsCSSKeyframesRule::AppendRule(const nsAString& aRule) 1.2587 +{ 1.2588 + // The spec is confusing, and I think we should just append the rule, 1.2589 + // which also turns out to match WebKit: 1.2590 + // http://lists.w3.org/Archives/Public/www-style/2011Apr/0034.html 1.2591 + nsCSSParser parser; 1.2592 + 1.2593 + // FIXME: pass filename and line number 1.2594 + nsRefPtr<nsCSSKeyframeRule> rule = 1.2595 + parser.ParseKeyframeRule(aRule, nullptr, 0); 1.2596 + if (rule) { 1.2597 + nsIDocument* doc = GetDocument(); 1.2598 + MOZ_AUTO_DOC_UPDATE(doc, UPDATE_STYLE, true); 1.2599 + 1.2600 + AppendStyleRule(rule); 1.2601 + 1.2602 + nsCSSStyleSheet* sheet = GetStyleSheet(); 1.2603 + if (sheet) { 1.2604 + sheet->SetModifiedByChildRule(); 1.2605 + 1.2606 + if (doc) { 1.2607 + doc->StyleRuleChanged(sheet, this, this); 1.2608 + } 1.2609 + } 1.2610 + } 1.2611 + 1.2612 + return NS_OK; 1.2613 +} 1.2614 + 1.2615 +static const uint32_t RULE_NOT_FOUND = uint32_t(-1); 1.2616 + 1.2617 +uint32_t 1.2618 +nsCSSKeyframesRule::FindRuleIndexForKey(const nsAString& aKey) 1.2619 +{ 1.2620 + nsCSSParser parser; 1.2621 + 1.2622 + InfallibleTArray<float> keys; 1.2623 + // FIXME: pass filename and line number 1.2624 + if (parser.ParseKeyframeSelectorString(aKey, nullptr, 0, keys)) { 1.2625 + // The spec isn't clear, but we'll match on the key list, which 1.2626 + // mostly matches what WebKit does, except we'll do last-match 1.2627 + // instead of first-match, and handling parsing differences better. 1.2628 + // http://lists.w3.org/Archives/Public/www-style/2011Apr/0036.html 1.2629 + // http://lists.w3.org/Archives/Public/www-style/2011Apr/0037.html 1.2630 + for (uint32_t i = mRules.Count(); i-- != 0; ) { 1.2631 + if (static_cast<nsCSSKeyframeRule*>(mRules[i])->GetKeys() == keys) { 1.2632 + return i; 1.2633 + } 1.2634 + } 1.2635 + } 1.2636 + 1.2637 + return RULE_NOT_FOUND; 1.2638 +} 1.2639 + 1.2640 +NS_IMETHODIMP 1.2641 +nsCSSKeyframesRule::DeleteRule(const nsAString& aKey) 1.2642 +{ 1.2643 + uint32_t index = FindRuleIndexForKey(aKey); 1.2644 + if (index != RULE_NOT_FOUND) { 1.2645 + nsIDocument* doc = GetDocument(); 1.2646 + MOZ_AUTO_DOC_UPDATE(doc, UPDATE_STYLE, true); 1.2647 + 1.2648 + mRules.RemoveObjectAt(index); 1.2649 + 1.2650 + nsCSSStyleSheet* sheet = GetStyleSheet(); 1.2651 + if (sheet) { 1.2652 + sheet->SetModifiedByChildRule(); 1.2653 + 1.2654 + if (doc) { 1.2655 + doc->StyleRuleChanged(sheet, this, this); 1.2656 + } 1.2657 + } 1.2658 + } 1.2659 + return NS_OK; 1.2660 +} 1.2661 + 1.2662 +NS_IMETHODIMP 1.2663 +nsCSSKeyframesRule::FindRule(const nsAString& aKey, 1.2664 + nsIDOMMozCSSKeyframeRule** aResult) 1.2665 +{ 1.2666 + uint32_t index = FindRuleIndexForKey(aKey); 1.2667 + if (index == RULE_NOT_FOUND) { 1.2668 + *aResult = nullptr; 1.2669 + } else { 1.2670 + NS_ADDREF(*aResult = static_cast<nsCSSKeyframeRule*>(mRules[index])); 1.2671 + } 1.2672 + return NS_OK; 1.2673 +} 1.2674 + 1.2675 +// GroupRule interface 1.2676 +/* virtual */ bool 1.2677 +nsCSSKeyframesRule::UseForPresentation(nsPresContext* aPresContext, 1.2678 + nsMediaQueryResultCacheKey& aKey) 1.2679 +{ 1.2680 + NS_ABORT_IF_FALSE(false, "should not be called"); 1.2681 + return false; 1.2682 +} 1.2683 + 1.2684 +/* virtual */ size_t 1.2685 +nsCSSKeyframesRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const 1.2686 +{ 1.2687 + size_t n = aMallocSizeOf(this); 1.2688 + n += GroupRule::SizeOfExcludingThis(aMallocSizeOf); 1.2689 + 1.2690 + // Measurement of the following members may be added later if DMD finds it is 1.2691 + // worthwhile: 1.2692 + // - mName 1.2693 + 1.2694 + return n; 1.2695 +} 1.2696 + 1.2697 +// ------------------------------------------- 1.2698 +// nsCSSPageStyleDeclaration 1.2699 +// 1.2700 + 1.2701 +nsCSSPageStyleDeclaration::nsCSSPageStyleDeclaration(nsCSSPageRule* aRule) 1.2702 + : mRule(aRule) 1.2703 +{ 1.2704 +} 1.2705 + 1.2706 +nsCSSPageStyleDeclaration::~nsCSSPageStyleDeclaration() 1.2707 +{ 1.2708 + NS_ASSERTION(!mRule, "DropReference not called."); 1.2709 +} 1.2710 + 1.2711 +NS_IMPL_CYCLE_COLLECTING_ADDREF(nsCSSPageStyleDeclaration) 1.2712 +NS_IMPL_CYCLE_COLLECTING_RELEASE(nsCSSPageStyleDeclaration) 1.2713 + 1.2714 +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(nsCSSPageStyleDeclaration) 1.2715 + 1.2716 +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsCSSPageStyleDeclaration) 1.2717 + NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY 1.2718 +NS_INTERFACE_MAP_END_INHERITING(nsDOMCSSDeclaration) 1.2719 + 1.2720 +css::Declaration* 1.2721 +nsCSSPageStyleDeclaration::GetCSSDeclaration(bool aAllocate) 1.2722 +{ 1.2723 + if (mRule) { 1.2724 + return mRule->Declaration(); 1.2725 + } else { 1.2726 + return nullptr; 1.2727 + } 1.2728 +} 1.2729 + 1.2730 +void 1.2731 +nsCSSPageStyleDeclaration::GetCSSParsingEnvironment(CSSParsingEnvironment& aCSSParseEnv) 1.2732 +{ 1.2733 + GetCSSParsingEnvironmentForRule(mRule, aCSSParseEnv); 1.2734 +} 1.2735 + 1.2736 +NS_IMETHODIMP 1.2737 +nsCSSPageStyleDeclaration::GetParentRule(nsIDOMCSSRule** aParent) 1.2738 +{ 1.2739 + NS_ENSURE_ARG_POINTER(aParent); 1.2740 + 1.2741 + NS_IF_ADDREF(*aParent = mRule); 1.2742 + return NS_OK; 1.2743 +} 1.2744 + 1.2745 +nsresult 1.2746 +nsCSSPageStyleDeclaration::SetCSSDeclaration(css::Declaration* aDecl) 1.2747 +{ 1.2748 + NS_ABORT_IF_FALSE(aDecl, "must be non-null"); 1.2749 + mRule->ChangeDeclaration(aDecl); 1.2750 + return NS_OK; 1.2751 +} 1.2752 + 1.2753 +nsIDocument* 1.2754 +nsCSSPageStyleDeclaration::DocToUpdate() 1.2755 +{ 1.2756 + return nullptr; 1.2757 +} 1.2758 + 1.2759 +nsINode* 1.2760 +nsCSSPageStyleDeclaration::GetParentObject() 1.2761 +{ 1.2762 + return mRule ? mRule->GetDocument() : nullptr; 1.2763 +} 1.2764 + 1.2765 +// ------------------------------------------- 1.2766 +// nsCSSPageRule 1.2767 +// 1.2768 + 1.2769 +nsCSSPageRule::nsCSSPageRule(const nsCSSPageRule& aCopy) 1.2770 + // copy everything except our reference count and mDOMDeclaration 1.2771 + : Rule(aCopy) 1.2772 + , mDeclaration(new css::Declaration(*aCopy.mDeclaration)) 1.2773 +{ 1.2774 +} 1.2775 + 1.2776 +nsCSSPageRule::~nsCSSPageRule() 1.2777 +{ 1.2778 + if (mDOMDeclaration) { 1.2779 + mDOMDeclaration->DropReference(); 1.2780 + } 1.2781 +} 1.2782 + 1.2783 +/* virtual */ already_AddRefed<css::Rule> 1.2784 +nsCSSPageRule::Clone() const 1.2785 +{ 1.2786 + nsRefPtr<css::Rule> clone = new nsCSSPageRule(*this); 1.2787 + return clone.forget(); 1.2788 +} 1.2789 + 1.2790 +NS_IMPL_CYCLE_COLLECTING_ADDREF(nsCSSPageRule) 1.2791 +NS_IMPL_CYCLE_COLLECTING_RELEASE(nsCSSPageRule) 1.2792 + 1.2793 +NS_IMPL_CYCLE_COLLECTION_CLASS(nsCSSPageRule) 1.2794 + 1.2795 +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsCSSPageRule) 1.2796 + if (tmp->mDOMDeclaration) { 1.2797 + tmp->mDOMDeclaration->DropReference(); 1.2798 + tmp->mDOMDeclaration = nullptr; 1.2799 + } 1.2800 +NS_IMPL_CYCLE_COLLECTION_UNLINK_END 1.2801 +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsCSSPageRule) 1.2802 + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDOMDeclaration) 1.2803 +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END 1.2804 + 1.2805 +DOMCI_DATA(CSSPageRule, nsCSSPageRule) 1.2806 + 1.2807 +// QueryInterface implementation for nsCSSPageRule 1.2808 +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsCSSPageRule) 1.2809 + NS_INTERFACE_MAP_ENTRY(nsIStyleRule) 1.2810 + NS_INTERFACE_MAP_ENTRY(nsIDOMCSSPageRule) 1.2811 + NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule) 1.2812 + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStyleRule) 1.2813 + NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSPageRule) 1.2814 +NS_INTERFACE_MAP_END 1.2815 + 1.2816 +IMPL_STYLE_RULE_INHERIT_GET_DOM_RULE_WEAK(nsCSSPageRule, Rule) 1.2817 + 1.2818 +#ifdef DEBUG 1.2819 +void 1.2820 +nsCSSPageRule::List(FILE* out, int32_t aIndent) const 1.2821 +{ 1.2822 + for (int32_t indent = aIndent; --indent >= 0; ) fputs(" ", out); 1.2823 + 1.2824 + fputs("@page ", out); 1.2825 + mDeclaration->List(out, aIndent); 1.2826 + fputs("\n", out); 1.2827 +} 1.2828 +#endif 1.2829 + 1.2830 +/* virtual */ int32_t 1.2831 +nsCSSPageRule::GetType() const 1.2832 +{ 1.2833 + return Rule::PAGE_RULE; 1.2834 +} 1.2835 + 1.2836 +NS_IMETHODIMP 1.2837 +nsCSSPageRule::GetType(uint16_t* aType) 1.2838 +{ 1.2839 + *aType = nsIDOMCSSRule::PAGE_RULE; 1.2840 + return NS_OK; 1.2841 +} 1.2842 + 1.2843 +NS_IMETHODIMP 1.2844 +nsCSSPageRule::GetCssText(nsAString& aCssText) 1.2845 +{ 1.2846 + aCssText.AppendLiteral("@page { "); 1.2847 + nsAutoString tmp; 1.2848 + mDeclaration->ToString(tmp); 1.2849 + aCssText.Append(tmp); 1.2850 + aCssText.AppendLiteral(" }"); 1.2851 + return NS_OK; 1.2852 +} 1.2853 + 1.2854 +NS_IMETHODIMP 1.2855 +nsCSSPageRule::SetCssText(const nsAString& aCssText) 1.2856 +{ 1.2857 + // FIXME: implement??? 1.2858 + return NS_ERROR_NOT_IMPLEMENTED; 1.2859 +} 1.2860 + 1.2861 +NS_IMETHODIMP 1.2862 +nsCSSPageRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet) 1.2863 +{ 1.2864 + return Rule::GetParentStyleSheet(aSheet); 1.2865 +} 1.2866 + 1.2867 +NS_IMETHODIMP 1.2868 +nsCSSPageRule::GetParentRule(nsIDOMCSSRule** aParentRule) 1.2869 +{ 1.2870 + return Rule::GetParentRule(aParentRule); 1.2871 +} 1.2872 + 1.2873 +css::ImportantRule* 1.2874 +nsCSSPageRule::GetImportantRule() 1.2875 +{ 1.2876 + if (!mDeclaration->HasImportantData()) { 1.2877 + return nullptr; 1.2878 + } 1.2879 + if (!mImportantRule) { 1.2880 + mImportantRule = new css::ImportantRule(mDeclaration); 1.2881 + } 1.2882 + return mImportantRule; 1.2883 +} 1.2884 + 1.2885 +/* virtual */ void 1.2886 +nsCSSPageRule::MapRuleInfoInto(nsRuleData* aRuleData) 1.2887 +{ 1.2888 + mDeclaration->MapNormalRuleInfoInto(aRuleData); 1.2889 +} 1.2890 + 1.2891 +NS_IMETHODIMP 1.2892 +nsCSSPageRule::GetStyle(nsIDOMCSSStyleDeclaration** aStyle) 1.2893 +{ 1.2894 + if (!mDOMDeclaration) { 1.2895 + mDOMDeclaration = new nsCSSPageStyleDeclaration(this); 1.2896 + } 1.2897 + NS_ADDREF(*aStyle = mDOMDeclaration); 1.2898 + return NS_OK; 1.2899 +} 1.2900 + 1.2901 +void 1.2902 +nsCSSPageRule::ChangeDeclaration(css::Declaration* aDeclaration) 1.2903 +{ 1.2904 + mImportantRule = nullptr; 1.2905 + // Be careful to not assign to an nsAutoPtr if we would be assigning 1.2906 + // the thing it already holds. 1.2907 + if (aDeclaration != mDeclaration) { 1.2908 + mDeclaration = aDeclaration; 1.2909 + } 1.2910 + 1.2911 + nsCSSStyleSheet* sheet = GetStyleSheet(); 1.2912 + if (sheet) { 1.2913 + sheet->SetModifiedByChildRule(); 1.2914 + } 1.2915 +} 1.2916 + 1.2917 +/* virtual */ size_t 1.2918 +nsCSSPageRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const 1.2919 +{ 1.2920 + return aMallocSizeOf(this); 1.2921 +} 1.2922 + 1.2923 +namespace mozilla { 1.2924 + 1.2925 +CSSSupportsRule::CSSSupportsRule(bool aConditionMet, 1.2926 + const nsString& aCondition) 1.2927 + : mUseGroup(aConditionMet), 1.2928 + mCondition(aCondition) 1.2929 +{ 1.2930 +} 1.2931 + 1.2932 +CSSSupportsRule::CSSSupportsRule(const CSSSupportsRule& aCopy) 1.2933 + : css::GroupRule(aCopy), 1.2934 + mUseGroup(aCopy.mUseGroup), 1.2935 + mCondition(aCopy.mCondition) 1.2936 +{ 1.2937 +} 1.2938 + 1.2939 +#ifdef DEBUG 1.2940 +/* virtual */ void 1.2941 +CSSSupportsRule::List(FILE* out, int32_t aIndent) const 1.2942 +{ 1.2943 + for (int32_t indent = aIndent; --indent >= 0; ) fputs(" ", out); 1.2944 + 1.2945 + fputs("@supports ", out); 1.2946 + fputs(NS_ConvertUTF16toUTF8(mCondition).get(), out); 1.2947 + css::GroupRule::List(out, aIndent); 1.2948 +} 1.2949 +#endif 1.2950 + 1.2951 +/* virtual */ int32_t 1.2952 +CSSSupportsRule::GetType() const 1.2953 +{ 1.2954 + return Rule::SUPPORTS_RULE; 1.2955 +} 1.2956 + 1.2957 +/* virtual */ already_AddRefed<mozilla::css::Rule> 1.2958 +CSSSupportsRule::Clone() const 1.2959 +{ 1.2960 + nsRefPtr<css::Rule> clone = new CSSSupportsRule(*this); 1.2961 + return clone.forget(); 1.2962 +} 1.2963 + 1.2964 +/* virtual */ bool 1.2965 +CSSSupportsRule::UseForPresentation(nsPresContext* aPresContext, 1.2966 + nsMediaQueryResultCacheKey& aKey) 1.2967 +{ 1.2968 + return mUseGroup; 1.2969 +} 1.2970 + 1.2971 +NS_IMPL_ADDREF_INHERITED(CSSSupportsRule, css::GroupRule) 1.2972 +NS_IMPL_RELEASE_INHERITED(CSSSupportsRule, css::GroupRule) 1.2973 + 1.2974 +// QueryInterface implementation for CSSSupportsRule 1.2975 +NS_INTERFACE_MAP_BEGIN(CSSSupportsRule) 1.2976 + NS_INTERFACE_MAP_ENTRY(nsIStyleRule) 1.2977 + NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule) 1.2978 + NS_INTERFACE_MAP_ENTRY(nsIDOMCSSGroupingRule) 1.2979 + NS_INTERFACE_MAP_ENTRY(nsIDOMCSSConditionRule) 1.2980 + NS_INTERFACE_MAP_ENTRY(nsIDOMCSSSupportsRule) 1.2981 + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStyleRule) 1.2982 + NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSSupportsRule) 1.2983 +NS_INTERFACE_MAP_END_INHERITING(GroupRule) 1.2984 + 1.2985 +// nsIDOMCSSRule methods 1.2986 +NS_IMETHODIMP 1.2987 +CSSSupportsRule::GetType(uint16_t* aType) 1.2988 +{ 1.2989 + *aType = nsIDOMCSSRule::SUPPORTS_RULE; 1.2990 + return NS_OK; 1.2991 +} 1.2992 + 1.2993 +NS_IMETHODIMP 1.2994 +CSSSupportsRule::GetCssText(nsAString& aCssText) 1.2995 +{ 1.2996 + aCssText.AssignLiteral("@supports "); 1.2997 + aCssText.Append(mCondition); 1.2998 + css::GroupRule::AppendRulesToCssText(aCssText); 1.2999 + return NS_OK; 1.3000 +} 1.3001 + 1.3002 +NS_IMETHODIMP 1.3003 +CSSSupportsRule::SetCssText(const nsAString& aCssText) 1.3004 +{ 1.3005 + return NS_ERROR_NOT_IMPLEMENTED; 1.3006 +} 1.3007 + 1.3008 +NS_IMETHODIMP 1.3009 +CSSSupportsRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet) 1.3010 +{ 1.3011 + return css::GroupRule::GetParentStyleSheet(aSheet); 1.3012 +} 1.3013 + 1.3014 +NS_IMETHODIMP 1.3015 +CSSSupportsRule::GetParentRule(nsIDOMCSSRule** aParentRule) 1.3016 +{ 1.3017 + return css::GroupRule::GetParentRule(aParentRule); 1.3018 +} 1.3019 + 1.3020 +// nsIDOMCSSGroupingRule methods 1.3021 +NS_IMETHODIMP 1.3022 +CSSSupportsRule::GetCssRules(nsIDOMCSSRuleList* *aRuleList) 1.3023 +{ 1.3024 + return css::GroupRule::GetCssRules(aRuleList); 1.3025 +} 1.3026 + 1.3027 +NS_IMETHODIMP 1.3028 +CSSSupportsRule::InsertRule(const nsAString & aRule, uint32_t aIndex, uint32_t* _retval) 1.3029 +{ 1.3030 + return css::GroupRule::InsertRule(aRule, aIndex, _retval); 1.3031 +} 1.3032 + 1.3033 +NS_IMETHODIMP 1.3034 +CSSSupportsRule::DeleteRule(uint32_t aIndex) 1.3035 +{ 1.3036 + return css::GroupRule::DeleteRule(aIndex); 1.3037 +} 1.3038 + 1.3039 +// nsIDOMCSSConditionRule methods 1.3040 +NS_IMETHODIMP 1.3041 +CSSSupportsRule::GetConditionText(nsAString& aConditionText) 1.3042 +{ 1.3043 + aConditionText.Assign(mCondition); 1.3044 + return NS_OK; 1.3045 +} 1.3046 + 1.3047 +NS_IMETHODIMP 1.3048 +CSSSupportsRule::SetConditionText(const nsAString& aConditionText) 1.3049 +{ 1.3050 + return NS_ERROR_NOT_IMPLEMENTED; 1.3051 +} 1.3052 + 1.3053 +/* virtual */ size_t 1.3054 +CSSSupportsRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const 1.3055 +{ 1.3056 + size_t n = aMallocSizeOf(this); 1.3057 + n += css::GroupRule::SizeOfExcludingThis(aMallocSizeOf); 1.3058 + n += mCondition.SizeOfExcludingThisIfUnshared(aMallocSizeOf); 1.3059 + return n; 1.3060 +} 1.3061 + 1.3062 +} // namespace mozilla 1.3063 + 1.3064 +// Must be outside namespace 1.3065 +DOMCI_DATA(CSSSupportsRule, mozilla::CSSSupportsRule)