layout/style/nsCSSRules.cpp

Wed, 31 Dec 2014 06:55:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:50 +0100
changeset 2
7e26c7da4463
permissions
-rw-r--r--

Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 /* rules in a CSS stylesheet other than style rules (e.g., @import rules) */
michael@0 7
michael@0 8 #include "mozilla/Attributes.h"
michael@0 9
michael@0 10 #include "nsCSSRules.h"
michael@0 11 #include "nsCSSValue.h"
michael@0 12 #include "mozilla/MemoryReporting.h"
michael@0 13 #include "mozilla/css/ImportRule.h"
michael@0 14 #include "mozilla/css/NameSpaceRule.h"
michael@0 15
michael@0 16 #include "nsString.h"
michael@0 17 #include "nsIAtom.h"
michael@0 18
michael@0 19 #include "nsCSSProps.h"
michael@0 20 #include "nsCSSStyleSheet.h"
michael@0 21
michael@0 22 #include "nsCOMPtr.h"
michael@0 23 #include "nsIDOMCSSStyleSheet.h"
michael@0 24 #include "nsIMediaList.h"
michael@0 25 #include "nsICSSRuleList.h"
michael@0 26 #include "nsIDocument.h"
michael@0 27 #include "nsPresContext.h"
michael@0 28
michael@0 29 #include "nsContentUtils.h"
michael@0 30 #include "nsError.h"
michael@0 31 #include "nsStyleUtil.h"
michael@0 32 #include "mozilla/css/Declaration.h"
michael@0 33 #include "nsCSSParser.h"
michael@0 34 #include "nsPrintfCString.h"
michael@0 35 #include "nsDOMClassInfoID.h"
michael@0 36 #include "mozilla/dom/CSSStyleDeclarationBinding.h"
michael@0 37 #include "StyleRule.h"
michael@0 38 #include "nsFont.h"
michael@0 39 #include "nsIURI.h"
michael@0 40 #include "mozAutoDocUpdate.h"
michael@0 41
michael@0 42 using namespace mozilla;
michael@0 43
michael@0 44 #define IMPL_STYLE_RULE_INHERIT_GET_DOM_RULE_WEAK(class_, super_) \
michael@0 45 /* virtual */ nsIDOMCSSRule* class_::GetDOMRule() \
michael@0 46 { return this; } \
michael@0 47 /* virtual */ nsIDOMCSSRule* class_::GetExistingDOMRule() \
michael@0 48 { return this; }
michael@0 49 #define IMPL_STYLE_RULE_INHERIT_MAP_RULE_INFO_INTO(class_, super_) \
michael@0 50 /* virtual */ void class_::MapRuleInfoInto(nsRuleData* aRuleData) \
michael@0 51 { NS_ABORT_IF_FALSE(false, "should not be called"); }
michael@0 52
michael@0 53 #define IMPL_STYLE_RULE_INHERIT(class_, super_) \
michael@0 54 IMPL_STYLE_RULE_INHERIT_GET_DOM_RULE_WEAK(class_, super_) \
michael@0 55 IMPL_STYLE_RULE_INHERIT_MAP_RULE_INFO_INTO(class_, super_)
michael@0 56
michael@0 57 // base class for all rule types in a CSS style sheet
michael@0 58
michael@0 59 namespace mozilla {
michael@0 60 namespace css {
michael@0 61
michael@0 62 nsCSSStyleSheet*
michael@0 63 Rule::GetStyleSheet() const
michael@0 64 {
michael@0 65 if (!(mSheet & 0x1)) {
michael@0 66 return reinterpret_cast<nsCSSStyleSheet*>(mSheet);
michael@0 67 }
michael@0 68
michael@0 69 return nullptr;
michael@0 70 }
michael@0 71
michael@0 72 nsHTMLCSSStyleSheet*
michael@0 73 Rule::GetHTMLCSSStyleSheet() const
michael@0 74 {
michael@0 75 if (mSheet & 0x1) {
michael@0 76 return reinterpret_cast<nsHTMLCSSStyleSheet*>(mSheet & ~uintptr_t(0x1));
michael@0 77 }
michael@0 78
michael@0 79 return nullptr;
michael@0 80 }
michael@0 81
michael@0 82 /* virtual */ void
michael@0 83 Rule::SetStyleSheet(nsCSSStyleSheet* aSheet)
michael@0 84 {
michael@0 85 // We don't reference count this up reference. The style sheet
michael@0 86 // will tell us when it's going away or when we're detached from
michael@0 87 // it.
michael@0 88 mSheet = reinterpret_cast<uintptr_t>(aSheet);
michael@0 89 }
michael@0 90
michael@0 91 void
michael@0 92 Rule::SetHTMLCSSStyleSheet(nsHTMLCSSStyleSheet* aSheet)
michael@0 93 {
michael@0 94 // We don't reference count this up reference. The style sheet
michael@0 95 // will tell us when it's going away or when we're detached from
michael@0 96 // it.
michael@0 97 mSheet = reinterpret_cast<uintptr_t>(aSheet);
michael@0 98 mSheet |= 0x1;
michael@0 99 }
michael@0 100
michael@0 101 nsresult
michael@0 102 Rule::GetParentRule(nsIDOMCSSRule** aParentRule)
michael@0 103 {
michael@0 104 if (mParentRule) {
michael@0 105 NS_IF_ADDREF(*aParentRule = mParentRule->GetDOMRule());
michael@0 106 } else {
michael@0 107 *aParentRule = nullptr;
michael@0 108 }
michael@0 109 return NS_OK;
michael@0 110 }
michael@0 111
michael@0 112 nsresult
michael@0 113 Rule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
michael@0 114 {
michael@0 115 NS_ENSURE_ARG_POINTER(aSheet);
michael@0 116
michael@0 117 NS_IF_ADDREF(*aSheet = GetStyleSheet());
michael@0 118 return NS_OK;
michael@0 119 }
michael@0 120
michael@0 121 size_t
michael@0 122 Rule::SizeOfCOMArrayElementIncludingThis(css::Rule* aElement,
michael@0 123 MallocSizeOf aMallocSizeOf,
michael@0 124 void* aData)
michael@0 125 {
michael@0 126 return aElement->SizeOfIncludingThis(aMallocSizeOf);
michael@0 127 }
michael@0 128
michael@0 129 // -------------------------------
michael@0 130 // Style Rule List for group rules
michael@0 131 //
michael@0 132
michael@0 133 class GroupRuleRuleList MOZ_FINAL : public nsICSSRuleList
michael@0 134 {
michael@0 135 public:
michael@0 136 GroupRuleRuleList(GroupRule *aGroupRule);
michael@0 137
michael@0 138 NS_DECL_ISUPPORTS
michael@0 139
michael@0 140 virtual nsIDOMCSSRule*
michael@0 141 IndexedGetter(uint32_t aIndex, bool& aFound) MOZ_OVERRIDE;
michael@0 142 virtual uint32_t
michael@0 143 Length() MOZ_OVERRIDE;
michael@0 144
michael@0 145 void DropReference() { mGroupRule = nullptr; }
michael@0 146
michael@0 147 private:
michael@0 148 ~GroupRuleRuleList();
michael@0 149
michael@0 150 private:
michael@0 151 GroupRule* mGroupRule;
michael@0 152 };
michael@0 153
michael@0 154 GroupRuleRuleList::GroupRuleRuleList(GroupRule *aGroupRule)
michael@0 155 {
michael@0 156 // Not reference counted to avoid circular references.
michael@0 157 // The rule will tell us when its going away.
michael@0 158 mGroupRule = aGroupRule;
michael@0 159 }
michael@0 160
michael@0 161 GroupRuleRuleList::~GroupRuleRuleList()
michael@0 162 {
michael@0 163 }
michael@0 164
michael@0 165 // QueryInterface implementation for GroupRuleRuleList
michael@0 166 NS_INTERFACE_MAP_BEGIN(GroupRuleRuleList)
michael@0 167 NS_INTERFACE_MAP_ENTRY(nsICSSRuleList)
michael@0 168 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRuleList)
michael@0 169 NS_INTERFACE_MAP_ENTRY(nsISupports)
michael@0 170 NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSRuleList)
michael@0 171 NS_INTERFACE_MAP_END
michael@0 172
michael@0 173
michael@0 174 NS_IMPL_ADDREF(GroupRuleRuleList)
michael@0 175 NS_IMPL_RELEASE(GroupRuleRuleList)
michael@0 176
michael@0 177 uint32_t
michael@0 178 GroupRuleRuleList::Length()
michael@0 179 {
michael@0 180 if (!mGroupRule) {
michael@0 181 return 0;
michael@0 182 }
michael@0 183
michael@0 184 return SafeCast<uint32_t>(mGroupRule->StyleRuleCount());
michael@0 185 }
michael@0 186
michael@0 187 nsIDOMCSSRule*
michael@0 188 GroupRuleRuleList::IndexedGetter(uint32_t aIndex, bool& aFound)
michael@0 189 {
michael@0 190 aFound = false;
michael@0 191
michael@0 192 if (mGroupRule) {
michael@0 193 nsRefPtr<Rule> rule = mGroupRule->GetStyleRuleAt(aIndex);
michael@0 194 if (rule) {
michael@0 195 aFound = true;
michael@0 196 return rule->GetDOMRule();
michael@0 197 }
michael@0 198 }
michael@0 199
michael@0 200 return nullptr;
michael@0 201 }
michael@0 202
michael@0 203 } // namespace css
michael@0 204 } // namespace mozilla
michael@0 205
michael@0 206 // -------------------------------------------
michael@0 207 // CharsetRule
michael@0 208 //
michael@0 209
michael@0 210 // Must be outside namespace
michael@0 211 DOMCI_DATA(CSSCharsetRule, css::CharsetRule)
michael@0 212
michael@0 213 namespace mozilla {
michael@0 214 namespace css {
michael@0 215
michael@0 216 CharsetRule::CharsetRule(const nsAString& aEncoding)
michael@0 217 : Rule(),
michael@0 218 mEncoding(aEncoding)
michael@0 219 {
michael@0 220 }
michael@0 221
michael@0 222 CharsetRule::CharsetRule(const CharsetRule& aCopy)
michael@0 223 : Rule(aCopy),
michael@0 224 mEncoding(aCopy.mEncoding)
michael@0 225 {
michael@0 226 }
michael@0 227
michael@0 228 NS_IMPL_ADDREF(CharsetRule)
michael@0 229 NS_IMPL_RELEASE(CharsetRule)
michael@0 230
michael@0 231 // QueryInterface implementation for CharsetRule
michael@0 232 NS_INTERFACE_MAP_BEGIN(CharsetRule)
michael@0 233 NS_INTERFACE_MAP_ENTRY(nsIStyleRule)
michael@0 234 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
michael@0 235 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSCharsetRule)
michael@0 236 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStyleRule)
michael@0 237 NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSCharsetRule)
michael@0 238 NS_INTERFACE_MAP_END
michael@0 239
michael@0 240 IMPL_STYLE_RULE_INHERIT(CharsetRule, Rule)
michael@0 241
michael@0 242 #ifdef DEBUG
michael@0 243 /* virtual */ void
michael@0 244 CharsetRule::List(FILE* out, int32_t aIndent) const
michael@0 245 {
michael@0 246 // Indent
michael@0 247 for (int32_t indent = aIndent; --indent >= 0; ) fputs(" ", out);
michael@0 248
michael@0 249 fputs("@charset \"", out);
michael@0 250 fputs(NS_LossyConvertUTF16toASCII(mEncoding).get(), out);
michael@0 251 fputs("\"\n", out);
michael@0 252 }
michael@0 253 #endif
michael@0 254
michael@0 255 /* virtual */ int32_t
michael@0 256 CharsetRule::GetType() const
michael@0 257 {
michael@0 258 return Rule::CHARSET_RULE;
michael@0 259 }
michael@0 260
michael@0 261 /* virtual */ already_AddRefed<Rule>
michael@0 262 CharsetRule::Clone() const
michael@0 263 {
michael@0 264 nsRefPtr<Rule> clone = new CharsetRule(*this);
michael@0 265 return clone.forget();
michael@0 266 }
michael@0 267
michael@0 268 NS_IMETHODIMP
michael@0 269 CharsetRule::GetEncoding(nsAString& aEncoding)
michael@0 270 {
michael@0 271 aEncoding = mEncoding;
michael@0 272 return NS_OK;
michael@0 273 }
michael@0 274
michael@0 275 NS_IMETHODIMP
michael@0 276 CharsetRule::SetEncoding(const nsAString& aEncoding)
michael@0 277 {
michael@0 278 mEncoding = aEncoding;
michael@0 279 return NS_OK;
michael@0 280 }
michael@0 281
michael@0 282 NS_IMETHODIMP
michael@0 283 CharsetRule::GetType(uint16_t* aType)
michael@0 284 {
michael@0 285 *aType = nsIDOMCSSRule::CHARSET_RULE;
michael@0 286 return NS_OK;
michael@0 287 }
michael@0 288
michael@0 289 NS_IMETHODIMP
michael@0 290 CharsetRule::GetCssText(nsAString& aCssText)
michael@0 291 {
michael@0 292 aCssText.AssignLiteral("@charset \"");
michael@0 293 aCssText.Append(mEncoding);
michael@0 294 aCssText.AppendLiteral("\";");
michael@0 295 return NS_OK;
michael@0 296 }
michael@0 297
michael@0 298 NS_IMETHODIMP
michael@0 299 CharsetRule::SetCssText(const nsAString& aCssText)
michael@0 300 {
michael@0 301 return NS_ERROR_NOT_IMPLEMENTED;
michael@0 302 }
michael@0 303
michael@0 304 NS_IMETHODIMP
michael@0 305 CharsetRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
michael@0 306 {
michael@0 307 return Rule::GetParentStyleSheet(aSheet);
michael@0 308 }
michael@0 309
michael@0 310 NS_IMETHODIMP
michael@0 311 CharsetRule::GetParentRule(nsIDOMCSSRule** aParentRule)
michael@0 312 {
michael@0 313 return Rule::GetParentRule(aParentRule);
michael@0 314 }
michael@0 315
michael@0 316 /* virtual */ size_t
michael@0 317 CharsetRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
michael@0 318 {
michael@0 319 return aMallocSizeOf(this);
michael@0 320
michael@0 321 // Measurement of the following members may be added later if DMD finds it is
michael@0 322 // worthwhile:
michael@0 323 // - mEncoding
michael@0 324 }
michael@0 325
michael@0 326 // -------------------------------------------
michael@0 327 // ImportRule
michael@0 328 //
michael@0 329
michael@0 330 ImportRule::ImportRule(nsMediaList* aMedia, const nsString& aURLSpec)
michael@0 331 : Rule()
michael@0 332 , mURLSpec(aURLSpec)
michael@0 333 , mMedia(aMedia)
michael@0 334 {
michael@0 335 // XXXbz This is really silly.... the mMedia here will be replaced
michael@0 336 // with itself if we manage to load a sheet. Which should really
michael@0 337 // never fail nowadays, in sane cases.
michael@0 338 }
michael@0 339
michael@0 340 ImportRule::ImportRule(const ImportRule& aCopy)
michael@0 341 : Rule(aCopy),
michael@0 342 mURLSpec(aCopy.mURLSpec)
michael@0 343 {
michael@0 344 // Whether or not an @import rule has a null sheet is a permanent
michael@0 345 // property of that @import rule, since it is null only if the target
michael@0 346 // sheet failed security checks.
michael@0 347 if (aCopy.mChildSheet) {
michael@0 348 nsRefPtr<nsCSSStyleSheet> sheet =
michael@0 349 aCopy.mChildSheet->Clone(nullptr, this, nullptr, nullptr);
michael@0 350 SetSheet(sheet);
michael@0 351 // SetSheet sets mMedia appropriately
michael@0 352 }
michael@0 353 }
michael@0 354
michael@0 355 ImportRule::~ImportRule()
michael@0 356 {
michael@0 357 if (mChildSheet) {
michael@0 358 mChildSheet->SetOwnerRule(nullptr);
michael@0 359 }
michael@0 360 }
michael@0 361
michael@0 362 NS_IMPL_ADDREF(ImportRule)
michael@0 363 NS_IMPL_RELEASE(ImportRule)
michael@0 364
michael@0 365 // QueryInterface implementation for ImportRule
michael@0 366 NS_INTERFACE_MAP_BEGIN(ImportRule)
michael@0 367 NS_INTERFACE_MAP_ENTRY(nsIStyleRule)
michael@0 368 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
michael@0 369 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSImportRule)
michael@0 370 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStyleRule)
michael@0 371 NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSImportRule)
michael@0 372 NS_INTERFACE_MAP_END
michael@0 373
michael@0 374 IMPL_STYLE_RULE_INHERIT(ImportRule, Rule)
michael@0 375
michael@0 376 #ifdef DEBUG
michael@0 377 /* virtual */ void
michael@0 378 ImportRule::List(FILE* out, int32_t aIndent) const
michael@0 379 {
michael@0 380 // Indent
michael@0 381 for (int32_t indent = aIndent; --indent >= 0; ) fputs(" ", out);
michael@0 382
michael@0 383 fputs("@import \"", out);
michael@0 384 fputs(NS_LossyConvertUTF16toASCII(mURLSpec).get(), out);
michael@0 385 fputs("\" ", out);
michael@0 386
michael@0 387 nsAutoString mediaText;
michael@0 388 mMedia->GetText(mediaText);
michael@0 389 fputs(NS_LossyConvertUTF16toASCII(mediaText).get(), out);
michael@0 390 fputs("\n", out);
michael@0 391 }
michael@0 392 #endif
michael@0 393
michael@0 394 /* virtual */ int32_t
michael@0 395 ImportRule::GetType() const
michael@0 396 {
michael@0 397 return Rule::IMPORT_RULE;
michael@0 398 }
michael@0 399
michael@0 400 /* virtual */ already_AddRefed<Rule>
michael@0 401 ImportRule::Clone() const
michael@0 402 {
michael@0 403 nsRefPtr<Rule> clone = new ImportRule(*this);
michael@0 404 return clone.forget();
michael@0 405 }
michael@0 406
michael@0 407 void
michael@0 408 ImportRule::SetSheet(nsCSSStyleSheet* aSheet)
michael@0 409 {
michael@0 410 NS_PRECONDITION(aSheet, "null arg");
michael@0 411
michael@0 412 // set the new sheet
michael@0 413 mChildSheet = aSheet;
michael@0 414 aSheet->SetOwnerRule(this);
michael@0 415
michael@0 416 // set our medialist to be the same as the sheet's medialist
michael@0 417 mMedia = mChildSheet->Media();
michael@0 418 }
michael@0 419
michael@0 420 NS_IMETHODIMP
michael@0 421 ImportRule::GetType(uint16_t* aType)
michael@0 422 {
michael@0 423 NS_ENSURE_ARG_POINTER(aType);
michael@0 424 *aType = nsIDOMCSSRule::IMPORT_RULE;
michael@0 425 return NS_OK;
michael@0 426 }
michael@0 427
michael@0 428 NS_IMETHODIMP
michael@0 429 ImportRule::GetCssText(nsAString& aCssText)
michael@0 430 {
michael@0 431 aCssText.AssignLiteral("@import url(");
michael@0 432 nsStyleUtil::AppendEscapedCSSString(mURLSpec, aCssText);
michael@0 433 aCssText.Append(NS_LITERAL_STRING(")"));
michael@0 434 if (mMedia) {
michael@0 435 nsAutoString mediaText;
michael@0 436 mMedia->GetText(mediaText);
michael@0 437 if (!mediaText.IsEmpty()) {
michael@0 438 aCssText.AppendLiteral(" ");
michael@0 439 aCssText.Append(mediaText);
michael@0 440 }
michael@0 441 }
michael@0 442 aCssText.AppendLiteral(";");
michael@0 443 return NS_OK;
michael@0 444 }
michael@0 445
michael@0 446 NS_IMETHODIMP
michael@0 447 ImportRule::SetCssText(const nsAString& aCssText)
michael@0 448 {
michael@0 449 return NS_ERROR_NOT_IMPLEMENTED;
michael@0 450 }
michael@0 451
michael@0 452 NS_IMETHODIMP
michael@0 453 ImportRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
michael@0 454 {
michael@0 455 return Rule::GetParentStyleSheet(aSheet);
michael@0 456 }
michael@0 457
michael@0 458 NS_IMETHODIMP
michael@0 459 ImportRule::GetParentRule(nsIDOMCSSRule** aParentRule)
michael@0 460 {
michael@0 461 return Rule::GetParentRule(aParentRule);
michael@0 462 }
michael@0 463
michael@0 464 NS_IMETHODIMP
michael@0 465 ImportRule::GetHref(nsAString & aHref)
michael@0 466 {
michael@0 467 aHref = mURLSpec;
michael@0 468 return NS_OK;
michael@0 469 }
michael@0 470
michael@0 471 NS_IMETHODIMP
michael@0 472 ImportRule::GetMedia(nsIDOMMediaList * *aMedia)
michael@0 473 {
michael@0 474 NS_ENSURE_ARG_POINTER(aMedia);
michael@0 475
michael@0 476 NS_IF_ADDREF(*aMedia = mMedia);
michael@0 477 return NS_OK;
michael@0 478 }
michael@0 479
michael@0 480 NS_IMETHODIMP
michael@0 481 ImportRule::GetStyleSheet(nsIDOMCSSStyleSheet * *aStyleSheet)
michael@0 482 {
michael@0 483 NS_ENSURE_ARG_POINTER(aStyleSheet);
michael@0 484
michael@0 485 NS_IF_ADDREF(*aStyleSheet = mChildSheet);
michael@0 486 return NS_OK;
michael@0 487 }
michael@0 488
michael@0 489 /* virtual */ size_t
michael@0 490 ImportRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
michael@0 491 {
michael@0 492 return aMallocSizeOf(this);
michael@0 493
michael@0 494 // Measurement of the following members may be added later if DMD finds it is
michael@0 495 // worthwhile:
michael@0 496 // - mURLSpec
michael@0 497 //
michael@0 498 // The following members are not measured:
michael@0 499 // - mMedia, because it is measured via nsCSSStyleSheet::mMedia
michael@0 500 // - mChildSheet, because it is measured via nsCSSStyleSheetInner::mSheets
michael@0 501 }
michael@0 502
michael@0 503 } // namespace css
michael@0 504 } // namespace mozilla
michael@0 505
michael@0 506 // must be outside the namespace
michael@0 507 DOMCI_DATA(CSSImportRule, css::ImportRule)
michael@0 508
michael@0 509 namespace mozilla {
michael@0 510 namespace css {
michael@0 511
michael@0 512 GroupRule::GroupRule()
michael@0 513 : Rule()
michael@0 514 {
michael@0 515 }
michael@0 516
michael@0 517 static bool
michael@0 518 SetParentRuleReference(Rule* aRule, void* aParentRule)
michael@0 519 {
michael@0 520 GroupRule* parentRule = static_cast<GroupRule*>(aParentRule);
michael@0 521 aRule->SetParentRule(parentRule);
michael@0 522 return true;
michael@0 523 }
michael@0 524
michael@0 525 GroupRule::GroupRule(const GroupRule& aCopy)
michael@0 526 : Rule(aCopy)
michael@0 527 {
michael@0 528 const_cast<GroupRule&>(aCopy).mRules.EnumerateForwards(GroupRule::CloneRuleInto, &mRules);
michael@0 529 mRules.EnumerateForwards(SetParentRuleReference, this);
michael@0 530 }
michael@0 531
michael@0 532 GroupRule::~GroupRule()
michael@0 533 {
michael@0 534 NS_ABORT_IF_FALSE(!mSheet, "SetStyleSheet should have been called");
michael@0 535 mRules.EnumerateForwards(SetParentRuleReference, nullptr);
michael@0 536 if (mRuleCollection) {
michael@0 537 mRuleCollection->DropReference();
michael@0 538 }
michael@0 539 }
michael@0 540
michael@0 541 NS_IMPL_CYCLE_COLLECTING_ADDREF(GroupRule)
michael@0 542 NS_IMPL_CYCLE_COLLECTING_RELEASE(GroupRule)
michael@0 543
michael@0 544 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(GroupRule)
michael@0 545 NS_INTERFACE_MAP_END
michael@0 546
michael@0 547 IMPL_STYLE_RULE_INHERIT_MAP_RULE_INFO_INTO(GroupRule, Rule)
michael@0 548
michael@0 549 static bool
michael@0 550 SetStyleSheetReference(Rule* aRule, void* aSheet)
michael@0 551 {
michael@0 552 nsCSSStyleSheet* sheet = (nsCSSStyleSheet*)aSheet;
michael@0 553 aRule->SetStyleSheet(sheet);
michael@0 554 return true;
michael@0 555 }
michael@0 556
michael@0 557 NS_IMPL_CYCLE_COLLECTION_CLASS(GroupRule)
michael@0 558
michael@0 559 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(GroupRule)
michael@0 560 tmp->mRules.EnumerateForwards(SetParentRuleReference, nullptr);
michael@0 561 // If tmp does not have a stylesheet, neither do its descendants. In that
michael@0 562 // case, don't try to null out their stylesheet, to avoid O(N^2) behavior in
michael@0 563 // depth of group rule nesting. But if tmp _does_ have a stylesheet (which
michael@0 564 // can happen if it gets unlinked earlier than its owning stylesheet), then we
michael@0 565 // need to null out the stylesheet pointer on descendants now, before we clear
michael@0 566 // tmp->mRules.
michael@0 567 if (tmp->GetStyleSheet()) {
michael@0 568 tmp->mRules.EnumerateForwards(SetStyleSheetReference, nullptr);
michael@0 569 }
michael@0 570 tmp->mRules.Clear();
michael@0 571 if (tmp->mRuleCollection) {
michael@0 572 tmp->mRuleCollection->DropReference();
michael@0 573 tmp->mRuleCollection = nullptr;
michael@0 574 }
michael@0 575 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
michael@0 576
michael@0 577 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(GroupRule)
michael@0 578 const nsCOMArray<Rule>& rules = tmp->mRules;
michael@0 579 for (int32_t i = 0, count = rules.Count(); i < count; ++i) {
michael@0 580 NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mRules[i]");
michael@0 581 cb.NoteXPCOMChild(rules[i]->GetExistingDOMRule());
michael@0 582 }
michael@0 583 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRuleCollection)
michael@0 584 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
michael@0 585
michael@0 586 /* virtual */ void
michael@0 587 GroupRule::SetStyleSheet(nsCSSStyleSheet* aSheet)
michael@0 588 {
michael@0 589 // Don't set the sheet on the kids if it's already the same as the sheet we
michael@0 590 // already have. This is needed to avoid O(N^2) behavior in group nesting
michael@0 591 // depth when seting the sheet to null during unlink, if we happen to unlin in
michael@0 592 // order from most nested rule up to least nested rule.
michael@0 593 if (aSheet != GetStyleSheet()) {
michael@0 594 mRules.EnumerateForwards(SetStyleSheetReference, aSheet);
michael@0 595 Rule::SetStyleSheet(aSheet);
michael@0 596 }
michael@0 597 }
michael@0 598
michael@0 599 #ifdef DEBUG
michael@0 600 /* virtual */ void
michael@0 601 GroupRule::List(FILE* out, int32_t aIndent) const
michael@0 602 {
michael@0 603 fputs(" {\n", out);
michael@0 604
michael@0 605 for (int32_t index = 0, count = mRules.Count(); index < count; ++index) {
michael@0 606 mRules.ObjectAt(index)->List(out, aIndent + 1);
michael@0 607 }
michael@0 608
michael@0 609 for (int32_t indent = aIndent; --indent >= 0; ) fputs(" ", out);
michael@0 610 fputs("}\n", out);
michael@0 611 }
michael@0 612 #endif
michael@0 613
michael@0 614 void
michael@0 615 GroupRule::AppendStyleRule(Rule* aRule)
michael@0 616 {
michael@0 617 mRules.AppendObject(aRule);
michael@0 618 nsCSSStyleSheet* sheet = GetStyleSheet();
michael@0 619 aRule->SetStyleSheet(sheet);
michael@0 620 aRule->SetParentRule(this);
michael@0 621 if (sheet) {
michael@0 622 sheet->SetModifiedByChildRule();
michael@0 623 }
michael@0 624 }
michael@0 625
michael@0 626 Rule*
michael@0 627 GroupRule::GetStyleRuleAt(int32_t aIndex) const
michael@0 628 {
michael@0 629 return mRules.SafeObjectAt(aIndex);
michael@0 630 }
michael@0 631
michael@0 632 bool
michael@0 633 GroupRule::EnumerateRulesForwards(RuleEnumFunc aFunc, void * aData) const
michael@0 634 {
michael@0 635 return
michael@0 636 const_cast<GroupRule*>(this)->mRules.EnumerateForwards(aFunc, aData);
michael@0 637 }
michael@0 638
michael@0 639 /*
michael@0 640 * The next two methods (DeleteStyleRuleAt and InsertStyleRuleAt)
michael@0 641 * should never be called unless you have first called WillDirty() on
michael@0 642 * the parents stylesheet. After they are called, DidDirty() needs to
michael@0 643 * be called on the sheet
michael@0 644 */
michael@0 645 nsresult
michael@0 646 GroupRule::DeleteStyleRuleAt(uint32_t aIndex)
michael@0 647 {
michael@0 648 Rule* rule = mRules.SafeObjectAt(aIndex);
michael@0 649 if (rule) {
michael@0 650 rule->SetStyleSheet(nullptr);
michael@0 651 rule->SetParentRule(nullptr);
michael@0 652 }
michael@0 653 return mRules.RemoveObjectAt(aIndex) ? NS_OK : NS_ERROR_ILLEGAL_VALUE;
michael@0 654 }
michael@0 655
michael@0 656 nsresult
michael@0 657 GroupRule::InsertStyleRuleAt(uint32_t aIndex, Rule* aRule)
michael@0 658 {
michael@0 659 aRule->SetStyleSheet(GetStyleSheet());
michael@0 660 aRule->SetParentRule(this);
michael@0 661 if (! mRules.InsertObjectAt(aRule, aIndex)) {
michael@0 662 return NS_ERROR_FAILURE;
michael@0 663 }
michael@0 664 return NS_OK;
michael@0 665 }
michael@0 666
michael@0 667 nsresult
michael@0 668 GroupRule::ReplaceStyleRule(Rule* aOld, Rule* aNew)
michael@0 669 {
michael@0 670 int32_t index = mRules.IndexOf(aOld);
michael@0 671 NS_ENSURE_TRUE(index != -1, NS_ERROR_UNEXPECTED);
michael@0 672 mRules.ReplaceObjectAt(aNew, index);
michael@0 673 aNew->SetStyleSheet(GetStyleSheet());
michael@0 674 aNew->SetParentRule(this);
michael@0 675 aOld->SetStyleSheet(nullptr);
michael@0 676 aOld->SetParentRule(nullptr);
michael@0 677 return NS_OK;
michael@0 678 }
michael@0 679
michael@0 680 void
michael@0 681 GroupRule::AppendRulesToCssText(nsAString& aCssText)
michael@0 682 {
michael@0 683 aCssText.AppendLiteral(" {\n");
michael@0 684
michael@0 685 // get all the rules
michael@0 686 for (int32_t index = 0, count = mRules.Count(); index < count; ++index) {
michael@0 687 Rule* rule = mRules.ObjectAt(index);
michael@0 688 nsIDOMCSSRule* domRule = rule->GetDOMRule();
michael@0 689 if (domRule) {
michael@0 690 nsAutoString cssText;
michael@0 691 domRule->GetCssText(cssText);
michael@0 692 aCssText.Append(NS_LITERAL_STRING(" ") +
michael@0 693 cssText +
michael@0 694 NS_LITERAL_STRING("\n"));
michael@0 695 }
michael@0 696 }
michael@0 697
michael@0 698 aCssText.AppendLiteral("}");
michael@0 699 }
michael@0 700
michael@0 701 // nsIDOMCSSMediaRule or nsIDOMCSSMozDocumentRule methods
michael@0 702 nsresult
michael@0 703 GroupRule::GetCssRules(nsIDOMCSSRuleList* *aRuleList)
michael@0 704 {
michael@0 705 if (!mRuleCollection) {
michael@0 706 mRuleCollection = new css::GroupRuleRuleList(this);
michael@0 707 }
michael@0 708
michael@0 709 NS_ADDREF(*aRuleList = mRuleCollection);
michael@0 710 return NS_OK;
michael@0 711 }
michael@0 712
michael@0 713 nsresult
michael@0 714 GroupRule::InsertRule(const nsAString & aRule, uint32_t aIndex, uint32_t* _retval)
michael@0 715 {
michael@0 716 nsCSSStyleSheet* sheet = GetStyleSheet();
michael@0 717 NS_ENSURE_TRUE(sheet, NS_ERROR_FAILURE);
michael@0 718
michael@0 719 if (aIndex > uint32_t(mRules.Count()))
michael@0 720 return NS_ERROR_DOM_INDEX_SIZE_ERR;
michael@0 721
michael@0 722 NS_ASSERTION(uint32_t(mRules.Count()) <= INT32_MAX,
michael@0 723 "Too many style rules!");
michael@0 724
michael@0 725 return sheet->InsertRuleIntoGroup(aRule, this, aIndex, _retval);
michael@0 726 }
michael@0 727
michael@0 728 nsresult
michael@0 729 GroupRule::DeleteRule(uint32_t aIndex)
michael@0 730 {
michael@0 731 nsCSSStyleSheet* sheet = GetStyleSheet();
michael@0 732 NS_ENSURE_TRUE(sheet, NS_ERROR_FAILURE);
michael@0 733
michael@0 734 if (aIndex >= uint32_t(mRules.Count()))
michael@0 735 return NS_ERROR_DOM_INDEX_SIZE_ERR;
michael@0 736
michael@0 737 NS_ASSERTION(uint32_t(mRules.Count()) <= INT32_MAX,
michael@0 738 "Too many style rules!");
michael@0 739
michael@0 740 return sheet->DeleteRuleFromGroup(this, aIndex);
michael@0 741 }
michael@0 742
michael@0 743 /* virtual */ size_t
michael@0 744 GroupRule::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
michael@0 745 {
michael@0 746 return mRules.SizeOfExcludingThis(Rule::SizeOfCOMArrayElementIncludingThis,
michael@0 747 aMallocSizeOf);
michael@0 748
michael@0 749 // Measurement of the following members may be added later if DMD finds it is
michael@0 750 // worthwhile:
michael@0 751 // - mRuleCollection
michael@0 752 }
michael@0 753
michael@0 754
michael@0 755 // -------------------------------------------
michael@0 756 // nsICSSMediaRule
michael@0 757 //
michael@0 758 MediaRule::MediaRule()
michael@0 759 {
michael@0 760 }
michael@0 761
michael@0 762 MediaRule::MediaRule(const MediaRule& aCopy)
michael@0 763 : GroupRule(aCopy)
michael@0 764 {
michael@0 765 if (aCopy.mMedia) {
michael@0 766 mMedia = aCopy.mMedia->Clone();
michael@0 767 // XXXldb This doesn't really make sense.
michael@0 768 mMedia->SetStyleSheet(aCopy.GetStyleSheet());
michael@0 769 }
michael@0 770 }
michael@0 771
michael@0 772 MediaRule::~MediaRule()
michael@0 773 {
michael@0 774 if (mMedia) {
michael@0 775 mMedia->SetStyleSheet(nullptr);
michael@0 776 }
michael@0 777 }
michael@0 778
michael@0 779 NS_IMPL_ADDREF_INHERITED(MediaRule, GroupRule)
michael@0 780 NS_IMPL_RELEASE_INHERITED(MediaRule, GroupRule)
michael@0 781
michael@0 782 // QueryInterface implementation for MediaRule
michael@0 783 NS_INTERFACE_MAP_BEGIN(MediaRule)
michael@0 784 NS_INTERFACE_MAP_ENTRY(nsIStyleRule)
michael@0 785 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
michael@0 786 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSGroupingRule)
michael@0 787 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSConditionRule)
michael@0 788 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSMediaRule)
michael@0 789 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStyleRule)
michael@0 790 NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSMediaRule)
michael@0 791 NS_INTERFACE_MAP_END_INHERITING(GroupRule)
michael@0 792
michael@0 793 /* virtual */ void
michael@0 794 MediaRule::SetStyleSheet(nsCSSStyleSheet* aSheet)
michael@0 795 {
michael@0 796 if (mMedia) {
michael@0 797 // Set to null so it knows it's leaving one sheet and joining another.
michael@0 798 mMedia->SetStyleSheet(nullptr);
michael@0 799 mMedia->SetStyleSheet(aSheet);
michael@0 800 }
michael@0 801
michael@0 802 GroupRule::SetStyleSheet(aSheet);
michael@0 803 }
michael@0 804
michael@0 805 #ifdef DEBUG
michael@0 806 /* virtual */ void
michael@0 807 MediaRule::List(FILE* out, int32_t aIndent) const
michael@0 808 {
michael@0 809 for (int32_t indent = aIndent; --indent >= 0; ) fputs(" ", out);
michael@0 810
michael@0 811 nsAutoString buffer;
michael@0 812
michael@0 813 fputs("@media ", out);
michael@0 814
michael@0 815 if (mMedia) {
michael@0 816 nsAutoString mediaText;
michael@0 817 mMedia->GetText(mediaText);
michael@0 818 fputs(NS_LossyConvertUTF16toASCII(mediaText).get(), out);
michael@0 819 }
michael@0 820
michael@0 821 GroupRule::List(out, aIndent);
michael@0 822 }
michael@0 823 #endif
michael@0 824
michael@0 825 /* virtual */ int32_t
michael@0 826 MediaRule::GetType() const
michael@0 827 {
michael@0 828 return Rule::MEDIA_RULE;
michael@0 829 }
michael@0 830
michael@0 831 /* virtual */ already_AddRefed<Rule>
michael@0 832 MediaRule::Clone() const
michael@0 833 {
michael@0 834 nsRefPtr<Rule> clone = new MediaRule(*this);
michael@0 835 return clone.forget();
michael@0 836 }
michael@0 837
michael@0 838 nsresult
michael@0 839 MediaRule::SetMedia(nsMediaList* aMedia)
michael@0 840 {
michael@0 841 mMedia = aMedia;
michael@0 842 if (aMedia)
michael@0 843 mMedia->SetStyleSheet(GetStyleSheet());
michael@0 844 return NS_OK;
michael@0 845 }
michael@0 846
michael@0 847 // nsIDOMCSSRule methods
michael@0 848 NS_IMETHODIMP
michael@0 849 MediaRule::GetType(uint16_t* aType)
michael@0 850 {
michael@0 851 *aType = nsIDOMCSSRule::MEDIA_RULE;
michael@0 852 return NS_OK;
michael@0 853 }
michael@0 854
michael@0 855 NS_IMETHODIMP
michael@0 856 MediaRule::GetCssText(nsAString& aCssText)
michael@0 857 {
michael@0 858 aCssText.AssignLiteral("@media ");
michael@0 859 AppendConditionText(aCssText);
michael@0 860 GroupRule::AppendRulesToCssText(aCssText);
michael@0 861 return NS_OK;
michael@0 862 }
michael@0 863
michael@0 864 NS_IMETHODIMP
michael@0 865 MediaRule::SetCssText(const nsAString& aCssText)
michael@0 866 {
michael@0 867 return NS_ERROR_NOT_IMPLEMENTED;
michael@0 868 }
michael@0 869
michael@0 870 NS_IMETHODIMP
michael@0 871 MediaRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
michael@0 872 {
michael@0 873 return GroupRule::GetParentStyleSheet(aSheet);
michael@0 874 }
michael@0 875
michael@0 876 NS_IMETHODIMP
michael@0 877 MediaRule::GetParentRule(nsIDOMCSSRule** aParentRule)
michael@0 878 {
michael@0 879 return GroupRule::GetParentRule(aParentRule);
michael@0 880 }
michael@0 881
michael@0 882 // nsIDOMCSSGroupingRule methods
michael@0 883 NS_IMETHODIMP
michael@0 884 MediaRule::GetCssRules(nsIDOMCSSRuleList* *aRuleList)
michael@0 885 {
michael@0 886 return GroupRule::GetCssRules(aRuleList);
michael@0 887 }
michael@0 888
michael@0 889 NS_IMETHODIMP
michael@0 890 MediaRule::InsertRule(const nsAString & aRule, uint32_t aIndex, uint32_t* _retval)
michael@0 891 {
michael@0 892 return GroupRule::InsertRule(aRule, aIndex, _retval);
michael@0 893 }
michael@0 894
michael@0 895 NS_IMETHODIMP
michael@0 896 MediaRule::DeleteRule(uint32_t aIndex)
michael@0 897 {
michael@0 898 return GroupRule::DeleteRule(aIndex);
michael@0 899 }
michael@0 900
michael@0 901 // nsIDOMCSSConditionRule methods
michael@0 902 NS_IMETHODIMP
michael@0 903 MediaRule::GetConditionText(nsAString& aConditionText)
michael@0 904 {
michael@0 905 aConditionText.Truncate(0);
michael@0 906 AppendConditionText(aConditionText);
michael@0 907 return NS_OK;
michael@0 908 }
michael@0 909
michael@0 910 NS_IMETHODIMP
michael@0 911 MediaRule::SetConditionText(const nsAString& aConditionText)
michael@0 912 {
michael@0 913 if (!mMedia) {
michael@0 914 nsRefPtr<nsMediaList> media = new nsMediaList();
michael@0 915 media->SetStyleSheet(GetStyleSheet());
michael@0 916 nsresult rv = media->SetMediaText(aConditionText);
michael@0 917 if (NS_SUCCEEDED(rv)) {
michael@0 918 mMedia = media;
michael@0 919 }
michael@0 920 return rv;
michael@0 921 }
michael@0 922
michael@0 923 return mMedia->SetMediaText(aConditionText);
michael@0 924 }
michael@0 925
michael@0 926 // nsIDOMCSSMediaRule methods
michael@0 927 NS_IMETHODIMP
michael@0 928 MediaRule::GetMedia(nsIDOMMediaList* *aMedia)
michael@0 929 {
michael@0 930 NS_ENSURE_ARG_POINTER(aMedia);
michael@0 931 NS_IF_ADDREF(*aMedia = mMedia);
michael@0 932 return NS_OK;
michael@0 933 }
michael@0 934
michael@0 935 // GroupRule interface
michael@0 936 /* virtual */ bool
michael@0 937 MediaRule::UseForPresentation(nsPresContext* aPresContext,
michael@0 938 nsMediaQueryResultCacheKey& aKey)
michael@0 939 {
michael@0 940 if (mMedia) {
michael@0 941 return mMedia->Matches(aPresContext, &aKey);
michael@0 942 }
michael@0 943 return true;
michael@0 944 }
michael@0 945
michael@0 946 /* virtual */ size_t
michael@0 947 MediaRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
michael@0 948 {
michael@0 949 size_t n = aMallocSizeOf(this);
michael@0 950 n += GroupRule::SizeOfExcludingThis(aMallocSizeOf);
michael@0 951
michael@0 952 // Measurement of the following members may be added later if DMD finds it is
michael@0 953 // worthwhile:
michael@0 954 // - mMedia
michael@0 955
michael@0 956 return n;
michael@0 957 }
michael@0 958
michael@0 959 void
michael@0 960 MediaRule::AppendConditionText(nsAString& aOutput)
michael@0 961 {
michael@0 962 if (mMedia) {
michael@0 963 nsAutoString mediaText;
michael@0 964 mMedia->GetText(mediaText);
michael@0 965 aOutput.Append(mediaText);
michael@0 966 }
michael@0 967 }
michael@0 968
michael@0 969 } // namespace css
michael@0 970 } // namespace mozilla
michael@0 971
michael@0 972 // Must be outside namespace
michael@0 973 DOMCI_DATA(CSSMediaRule, css::MediaRule)
michael@0 974
michael@0 975 namespace mozilla {
michael@0 976 namespace css {
michael@0 977
michael@0 978 DocumentRule::DocumentRule()
michael@0 979 {
michael@0 980 }
michael@0 981
michael@0 982 DocumentRule::DocumentRule(const DocumentRule& aCopy)
michael@0 983 : GroupRule(aCopy)
michael@0 984 , mURLs(new URL(*aCopy.mURLs))
michael@0 985 {
michael@0 986 }
michael@0 987
michael@0 988 DocumentRule::~DocumentRule()
michael@0 989 {
michael@0 990 }
michael@0 991
michael@0 992 NS_IMPL_ADDREF_INHERITED(DocumentRule, GroupRule)
michael@0 993 NS_IMPL_RELEASE_INHERITED(DocumentRule, GroupRule)
michael@0 994
michael@0 995 // QueryInterface implementation for DocumentRule
michael@0 996 NS_INTERFACE_MAP_BEGIN(DocumentRule)
michael@0 997 NS_INTERFACE_MAP_ENTRY(nsIStyleRule)
michael@0 998 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
michael@0 999 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSGroupingRule)
michael@0 1000 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSConditionRule)
michael@0 1001 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSMozDocumentRule)
michael@0 1002 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStyleRule)
michael@0 1003 NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSMozDocumentRule)
michael@0 1004 NS_INTERFACE_MAP_END_INHERITING(GroupRule)
michael@0 1005
michael@0 1006 #ifdef DEBUG
michael@0 1007 /* virtual */ void
michael@0 1008 DocumentRule::List(FILE* out, int32_t aIndent) const
michael@0 1009 {
michael@0 1010 for (int32_t indent = aIndent; --indent >= 0; ) fputs(" ", out);
michael@0 1011
michael@0 1012 nsAutoCString str;
michael@0 1013 str.AssignLiteral("@-moz-document ");
michael@0 1014 for (URL *url = mURLs; url; url = url->next) {
michael@0 1015 switch (url->func) {
michael@0 1016 case eURL:
michael@0 1017 str.AppendLiteral("url(\"");
michael@0 1018 break;
michael@0 1019 case eURLPrefix:
michael@0 1020 str.AppendLiteral("url-prefix(\"");
michael@0 1021 break;
michael@0 1022 case eDomain:
michael@0 1023 str.AppendLiteral("domain(\"");
michael@0 1024 break;
michael@0 1025 case eRegExp:
michael@0 1026 str.AppendLiteral("regexp(\"");
michael@0 1027 break;
michael@0 1028 }
michael@0 1029 nsAutoCString escapedURL(url->url);
michael@0 1030 escapedURL.ReplaceSubstring("\"", "\\\""); // escape quotes
michael@0 1031 str.Append(escapedURL);
michael@0 1032 str.AppendLiteral("\"), ");
michael@0 1033 }
michael@0 1034 str.Cut(str.Length() - 2, 1); // remove last ,
michael@0 1035 fputs(str.get(), out);
michael@0 1036
michael@0 1037 GroupRule::List(out, aIndent);
michael@0 1038 }
michael@0 1039 #endif
michael@0 1040
michael@0 1041 /* virtual */ int32_t
michael@0 1042 DocumentRule::GetType() const
michael@0 1043 {
michael@0 1044 return Rule::DOCUMENT_RULE;
michael@0 1045 }
michael@0 1046
michael@0 1047 /* virtual */ already_AddRefed<Rule>
michael@0 1048 DocumentRule::Clone() const
michael@0 1049 {
michael@0 1050 nsRefPtr<Rule> clone = new DocumentRule(*this);
michael@0 1051 return clone.forget();
michael@0 1052 }
michael@0 1053
michael@0 1054 // nsIDOMCSSRule methods
michael@0 1055 NS_IMETHODIMP
michael@0 1056 DocumentRule::GetType(uint16_t* aType)
michael@0 1057 {
michael@0 1058 // XXX What should really happen here?
michael@0 1059 *aType = nsIDOMCSSRule::UNKNOWN_RULE;
michael@0 1060 return NS_OK;
michael@0 1061 }
michael@0 1062
michael@0 1063 NS_IMETHODIMP
michael@0 1064 DocumentRule::GetCssText(nsAString& aCssText)
michael@0 1065 {
michael@0 1066 aCssText.AssignLiteral("@-moz-document ");
michael@0 1067 AppendConditionText(aCssText);
michael@0 1068 GroupRule::AppendRulesToCssText(aCssText);
michael@0 1069 return NS_OK;
michael@0 1070 }
michael@0 1071
michael@0 1072 NS_IMETHODIMP
michael@0 1073 DocumentRule::SetCssText(const nsAString& aCssText)
michael@0 1074 {
michael@0 1075 return NS_ERROR_NOT_IMPLEMENTED;
michael@0 1076 }
michael@0 1077
michael@0 1078 NS_IMETHODIMP
michael@0 1079 DocumentRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
michael@0 1080 {
michael@0 1081 return GroupRule::GetParentStyleSheet(aSheet);
michael@0 1082 }
michael@0 1083
michael@0 1084 NS_IMETHODIMP
michael@0 1085 DocumentRule::GetParentRule(nsIDOMCSSRule** aParentRule)
michael@0 1086 {
michael@0 1087 return GroupRule::GetParentRule(aParentRule);
michael@0 1088 }
michael@0 1089
michael@0 1090 // nsIDOMCSSGroupingRule methods
michael@0 1091 NS_IMETHODIMP
michael@0 1092 DocumentRule::GetCssRules(nsIDOMCSSRuleList* *aRuleList)
michael@0 1093 {
michael@0 1094 return GroupRule::GetCssRules(aRuleList);
michael@0 1095 }
michael@0 1096
michael@0 1097 NS_IMETHODIMP
michael@0 1098 DocumentRule::InsertRule(const nsAString & aRule, uint32_t aIndex, uint32_t* _retval)
michael@0 1099 {
michael@0 1100 return GroupRule::InsertRule(aRule, aIndex, _retval);
michael@0 1101 }
michael@0 1102
michael@0 1103 NS_IMETHODIMP
michael@0 1104 DocumentRule::DeleteRule(uint32_t aIndex)
michael@0 1105 {
michael@0 1106 return GroupRule::DeleteRule(aIndex);
michael@0 1107 }
michael@0 1108
michael@0 1109 // nsIDOMCSSConditionRule methods
michael@0 1110 NS_IMETHODIMP
michael@0 1111 DocumentRule::GetConditionText(nsAString& aConditionText)
michael@0 1112 {
michael@0 1113 aConditionText.Truncate(0);
michael@0 1114 AppendConditionText(aConditionText);
michael@0 1115 return NS_OK;
michael@0 1116 }
michael@0 1117
michael@0 1118 NS_IMETHODIMP
michael@0 1119 DocumentRule::SetConditionText(const nsAString& aConditionText)
michael@0 1120 {
michael@0 1121 return NS_ERROR_NOT_IMPLEMENTED;
michael@0 1122 }
michael@0 1123
michael@0 1124 // GroupRule interface
michael@0 1125 /* virtual */ bool
michael@0 1126 DocumentRule::UseForPresentation(nsPresContext* aPresContext,
michael@0 1127 nsMediaQueryResultCacheKey& aKey)
michael@0 1128 {
michael@0 1129 nsIDocument *doc = aPresContext->Document();
michael@0 1130 nsIURI *docURI = doc->GetDocumentURI();
michael@0 1131 nsAutoCString docURISpec;
michael@0 1132 if (docURI)
michael@0 1133 docURI->GetSpec(docURISpec);
michael@0 1134
michael@0 1135 for (URL *url = mURLs; url; url = url->next) {
michael@0 1136 switch (url->func) {
michael@0 1137 case eURL: {
michael@0 1138 if (docURISpec == url->url)
michael@0 1139 return true;
michael@0 1140 } break;
michael@0 1141 case eURLPrefix: {
michael@0 1142 if (StringBeginsWith(docURISpec, url->url))
michael@0 1143 return true;
michael@0 1144 } break;
michael@0 1145 case eDomain: {
michael@0 1146 nsAutoCString host;
michael@0 1147 if (docURI)
michael@0 1148 docURI->GetHost(host);
michael@0 1149 int32_t lenDiff = host.Length() - url->url.Length();
michael@0 1150 if (lenDiff == 0) {
michael@0 1151 if (host == url->url)
michael@0 1152 return true;
michael@0 1153 } else {
michael@0 1154 if (StringEndsWith(host, url->url) &&
michael@0 1155 host.CharAt(lenDiff - 1) == '.')
michael@0 1156 return true;
michael@0 1157 }
michael@0 1158 } break;
michael@0 1159 case eRegExp: {
michael@0 1160 NS_ConvertUTF8toUTF16 spec(docURISpec);
michael@0 1161 NS_ConvertUTF8toUTF16 regex(url->url);
michael@0 1162 if (nsContentUtils::IsPatternMatching(spec, regex, doc)) {
michael@0 1163 return true;
michael@0 1164 }
michael@0 1165 } break;
michael@0 1166 }
michael@0 1167 }
michael@0 1168
michael@0 1169 return false;
michael@0 1170 }
michael@0 1171
michael@0 1172 DocumentRule::URL::~URL()
michael@0 1173 {
michael@0 1174 NS_CSS_DELETE_LIST_MEMBER(DocumentRule::URL, this, next);
michael@0 1175 }
michael@0 1176
michael@0 1177 /* virtual */ size_t
michael@0 1178 DocumentRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
michael@0 1179 {
michael@0 1180 size_t n = aMallocSizeOf(this);
michael@0 1181 n += GroupRule::SizeOfExcludingThis(aMallocSizeOf);
michael@0 1182
michael@0 1183 // Measurement of the following members may be added later if DMD finds it is
michael@0 1184 // worthwhile:
michael@0 1185 // - mURLs
michael@0 1186
michael@0 1187 return n;
michael@0 1188 }
michael@0 1189
michael@0 1190 void
michael@0 1191 DocumentRule::AppendConditionText(nsAString& aCssText)
michael@0 1192 {
michael@0 1193 for (URL *url = mURLs; url; url = url->next) {
michael@0 1194 switch (url->func) {
michael@0 1195 case eURL:
michael@0 1196 aCssText.AppendLiteral("url(");
michael@0 1197 break;
michael@0 1198 case eURLPrefix:
michael@0 1199 aCssText.AppendLiteral("url-prefix(");
michael@0 1200 break;
michael@0 1201 case eDomain:
michael@0 1202 aCssText.AppendLiteral("domain(");
michael@0 1203 break;
michael@0 1204 case eRegExp:
michael@0 1205 aCssText.AppendLiteral("regexp(");
michael@0 1206 break;
michael@0 1207 }
michael@0 1208 nsStyleUtil::AppendEscapedCSSString(NS_ConvertUTF8toUTF16(url->url),
michael@0 1209 aCssText);
michael@0 1210 aCssText.AppendLiteral("), ");
michael@0 1211 }
michael@0 1212 aCssText.Truncate(aCssText.Length() - 2); // remove last ", "
michael@0 1213 }
michael@0 1214
michael@0 1215 } // namespace css
michael@0 1216 } // namespace mozilla
michael@0 1217
michael@0 1218 // Must be outside namespace
michael@0 1219 DOMCI_DATA(CSSMozDocumentRule, css::DocumentRule)
michael@0 1220
michael@0 1221 // -------------------------------------------
michael@0 1222 // NameSpaceRule
michael@0 1223 //
michael@0 1224
michael@0 1225 namespace mozilla {
michael@0 1226 namespace css {
michael@0 1227
michael@0 1228 NameSpaceRule::NameSpaceRule(nsIAtom* aPrefix, const nsString& aURLSpec)
michael@0 1229 : Rule(),
michael@0 1230 mPrefix(aPrefix),
michael@0 1231 mURLSpec(aURLSpec)
michael@0 1232 {
michael@0 1233 }
michael@0 1234
michael@0 1235 NameSpaceRule::NameSpaceRule(const NameSpaceRule& aCopy)
michael@0 1236 : Rule(aCopy),
michael@0 1237 mPrefix(aCopy.mPrefix),
michael@0 1238 mURLSpec(aCopy.mURLSpec)
michael@0 1239 {
michael@0 1240 }
michael@0 1241
michael@0 1242 NameSpaceRule::~NameSpaceRule()
michael@0 1243 {
michael@0 1244 }
michael@0 1245
michael@0 1246 NS_IMPL_ADDREF(NameSpaceRule)
michael@0 1247 NS_IMPL_RELEASE(NameSpaceRule)
michael@0 1248
michael@0 1249 // QueryInterface implementation for NameSpaceRule
michael@0 1250 NS_INTERFACE_MAP_BEGIN(NameSpaceRule)
michael@0 1251 if (aIID.Equals(NS_GET_IID(css::NameSpaceRule))) {
michael@0 1252 *aInstancePtr = this;
michael@0 1253 NS_ADDREF_THIS();
michael@0 1254 return NS_OK;
michael@0 1255 }
michael@0 1256 else
michael@0 1257 NS_INTERFACE_MAP_ENTRY(nsIStyleRule)
michael@0 1258 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
michael@0 1259 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStyleRule)
michael@0 1260 NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSNameSpaceRule)
michael@0 1261 NS_INTERFACE_MAP_END
michael@0 1262
michael@0 1263 IMPL_STYLE_RULE_INHERIT(NameSpaceRule, Rule)
michael@0 1264
michael@0 1265 #ifdef DEBUG
michael@0 1266 /* virtual */ void
michael@0 1267 NameSpaceRule::List(FILE* out, int32_t aIndent) const
michael@0 1268 {
michael@0 1269 for (int32_t indent = aIndent; --indent >= 0; ) fputs(" ", out);
michael@0 1270
michael@0 1271 nsAutoString buffer;
michael@0 1272
michael@0 1273 fputs("@namespace ", out);
michael@0 1274
michael@0 1275 if (mPrefix) {
michael@0 1276 mPrefix->ToString(buffer);
michael@0 1277 fputs(NS_LossyConvertUTF16toASCII(buffer).get(), out);
michael@0 1278 fputs(" ", out);
michael@0 1279 }
michael@0 1280
michael@0 1281 fputs("url(", out);
michael@0 1282 fputs(NS_LossyConvertUTF16toASCII(mURLSpec).get(), out);
michael@0 1283 fputs(")\n", out);
michael@0 1284 }
michael@0 1285 #endif
michael@0 1286
michael@0 1287 /* virtual */ int32_t
michael@0 1288 NameSpaceRule::GetType() const
michael@0 1289 {
michael@0 1290 return Rule::NAMESPACE_RULE;
michael@0 1291 }
michael@0 1292
michael@0 1293 /* virtual */ already_AddRefed<Rule>
michael@0 1294 NameSpaceRule::Clone() const
michael@0 1295 {
michael@0 1296 nsRefPtr<Rule> clone = new NameSpaceRule(*this);
michael@0 1297 return clone.forget();
michael@0 1298 }
michael@0 1299
michael@0 1300 NS_IMETHODIMP
michael@0 1301 NameSpaceRule::GetType(uint16_t* aType)
michael@0 1302 {
michael@0 1303 *aType = nsIDOMCSSRule::NAMESPACE_RULE;
michael@0 1304 return NS_OK;
michael@0 1305 }
michael@0 1306
michael@0 1307 NS_IMETHODIMP
michael@0 1308 NameSpaceRule::GetCssText(nsAString& aCssText)
michael@0 1309 {
michael@0 1310 aCssText.AssignLiteral("@namespace ");
michael@0 1311 if (mPrefix) {
michael@0 1312 aCssText.Append(nsDependentAtomString(mPrefix) + NS_LITERAL_STRING(" "));
michael@0 1313 }
michael@0 1314 aCssText.AppendLiteral("url(");
michael@0 1315 nsStyleUtil::AppendEscapedCSSString(mURLSpec, aCssText);
michael@0 1316 aCssText.Append(NS_LITERAL_STRING(");"));
michael@0 1317 return NS_OK;
michael@0 1318 }
michael@0 1319
michael@0 1320 NS_IMETHODIMP
michael@0 1321 NameSpaceRule::SetCssText(const nsAString& aCssText)
michael@0 1322 {
michael@0 1323 return NS_ERROR_NOT_IMPLEMENTED;
michael@0 1324 }
michael@0 1325
michael@0 1326 NS_IMETHODIMP
michael@0 1327 NameSpaceRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
michael@0 1328 {
michael@0 1329 return Rule::GetParentStyleSheet(aSheet);
michael@0 1330 }
michael@0 1331
michael@0 1332 NS_IMETHODIMP
michael@0 1333 NameSpaceRule::GetParentRule(nsIDOMCSSRule** aParentRule)
michael@0 1334 {
michael@0 1335 return Rule::GetParentRule(aParentRule);
michael@0 1336 }
michael@0 1337
michael@0 1338 /* virtual */ size_t
michael@0 1339 NameSpaceRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
michael@0 1340 {
michael@0 1341 return aMallocSizeOf(this);
michael@0 1342
michael@0 1343 // Measurement of the following members may be added later if DMD finds it is
michael@0 1344 // worthwhile:
michael@0 1345 // - mPrefix
michael@0 1346 // - mURLSpec
michael@0 1347 }
michael@0 1348
michael@0 1349
michael@0 1350 } // namespace css
michael@0 1351 } // namespace mozilla
michael@0 1352
michael@0 1353 // Must be outside namespace
michael@0 1354 DOMCI_DATA(CSSNameSpaceRule, css::NameSpaceRule)
michael@0 1355
michael@0 1356 // -------------------------------------------
michael@0 1357 // nsCSSFontFaceStyleDecl and related routines
michael@0 1358 //
michael@0 1359
michael@0 1360 // A src: descriptor is represented as an array value; each entry in
michael@0 1361 // the array can be eCSSUnit_URL, eCSSUnit_Local_Font, or
michael@0 1362 // eCSSUnit_Font_Format. Blocks of eCSSUnit_Font_Format may appear
michael@0 1363 // only after one of the first two. (css3-fonts only contemplates
michael@0 1364 // annotating URLs with formats, but we handle the general case.)
michael@0 1365 static void
michael@0 1366 AppendSerializedFontSrc(const nsCSSValue& src, nsAString & aResult)
michael@0 1367 {
michael@0 1368 NS_PRECONDITION(src.GetUnit() == eCSSUnit_Array,
michael@0 1369 "improper value unit for src:");
michael@0 1370
michael@0 1371 const nsCSSValue::Array& sources = *src.GetArrayValue();
michael@0 1372 size_t i = 0;
michael@0 1373
michael@0 1374 while (i < sources.Count()) {
michael@0 1375 nsAutoString formats;
michael@0 1376
michael@0 1377 if (sources[i].GetUnit() == eCSSUnit_URL) {
michael@0 1378 aResult.AppendLiteral("url(");
michael@0 1379 nsDependentString url(sources[i].GetOriginalURLValue());
michael@0 1380 nsStyleUtil::AppendEscapedCSSString(url, aResult);
michael@0 1381 aResult.AppendLiteral(")");
michael@0 1382 } else if (sources[i].GetUnit() == eCSSUnit_Local_Font) {
michael@0 1383 aResult.AppendLiteral("local(");
michael@0 1384 nsDependentString local(sources[i].GetStringBufferValue());
michael@0 1385 nsStyleUtil::AppendEscapedCSSString(local, aResult);
michael@0 1386 aResult.AppendLiteral(")");
michael@0 1387 } else {
michael@0 1388 NS_NOTREACHED("entry in src: descriptor with improper unit");
michael@0 1389 i++;
michael@0 1390 continue;
michael@0 1391 }
michael@0 1392
michael@0 1393 i++;
michael@0 1394 formats.Truncate();
michael@0 1395 while (i < sources.Count() &&
michael@0 1396 sources[i].GetUnit() == eCSSUnit_Font_Format) {
michael@0 1397 formats.Append('"');
michael@0 1398 formats.Append(sources[i].GetStringBufferValue());
michael@0 1399 formats.AppendLiteral("\", ");
michael@0 1400 i++;
michael@0 1401 }
michael@0 1402 if (formats.Length() > 0) {
michael@0 1403 formats.Truncate(formats.Length() - 2); // remove the last comma
michael@0 1404 aResult.AppendLiteral(" format(");
michael@0 1405 aResult.Append(formats);
michael@0 1406 aResult.Append(')');
michael@0 1407 }
michael@0 1408 aResult.AppendLiteral(", ");
michael@0 1409 }
michael@0 1410 aResult.Truncate(aResult.Length() - 2); // remove the last comma-space
michael@0 1411 }
michael@0 1412
michael@0 1413 // print all characters with at least four hex digits
michael@0 1414 static void
michael@0 1415 AppendSerializedUnicodePoint(uint32_t aCode, nsACString &aBuf)
michael@0 1416 {
michael@0 1417 aBuf.Append(nsPrintfCString("%04X", aCode));
michael@0 1418 }
michael@0 1419
michael@0 1420 // A unicode-range: descriptor is represented as an array of integers,
michael@0 1421 // to be interpreted as a sequence of pairs: min max min max ...
michael@0 1422 // It is in source order. (Possibly it should be sorted and overlaps
michael@0 1423 // consolidated, but right now we don't do that.)
michael@0 1424 static void
michael@0 1425 AppendSerializedUnicodeRange(nsCSSValue const & aValue,
michael@0 1426 nsAString & aResult)
michael@0 1427 {
michael@0 1428 NS_PRECONDITION(aValue.GetUnit() == eCSSUnit_Null ||
michael@0 1429 aValue.GetUnit() == eCSSUnit_Array,
michael@0 1430 "improper value unit for unicode-range:");
michael@0 1431 aResult.Truncate();
michael@0 1432 if (aValue.GetUnit() != eCSSUnit_Array)
michael@0 1433 return;
michael@0 1434
michael@0 1435 nsCSSValue::Array const & sources = *aValue.GetArrayValue();
michael@0 1436 nsAutoCString buf;
michael@0 1437
michael@0 1438 NS_ABORT_IF_FALSE(sources.Count() % 2 == 0,
michael@0 1439 "odd number of entries in a unicode-range: array");
michael@0 1440
michael@0 1441 for (uint32_t i = 0; i < sources.Count(); i += 2) {
michael@0 1442 uint32_t min = sources[i].GetIntValue();
michael@0 1443 uint32_t max = sources[i+1].GetIntValue();
michael@0 1444
michael@0 1445 // We don't try to replicate the U+XX?? notation.
michael@0 1446 buf.AppendLiteral("U+");
michael@0 1447 AppendSerializedUnicodePoint(min, buf);
michael@0 1448
michael@0 1449 if (min != max) {
michael@0 1450 buf.Append('-');
michael@0 1451 AppendSerializedUnicodePoint(max, buf);
michael@0 1452 }
michael@0 1453 buf.AppendLiteral(", ");
michael@0 1454 }
michael@0 1455 buf.Truncate(buf.Length() - 2); // remove the last comma-space
michael@0 1456 CopyASCIItoUTF16(buf, aResult);
michael@0 1457 }
michael@0 1458
michael@0 1459 // Mapping from nsCSSFontDesc codes to nsCSSFontFaceStyleDecl fields.
michael@0 1460 nsCSSValue nsCSSFontFaceStyleDecl::* const
michael@0 1461 nsCSSFontFaceStyleDecl::Fields[] = {
michael@0 1462 #define CSS_FONT_DESC(name_, method_) &nsCSSFontFaceStyleDecl::m##method_,
michael@0 1463 #include "nsCSSFontDescList.h"
michael@0 1464 #undef CSS_FONT_DESC
michael@0 1465 };
michael@0 1466
michael@0 1467 // QueryInterface implementation for nsCSSFontFaceStyleDecl
michael@0 1468 NS_INTERFACE_MAP_BEGIN(nsCSSFontFaceStyleDecl)
michael@0 1469 NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
michael@0 1470 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSStyleDeclaration)
michael@0 1471 NS_INTERFACE_MAP_ENTRY(nsICSSDeclaration)
michael@0 1472 NS_INTERFACE_MAP_ENTRY(nsISupports)
michael@0 1473 // We forward the cycle collection interfaces to ContainingRule(), which is
michael@0 1474 // never null (in fact, we're part of that object!)
michael@0 1475 if (aIID.Equals(NS_GET_IID(nsCycleCollectionISupports)) ||
michael@0 1476 aIID.Equals(NS_GET_IID(nsXPCOMCycleCollectionParticipant))) {
michael@0 1477 return ContainingRule()->QueryInterface(aIID, aInstancePtr);
michael@0 1478 }
michael@0 1479 else
michael@0 1480 NS_INTERFACE_MAP_END
michael@0 1481
michael@0 1482 NS_IMPL_ADDREF_USING_AGGREGATOR(nsCSSFontFaceStyleDecl, ContainingRule())
michael@0 1483 NS_IMPL_RELEASE_USING_AGGREGATOR(nsCSSFontFaceStyleDecl, ContainingRule())
michael@0 1484
michael@0 1485 // helper for string GetPropertyValue and RemovePropertyValue
michael@0 1486 nsresult
michael@0 1487 nsCSSFontFaceStyleDecl::GetPropertyValue(nsCSSFontDesc aFontDescID,
michael@0 1488 nsAString & aResult) const
michael@0 1489 {
michael@0 1490 NS_ENSURE_ARG_RANGE(aFontDescID, eCSSFontDesc_UNKNOWN,
michael@0 1491 eCSSFontDesc_COUNT - 1);
michael@0 1492
michael@0 1493 aResult.Truncate();
michael@0 1494 if (aFontDescID == eCSSFontDesc_UNKNOWN)
michael@0 1495 return NS_OK;
michael@0 1496
michael@0 1497 const nsCSSValue& val = this->*nsCSSFontFaceStyleDecl::Fields[aFontDescID];
michael@0 1498
michael@0 1499 if (val.GetUnit() == eCSSUnit_Null) {
michael@0 1500 // Avoid having to check no-value in the Family and Src cases below.
michael@0 1501 return NS_OK;
michael@0 1502 }
michael@0 1503
michael@0 1504 switch (aFontDescID) {
michael@0 1505 case eCSSFontDesc_Family: {
michael@0 1506 // we don't use nsCSSValue::AppendToString here because it doesn't
michael@0 1507 // canonicalize the way we want, and anyway it's overkill when
michael@0 1508 // we know we have eCSSUnit_String
michael@0 1509 NS_ASSERTION(val.GetUnit() == eCSSUnit_String, "unexpected unit");
michael@0 1510 nsDependentString family(val.GetStringBufferValue());
michael@0 1511 nsStyleUtil::AppendEscapedCSSString(family, aResult);
michael@0 1512 return NS_OK;
michael@0 1513 }
michael@0 1514
michael@0 1515 case eCSSFontDesc_Style:
michael@0 1516 val.AppendToString(eCSSProperty_font_style, aResult,
michael@0 1517 nsCSSValue::eNormalized);
michael@0 1518 return NS_OK;
michael@0 1519
michael@0 1520 case eCSSFontDesc_Weight:
michael@0 1521 val.AppendToString(eCSSProperty_font_weight, aResult,
michael@0 1522 nsCSSValue::eNormalized);
michael@0 1523 return NS_OK;
michael@0 1524
michael@0 1525 case eCSSFontDesc_Stretch:
michael@0 1526 val.AppendToString(eCSSProperty_font_stretch, aResult,
michael@0 1527 nsCSSValue::eNormalized);
michael@0 1528 return NS_OK;
michael@0 1529
michael@0 1530 case eCSSFontDesc_FontFeatureSettings:
michael@0 1531 nsStyleUtil::AppendFontFeatureSettings(val, aResult);
michael@0 1532 return NS_OK;
michael@0 1533
michael@0 1534 case eCSSFontDesc_FontLanguageOverride:
michael@0 1535 val.AppendToString(eCSSProperty_font_language_override, aResult,
michael@0 1536 nsCSSValue::eNormalized);
michael@0 1537 return NS_OK;
michael@0 1538
michael@0 1539 case eCSSFontDesc_Src:
michael@0 1540 AppendSerializedFontSrc(val, aResult);
michael@0 1541 return NS_OK;
michael@0 1542
michael@0 1543 case eCSSFontDesc_UnicodeRange:
michael@0 1544 AppendSerializedUnicodeRange(val, aResult);
michael@0 1545 return NS_OK;
michael@0 1546
michael@0 1547 case eCSSFontDesc_UNKNOWN:
michael@0 1548 case eCSSFontDesc_COUNT:
michael@0 1549 ;
michael@0 1550 }
michael@0 1551 NS_NOTREACHED("nsCSSFontFaceStyleDecl::GetPropertyValue: "
michael@0 1552 "out-of-range value got to the switch");
michael@0 1553 return NS_ERROR_INVALID_ARG;
michael@0 1554 }
michael@0 1555
michael@0 1556
michael@0 1557 // attribute DOMString cssText;
michael@0 1558 NS_IMETHODIMP
michael@0 1559 nsCSSFontFaceStyleDecl::GetCssText(nsAString & aCssText)
michael@0 1560 {
michael@0 1561 nsAutoString descStr;
michael@0 1562
michael@0 1563 aCssText.Truncate();
michael@0 1564 for (nsCSSFontDesc id = nsCSSFontDesc(eCSSFontDesc_UNKNOWN + 1);
michael@0 1565 id < eCSSFontDesc_COUNT;
michael@0 1566 id = nsCSSFontDesc(id + 1)) {
michael@0 1567 if ((this->*nsCSSFontFaceStyleDecl::Fields[id]).GetUnit()
michael@0 1568 != eCSSUnit_Null &&
michael@0 1569 NS_SUCCEEDED(GetPropertyValue(id, descStr))) {
michael@0 1570 NS_ASSERTION(descStr.Length() > 0,
michael@0 1571 "GetCssText: non-null unit, empty property value");
michael@0 1572 aCssText.AppendLiteral(" ");
michael@0 1573 aCssText.AppendASCII(nsCSSProps::GetStringValue(id).get());
michael@0 1574 aCssText.AppendLiteral(": ");
michael@0 1575 aCssText.Append(descStr);
michael@0 1576 aCssText.AppendLiteral(";\n");
michael@0 1577 }
michael@0 1578 }
michael@0 1579 return NS_OK;
michael@0 1580 }
michael@0 1581
michael@0 1582 NS_IMETHODIMP
michael@0 1583 nsCSSFontFaceStyleDecl::SetCssText(const nsAString & aCssText)
michael@0 1584 {
michael@0 1585 return NS_ERROR_NOT_IMPLEMENTED; // bug 443978
michael@0 1586 }
michael@0 1587
michael@0 1588 // DOMString getPropertyValue (in DOMString propertyName);
michael@0 1589 NS_IMETHODIMP
michael@0 1590 nsCSSFontFaceStyleDecl::GetPropertyValue(const nsAString & propertyName,
michael@0 1591 nsAString & aResult)
michael@0 1592 {
michael@0 1593 return GetPropertyValue(nsCSSProps::LookupFontDesc(propertyName), aResult);
michael@0 1594 }
michael@0 1595
michael@0 1596 NS_IMETHODIMP
michael@0 1597 nsCSSFontFaceStyleDecl::GetAuthoredPropertyValue(const nsAString& propertyName,
michael@0 1598 nsAString& aResult)
michael@0 1599 {
michael@0 1600 // We don't return any authored property values different from
michael@0 1601 // GetPropertyValue, currently.
michael@0 1602 return GetPropertyValue(nsCSSProps::LookupFontDesc(propertyName), aResult);
michael@0 1603 }
michael@0 1604
michael@0 1605 // nsIDOMCSSValue getPropertyCSSValue (in DOMString propertyName);
michael@0 1606 already_AddRefed<dom::CSSValue>
michael@0 1607 nsCSSFontFaceStyleDecl::GetPropertyCSSValue(const nsAString & propertyName,
michael@0 1608 ErrorResult& aRv)
michael@0 1609 {
michael@0 1610 // ??? nsDOMCSSDeclaration returns null/NS_OK, but that seems wrong.
michael@0 1611 aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
michael@0 1612 return nullptr;
michael@0 1613 }
michael@0 1614
michael@0 1615 // DOMString removeProperty (in DOMString propertyName) raises (DOMException);
michael@0 1616 NS_IMETHODIMP
michael@0 1617 nsCSSFontFaceStyleDecl::RemoveProperty(const nsAString & propertyName,
michael@0 1618 nsAString & aResult)
michael@0 1619 {
michael@0 1620 nsCSSFontDesc descID = nsCSSProps::LookupFontDesc(propertyName);
michael@0 1621 NS_ASSERTION(descID >= eCSSFontDesc_UNKNOWN &&
michael@0 1622 descID < eCSSFontDesc_COUNT,
michael@0 1623 "LookupFontDesc returned value out of range");
michael@0 1624
michael@0 1625 if (descID == eCSSFontDesc_UNKNOWN) {
michael@0 1626 aResult.Truncate();
michael@0 1627 } else {
michael@0 1628 nsresult rv = GetPropertyValue(descID, aResult);
michael@0 1629 NS_ENSURE_SUCCESS(rv, rv);
michael@0 1630 (this->*nsCSSFontFaceStyleDecl::Fields[descID]).Reset();
michael@0 1631 }
michael@0 1632 return NS_OK;
michael@0 1633 }
michael@0 1634
michael@0 1635 // DOMString getPropertyPriority (in DOMString propertyName);
michael@0 1636 NS_IMETHODIMP
michael@0 1637 nsCSSFontFaceStyleDecl::GetPropertyPriority(const nsAString & propertyName,
michael@0 1638 nsAString & aResult)
michael@0 1639 {
michael@0 1640 // font descriptors do not have priorities at present
michael@0 1641 aResult.Truncate();
michael@0 1642 return NS_OK;
michael@0 1643 }
michael@0 1644
michael@0 1645 // void setProperty (in DOMString propertyName, in DOMString value,
michael@0 1646 // in DOMString priority) raises (DOMException);
michael@0 1647 NS_IMETHODIMP
michael@0 1648 nsCSSFontFaceStyleDecl::SetProperty(const nsAString & propertyName,
michael@0 1649 const nsAString & value,
michael@0 1650 const nsAString & priority)
michael@0 1651 {
michael@0 1652 return NS_ERROR_NOT_IMPLEMENTED; // bug 443978
michael@0 1653 }
michael@0 1654
michael@0 1655 // readonly attribute unsigned long length;
michael@0 1656 NS_IMETHODIMP
michael@0 1657 nsCSSFontFaceStyleDecl::GetLength(uint32_t *aLength)
michael@0 1658 {
michael@0 1659 uint32_t len = 0;
michael@0 1660 for (nsCSSFontDesc id = nsCSSFontDesc(eCSSFontDesc_UNKNOWN + 1);
michael@0 1661 id < eCSSFontDesc_COUNT;
michael@0 1662 id = nsCSSFontDesc(id + 1))
michael@0 1663 if ((this->*nsCSSFontFaceStyleDecl::Fields[id]).GetUnit() != eCSSUnit_Null)
michael@0 1664 len++;
michael@0 1665
michael@0 1666 *aLength = len;
michael@0 1667 return NS_OK;
michael@0 1668 }
michael@0 1669
michael@0 1670 // DOMString item (in unsigned long index);
michael@0 1671 NS_IMETHODIMP
michael@0 1672 nsCSSFontFaceStyleDecl::Item(uint32_t aIndex, nsAString& aReturn)
michael@0 1673 {
michael@0 1674 bool found;
michael@0 1675 IndexedGetter(aIndex, found, aReturn);
michael@0 1676 if (!found) {
michael@0 1677 aReturn.Truncate();
michael@0 1678 }
michael@0 1679 return NS_OK;
michael@0 1680 }
michael@0 1681
michael@0 1682 void
michael@0 1683 nsCSSFontFaceStyleDecl::IndexedGetter(uint32_t index, bool& aFound, nsAString & aResult)
michael@0 1684 {
michael@0 1685 int32_t nset = -1;
michael@0 1686 for (nsCSSFontDesc id = nsCSSFontDesc(eCSSFontDesc_UNKNOWN + 1);
michael@0 1687 id < eCSSFontDesc_COUNT;
michael@0 1688 id = nsCSSFontDesc(id + 1)) {
michael@0 1689 if ((this->*nsCSSFontFaceStyleDecl::Fields[id]).GetUnit()
michael@0 1690 != eCSSUnit_Null) {
michael@0 1691 nset++;
michael@0 1692 if (nset == int32_t(index)) {
michael@0 1693 aFound = true;
michael@0 1694 aResult.AssignASCII(nsCSSProps::GetStringValue(id).get());
michael@0 1695 return;
michael@0 1696 }
michael@0 1697 }
michael@0 1698 }
michael@0 1699 aFound = false;
michael@0 1700 }
michael@0 1701
michael@0 1702 // readonly attribute nsIDOMCSSRule parentRule;
michael@0 1703 NS_IMETHODIMP
michael@0 1704 nsCSSFontFaceStyleDecl::GetParentRule(nsIDOMCSSRule** aParentRule)
michael@0 1705 {
michael@0 1706 NS_IF_ADDREF(*aParentRule = ContainingRule()->GetDOMRule());
michael@0 1707 return NS_OK;
michael@0 1708 }
michael@0 1709
michael@0 1710 NS_IMETHODIMP
michael@0 1711 nsCSSFontFaceStyleDecl::GetPropertyValue(const nsCSSProperty aPropID,
michael@0 1712 nsAString& aValue)
michael@0 1713 {
michael@0 1714 return
michael@0 1715 GetPropertyValue(NS_ConvertUTF8toUTF16(nsCSSProps::GetStringValue(aPropID)),
michael@0 1716 aValue);
michael@0 1717 }
michael@0 1718
michael@0 1719 NS_IMETHODIMP
michael@0 1720 nsCSSFontFaceStyleDecl::SetPropertyValue(const nsCSSProperty aPropID,
michael@0 1721 const nsAString& aValue)
michael@0 1722 {
michael@0 1723 return SetProperty(NS_ConvertUTF8toUTF16(nsCSSProps::GetStringValue(aPropID)),
michael@0 1724 aValue, EmptyString());
michael@0 1725 }
michael@0 1726
michael@0 1727 nsINode*
michael@0 1728 nsCSSFontFaceStyleDecl::GetParentObject()
michael@0 1729 {
michael@0 1730 return ContainingRule()->GetDocument();
michael@0 1731 }
michael@0 1732
michael@0 1733 JSObject*
michael@0 1734 nsCSSFontFaceStyleDecl::WrapObject(JSContext *cx)
michael@0 1735 {
michael@0 1736 return mozilla::dom::CSSStyleDeclarationBinding::Wrap(cx, this);
michael@0 1737 }
michael@0 1738
michael@0 1739 // -------------------------------------------
michael@0 1740 // nsCSSFontFaceRule
michael@0 1741 //
michael@0 1742
michael@0 1743 /* virtual */ already_AddRefed<css::Rule>
michael@0 1744 nsCSSFontFaceRule::Clone() const
michael@0 1745 {
michael@0 1746 nsRefPtr<css::Rule> clone = new nsCSSFontFaceRule(*this);
michael@0 1747 return clone.forget();
michael@0 1748 }
michael@0 1749
michael@0 1750 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsCSSFontFaceRule)
michael@0 1751 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsCSSFontFaceRule)
michael@0 1752
michael@0 1753 NS_IMPL_CYCLE_COLLECTION_CLASS(nsCSSFontFaceRule)
michael@0 1754
michael@0 1755 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsCSSFontFaceRule)
michael@0 1756 // Trace the wrapper for our declaration. This just expands out
michael@0 1757 // NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER which we can't use
michael@0 1758 // directly because the wrapper is on the declaration, not on us.
michael@0 1759 tmp->mDecl.TraceWrapper(aCallbacks, aClosure);
michael@0 1760 NS_IMPL_CYCLE_COLLECTION_TRACE_END
michael@0 1761
michael@0 1762 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsCSSFontFaceRule)
michael@0 1763 // Unlink the wrapper for our declaraton. This just expands out
michael@0 1764 // NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER which we can't use
michael@0 1765 // directly because the wrapper is on the declaration, not on us.
michael@0 1766 tmp->mDecl.ReleaseWrapper(static_cast<nsISupports*>(p));
michael@0 1767 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
michael@0 1768
michael@0 1769 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsCSSFontFaceRule)
michael@0 1770 // Just NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS here: that will call
michael@0 1771 // into our Trace hook, where we do the right thing with declarations
michael@0 1772 // already.
michael@0 1773 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
michael@0 1774 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
michael@0 1775
michael@0 1776 DOMCI_DATA(CSSFontFaceRule, nsCSSFontFaceRule)
michael@0 1777
michael@0 1778 // QueryInterface implementation for nsCSSFontFaceRule
michael@0 1779 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsCSSFontFaceRule)
michael@0 1780 NS_INTERFACE_MAP_ENTRY(nsIStyleRule)
michael@0 1781 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSFontFaceRule)
michael@0 1782 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
michael@0 1783 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStyleRule)
michael@0 1784 NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSFontFaceRule)
michael@0 1785 NS_INTERFACE_MAP_END
michael@0 1786
michael@0 1787 IMPL_STYLE_RULE_INHERIT(nsCSSFontFaceRule, Rule)
michael@0 1788
michael@0 1789 #ifdef DEBUG
michael@0 1790 void
michael@0 1791 nsCSSFontFaceRule::List(FILE* out, int32_t aIndent) const
michael@0 1792 {
michael@0 1793 nsCString baseInd, descInd;
michael@0 1794 for (int32_t indent = aIndent; --indent >= 0; ) {
michael@0 1795 baseInd.AppendLiteral(" ");
michael@0 1796 descInd.AppendLiteral(" ");
michael@0 1797 }
michael@0 1798 descInd.AppendLiteral(" ");
michael@0 1799
michael@0 1800 nsString descStr;
michael@0 1801
michael@0 1802 fprintf(out, "%s@font-face {\n", baseInd.get());
michael@0 1803 for (nsCSSFontDesc id = nsCSSFontDesc(eCSSFontDesc_UNKNOWN + 1);
michael@0 1804 id < eCSSFontDesc_COUNT;
michael@0 1805 id = nsCSSFontDesc(id + 1))
michael@0 1806 if ((mDecl.*nsCSSFontFaceStyleDecl::Fields[id]).GetUnit()
michael@0 1807 != eCSSUnit_Null) {
michael@0 1808 if (NS_FAILED(mDecl.GetPropertyValue(id, descStr)))
michael@0 1809 descStr.AssignLiteral("#<serialization error>");
michael@0 1810 else if (descStr.Length() == 0)
michael@0 1811 descStr.AssignLiteral("#<serialization missing>");
michael@0 1812 fprintf(out, "%s%s: %s\n",
michael@0 1813 descInd.get(), nsCSSProps::GetStringValue(id).get(),
michael@0 1814 NS_ConvertUTF16toUTF8(descStr).get());
michael@0 1815 }
michael@0 1816 fprintf(out, "%s}\n", baseInd.get());
michael@0 1817 }
michael@0 1818 #endif
michael@0 1819
michael@0 1820 /* virtual */ int32_t
michael@0 1821 nsCSSFontFaceRule::GetType() const
michael@0 1822 {
michael@0 1823 return Rule::FONT_FACE_RULE;
michael@0 1824 }
michael@0 1825
michael@0 1826 NS_IMETHODIMP
michael@0 1827 nsCSSFontFaceRule::GetType(uint16_t* aType)
michael@0 1828 {
michael@0 1829 *aType = nsIDOMCSSRule::FONT_FACE_RULE;
michael@0 1830 return NS_OK;
michael@0 1831 }
michael@0 1832
michael@0 1833 NS_IMETHODIMP
michael@0 1834 nsCSSFontFaceRule::GetCssText(nsAString& aCssText)
michael@0 1835 {
michael@0 1836 nsAutoString propText;
michael@0 1837 mDecl.GetCssText(propText);
michael@0 1838
michael@0 1839 aCssText.AssignLiteral("@font-face {\n");
michael@0 1840 aCssText.Append(propText);
michael@0 1841 aCssText.Append('}');
michael@0 1842 return NS_OK;
michael@0 1843 }
michael@0 1844
michael@0 1845 NS_IMETHODIMP
michael@0 1846 nsCSSFontFaceRule::SetCssText(const nsAString& aCssText)
michael@0 1847 {
michael@0 1848 return NS_ERROR_NOT_IMPLEMENTED; // bug 443978
michael@0 1849 }
michael@0 1850
michael@0 1851 NS_IMETHODIMP
michael@0 1852 nsCSSFontFaceRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
michael@0 1853 {
michael@0 1854 return Rule::GetParentStyleSheet(aSheet);
michael@0 1855 }
michael@0 1856
michael@0 1857 NS_IMETHODIMP
michael@0 1858 nsCSSFontFaceRule::GetParentRule(nsIDOMCSSRule** aParentRule)
michael@0 1859 {
michael@0 1860 return Rule::GetParentRule(aParentRule);
michael@0 1861 }
michael@0 1862
michael@0 1863 NS_IMETHODIMP
michael@0 1864 nsCSSFontFaceRule::GetStyle(nsIDOMCSSStyleDeclaration** aStyle)
michael@0 1865 {
michael@0 1866 NS_IF_ADDREF(*aStyle = &mDecl);
michael@0 1867 return NS_OK;
michael@0 1868 }
michael@0 1869
michael@0 1870 // Arguably these should forward to nsCSSFontFaceStyleDecl methods.
michael@0 1871 void
michael@0 1872 nsCSSFontFaceRule::SetDesc(nsCSSFontDesc aDescID, nsCSSValue const & aValue)
michael@0 1873 {
michael@0 1874 NS_PRECONDITION(aDescID > eCSSFontDesc_UNKNOWN &&
michael@0 1875 aDescID < eCSSFontDesc_COUNT,
michael@0 1876 "aDescID out of range in nsCSSFontFaceRule::SetDesc");
michael@0 1877
michael@0 1878 // FIXME: handle dynamic changes
michael@0 1879
michael@0 1880 mDecl.*nsCSSFontFaceStyleDecl::Fields[aDescID] = aValue;
michael@0 1881 }
michael@0 1882
michael@0 1883 void
michael@0 1884 nsCSSFontFaceRule::GetDesc(nsCSSFontDesc aDescID, nsCSSValue & aValue)
michael@0 1885 {
michael@0 1886 NS_PRECONDITION(aDescID > eCSSFontDesc_UNKNOWN &&
michael@0 1887 aDescID < eCSSFontDesc_COUNT,
michael@0 1888 "aDescID out of range in nsCSSFontFaceRule::GetDesc");
michael@0 1889
michael@0 1890 aValue = mDecl.*nsCSSFontFaceStyleDecl::Fields[aDescID];
michael@0 1891 }
michael@0 1892
michael@0 1893 /* virtual */ size_t
michael@0 1894 nsCSSFontFaceRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
michael@0 1895 {
michael@0 1896 return aMallocSizeOf(this);
michael@0 1897
michael@0 1898 // Measurement of the following members may be added later if DMD finds it is
michael@0 1899 // worthwhile:
michael@0 1900 // - mDecl
michael@0 1901 }
michael@0 1902
michael@0 1903
michael@0 1904 // -----------------------------------
michael@0 1905 // nsCSSFontFeatureValuesRule
michael@0 1906 //
michael@0 1907
michael@0 1908 /* virtual */ already_AddRefed<css::Rule>
michael@0 1909 nsCSSFontFeatureValuesRule::Clone() const
michael@0 1910 {
michael@0 1911 nsRefPtr<css::Rule> clone = new nsCSSFontFeatureValuesRule(*this);
michael@0 1912 return clone.forget();
michael@0 1913 }
michael@0 1914
michael@0 1915 NS_IMPL_ADDREF(nsCSSFontFeatureValuesRule)
michael@0 1916 NS_IMPL_RELEASE(nsCSSFontFeatureValuesRule)
michael@0 1917
michael@0 1918 DOMCI_DATA(CSSFontFeatureValuesRule, nsCSSFontFeatureValuesRule)
michael@0 1919
michael@0 1920 // QueryInterface implementation for nsCSSFontFeatureValuesRule
michael@0 1921 NS_INTERFACE_MAP_BEGIN(nsCSSFontFeatureValuesRule)
michael@0 1922 NS_INTERFACE_MAP_ENTRY(nsIStyleRule)
michael@0 1923 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSFontFeatureValuesRule)
michael@0 1924 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
michael@0 1925 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStyleRule)
michael@0 1926 NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSFontFeatureValuesRule)
michael@0 1927 NS_INTERFACE_MAP_END
michael@0 1928
michael@0 1929 IMPL_STYLE_RULE_INHERIT(nsCSSFontFeatureValuesRule, Rule)
michael@0 1930
michael@0 1931 static void
michael@0 1932 FamilyListToString(const nsTArray<nsString>& aFamilyList, nsAString& aOutStr)
michael@0 1933 {
michael@0 1934 uint32_t i, n = aFamilyList.Length();
michael@0 1935
michael@0 1936 for (i = 0; i < n; i++) {
michael@0 1937 nsStyleUtil::AppendEscapedCSSString(aFamilyList[i], aOutStr);
michael@0 1938 if (i != n - 1) {
michael@0 1939 aOutStr.AppendLiteral(", ");
michael@0 1940 }
michael@0 1941 }
michael@0 1942 }
michael@0 1943
michael@0 1944 static void
michael@0 1945 FeatureValuesToString(
michael@0 1946 const nsTArray<gfxFontFeatureValueSet::FeatureValues>& aFeatureValues,
michael@0 1947 nsAString& aOutStr)
michael@0 1948 {
michael@0 1949 uint32_t i, n;
michael@0 1950
michael@0 1951 // append values
michael@0 1952 n = aFeatureValues.Length();
michael@0 1953 for (i = 0; i < n; i++) {
michael@0 1954 const gfxFontFeatureValueSet::FeatureValues& fv = aFeatureValues[i];
michael@0 1955
michael@0 1956 // @alternate
michael@0 1957 aOutStr.AppendLiteral(" @");
michael@0 1958 nsAutoString functAlt;
michael@0 1959 nsStyleUtil::GetFunctionalAlternatesName(fv.alternate, functAlt);
michael@0 1960 aOutStr.Append(functAlt);
michael@0 1961 aOutStr.AppendLiteral(" {");
michael@0 1962
michael@0 1963 // for each ident-values tuple
michael@0 1964 uint32_t j, numValues = fv.valuelist.Length();
michael@0 1965 for (j = 0; j < numValues; j++) {
michael@0 1966 aOutStr.AppendLiteral(" ");
michael@0 1967 const gfxFontFeatureValueSet::ValueList& vlist = fv.valuelist[j];
michael@0 1968 nsStyleUtil::AppendEscapedCSSIdent(vlist.name, aOutStr);
michael@0 1969 aOutStr.AppendLiteral(":");
michael@0 1970
michael@0 1971 uint32_t k, numSelectors = vlist.featureSelectors.Length();
michael@0 1972 for (k = 0; k < numSelectors; k++) {
michael@0 1973 aOutStr.AppendLiteral(" ");
michael@0 1974 aOutStr.AppendInt(vlist.featureSelectors[k]);
michael@0 1975 }
michael@0 1976
michael@0 1977 aOutStr.AppendLiteral(";");
michael@0 1978 }
michael@0 1979 aOutStr.AppendLiteral(" }\n");
michael@0 1980 }
michael@0 1981 }
michael@0 1982
michael@0 1983 static void
michael@0 1984 FontFeatureValuesRuleToString(
michael@0 1985 const nsTArray<nsString>& aFamilyList,
michael@0 1986 const nsTArray<gfxFontFeatureValueSet::FeatureValues>& aFeatureValues,
michael@0 1987 nsAString& aOutStr)
michael@0 1988 {
michael@0 1989 aOutStr.AssignLiteral("@font-feature-values ");
michael@0 1990 nsAutoString familyListStr, valueTextStr;
michael@0 1991 FamilyListToString(aFamilyList, familyListStr);
michael@0 1992 aOutStr.Append(familyListStr);
michael@0 1993 aOutStr.AppendLiteral(" {\n");
michael@0 1994 FeatureValuesToString(aFeatureValues, valueTextStr);
michael@0 1995 aOutStr.Append(valueTextStr);
michael@0 1996 aOutStr.AppendLiteral("}");
michael@0 1997 }
michael@0 1998
michael@0 1999 #ifdef DEBUG
michael@0 2000 void
michael@0 2001 nsCSSFontFeatureValuesRule::List(FILE* out, int32_t aIndent) const
michael@0 2002 {
michael@0 2003 nsAutoString text;
michael@0 2004 FontFeatureValuesRuleToString(mFamilyList, mFeatureValues, text);
michael@0 2005 NS_ConvertUTF16toUTF8 utf8(text);
michael@0 2006
michael@0 2007 // replace newlines with newlines plus indent spaces
michael@0 2008 char* indent = new char[(aIndent + 1) * 2];
michael@0 2009 int32_t i;
michael@0 2010 for (i = 1; i < (aIndent + 1) * 2 - 1; i++) {
michael@0 2011 indent[i] = 0x20;
michael@0 2012 }
michael@0 2013 indent[0] = 0xa;
michael@0 2014 indent[aIndent * 2 + 1] = 0;
michael@0 2015 utf8.ReplaceSubstring("\n", indent);
michael@0 2016 delete [] indent;
michael@0 2017
michael@0 2018 for (i = aIndent; --i >= 0; ) fputs(" ", out);
michael@0 2019 fprintf(out, "%s\n", utf8.get());
michael@0 2020 }
michael@0 2021 #endif
michael@0 2022
michael@0 2023 /* virtual */ int32_t
michael@0 2024 nsCSSFontFeatureValuesRule::GetType() const
michael@0 2025 {
michael@0 2026 return Rule::FONT_FEATURE_VALUES_RULE;
michael@0 2027 }
michael@0 2028
michael@0 2029 NS_IMETHODIMP
michael@0 2030 nsCSSFontFeatureValuesRule::GetType(uint16_t* aType)
michael@0 2031 {
michael@0 2032 *aType = nsIDOMCSSRule::FONT_FEATURE_VALUES_RULE;
michael@0 2033 return NS_OK;
michael@0 2034 }
michael@0 2035
michael@0 2036 NS_IMETHODIMP
michael@0 2037 nsCSSFontFeatureValuesRule::GetCssText(nsAString& aCssText)
michael@0 2038 {
michael@0 2039 FontFeatureValuesRuleToString(mFamilyList, mFeatureValues, aCssText);
michael@0 2040 return NS_OK;
michael@0 2041 }
michael@0 2042
michael@0 2043 NS_IMETHODIMP
michael@0 2044 nsCSSFontFeatureValuesRule::SetCssText(const nsAString& aCssText)
michael@0 2045 {
michael@0 2046 // FIXME: implement???
michael@0 2047 return NS_ERROR_NOT_IMPLEMENTED;
michael@0 2048 }
michael@0 2049
michael@0 2050 NS_IMETHODIMP
michael@0 2051 nsCSSFontFeatureValuesRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
michael@0 2052 {
michael@0 2053 return Rule::GetParentStyleSheet(aSheet);
michael@0 2054 }
michael@0 2055
michael@0 2056 NS_IMETHODIMP
michael@0 2057 nsCSSFontFeatureValuesRule::GetParentRule(nsIDOMCSSRule** aParentRule)
michael@0 2058 {
michael@0 2059 return Rule::GetParentRule(aParentRule);
michael@0 2060 }
michael@0 2061
michael@0 2062 NS_IMETHODIMP
michael@0 2063 nsCSSFontFeatureValuesRule::GetFontFamily(nsAString& aFontFamily)
michael@0 2064 {
michael@0 2065 FamilyListToString(mFamilyList, aFontFamily);
michael@0 2066 return NS_OK;
michael@0 2067 }
michael@0 2068
michael@0 2069 NS_IMETHODIMP
michael@0 2070 nsCSSFontFeatureValuesRule::SetFontFamily(const nsAString& aFontFamily)
michael@0 2071 {
michael@0 2072 return NS_ERROR_NOT_IMPLEMENTED;
michael@0 2073 }
michael@0 2074
michael@0 2075 NS_IMETHODIMP
michael@0 2076 nsCSSFontFeatureValuesRule::GetValueText(nsAString& aValueText)
michael@0 2077 {
michael@0 2078 FeatureValuesToString(mFeatureValues, aValueText);
michael@0 2079 return NS_OK;
michael@0 2080 }
michael@0 2081
michael@0 2082 NS_IMETHODIMP
michael@0 2083 nsCSSFontFeatureValuesRule::SetValueText(const nsAString& aValueText)
michael@0 2084 {
michael@0 2085 return NS_ERROR_NOT_IMPLEMENTED;
michael@0 2086 }
michael@0 2087
michael@0 2088 struct MakeFamilyArray {
michael@0 2089 MakeFamilyArray(nsTArray<nsString>& aFamilyArray)
michael@0 2090 : familyArray(aFamilyArray), hasGeneric(false)
michael@0 2091 {}
michael@0 2092
michael@0 2093 static bool
michael@0 2094 AddFamily(const nsString& aFamily, bool aGeneric, void* aData)
michael@0 2095 {
michael@0 2096 MakeFamilyArray *familyArr = reinterpret_cast<MakeFamilyArray*> (aData);
michael@0 2097 if (!aGeneric && !aFamily.IsEmpty()) {
michael@0 2098 familyArr->familyArray.AppendElement(aFamily);
michael@0 2099 }
michael@0 2100 if (aGeneric) {
michael@0 2101 familyArr->hasGeneric = true;
michael@0 2102 }
michael@0 2103 return true;
michael@0 2104 }
michael@0 2105
michael@0 2106 nsTArray<nsString>& familyArray;
michael@0 2107 bool hasGeneric;
michael@0 2108 };
michael@0 2109
michael@0 2110 void
michael@0 2111 nsCSSFontFeatureValuesRule::SetFamilyList(const nsAString& aFamilyList,
michael@0 2112 bool& aContainsGeneric)
michael@0 2113 {
michael@0 2114 nsFont font(aFamilyList, 0, 0, 0, 0, 0, 0);
michael@0 2115 MakeFamilyArray families(mFamilyList);
michael@0 2116 font.EnumerateFamilies(MakeFamilyArray::AddFamily, (void*) &families);
michael@0 2117 aContainsGeneric = families.hasGeneric;
michael@0 2118 }
michael@0 2119
michael@0 2120 void
michael@0 2121 nsCSSFontFeatureValuesRule::AddValueList(int32_t aVariantAlternate,
michael@0 2122 nsTArray<gfxFontFeatureValueSet::ValueList>& aValueList)
michael@0 2123 {
michael@0 2124 uint32_t i, len = mFeatureValues.Length();
michael@0 2125 bool foundAlternate = false;
michael@0 2126
michael@0 2127 // add to an existing list for a given property value
michael@0 2128 for (i = 0; i < len; i++) {
michael@0 2129 gfxFontFeatureValueSet::FeatureValues& f = mFeatureValues.ElementAt(i);
michael@0 2130
michael@0 2131 if (f.alternate == uint32_t(aVariantAlternate)) {
michael@0 2132 f.valuelist.AppendElements(aValueList);
michael@0 2133 foundAlternate = true;
michael@0 2134 break;
michael@0 2135 }
michael@0 2136 }
michael@0 2137
michael@0 2138 // create a new list for a given property value
michael@0 2139 if (!foundAlternate) {
michael@0 2140 gfxFontFeatureValueSet::FeatureValues &f = *mFeatureValues.AppendElement();
michael@0 2141 f.alternate = aVariantAlternate;
michael@0 2142 f.valuelist.AppendElements(aValueList);
michael@0 2143 }
michael@0 2144 }
michael@0 2145
michael@0 2146 size_t
michael@0 2147 nsCSSFontFeatureValuesRule::SizeOfIncludingThis(
michael@0 2148 MallocSizeOf aMallocSizeOf) const
michael@0 2149 {
michael@0 2150 return aMallocSizeOf(this);
michael@0 2151 }
michael@0 2152
michael@0 2153 // -------------------------------------------
michael@0 2154 // nsCSSKeyframeStyleDeclaration
michael@0 2155 //
michael@0 2156
michael@0 2157 nsCSSKeyframeStyleDeclaration::nsCSSKeyframeStyleDeclaration(nsCSSKeyframeRule *aRule)
michael@0 2158 : mRule(aRule)
michael@0 2159 {
michael@0 2160 }
michael@0 2161
michael@0 2162 nsCSSKeyframeStyleDeclaration::~nsCSSKeyframeStyleDeclaration()
michael@0 2163 {
michael@0 2164 NS_ASSERTION(!mRule, "DropReference not called.");
michael@0 2165 }
michael@0 2166
michael@0 2167 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsCSSKeyframeStyleDeclaration)
michael@0 2168 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsCSSKeyframeStyleDeclaration)
michael@0 2169
michael@0 2170 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(nsCSSKeyframeStyleDeclaration)
michael@0 2171
michael@0 2172 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsCSSKeyframeStyleDeclaration)
michael@0 2173 NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
michael@0 2174 NS_INTERFACE_MAP_END_INHERITING(nsDOMCSSDeclaration)
michael@0 2175
michael@0 2176 css::Declaration*
michael@0 2177 nsCSSKeyframeStyleDeclaration::GetCSSDeclaration(bool aAllocate)
michael@0 2178 {
michael@0 2179 if (mRule) {
michael@0 2180 return mRule->Declaration();
michael@0 2181 } else {
michael@0 2182 return nullptr;
michael@0 2183 }
michael@0 2184 }
michael@0 2185
michael@0 2186 void
michael@0 2187 nsCSSKeyframeStyleDeclaration::GetCSSParsingEnvironment(CSSParsingEnvironment& aCSSParseEnv)
michael@0 2188 {
michael@0 2189 GetCSSParsingEnvironmentForRule(mRule, aCSSParseEnv);
michael@0 2190 }
michael@0 2191
michael@0 2192 NS_IMETHODIMP
michael@0 2193 nsCSSKeyframeStyleDeclaration::GetParentRule(nsIDOMCSSRule **aParent)
michael@0 2194 {
michael@0 2195 NS_ENSURE_ARG_POINTER(aParent);
michael@0 2196
michael@0 2197 NS_IF_ADDREF(*aParent = mRule);
michael@0 2198 return NS_OK;
michael@0 2199 }
michael@0 2200
michael@0 2201 nsresult
michael@0 2202 nsCSSKeyframeStyleDeclaration::SetCSSDeclaration(css::Declaration* aDecl)
michael@0 2203 {
michael@0 2204 NS_ABORT_IF_FALSE(aDecl, "must be non-null");
michael@0 2205 mRule->ChangeDeclaration(aDecl);
michael@0 2206 return NS_OK;
michael@0 2207 }
michael@0 2208
michael@0 2209 nsIDocument*
michael@0 2210 nsCSSKeyframeStyleDeclaration::DocToUpdate()
michael@0 2211 {
michael@0 2212 return nullptr;
michael@0 2213 }
michael@0 2214
michael@0 2215 nsINode*
michael@0 2216 nsCSSKeyframeStyleDeclaration::GetParentObject()
michael@0 2217 {
michael@0 2218 return mRule ? mRule->GetDocument() : nullptr;
michael@0 2219 }
michael@0 2220
michael@0 2221 // -------------------------------------------
michael@0 2222 // nsCSSKeyframeRule
michael@0 2223 //
michael@0 2224
michael@0 2225 nsCSSKeyframeRule::nsCSSKeyframeRule(const nsCSSKeyframeRule& aCopy)
michael@0 2226 // copy everything except our reference count and mDOMDeclaration
michael@0 2227 : Rule(aCopy)
michael@0 2228 , mKeys(aCopy.mKeys)
michael@0 2229 , mDeclaration(new css::Declaration(*aCopy.mDeclaration))
michael@0 2230 {
michael@0 2231 }
michael@0 2232
michael@0 2233 nsCSSKeyframeRule::~nsCSSKeyframeRule()
michael@0 2234 {
michael@0 2235 if (mDOMDeclaration) {
michael@0 2236 mDOMDeclaration->DropReference();
michael@0 2237 }
michael@0 2238 }
michael@0 2239
michael@0 2240 /* virtual */ already_AddRefed<css::Rule>
michael@0 2241 nsCSSKeyframeRule::Clone() const
michael@0 2242 {
michael@0 2243 nsRefPtr<css::Rule> clone = new nsCSSKeyframeRule(*this);
michael@0 2244 return clone.forget();
michael@0 2245 }
michael@0 2246
michael@0 2247 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsCSSKeyframeRule)
michael@0 2248 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsCSSKeyframeRule)
michael@0 2249
michael@0 2250 NS_IMPL_CYCLE_COLLECTION_CLASS(nsCSSKeyframeRule)
michael@0 2251
michael@0 2252 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsCSSKeyframeRule)
michael@0 2253 if (tmp->mDOMDeclaration) {
michael@0 2254 tmp->mDOMDeclaration->DropReference();
michael@0 2255 tmp->mDOMDeclaration = nullptr;
michael@0 2256 }
michael@0 2257 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
michael@0 2258 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsCSSKeyframeRule)
michael@0 2259 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDOMDeclaration)
michael@0 2260 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
michael@0 2261
michael@0 2262 DOMCI_DATA(MozCSSKeyframeRule, nsCSSKeyframeRule)
michael@0 2263
michael@0 2264 // QueryInterface implementation for nsCSSKeyframeRule
michael@0 2265 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsCSSKeyframeRule)
michael@0 2266 NS_INTERFACE_MAP_ENTRY(nsIStyleRule)
michael@0 2267 NS_INTERFACE_MAP_ENTRY(nsIDOMMozCSSKeyframeRule)
michael@0 2268 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
michael@0 2269 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStyleRule)
michael@0 2270 NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MozCSSKeyframeRule)
michael@0 2271 NS_INTERFACE_MAP_END
michael@0 2272
michael@0 2273 IMPL_STYLE_RULE_INHERIT_GET_DOM_RULE_WEAK(nsCSSKeyframeRule, Rule)
michael@0 2274
michael@0 2275 /* virtual */ void
michael@0 2276 nsCSSKeyframeRule::MapRuleInfoInto(nsRuleData* aRuleData)
michael@0 2277 {
michael@0 2278 // We need to implement MapRuleInfoInto because the animation manager
michael@0 2279 // constructs a rule node pointing to us in order to compute the
michael@0 2280 // styles it needs to animate.
michael@0 2281
michael@0 2282 // The spec says that !important declarations should just be ignored
michael@0 2283 NS_ASSERTION(!mDeclaration->HasImportantData(),
michael@0 2284 "Keyframe rules has !important data");
michael@0 2285
michael@0 2286 mDeclaration->MapNormalRuleInfoInto(aRuleData);
michael@0 2287 }
michael@0 2288
michael@0 2289 #ifdef DEBUG
michael@0 2290 void
michael@0 2291 nsCSSKeyframeRule::List(FILE* out, int32_t aIndent) const
michael@0 2292 {
michael@0 2293 for (int32_t index = aIndent; --index >= 0; ) fputs(" ", out);
michael@0 2294
michael@0 2295 nsAutoString tmp;
michael@0 2296 DoGetKeyText(tmp);
michael@0 2297 fputs(NS_ConvertUTF16toUTF8(tmp).get(), out);
michael@0 2298 fputs(" ", out);
michael@0 2299 mDeclaration->List(out, aIndent);
michael@0 2300 fputs("\n", out);
michael@0 2301 }
michael@0 2302 #endif
michael@0 2303
michael@0 2304 /* virtual */ int32_t
michael@0 2305 nsCSSKeyframeRule::GetType() const
michael@0 2306 {
michael@0 2307 return Rule::KEYFRAME_RULE;
michael@0 2308 }
michael@0 2309
michael@0 2310 NS_IMETHODIMP
michael@0 2311 nsCSSKeyframeRule::GetType(uint16_t* aType)
michael@0 2312 {
michael@0 2313 *aType = nsIDOMCSSRule::KEYFRAME_RULE;
michael@0 2314 return NS_OK;
michael@0 2315 }
michael@0 2316
michael@0 2317 NS_IMETHODIMP
michael@0 2318 nsCSSKeyframeRule::GetCssText(nsAString& aCssText)
michael@0 2319 {
michael@0 2320 DoGetKeyText(aCssText);
michael@0 2321 aCssText.AppendLiteral(" { ");
michael@0 2322 nsAutoString tmp;
michael@0 2323 mDeclaration->ToString(tmp);
michael@0 2324 aCssText.Append(tmp);
michael@0 2325 aCssText.AppendLiteral(" }");
michael@0 2326 return NS_OK;
michael@0 2327 }
michael@0 2328
michael@0 2329 NS_IMETHODIMP
michael@0 2330 nsCSSKeyframeRule::SetCssText(const nsAString& aCssText)
michael@0 2331 {
michael@0 2332 // FIXME: implement???
michael@0 2333 return NS_ERROR_NOT_IMPLEMENTED;
michael@0 2334 }
michael@0 2335
michael@0 2336 NS_IMETHODIMP
michael@0 2337 nsCSSKeyframeRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
michael@0 2338 {
michael@0 2339 return Rule::GetParentStyleSheet(aSheet);
michael@0 2340 }
michael@0 2341
michael@0 2342 NS_IMETHODIMP
michael@0 2343 nsCSSKeyframeRule::GetParentRule(nsIDOMCSSRule** aParentRule)
michael@0 2344 {
michael@0 2345 return Rule::GetParentRule(aParentRule);
michael@0 2346 }
michael@0 2347
michael@0 2348 NS_IMETHODIMP
michael@0 2349 nsCSSKeyframeRule::GetKeyText(nsAString& aKeyText)
michael@0 2350 {
michael@0 2351 DoGetKeyText(aKeyText);
michael@0 2352 return NS_OK;
michael@0 2353 }
michael@0 2354
michael@0 2355 void
michael@0 2356 nsCSSKeyframeRule::DoGetKeyText(nsAString& aKeyText) const
michael@0 2357 {
michael@0 2358 aKeyText.Truncate();
michael@0 2359 uint32_t i = 0, i_end = mKeys.Length();
michael@0 2360 NS_ABORT_IF_FALSE(i_end != 0, "must have some keys");
michael@0 2361 for (;;) {
michael@0 2362 aKeyText.AppendFloat(mKeys[i] * 100.0f);
michael@0 2363 aKeyText.Append(char16_t('%'));
michael@0 2364 if (++i == i_end) {
michael@0 2365 break;
michael@0 2366 }
michael@0 2367 aKeyText.AppendLiteral(", ");
michael@0 2368 }
michael@0 2369 }
michael@0 2370
michael@0 2371 NS_IMETHODIMP
michael@0 2372 nsCSSKeyframeRule::SetKeyText(const nsAString& aKeyText)
michael@0 2373 {
michael@0 2374 nsCSSParser parser;
michael@0 2375
michael@0 2376 InfallibleTArray<float> newSelectors;
michael@0 2377 // FIXME: pass filename and line number
michael@0 2378 if (!parser.ParseKeyframeSelectorString(aKeyText, nullptr, 0, newSelectors)) {
michael@0 2379 // for now, we don't do anything if the parse fails
michael@0 2380 return NS_OK;
michael@0 2381 }
michael@0 2382
michael@0 2383 nsIDocument* doc = GetDocument();
michael@0 2384 MOZ_AUTO_DOC_UPDATE(doc, UPDATE_STYLE, true);
michael@0 2385
michael@0 2386 newSelectors.SwapElements(mKeys);
michael@0 2387
michael@0 2388 nsCSSStyleSheet* sheet = GetStyleSheet();
michael@0 2389 if (sheet) {
michael@0 2390 sheet->SetModifiedByChildRule();
michael@0 2391
michael@0 2392 if (doc) {
michael@0 2393 doc->StyleRuleChanged(sheet, this, this);
michael@0 2394 }
michael@0 2395 }
michael@0 2396
michael@0 2397 return NS_OK;
michael@0 2398 }
michael@0 2399
michael@0 2400 NS_IMETHODIMP
michael@0 2401 nsCSSKeyframeRule::GetStyle(nsIDOMCSSStyleDeclaration** aStyle)
michael@0 2402 {
michael@0 2403 if (!mDOMDeclaration) {
michael@0 2404 mDOMDeclaration = new nsCSSKeyframeStyleDeclaration(this);
michael@0 2405 }
michael@0 2406 NS_ADDREF(*aStyle = mDOMDeclaration);
michael@0 2407 return NS_OK;
michael@0 2408 }
michael@0 2409
michael@0 2410 void
michael@0 2411 nsCSSKeyframeRule::ChangeDeclaration(css::Declaration* aDeclaration)
michael@0 2412 {
michael@0 2413 // Our caller already did a BeginUpdate/EndUpdate, but with
michael@0 2414 // UPDATE_CONTENT, and we need UPDATE_STYLE to trigger work in
michael@0 2415 // PresShell::EndUpdate.
michael@0 2416 nsIDocument* doc = GetDocument();
michael@0 2417 MOZ_AUTO_DOC_UPDATE(doc, UPDATE_STYLE, true);
michael@0 2418
michael@0 2419 // Be careful to not assign to an nsAutoPtr if we would be assigning
michael@0 2420 // the thing it already holds.
michael@0 2421 if (aDeclaration != mDeclaration) {
michael@0 2422 mDeclaration = aDeclaration;
michael@0 2423 }
michael@0 2424
michael@0 2425 nsCSSStyleSheet* sheet = GetStyleSheet();
michael@0 2426 if (sheet) {
michael@0 2427 sheet->SetModifiedByChildRule();
michael@0 2428
michael@0 2429 if (doc) {
michael@0 2430 doc->StyleRuleChanged(sheet, this, this);
michael@0 2431 }
michael@0 2432 }
michael@0 2433 }
michael@0 2434
michael@0 2435 /* virtual */ size_t
michael@0 2436 nsCSSKeyframeRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
michael@0 2437 {
michael@0 2438 return aMallocSizeOf(this);
michael@0 2439
michael@0 2440 // Measurement of the following members may be added later if DMD finds it is
michael@0 2441 // worthwhile:
michael@0 2442 // - mKeys
michael@0 2443 // - mDeclaration
michael@0 2444 // - mDOMDeclaration
michael@0 2445 }
michael@0 2446
michael@0 2447
michael@0 2448 // -------------------------------------------
michael@0 2449 // nsCSSKeyframesRule
michael@0 2450 //
michael@0 2451
michael@0 2452 nsCSSKeyframesRule::nsCSSKeyframesRule(const nsCSSKeyframesRule& aCopy)
michael@0 2453 // copy everything except our reference count. GroupRule's copy
michael@0 2454 // constructor also doesn't copy the lazily-constructed
michael@0 2455 // mRuleCollection.
michael@0 2456 : GroupRule(aCopy),
michael@0 2457 mName(aCopy.mName)
michael@0 2458 {
michael@0 2459 }
michael@0 2460
michael@0 2461 nsCSSKeyframesRule::~nsCSSKeyframesRule()
michael@0 2462 {
michael@0 2463 }
michael@0 2464
michael@0 2465 /* virtual */ already_AddRefed<css::Rule>
michael@0 2466 nsCSSKeyframesRule::Clone() const
michael@0 2467 {
michael@0 2468 nsRefPtr<css::Rule> clone = new nsCSSKeyframesRule(*this);
michael@0 2469 return clone.forget();
michael@0 2470 }
michael@0 2471
michael@0 2472 NS_IMPL_ADDREF_INHERITED(nsCSSKeyframesRule, css::GroupRule)
michael@0 2473 NS_IMPL_RELEASE_INHERITED(nsCSSKeyframesRule, css::GroupRule)
michael@0 2474
michael@0 2475 DOMCI_DATA(MozCSSKeyframesRule, nsCSSKeyframesRule)
michael@0 2476
michael@0 2477 // QueryInterface implementation for nsCSSKeyframesRule
michael@0 2478 NS_INTERFACE_MAP_BEGIN(nsCSSKeyframesRule)
michael@0 2479 NS_INTERFACE_MAP_ENTRY(nsIStyleRule)
michael@0 2480 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
michael@0 2481 NS_INTERFACE_MAP_ENTRY(nsIDOMMozCSSKeyframesRule)
michael@0 2482 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStyleRule)
michael@0 2483 NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MozCSSKeyframesRule)
michael@0 2484 NS_INTERFACE_MAP_END_INHERITING(GroupRule)
michael@0 2485
michael@0 2486 #ifdef DEBUG
michael@0 2487 void
michael@0 2488 nsCSSKeyframesRule::List(FILE* out, int32_t aIndent) const
michael@0 2489 {
michael@0 2490 for (int32_t indent = aIndent; --indent >= 0; ) fputs(" ", out);
michael@0 2491
michael@0 2492 fprintf(out, "@keyframes %s", NS_ConvertUTF16toUTF8(mName).get());
michael@0 2493 GroupRule::List(out, aIndent);
michael@0 2494 }
michael@0 2495 #endif
michael@0 2496
michael@0 2497 /* virtual */ int32_t
michael@0 2498 nsCSSKeyframesRule::GetType() const
michael@0 2499 {
michael@0 2500 return Rule::KEYFRAMES_RULE;
michael@0 2501 }
michael@0 2502
michael@0 2503 NS_IMETHODIMP
michael@0 2504 nsCSSKeyframesRule::GetType(uint16_t* aType)
michael@0 2505 {
michael@0 2506 *aType = nsIDOMCSSRule::KEYFRAMES_RULE;
michael@0 2507 return NS_OK;
michael@0 2508 }
michael@0 2509
michael@0 2510 NS_IMETHODIMP
michael@0 2511 nsCSSKeyframesRule::GetCssText(nsAString& aCssText)
michael@0 2512 {
michael@0 2513 aCssText.AssignLiteral("@keyframes ");
michael@0 2514 aCssText.Append(mName);
michael@0 2515 aCssText.AppendLiteral(" {\n");
michael@0 2516 nsAutoString tmp;
michael@0 2517 for (uint32_t i = 0, i_end = mRules.Count(); i != i_end; ++i) {
michael@0 2518 static_cast<nsCSSKeyframeRule*>(mRules[i])->GetCssText(tmp);
michael@0 2519 aCssText.Append(tmp);
michael@0 2520 aCssText.AppendLiteral("\n");
michael@0 2521 }
michael@0 2522 aCssText.AppendLiteral("}");
michael@0 2523 return NS_OK;
michael@0 2524 }
michael@0 2525
michael@0 2526 NS_IMETHODIMP
michael@0 2527 nsCSSKeyframesRule::SetCssText(const nsAString& aCssText)
michael@0 2528 {
michael@0 2529 // FIXME: implement???
michael@0 2530 return NS_ERROR_NOT_IMPLEMENTED;
michael@0 2531 }
michael@0 2532
michael@0 2533 NS_IMETHODIMP
michael@0 2534 nsCSSKeyframesRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
michael@0 2535 {
michael@0 2536 return GroupRule::GetParentStyleSheet(aSheet);
michael@0 2537 }
michael@0 2538
michael@0 2539 NS_IMETHODIMP
michael@0 2540 nsCSSKeyframesRule::GetParentRule(nsIDOMCSSRule** aParentRule)
michael@0 2541 {
michael@0 2542 return GroupRule::GetParentRule(aParentRule);
michael@0 2543 }
michael@0 2544
michael@0 2545 NS_IMETHODIMP
michael@0 2546 nsCSSKeyframesRule::GetName(nsAString& aName)
michael@0 2547 {
michael@0 2548 aName = mName;
michael@0 2549 return NS_OK;
michael@0 2550 }
michael@0 2551
michael@0 2552 NS_IMETHODIMP
michael@0 2553 nsCSSKeyframesRule::SetName(const nsAString& aName)
michael@0 2554 {
michael@0 2555 if (mName == aName) {
michael@0 2556 return NS_OK;
michael@0 2557 }
michael@0 2558
michael@0 2559 nsIDocument* doc = GetDocument();
michael@0 2560 MOZ_AUTO_DOC_UPDATE(doc, UPDATE_STYLE, true);
michael@0 2561
michael@0 2562 mName = aName;
michael@0 2563
michael@0 2564 nsCSSStyleSheet* sheet = GetStyleSheet();
michael@0 2565 if (sheet) {
michael@0 2566 sheet->SetModifiedByChildRule();
michael@0 2567
michael@0 2568 if (doc) {
michael@0 2569 doc->StyleRuleChanged(sheet, this, this);
michael@0 2570 }
michael@0 2571 }
michael@0 2572
michael@0 2573 return NS_OK;
michael@0 2574 }
michael@0 2575
michael@0 2576 NS_IMETHODIMP
michael@0 2577 nsCSSKeyframesRule::GetCssRules(nsIDOMCSSRuleList* *aRuleList)
michael@0 2578 {
michael@0 2579 return GroupRule::GetCssRules(aRuleList);
michael@0 2580 }
michael@0 2581
michael@0 2582 NS_IMETHODIMP
michael@0 2583 nsCSSKeyframesRule::AppendRule(const nsAString& aRule)
michael@0 2584 {
michael@0 2585 // The spec is confusing, and I think we should just append the rule,
michael@0 2586 // which also turns out to match WebKit:
michael@0 2587 // http://lists.w3.org/Archives/Public/www-style/2011Apr/0034.html
michael@0 2588 nsCSSParser parser;
michael@0 2589
michael@0 2590 // FIXME: pass filename and line number
michael@0 2591 nsRefPtr<nsCSSKeyframeRule> rule =
michael@0 2592 parser.ParseKeyframeRule(aRule, nullptr, 0);
michael@0 2593 if (rule) {
michael@0 2594 nsIDocument* doc = GetDocument();
michael@0 2595 MOZ_AUTO_DOC_UPDATE(doc, UPDATE_STYLE, true);
michael@0 2596
michael@0 2597 AppendStyleRule(rule);
michael@0 2598
michael@0 2599 nsCSSStyleSheet* sheet = GetStyleSheet();
michael@0 2600 if (sheet) {
michael@0 2601 sheet->SetModifiedByChildRule();
michael@0 2602
michael@0 2603 if (doc) {
michael@0 2604 doc->StyleRuleChanged(sheet, this, this);
michael@0 2605 }
michael@0 2606 }
michael@0 2607 }
michael@0 2608
michael@0 2609 return NS_OK;
michael@0 2610 }
michael@0 2611
michael@0 2612 static const uint32_t RULE_NOT_FOUND = uint32_t(-1);
michael@0 2613
michael@0 2614 uint32_t
michael@0 2615 nsCSSKeyframesRule::FindRuleIndexForKey(const nsAString& aKey)
michael@0 2616 {
michael@0 2617 nsCSSParser parser;
michael@0 2618
michael@0 2619 InfallibleTArray<float> keys;
michael@0 2620 // FIXME: pass filename and line number
michael@0 2621 if (parser.ParseKeyframeSelectorString(aKey, nullptr, 0, keys)) {
michael@0 2622 // The spec isn't clear, but we'll match on the key list, which
michael@0 2623 // mostly matches what WebKit does, except we'll do last-match
michael@0 2624 // instead of first-match, and handling parsing differences better.
michael@0 2625 // http://lists.w3.org/Archives/Public/www-style/2011Apr/0036.html
michael@0 2626 // http://lists.w3.org/Archives/Public/www-style/2011Apr/0037.html
michael@0 2627 for (uint32_t i = mRules.Count(); i-- != 0; ) {
michael@0 2628 if (static_cast<nsCSSKeyframeRule*>(mRules[i])->GetKeys() == keys) {
michael@0 2629 return i;
michael@0 2630 }
michael@0 2631 }
michael@0 2632 }
michael@0 2633
michael@0 2634 return RULE_NOT_FOUND;
michael@0 2635 }
michael@0 2636
michael@0 2637 NS_IMETHODIMP
michael@0 2638 nsCSSKeyframesRule::DeleteRule(const nsAString& aKey)
michael@0 2639 {
michael@0 2640 uint32_t index = FindRuleIndexForKey(aKey);
michael@0 2641 if (index != RULE_NOT_FOUND) {
michael@0 2642 nsIDocument* doc = GetDocument();
michael@0 2643 MOZ_AUTO_DOC_UPDATE(doc, UPDATE_STYLE, true);
michael@0 2644
michael@0 2645 mRules.RemoveObjectAt(index);
michael@0 2646
michael@0 2647 nsCSSStyleSheet* sheet = GetStyleSheet();
michael@0 2648 if (sheet) {
michael@0 2649 sheet->SetModifiedByChildRule();
michael@0 2650
michael@0 2651 if (doc) {
michael@0 2652 doc->StyleRuleChanged(sheet, this, this);
michael@0 2653 }
michael@0 2654 }
michael@0 2655 }
michael@0 2656 return NS_OK;
michael@0 2657 }
michael@0 2658
michael@0 2659 NS_IMETHODIMP
michael@0 2660 nsCSSKeyframesRule::FindRule(const nsAString& aKey,
michael@0 2661 nsIDOMMozCSSKeyframeRule** aResult)
michael@0 2662 {
michael@0 2663 uint32_t index = FindRuleIndexForKey(aKey);
michael@0 2664 if (index == RULE_NOT_FOUND) {
michael@0 2665 *aResult = nullptr;
michael@0 2666 } else {
michael@0 2667 NS_ADDREF(*aResult = static_cast<nsCSSKeyframeRule*>(mRules[index]));
michael@0 2668 }
michael@0 2669 return NS_OK;
michael@0 2670 }
michael@0 2671
michael@0 2672 // GroupRule interface
michael@0 2673 /* virtual */ bool
michael@0 2674 nsCSSKeyframesRule::UseForPresentation(nsPresContext* aPresContext,
michael@0 2675 nsMediaQueryResultCacheKey& aKey)
michael@0 2676 {
michael@0 2677 NS_ABORT_IF_FALSE(false, "should not be called");
michael@0 2678 return false;
michael@0 2679 }
michael@0 2680
michael@0 2681 /* virtual */ size_t
michael@0 2682 nsCSSKeyframesRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
michael@0 2683 {
michael@0 2684 size_t n = aMallocSizeOf(this);
michael@0 2685 n += GroupRule::SizeOfExcludingThis(aMallocSizeOf);
michael@0 2686
michael@0 2687 // Measurement of the following members may be added later if DMD finds it is
michael@0 2688 // worthwhile:
michael@0 2689 // - mName
michael@0 2690
michael@0 2691 return n;
michael@0 2692 }
michael@0 2693
michael@0 2694 // -------------------------------------------
michael@0 2695 // nsCSSPageStyleDeclaration
michael@0 2696 //
michael@0 2697
michael@0 2698 nsCSSPageStyleDeclaration::nsCSSPageStyleDeclaration(nsCSSPageRule* aRule)
michael@0 2699 : mRule(aRule)
michael@0 2700 {
michael@0 2701 }
michael@0 2702
michael@0 2703 nsCSSPageStyleDeclaration::~nsCSSPageStyleDeclaration()
michael@0 2704 {
michael@0 2705 NS_ASSERTION(!mRule, "DropReference not called.");
michael@0 2706 }
michael@0 2707
michael@0 2708 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsCSSPageStyleDeclaration)
michael@0 2709 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsCSSPageStyleDeclaration)
michael@0 2710
michael@0 2711 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(nsCSSPageStyleDeclaration)
michael@0 2712
michael@0 2713 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsCSSPageStyleDeclaration)
michael@0 2714 NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
michael@0 2715 NS_INTERFACE_MAP_END_INHERITING(nsDOMCSSDeclaration)
michael@0 2716
michael@0 2717 css::Declaration*
michael@0 2718 nsCSSPageStyleDeclaration::GetCSSDeclaration(bool aAllocate)
michael@0 2719 {
michael@0 2720 if (mRule) {
michael@0 2721 return mRule->Declaration();
michael@0 2722 } else {
michael@0 2723 return nullptr;
michael@0 2724 }
michael@0 2725 }
michael@0 2726
michael@0 2727 void
michael@0 2728 nsCSSPageStyleDeclaration::GetCSSParsingEnvironment(CSSParsingEnvironment& aCSSParseEnv)
michael@0 2729 {
michael@0 2730 GetCSSParsingEnvironmentForRule(mRule, aCSSParseEnv);
michael@0 2731 }
michael@0 2732
michael@0 2733 NS_IMETHODIMP
michael@0 2734 nsCSSPageStyleDeclaration::GetParentRule(nsIDOMCSSRule** aParent)
michael@0 2735 {
michael@0 2736 NS_ENSURE_ARG_POINTER(aParent);
michael@0 2737
michael@0 2738 NS_IF_ADDREF(*aParent = mRule);
michael@0 2739 return NS_OK;
michael@0 2740 }
michael@0 2741
michael@0 2742 nsresult
michael@0 2743 nsCSSPageStyleDeclaration::SetCSSDeclaration(css::Declaration* aDecl)
michael@0 2744 {
michael@0 2745 NS_ABORT_IF_FALSE(aDecl, "must be non-null");
michael@0 2746 mRule->ChangeDeclaration(aDecl);
michael@0 2747 return NS_OK;
michael@0 2748 }
michael@0 2749
michael@0 2750 nsIDocument*
michael@0 2751 nsCSSPageStyleDeclaration::DocToUpdate()
michael@0 2752 {
michael@0 2753 return nullptr;
michael@0 2754 }
michael@0 2755
michael@0 2756 nsINode*
michael@0 2757 nsCSSPageStyleDeclaration::GetParentObject()
michael@0 2758 {
michael@0 2759 return mRule ? mRule->GetDocument() : nullptr;
michael@0 2760 }
michael@0 2761
michael@0 2762 // -------------------------------------------
michael@0 2763 // nsCSSPageRule
michael@0 2764 //
michael@0 2765
michael@0 2766 nsCSSPageRule::nsCSSPageRule(const nsCSSPageRule& aCopy)
michael@0 2767 // copy everything except our reference count and mDOMDeclaration
michael@0 2768 : Rule(aCopy)
michael@0 2769 , mDeclaration(new css::Declaration(*aCopy.mDeclaration))
michael@0 2770 {
michael@0 2771 }
michael@0 2772
michael@0 2773 nsCSSPageRule::~nsCSSPageRule()
michael@0 2774 {
michael@0 2775 if (mDOMDeclaration) {
michael@0 2776 mDOMDeclaration->DropReference();
michael@0 2777 }
michael@0 2778 }
michael@0 2779
michael@0 2780 /* virtual */ already_AddRefed<css::Rule>
michael@0 2781 nsCSSPageRule::Clone() const
michael@0 2782 {
michael@0 2783 nsRefPtr<css::Rule> clone = new nsCSSPageRule(*this);
michael@0 2784 return clone.forget();
michael@0 2785 }
michael@0 2786
michael@0 2787 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsCSSPageRule)
michael@0 2788 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsCSSPageRule)
michael@0 2789
michael@0 2790 NS_IMPL_CYCLE_COLLECTION_CLASS(nsCSSPageRule)
michael@0 2791
michael@0 2792 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsCSSPageRule)
michael@0 2793 if (tmp->mDOMDeclaration) {
michael@0 2794 tmp->mDOMDeclaration->DropReference();
michael@0 2795 tmp->mDOMDeclaration = nullptr;
michael@0 2796 }
michael@0 2797 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
michael@0 2798 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsCSSPageRule)
michael@0 2799 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDOMDeclaration)
michael@0 2800 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
michael@0 2801
michael@0 2802 DOMCI_DATA(CSSPageRule, nsCSSPageRule)
michael@0 2803
michael@0 2804 // QueryInterface implementation for nsCSSPageRule
michael@0 2805 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsCSSPageRule)
michael@0 2806 NS_INTERFACE_MAP_ENTRY(nsIStyleRule)
michael@0 2807 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSPageRule)
michael@0 2808 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
michael@0 2809 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStyleRule)
michael@0 2810 NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSPageRule)
michael@0 2811 NS_INTERFACE_MAP_END
michael@0 2812
michael@0 2813 IMPL_STYLE_RULE_INHERIT_GET_DOM_RULE_WEAK(nsCSSPageRule, Rule)
michael@0 2814
michael@0 2815 #ifdef DEBUG
michael@0 2816 void
michael@0 2817 nsCSSPageRule::List(FILE* out, int32_t aIndent) const
michael@0 2818 {
michael@0 2819 for (int32_t indent = aIndent; --indent >= 0; ) fputs(" ", out);
michael@0 2820
michael@0 2821 fputs("@page ", out);
michael@0 2822 mDeclaration->List(out, aIndent);
michael@0 2823 fputs("\n", out);
michael@0 2824 }
michael@0 2825 #endif
michael@0 2826
michael@0 2827 /* virtual */ int32_t
michael@0 2828 nsCSSPageRule::GetType() const
michael@0 2829 {
michael@0 2830 return Rule::PAGE_RULE;
michael@0 2831 }
michael@0 2832
michael@0 2833 NS_IMETHODIMP
michael@0 2834 nsCSSPageRule::GetType(uint16_t* aType)
michael@0 2835 {
michael@0 2836 *aType = nsIDOMCSSRule::PAGE_RULE;
michael@0 2837 return NS_OK;
michael@0 2838 }
michael@0 2839
michael@0 2840 NS_IMETHODIMP
michael@0 2841 nsCSSPageRule::GetCssText(nsAString& aCssText)
michael@0 2842 {
michael@0 2843 aCssText.AppendLiteral("@page { ");
michael@0 2844 nsAutoString tmp;
michael@0 2845 mDeclaration->ToString(tmp);
michael@0 2846 aCssText.Append(tmp);
michael@0 2847 aCssText.AppendLiteral(" }");
michael@0 2848 return NS_OK;
michael@0 2849 }
michael@0 2850
michael@0 2851 NS_IMETHODIMP
michael@0 2852 nsCSSPageRule::SetCssText(const nsAString& aCssText)
michael@0 2853 {
michael@0 2854 // FIXME: implement???
michael@0 2855 return NS_ERROR_NOT_IMPLEMENTED;
michael@0 2856 }
michael@0 2857
michael@0 2858 NS_IMETHODIMP
michael@0 2859 nsCSSPageRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
michael@0 2860 {
michael@0 2861 return Rule::GetParentStyleSheet(aSheet);
michael@0 2862 }
michael@0 2863
michael@0 2864 NS_IMETHODIMP
michael@0 2865 nsCSSPageRule::GetParentRule(nsIDOMCSSRule** aParentRule)
michael@0 2866 {
michael@0 2867 return Rule::GetParentRule(aParentRule);
michael@0 2868 }
michael@0 2869
michael@0 2870 css::ImportantRule*
michael@0 2871 nsCSSPageRule::GetImportantRule()
michael@0 2872 {
michael@0 2873 if (!mDeclaration->HasImportantData()) {
michael@0 2874 return nullptr;
michael@0 2875 }
michael@0 2876 if (!mImportantRule) {
michael@0 2877 mImportantRule = new css::ImportantRule(mDeclaration);
michael@0 2878 }
michael@0 2879 return mImportantRule;
michael@0 2880 }
michael@0 2881
michael@0 2882 /* virtual */ void
michael@0 2883 nsCSSPageRule::MapRuleInfoInto(nsRuleData* aRuleData)
michael@0 2884 {
michael@0 2885 mDeclaration->MapNormalRuleInfoInto(aRuleData);
michael@0 2886 }
michael@0 2887
michael@0 2888 NS_IMETHODIMP
michael@0 2889 nsCSSPageRule::GetStyle(nsIDOMCSSStyleDeclaration** aStyle)
michael@0 2890 {
michael@0 2891 if (!mDOMDeclaration) {
michael@0 2892 mDOMDeclaration = new nsCSSPageStyleDeclaration(this);
michael@0 2893 }
michael@0 2894 NS_ADDREF(*aStyle = mDOMDeclaration);
michael@0 2895 return NS_OK;
michael@0 2896 }
michael@0 2897
michael@0 2898 void
michael@0 2899 nsCSSPageRule::ChangeDeclaration(css::Declaration* aDeclaration)
michael@0 2900 {
michael@0 2901 mImportantRule = nullptr;
michael@0 2902 // Be careful to not assign to an nsAutoPtr if we would be assigning
michael@0 2903 // the thing it already holds.
michael@0 2904 if (aDeclaration != mDeclaration) {
michael@0 2905 mDeclaration = aDeclaration;
michael@0 2906 }
michael@0 2907
michael@0 2908 nsCSSStyleSheet* sheet = GetStyleSheet();
michael@0 2909 if (sheet) {
michael@0 2910 sheet->SetModifiedByChildRule();
michael@0 2911 }
michael@0 2912 }
michael@0 2913
michael@0 2914 /* virtual */ size_t
michael@0 2915 nsCSSPageRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
michael@0 2916 {
michael@0 2917 return aMallocSizeOf(this);
michael@0 2918 }
michael@0 2919
michael@0 2920 namespace mozilla {
michael@0 2921
michael@0 2922 CSSSupportsRule::CSSSupportsRule(bool aConditionMet,
michael@0 2923 const nsString& aCondition)
michael@0 2924 : mUseGroup(aConditionMet),
michael@0 2925 mCondition(aCondition)
michael@0 2926 {
michael@0 2927 }
michael@0 2928
michael@0 2929 CSSSupportsRule::CSSSupportsRule(const CSSSupportsRule& aCopy)
michael@0 2930 : css::GroupRule(aCopy),
michael@0 2931 mUseGroup(aCopy.mUseGroup),
michael@0 2932 mCondition(aCopy.mCondition)
michael@0 2933 {
michael@0 2934 }
michael@0 2935
michael@0 2936 #ifdef DEBUG
michael@0 2937 /* virtual */ void
michael@0 2938 CSSSupportsRule::List(FILE* out, int32_t aIndent) const
michael@0 2939 {
michael@0 2940 for (int32_t indent = aIndent; --indent >= 0; ) fputs(" ", out);
michael@0 2941
michael@0 2942 fputs("@supports ", out);
michael@0 2943 fputs(NS_ConvertUTF16toUTF8(mCondition).get(), out);
michael@0 2944 css::GroupRule::List(out, aIndent);
michael@0 2945 }
michael@0 2946 #endif
michael@0 2947
michael@0 2948 /* virtual */ int32_t
michael@0 2949 CSSSupportsRule::GetType() const
michael@0 2950 {
michael@0 2951 return Rule::SUPPORTS_RULE;
michael@0 2952 }
michael@0 2953
michael@0 2954 /* virtual */ already_AddRefed<mozilla::css::Rule>
michael@0 2955 CSSSupportsRule::Clone() const
michael@0 2956 {
michael@0 2957 nsRefPtr<css::Rule> clone = new CSSSupportsRule(*this);
michael@0 2958 return clone.forget();
michael@0 2959 }
michael@0 2960
michael@0 2961 /* virtual */ bool
michael@0 2962 CSSSupportsRule::UseForPresentation(nsPresContext* aPresContext,
michael@0 2963 nsMediaQueryResultCacheKey& aKey)
michael@0 2964 {
michael@0 2965 return mUseGroup;
michael@0 2966 }
michael@0 2967
michael@0 2968 NS_IMPL_ADDREF_INHERITED(CSSSupportsRule, css::GroupRule)
michael@0 2969 NS_IMPL_RELEASE_INHERITED(CSSSupportsRule, css::GroupRule)
michael@0 2970
michael@0 2971 // QueryInterface implementation for CSSSupportsRule
michael@0 2972 NS_INTERFACE_MAP_BEGIN(CSSSupportsRule)
michael@0 2973 NS_INTERFACE_MAP_ENTRY(nsIStyleRule)
michael@0 2974 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
michael@0 2975 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSGroupingRule)
michael@0 2976 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSConditionRule)
michael@0 2977 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSSupportsRule)
michael@0 2978 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStyleRule)
michael@0 2979 NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSSupportsRule)
michael@0 2980 NS_INTERFACE_MAP_END_INHERITING(GroupRule)
michael@0 2981
michael@0 2982 // nsIDOMCSSRule methods
michael@0 2983 NS_IMETHODIMP
michael@0 2984 CSSSupportsRule::GetType(uint16_t* aType)
michael@0 2985 {
michael@0 2986 *aType = nsIDOMCSSRule::SUPPORTS_RULE;
michael@0 2987 return NS_OK;
michael@0 2988 }
michael@0 2989
michael@0 2990 NS_IMETHODIMP
michael@0 2991 CSSSupportsRule::GetCssText(nsAString& aCssText)
michael@0 2992 {
michael@0 2993 aCssText.AssignLiteral("@supports ");
michael@0 2994 aCssText.Append(mCondition);
michael@0 2995 css::GroupRule::AppendRulesToCssText(aCssText);
michael@0 2996 return NS_OK;
michael@0 2997 }
michael@0 2998
michael@0 2999 NS_IMETHODIMP
michael@0 3000 CSSSupportsRule::SetCssText(const nsAString& aCssText)
michael@0 3001 {
michael@0 3002 return NS_ERROR_NOT_IMPLEMENTED;
michael@0 3003 }
michael@0 3004
michael@0 3005 NS_IMETHODIMP
michael@0 3006 CSSSupportsRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
michael@0 3007 {
michael@0 3008 return css::GroupRule::GetParentStyleSheet(aSheet);
michael@0 3009 }
michael@0 3010
michael@0 3011 NS_IMETHODIMP
michael@0 3012 CSSSupportsRule::GetParentRule(nsIDOMCSSRule** aParentRule)
michael@0 3013 {
michael@0 3014 return css::GroupRule::GetParentRule(aParentRule);
michael@0 3015 }
michael@0 3016
michael@0 3017 // nsIDOMCSSGroupingRule methods
michael@0 3018 NS_IMETHODIMP
michael@0 3019 CSSSupportsRule::GetCssRules(nsIDOMCSSRuleList* *aRuleList)
michael@0 3020 {
michael@0 3021 return css::GroupRule::GetCssRules(aRuleList);
michael@0 3022 }
michael@0 3023
michael@0 3024 NS_IMETHODIMP
michael@0 3025 CSSSupportsRule::InsertRule(const nsAString & aRule, uint32_t aIndex, uint32_t* _retval)
michael@0 3026 {
michael@0 3027 return css::GroupRule::InsertRule(aRule, aIndex, _retval);
michael@0 3028 }
michael@0 3029
michael@0 3030 NS_IMETHODIMP
michael@0 3031 CSSSupportsRule::DeleteRule(uint32_t aIndex)
michael@0 3032 {
michael@0 3033 return css::GroupRule::DeleteRule(aIndex);
michael@0 3034 }
michael@0 3035
michael@0 3036 // nsIDOMCSSConditionRule methods
michael@0 3037 NS_IMETHODIMP
michael@0 3038 CSSSupportsRule::GetConditionText(nsAString& aConditionText)
michael@0 3039 {
michael@0 3040 aConditionText.Assign(mCondition);
michael@0 3041 return NS_OK;
michael@0 3042 }
michael@0 3043
michael@0 3044 NS_IMETHODIMP
michael@0 3045 CSSSupportsRule::SetConditionText(const nsAString& aConditionText)
michael@0 3046 {
michael@0 3047 return NS_ERROR_NOT_IMPLEMENTED;
michael@0 3048 }
michael@0 3049
michael@0 3050 /* virtual */ size_t
michael@0 3051 CSSSupportsRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
michael@0 3052 {
michael@0 3053 size_t n = aMallocSizeOf(this);
michael@0 3054 n += css::GroupRule::SizeOfExcludingThis(aMallocSizeOf);
michael@0 3055 n += mCondition.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
michael@0 3056 return n;
michael@0 3057 }
michael@0 3058
michael@0 3059 } // namespace mozilla
michael@0 3060
michael@0 3061 // Must be outside namespace
michael@0 3062 DOMCI_DATA(CSSSupportsRule, mozilla::CSSSupportsRule)

mercurial