1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is mozilla.org code.
16 : *
17 : * The Initial Developer of the Original Code is
18 : * Netscape Communications Corporation.
19 : * Portions created by the Initial Developer are Copyright (C) 1999
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : * Boris Zbarsky <bzbarsky@mit.edu>
24 : *
25 : * Alternatively, the contents of this file may be used under the terms of
26 : * either of the GNU General Public License Version 2 or later (the "GPL"),
27 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 : * in which case the provisions of the GPL or the LGPL are applicable instead
29 : * of those above. If you wish to allow use of your version of this file only
30 : * under the terms of either the GPL or the LGPL, and not to allow others to
31 : * use your version of this file under the terms of the MPL, indicate your
32 : * decision by deleting the provisions above and replace them with the notice
33 : * and other provisions required by the GPL or the LGPL. If you do not delete
34 : * the provisions above, a recipient may use your version of this file under
35 : * the terms of any one of the MPL, the GPL or the LGPL.
36 : *
37 : * ***** END LICENSE BLOCK ***** */
38 :
39 : /* rules in a CSS stylesheet other than style rules (e.g., @import rules) */
40 :
41 : #include "mozilla/Attributes.h"
42 :
43 : #include "nsCSSRules.h"
44 : #include "nsCSSValue.h"
45 : #include "mozilla/css/ImportRule.h"
46 : #include "mozilla/css/NameSpaceRule.h"
47 :
48 : #include "nsString.h"
49 : #include "nsIAtom.h"
50 : #include "nsIURL.h"
51 :
52 : #include "nsCSSProps.h"
53 : #include "nsCSSStyleSheet.h"
54 :
55 : #include "nsCOMPtr.h"
56 : #include "nsIDOMCSSStyleSheet.h"
57 : #include "nsIMediaList.h"
58 : #include "nsICSSRuleList.h"
59 : #include "nsIDocument.h"
60 : #include "nsPresContext.h"
61 :
62 : #include "nsContentUtils.h"
63 : #include "nsStyleConsts.h"
64 : #include "nsDOMError.h"
65 : #include "nsStyleUtil.h"
66 : #include "mozilla/css/Declaration.h"
67 : #include "nsCSSParser.h"
68 : #include "nsPrintfCString.h"
69 :
70 : namespace css = mozilla::css;
71 :
72 : #define IMPL_STYLE_RULE_INHERIT_GET_DOM_RULE_WEAK(class_, super_) \
73 : /* virtual */ nsIDOMCSSRule* class_::GetDOMRule() \
74 : { return this; }
75 : #define IMPL_STYLE_RULE_INHERIT_MAP_RULE_INFO_INTO(class_, super_) \
76 : /* virtual */ void class_::MapRuleInfoInto(nsRuleData* aRuleData) \
77 : { NS_ABORT_IF_FALSE(false, "should not be called"); }
78 :
79 : #define IMPL_STYLE_RULE_INHERIT(class_, super_) \
80 : IMPL_STYLE_RULE_INHERIT_GET_DOM_RULE_WEAK(class_, super_) \
81 : IMPL_STYLE_RULE_INHERIT_MAP_RULE_INFO_INTO(class_, super_)
82 :
83 : // base class for all rule types in a CSS style sheet
84 :
85 : namespace mozilla {
86 : namespace css {
87 :
88 0 : NS_IMPL_ADDREF(Rule)
89 0 : NS_IMPL_RELEASE(Rule)
90 :
91 : /* virtual */ void
92 0 : Rule::SetStyleSheet(nsCSSStyleSheet* aSheet)
93 : {
94 : // We don't reference count this up reference. The style sheet
95 : // will tell us when it's going away or when we're detached from
96 : // it.
97 0 : mSheet = aSheet;
98 0 : }
99 :
100 : nsresult
101 0 : Rule::GetParentRule(nsIDOMCSSRule** aParentRule)
102 : {
103 0 : if (mParentRule) {
104 0 : NS_IF_ADDREF(*aParentRule = mParentRule->GetDOMRule());
105 : } else {
106 0 : *aParentRule = nsnull;
107 : }
108 0 : return NS_OK;
109 : }
110 :
111 : nsresult
112 0 : Rule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
113 : {
114 0 : NS_ENSURE_ARG_POINTER(aSheet);
115 :
116 0 : NS_IF_ADDREF(*aSheet = mSheet);
117 0 : return NS_OK;
118 : }
119 :
120 : size_t
121 0 : Rule::SizeOfCOMArrayElementIncludingThis(css::Rule* aElement,
122 : nsMallocSizeOfFun aMallocSizeOf,
123 : void* aData)
124 : {
125 0 : return aElement->SizeOfIncludingThis(aMallocSizeOf);
126 : }
127 :
128 : // -------------------------------
129 : // Style Rule List for group rules
130 : //
131 :
132 : class GroupRuleRuleList MOZ_FINAL : public nsICSSRuleList
133 : {
134 : public:
135 : GroupRuleRuleList(GroupRule *aGroupRule);
136 :
137 : NS_DECL_ISUPPORTS
138 :
139 : NS_DECL_NSIDOMCSSRULELIST
140 :
141 : virtual nsIDOMCSSRule* GetItemAt(PRUint32 aIndex, nsresult* aResult);
142 :
143 0 : void DropReference() { mGroupRule = nsnull; }
144 :
145 : private:
146 : ~GroupRuleRuleList();
147 :
148 : private:
149 : GroupRule* mGroupRule;
150 : };
151 :
152 0 : GroupRuleRuleList::GroupRuleRuleList(GroupRule *aGroupRule)
153 : {
154 : // Not reference counted to avoid circular references.
155 : // The rule will tell us when its going away.
156 0 : mGroupRule = aGroupRule;
157 0 : }
158 :
159 0 : GroupRuleRuleList::~GroupRuleRuleList()
160 : {
161 0 : }
162 :
163 : // QueryInterface implementation for CSSGroupRuleRuleList
164 0 : NS_INTERFACE_MAP_BEGIN(GroupRuleRuleList)
165 0 : NS_INTERFACE_MAP_ENTRY(nsICSSRuleList)
166 0 : NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRuleList)
167 0 : NS_INTERFACE_MAP_ENTRY(nsISupports)
168 0 : NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSGroupRuleRuleList)
169 0 : NS_INTERFACE_MAP_END
170 :
171 :
172 0 : NS_IMPL_ADDREF(GroupRuleRuleList)
173 0 : NS_IMPL_RELEASE(GroupRuleRuleList)
174 :
175 : NS_IMETHODIMP
176 0 : GroupRuleRuleList::GetLength(PRUint32* aLength)
177 : {
178 0 : if (mGroupRule) {
179 0 : *aLength = (PRUint32)mGroupRule->StyleRuleCount();
180 : } else {
181 0 : *aLength = 0;
182 : }
183 :
184 0 : return NS_OK;
185 : }
186 :
187 : nsIDOMCSSRule*
188 0 : GroupRuleRuleList::GetItemAt(PRUint32 aIndex, nsresult* aResult)
189 : {
190 0 : *aResult = NS_OK;
191 :
192 0 : if (mGroupRule) {
193 0 : nsRefPtr<Rule> rule = mGroupRule->GetStyleRuleAt(aIndex);
194 0 : if (rule) {
195 0 : return rule->GetDOMRule();
196 : }
197 : }
198 :
199 0 : return nsnull;
200 : }
201 :
202 : NS_IMETHODIMP
203 0 : GroupRuleRuleList::Item(PRUint32 aIndex, nsIDOMCSSRule** aReturn)
204 : {
205 : nsresult rv;
206 0 : nsIDOMCSSRule* rule = GetItemAt(aIndex, &rv);
207 0 : if (!rule) {
208 0 : *aReturn = nsnull;
209 0 : return rv;
210 : }
211 :
212 0 : NS_ADDREF(*aReturn = rule);
213 0 : return NS_OK;
214 : }
215 :
216 : } // namespace css
217 : } // namespace mozilla
218 :
219 : // Must be outside the namespace
220 : DOMCI_DATA(CSSGroupRuleRuleList, css::GroupRuleRuleList)
221 :
222 : // -------------------------------------------
223 : // CharsetRule
224 : //
225 :
226 : // Must be outside namespace
227 : DOMCI_DATA(CSSCharsetRule, css::CharsetRule)
228 :
229 : namespace mozilla {
230 : namespace css {
231 :
232 0 : CharsetRule::CharsetRule(const nsAString& aEncoding)
233 : : Rule(),
234 0 : mEncoding(aEncoding)
235 : {
236 0 : }
237 :
238 0 : CharsetRule::CharsetRule(const CharsetRule& aCopy)
239 : : Rule(aCopy),
240 0 : mEncoding(aCopy.mEncoding)
241 : {
242 0 : }
243 :
244 0 : NS_IMPL_ADDREF_INHERITED(CharsetRule, Rule)
245 0 : NS_IMPL_RELEASE_INHERITED(CharsetRule, Rule)
246 :
247 : // QueryInterface implementation for CharsetRule
248 0 : NS_INTERFACE_MAP_BEGIN(CharsetRule)
249 0 : NS_INTERFACE_MAP_ENTRY(nsIStyleRule)
250 0 : NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
251 0 : NS_INTERFACE_MAP_ENTRY(nsIDOMCSSCharsetRule)
252 0 : NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStyleRule)
253 0 : NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSCharsetRule)
254 0 : NS_INTERFACE_MAP_END
255 :
256 0 : IMPL_STYLE_RULE_INHERIT(CharsetRule, Rule)
257 :
258 : #ifdef DEBUG
259 : /* virtual */ void
260 0 : CharsetRule::List(FILE* out, PRInt32 aIndent) const
261 : {
262 : // Indent
263 0 : for (PRInt32 indent = aIndent; --indent >= 0; ) fputs(" ", out);
264 :
265 0 : fputs("@charset \"", out);
266 0 : fputs(NS_LossyConvertUTF16toASCII(mEncoding).get(), out);
267 0 : fputs("\"\n", out);
268 0 : }
269 : #endif
270 :
271 : /* virtual */ PRInt32
272 0 : CharsetRule::GetType() const
273 : {
274 0 : return Rule::CHARSET_RULE;
275 : }
276 :
277 : /* virtual */ already_AddRefed<Rule>
278 0 : CharsetRule::Clone() const
279 : {
280 0 : nsRefPtr<Rule> clone = new CharsetRule(*this);
281 0 : return clone.forget();
282 : }
283 :
284 : NS_IMETHODIMP
285 0 : CharsetRule::GetEncoding(nsAString& aEncoding)
286 : {
287 0 : aEncoding = mEncoding;
288 0 : return NS_OK;
289 : }
290 :
291 : NS_IMETHODIMP
292 0 : CharsetRule::SetEncoding(const nsAString& aEncoding)
293 : {
294 0 : mEncoding = aEncoding;
295 0 : return NS_OK;
296 : }
297 :
298 : NS_IMETHODIMP
299 0 : CharsetRule::GetType(PRUint16* aType)
300 : {
301 0 : *aType = nsIDOMCSSRule::CHARSET_RULE;
302 0 : return NS_OK;
303 : }
304 :
305 : NS_IMETHODIMP
306 0 : CharsetRule::GetCssText(nsAString& aCssText)
307 : {
308 0 : aCssText.AssignLiteral("@charset \"");
309 0 : aCssText.Append(mEncoding);
310 0 : aCssText.AppendLiteral("\";");
311 0 : return NS_OK;
312 : }
313 :
314 : NS_IMETHODIMP
315 0 : CharsetRule::SetCssText(const nsAString& aCssText)
316 : {
317 0 : return NS_ERROR_NOT_IMPLEMENTED;
318 : }
319 :
320 : NS_IMETHODIMP
321 0 : CharsetRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
322 : {
323 0 : return Rule::GetParentStyleSheet(aSheet);
324 : }
325 :
326 : NS_IMETHODIMP
327 0 : CharsetRule::GetParentRule(nsIDOMCSSRule** aParentRule)
328 : {
329 0 : return Rule::GetParentRule(aParentRule);
330 : }
331 :
332 : /* virtual */ size_t
333 0 : CharsetRule::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const
334 : {
335 0 : return aMallocSizeOf(this);
336 :
337 : // Measurement of the following members may be added later if DMD finds it is
338 : // worthwhile:
339 : // - mEncoding
340 : }
341 :
342 : // -------------------------------------------
343 : // ImportRule
344 : //
345 :
346 0 : ImportRule::ImportRule(nsMediaList* aMedia, const nsString& aURLSpec)
347 : : Rule()
348 : , mURLSpec(aURLSpec)
349 0 : , mMedia(aMedia)
350 : {
351 : // XXXbz This is really silly.... the mMedia here will be replaced
352 : // with itself if we manage to load a sheet. Which should really
353 : // never fail nowadays, in sane cases.
354 0 : }
355 :
356 0 : ImportRule::ImportRule(const ImportRule& aCopy)
357 : : Rule(aCopy),
358 0 : mURLSpec(aCopy.mURLSpec)
359 : {
360 : // Whether or not an @import rule has a null sheet is a permanent
361 : // property of that @import rule, since it is null only if the target
362 : // sheet failed security checks.
363 0 : if (aCopy.mChildSheet) {
364 : nsRefPtr<nsCSSStyleSheet> sheet =
365 0 : aCopy.mChildSheet->Clone(nsnull, this, nsnull, nsnull);
366 0 : SetSheet(sheet);
367 : // SetSheet sets mMedia appropriately
368 : }
369 0 : }
370 :
371 0 : ImportRule::~ImportRule()
372 : {
373 0 : if (mChildSheet) {
374 0 : mChildSheet->SetOwnerRule(nsnull);
375 : }
376 0 : }
377 :
378 0 : NS_IMPL_ADDREF_INHERITED(ImportRule, Rule)
379 0 : NS_IMPL_RELEASE_INHERITED(ImportRule, Rule)
380 :
381 : // QueryInterface implementation for ImportRule
382 0 : NS_INTERFACE_MAP_BEGIN(ImportRule)
383 0 : NS_INTERFACE_MAP_ENTRY(nsIStyleRule)
384 0 : NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
385 0 : NS_INTERFACE_MAP_ENTRY(nsIDOMCSSImportRule)
386 0 : NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStyleRule)
387 0 : NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSImportRule)
388 0 : NS_INTERFACE_MAP_END
389 :
390 0 : IMPL_STYLE_RULE_INHERIT(ImportRule, Rule)
391 :
392 : #ifdef DEBUG
393 : /* virtual */ void
394 0 : ImportRule::List(FILE* out, PRInt32 aIndent) const
395 : {
396 : // Indent
397 0 : for (PRInt32 indent = aIndent; --indent >= 0; ) fputs(" ", out);
398 :
399 0 : fputs("@import \"", out);
400 0 : fputs(NS_LossyConvertUTF16toASCII(mURLSpec).get(), out);
401 0 : fputs("\" ", out);
402 :
403 0 : nsAutoString mediaText;
404 0 : mMedia->GetText(mediaText);
405 0 : fputs(NS_LossyConvertUTF16toASCII(mediaText).get(), out);
406 0 : fputs("\n", out);
407 0 : }
408 : #endif
409 :
410 : /* virtual */ PRInt32
411 0 : ImportRule::GetType() const
412 : {
413 0 : return Rule::IMPORT_RULE;
414 : }
415 :
416 : /* virtual */ already_AddRefed<Rule>
417 0 : ImportRule::Clone() const
418 : {
419 0 : nsRefPtr<Rule> clone = new ImportRule(*this);
420 0 : return clone.forget();
421 : }
422 :
423 : void
424 0 : ImportRule::SetSheet(nsCSSStyleSheet* aSheet)
425 : {
426 0 : NS_PRECONDITION(aSheet, "null arg");
427 :
428 : // set the new sheet
429 0 : mChildSheet = aSheet;
430 0 : aSheet->SetOwnerRule(this);
431 :
432 : // set our medialist to be the same as the sheet's medialist
433 0 : nsCOMPtr<nsIDOMMediaList> mediaList;
434 0 : mChildSheet->GetMedia(getter_AddRefs(mediaList));
435 0 : NS_ABORT_IF_FALSE(mediaList, "GetMedia returned null");
436 0 : mMedia = static_cast<nsMediaList*>(mediaList.get());
437 0 : }
438 :
439 : NS_IMETHODIMP
440 0 : ImportRule::GetType(PRUint16* aType)
441 : {
442 0 : NS_ENSURE_ARG_POINTER(aType);
443 0 : *aType = nsIDOMCSSRule::IMPORT_RULE;
444 0 : return NS_OK;
445 : }
446 :
447 : NS_IMETHODIMP
448 0 : ImportRule::GetCssText(nsAString& aCssText)
449 : {
450 0 : aCssText.AssignLiteral("@import url(");
451 0 : nsStyleUtil::AppendEscapedCSSString(mURLSpec, aCssText);
452 0 : aCssText.Append(NS_LITERAL_STRING(")"));
453 0 : if (mMedia) {
454 0 : nsAutoString mediaText;
455 0 : mMedia->GetText(mediaText);
456 0 : if (!mediaText.IsEmpty()) {
457 0 : aCssText.AppendLiteral(" ");
458 0 : aCssText.Append(mediaText);
459 : }
460 : }
461 0 : aCssText.AppendLiteral(";");
462 0 : return NS_OK;
463 : }
464 :
465 : NS_IMETHODIMP
466 0 : ImportRule::SetCssText(const nsAString& aCssText)
467 : {
468 0 : return NS_ERROR_NOT_IMPLEMENTED;
469 : }
470 :
471 : NS_IMETHODIMP
472 0 : ImportRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
473 : {
474 0 : return Rule::GetParentStyleSheet(aSheet);
475 : }
476 :
477 : NS_IMETHODIMP
478 0 : ImportRule::GetParentRule(nsIDOMCSSRule** aParentRule)
479 : {
480 0 : return Rule::GetParentRule(aParentRule);
481 : }
482 :
483 : NS_IMETHODIMP
484 0 : ImportRule::GetHref(nsAString & aHref)
485 : {
486 0 : aHref = mURLSpec;
487 0 : return NS_OK;
488 : }
489 :
490 : NS_IMETHODIMP
491 0 : ImportRule::GetMedia(nsIDOMMediaList * *aMedia)
492 : {
493 0 : NS_ENSURE_ARG_POINTER(aMedia);
494 :
495 0 : NS_IF_ADDREF(*aMedia = mMedia);
496 0 : return NS_OK;
497 : }
498 :
499 : NS_IMETHODIMP
500 0 : ImportRule::GetStyleSheet(nsIDOMCSSStyleSheet * *aStyleSheet)
501 : {
502 0 : NS_ENSURE_ARG_POINTER(aStyleSheet);
503 :
504 0 : NS_IF_ADDREF(*aStyleSheet = mChildSheet);
505 0 : return NS_OK;
506 : }
507 :
508 : /* virtual */ size_t
509 0 : ImportRule::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const
510 : {
511 0 : return aMallocSizeOf(this);
512 :
513 : // Measurement of the following members may be added later if DMD finds it is
514 : // worthwhile:
515 : // - mURLSpec
516 : //
517 : // The following members are not measured:
518 : // - mMedia, because it is measured via nsCSSStyleSheet::mMedia
519 : // - mChildSheet, because it is measured via nsCSSStyleSheetInner::mSheets
520 : }
521 :
522 : } // namespace css
523 : } // namespace mozilla
524 :
525 : // must be outside the namespace
526 : DOMCI_DATA(CSSImportRule, css::ImportRule)
527 :
528 : static bool
529 0 : CloneRuleInto(css::Rule* aRule, void* aArray)
530 : {
531 0 : nsRefPtr<css::Rule> clone = aRule->Clone();
532 0 : static_cast<nsCOMArray<css::Rule>*>(aArray)->AppendObject(clone);
533 0 : return true;
534 : }
535 :
536 : namespace mozilla {
537 : namespace css {
538 :
539 0 : GroupRule::GroupRule()
540 0 : : Rule()
541 : {
542 0 : }
543 :
544 : static bool
545 0 : SetParentRuleReference(Rule* aRule, void* aParentRule)
546 : {
547 0 : GroupRule* parentRule = static_cast<GroupRule*>(aParentRule);
548 0 : aRule->SetParentRule(parentRule);
549 0 : return true;
550 : }
551 :
552 0 : GroupRule::GroupRule(const GroupRule& aCopy)
553 0 : : Rule(aCopy)
554 : {
555 0 : const_cast<GroupRule&>(aCopy).mRules.EnumerateForwards(CloneRuleInto, &mRules);
556 0 : mRules.EnumerateForwards(SetParentRuleReference, this);
557 0 : }
558 :
559 0 : GroupRule::~GroupRule()
560 : {
561 0 : NS_ABORT_IF_FALSE(!mSheet, "SetStyleSheet should have been called");
562 0 : mRules.EnumerateForwards(SetParentRuleReference, nsnull);
563 0 : if (mRuleCollection) {
564 0 : mRuleCollection->DropReference();
565 : }
566 0 : }
567 :
568 0 : IMPL_STYLE_RULE_INHERIT_MAP_RULE_INFO_INTO(GroupRule, Rule)
569 :
570 : static bool
571 0 : SetStyleSheetReference(Rule* aRule, void* aSheet)
572 : {
573 0 : nsCSSStyleSheet* sheet = (nsCSSStyleSheet*)aSheet;
574 0 : aRule->SetStyleSheet(sheet);
575 0 : return true;
576 : }
577 :
578 : /* virtual */ void
579 0 : GroupRule::SetStyleSheet(nsCSSStyleSheet* aSheet)
580 : {
581 0 : mRules.EnumerateForwards(SetStyleSheetReference, aSheet);
582 0 : Rule::SetStyleSheet(aSheet);
583 0 : }
584 :
585 : #ifdef DEBUG
586 : /* virtual */ void
587 0 : GroupRule::List(FILE* out, PRInt32 aIndent) const
588 : {
589 0 : fputs(" {\n", out);
590 :
591 0 : for (PRInt32 index = 0, count = mRules.Count(); index < count; ++index) {
592 0 : mRules.ObjectAt(index)->List(out, aIndent + 1);
593 : }
594 0 : fputs("}\n", out);
595 0 : }
596 : #endif
597 :
598 : void
599 0 : GroupRule::AppendStyleRule(Rule* aRule)
600 : {
601 0 : mRules.AppendObject(aRule);
602 0 : aRule->SetStyleSheet(mSheet);
603 0 : aRule->SetParentRule(this);
604 0 : if (mSheet) {
605 0 : mSheet->SetModifiedByChildRule();
606 : }
607 0 : }
608 :
609 : Rule*
610 0 : GroupRule::GetStyleRuleAt(PRInt32 aIndex) const
611 : {
612 0 : return mRules.SafeObjectAt(aIndex);
613 : }
614 :
615 : bool
616 0 : GroupRule::EnumerateRulesForwards(RuleEnumFunc aFunc, void * aData) const
617 : {
618 : return
619 0 : const_cast<GroupRule*>(this)->mRules.EnumerateForwards(aFunc, aData);
620 : }
621 :
622 : /*
623 : * The next two methods (DeleteStyleRuleAt and InsertStyleRulesAt)
624 : * should never be called unless you have first called WillDirty() on
625 : * the parents tylesheet. After they are called, DidDirty() needs to
626 : * be called on the sheet
627 : */
628 : nsresult
629 0 : GroupRule::DeleteStyleRuleAt(PRUint32 aIndex)
630 : {
631 0 : Rule* rule = mRules.SafeObjectAt(aIndex);
632 0 : if (rule) {
633 0 : rule->SetStyleSheet(nsnull);
634 0 : rule->SetParentRule(nsnull);
635 : }
636 0 : return mRules.RemoveObjectAt(aIndex) ? NS_OK : NS_ERROR_ILLEGAL_VALUE;
637 : }
638 :
639 : nsresult
640 0 : GroupRule::InsertStyleRulesAt(PRUint32 aIndex,
641 : nsCOMArray<Rule>& aRules)
642 : {
643 0 : aRules.EnumerateForwards(SetStyleSheetReference, mSheet);
644 0 : aRules.EnumerateForwards(SetParentRuleReference, this);
645 0 : if (! mRules.InsertObjectsAt(aRules, aIndex)) {
646 0 : return NS_ERROR_FAILURE;
647 : }
648 0 : return NS_OK;
649 : }
650 :
651 : nsresult
652 0 : GroupRule::ReplaceStyleRule(Rule* aOld, Rule* aNew)
653 : {
654 0 : PRInt32 index = mRules.IndexOf(aOld);
655 0 : NS_ENSURE_TRUE(index != -1, NS_ERROR_UNEXPECTED);
656 0 : mRules.ReplaceObjectAt(aNew, index);
657 0 : aNew->SetStyleSheet(mSheet);
658 0 : aNew->SetParentRule(this);
659 0 : aOld->SetStyleSheet(nsnull);
660 0 : aOld->SetParentRule(nsnull);
661 0 : return NS_OK;
662 : }
663 :
664 : nsresult
665 0 : GroupRule::AppendRulesToCssText(nsAString& aCssText)
666 : {
667 0 : aCssText.AppendLiteral(" {\n");
668 :
669 : // get all the rules
670 0 : for (PRInt32 index = 0, count = mRules.Count(); index < count; ++index) {
671 0 : Rule* rule = mRules.ObjectAt(index);
672 0 : nsIDOMCSSRule* domRule = rule->GetDOMRule();
673 0 : if (domRule) {
674 0 : nsAutoString cssText;
675 0 : domRule->GetCssText(cssText);
676 0 : aCssText.Append(NS_LITERAL_STRING(" ") +
677 0 : cssText +
678 0 : NS_LITERAL_STRING("\n"));
679 : }
680 : }
681 :
682 0 : aCssText.AppendLiteral("}");
683 :
684 0 : return NS_OK;
685 : }
686 :
687 : // nsIDOMCSSMediaRule or nsIDOMCSSMozDocumentRule methods
688 : nsresult
689 0 : GroupRule::GetCssRules(nsIDOMCSSRuleList* *aRuleList)
690 : {
691 0 : if (!mRuleCollection) {
692 0 : mRuleCollection = new css::GroupRuleRuleList(this);
693 : }
694 :
695 0 : NS_ADDREF(*aRuleList = mRuleCollection);
696 0 : return NS_OK;
697 : }
698 :
699 : nsresult
700 0 : GroupRule::InsertRule(const nsAString & aRule, PRUint32 aIndex, PRUint32* _retval)
701 : {
702 0 : NS_ENSURE_TRUE(mSheet, NS_ERROR_FAILURE);
703 :
704 0 : if (aIndex > PRUint32(mRules.Count()))
705 0 : return NS_ERROR_DOM_INDEX_SIZE_ERR;
706 :
707 0 : NS_ASSERTION(PRUint32(mRules.Count()) <= PR_INT32_MAX,
708 : "Too many style rules!");
709 :
710 0 : return mSheet->InsertRuleIntoGroup(aRule, this, aIndex, _retval);
711 : }
712 :
713 : nsresult
714 0 : GroupRule::DeleteRule(PRUint32 aIndex)
715 : {
716 0 : NS_ENSURE_TRUE(mSheet, NS_ERROR_FAILURE);
717 :
718 0 : if (aIndex >= PRUint32(mRules.Count()))
719 0 : return NS_ERROR_DOM_INDEX_SIZE_ERR;
720 :
721 0 : NS_ASSERTION(PRUint32(mRules.Count()) <= PR_INT32_MAX,
722 : "Too many style rules!");
723 :
724 0 : return mSheet->DeleteRuleFromGroup(this, aIndex);
725 : }
726 :
727 : /* virtual */ size_t
728 0 : GroupRule::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const
729 : {
730 : return mRules.SizeOfExcludingThis(Rule::SizeOfCOMArrayElementIncludingThis,
731 0 : aMallocSizeOf);
732 :
733 : // Measurement of the following members may be added later if DMD finds it is
734 : // worthwhile:
735 : // - mRuleCollection
736 : }
737 :
738 :
739 : // -------------------------------------------
740 : // nsICSSMediaRule
741 : //
742 0 : MediaRule::MediaRule()
743 : {
744 0 : }
745 :
746 0 : MediaRule::MediaRule(const MediaRule& aCopy)
747 0 : : GroupRule(aCopy)
748 : {
749 0 : if (aCopy.mMedia) {
750 0 : aCopy.mMedia->Clone(getter_AddRefs(mMedia));
751 0 : if (mMedia) {
752 : // XXXldb This doesn't really make sense.
753 0 : mMedia->SetStyleSheet(aCopy.mSheet);
754 : }
755 : }
756 0 : }
757 :
758 0 : MediaRule::~MediaRule()
759 : {
760 0 : if (mMedia) {
761 0 : mMedia->SetStyleSheet(nsnull);
762 : }
763 0 : }
764 :
765 0 : NS_IMPL_ADDREF_INHERITED(MediaRule, GroupRule)
766 0 : NS_IMPL_RELEASE_INHERITED(MediaRule, GroupRule)
767 :
768 : // QueryInterface implementation for MediaRule
769 0 : NS_INTERFACE_MAP_BEGIN(MediaRule)
770 0 : NS_INTERFACE_MAP_ENTRY(nsIStyleRule)
771 0 : NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
772 0 : NS_INTERFACE_MAP_ENTRY(nsIDOMCSSMediaRule)
773 0 : NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStyleRule)
774 0 : NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSMediaRule)
775 0 : NS_INTERFACE_MAP_END
776 :
777 : /* virtual */ void
778 0 : MediaRule::SetStyleSheet(nsCSSStyleSheet* aSheet)
779 : {
780 0 : if (mMedia) {
781 : // Set to null so it knows it's leaving one sheet and joining another.
782 0 : mMedia->SetStyleSheet(nsnull);
783 0 : mMedia->SetStyleSheet(aSheet);
784 : }
785 :
786 0 : GroupRule::SetStyleSheet(aSheet);
787 0 : }
788 :
789 : #ifdef DEBUG
790 : /* virtual */ void
791 0 : MediaRule::List(FILE* out, PRInt32 aIndent) const
792 : {
793 0 : for (PRInt32 indent = aIndent; --indent >= 0; ) fputs(" ", out);
794 :
795 0 : nsAutoString buffer;
796 :
797 0 : fputs("@media ", out);
798 :
799 0 : if (mMedia) {
800 0 : nsAutoString mediaText;
801 0 : mMedia->GetText(mediaText);
802 0 : fputs(NS_LossyConvertUTF16toASCII(mediaText).get(), out);
803 : }
804 :
805 0 : GroupRule::List(out, aIndent);
806 0 : }
807 : #endif
808 :
809 : /* virtual */ PRInt32
810 0 : MediaRule::GetType() const
811 : {
812 0 : return Rule::MEDIA_RULE;
813 : }
814 :
815 : /* virtual */ already_AddRefed<Rule>
816 0 : MediaRule::Clone() const
817 : {
818 0 : nsRefPtr<Rule> clone = new MediaRule(*this);
819 0 : return clone.forget();
820 : }
821 :
822 : nsresult
823 0 : MediaRule::SetMedia(nsMediaList* aMedia)
824 : {
825 0 : mMedia = aMedia;
826 0 : if (aMedia)
827 0 : mMedia->SetStyleSheet(mSheet);
828 0 : return NS_OK;
829 : }
830 :
831 : // nsIDOMCSSRule methods
832 : NS_IMETHODIMP
833 0 : MediaRule::GetType(PRUint16* aType)
834 : {
835 0 : *aType = nsIDOMCSSRule::MEDIA_RULE;
836 0 : return NS_OK;
837 : }
838 :
839 : NS_IMETHODIMP
840 0 : MediaRule::GetCssText(nsAString& aCssText)
841 : {
842 0 : aCssText.AssignLiteral("@media ");
843 : // get all the media
844 0 : if (mMedia) {
845 0 : nsAutoString mediaText;
846 0 : mMedia->GetText(mediaText);
847 0 : aCssText.Append(mediaText);
848 : }
849 :
850 0 : return GroupRule::AppendRulesToCssText(aCssText);
851 : }
852 :
853 : NS_IMETHODIMP
854 0 : MediaRule::SetCssText(const nsAString& aCssText)
855 : {
856 0 : return NS_ERROR_NOT_IMPLEMENTED;
857 : }
858 :
859 : NS_IMETHODIMP
860 0 : MediaRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
861 : {
862 0 : return GroupRule::GetParentStyleSheet(aSheet);
863 : }
864 :
865 : NS_IMETHODIMP
866 0 : MediaRule::GetParentRule(nsIDOMCSSRule** aParentRule)
867 : {
868 0 : return GroupRule::GetParentRule(aParentRule);
869 : }
870 :
871 : // nsIDOMCSSMediaRule methods
872 : NS_IMETHODIMP
873 0 : MediaRule::GetMedia(nsIDOMMediaList* *aMedia)
874 : {
875 0 : NS_ENSURE_ARG_POINTER(aMedia);
876 0 : NS_IF_ADDREF(*aMedia = mMedia);
877 0 : return NS_OK;
878 : }
879 :
880 : NS_IMETHODIMP
881 0 : MediaRule::GetCssRules(nsIDOMCSSRuleList* *aRuleList)
882 : {
883 0 : return GroupRule::GetCssRules(aRuleList);
884 : }
885 :
886 : NS_IMETHODIMP
887 0 : MediaRule::InsertRule(const nsAString & aRule, PRUint32 aIndex, PRUint32* _retval)
888 : {
889 0 : return GroupRule::InsertRule(aRule, aIndex, _retval);
890 : }
891 :
892 : NS_IMETHODIMP
893 0 : MediaRule::DeleteRule(PRUint32 aIndex)
894 : {
895 0 : return GroupRule::DeleteRule(aIndex);
896 : }
897 :
898 : // GroupRule interface
899 : /* virtual */ bool
900 0 : MediaRule::UseForPresentation(nsPresContext* aPresContext,
901 : nsMediaQueryResultCacheKey& aKey)
902 : {
903 0 : if (mMedia) {
904 0 : return mMedia->Matches(aPresContext, &aKey);
905 : }
906 0 : return true;
907 : }
908 :
909 : /* virtual */ size_t
910 0 : MediaRule::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const
911 : {
912 0 : size_t n = aMallocSizeOf(this);
913 0 : n += GroupRule::SizeOfExcludingThis(aMallocSizeOf);
914 :
915 : // Measurement of the following members may be added later if DMD finds it is
916 : // worthwhile:
917 : // - mMedia
918 :
919 0 : return n;
920 : }
921 :
922 : } // namespace css
923 : } // namespace mozilla
924 :
925 : // Must be outside namespace
926 : DOMCI_DATA(CSSMediaRule, css::MediaRule)
927 :
928 : namespace mozilla {
929 : namespace css {
930 :
931 0 : DocumentRule::DocumentRule()
932 : {
933 0 : }
934 :
935 0 : DocumentRule::DocumentRule(const DocumentRule& aCopy)
936 : : GroupRule(aCopy)
937 0 : , mURLs(new URL(*aCopy.mURLs))
938 : {
939 0 : }
940 :
941 0 : DocumentRule::~DocumentRule()
942 : {
943 0 : }
944 :
945 0 : NS_IMPL_ADDREF_INHERITED(DocumentRule, GroupRule)
946 0 : NS_IMPL_RELEASE_INHERITED(DocumentRule, GroupRule)
947 :
948 : // QueryInterface implementation for DocumentRule
949 0 : NS_INTERFACE_MAP_BEGIN(DocumentRule)
950 0 : NS_INTERFACE_MAP_ENTRY(nsIStyleRule)
951 0 : NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
952 0 : NS_INTERFACE_MAP_ENTRY(nsIDOMCSSMozDocumentRule)
953 0 : NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStyleRule)
954 0 : NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSMozDocumentRule)
955 0 : NS_INTERFACE_MAP_END
956 :
957 : #ifdef DEBUG
958 : /* virtual */ void
959 0 : DocumentRule::List(FILE* out, PRInt32 aIndent) const
960 : {
961 0 : for (PRInt32 indent = aIndent; --indent >= 0; ) fputs(" ", out);
962 :
963 0 : nsCAutoString str;
964 0 : str.AssignLiteral("@-moz-document ");
965 0 : for (URL *url = mURLs; url; url = url->next) {
966 0 : switch (url->func) {
967 : case eURL:
968 0 : str.AppendLiteral("url(\"");
969 0 : break;
970 : case eURLPrefix:
971 0 : str.AppendLiteral("url-prefix(\"");
972 0 : break;
973 : case eDomain:
974 0 : str.AppendLiteral("domain(\"");
975 0 : break;
976 : case eRegExp:
977 0 : str.AppendLiteral("regexp(\"");
978 0 : break;
979 : }
980 0 : nsCAutoString escapedURL(url->url);
981 0 : escapedURL.ReplaceSubstring("\"", "\\\""); // escape quotes
982 0 : str.Append(escapedURL);
983 0 : str.AppendLiteral("\"), ");
984 : }
985 0 : str.Cut(str.Length() - 2, 1); // remove last ,
986 0 : fputs(str.get(), out);
987 :
988 0 : GroupRule::List(out, aIndent);
989 0 : }
990 : #endif
991 :
992 : /* virtual */ PRInt32
993 0 : DocumentRule::GetType() const
994 : {
995 0 : return Rule::DOCUMENT_RULE;
996 : }
997 :
998 : /* virtual */ already_AddRefed<Rule>
999 0 : DocumentRule::Clone() const
1000 : {
1001 0 : nsRefPtr<Rule> clone = new DocumentRule(*this);
1002 0 : return clone.forget();
1003 : }
1004 :
1005 : // nsIDOMCSSRule methods
1006 : NS_IMETHODIMP
1007 0 : DocumentRule::GetType(PRUint16* aType)
1008 : {
1009 : // XXX What should really happen here?
1010 0 : *aType = nsIDOMCSSRule::UNKNOWN_RULE;
1011 0 : return NS_OK;
1012 : }
1013 :
1014 : NS_IMETHODIMP
1015 0 : DocumentRule::GetCssText(nsAString& aCssText)
1016 : {
1017 0 : aCssText.AssignLiteral("@-moz-document ");
1018 0 : for (URL *url = mURLs; url; url = url->next) {
1019 0 : switch (url->func) {
1020 : case eURL:
1021 0 : aCssText.AppendLiteral("url(");
1022 0 : break;
1023 : case eURLPrefix:
1024 0 : aCssText.AppendLiteral("url-prefix(");
1025 0 : break;
1026 : case eDomain:
1027 0 : aCssText.AppendLiteral("domain(");
1028 0 : break;
1029 : case eRegExp:
1030 0 : aCssText.AppendLiteral("regexp(");
1031 0 : break;
1032 : }
1033 0 : nsStyleUtil::AppendEscapedCSSString(NS_ConvertUTF8toUTF16(url->url),
1034 0 : aCssText);
1035 0 : aCssText.AppendLiteral("), ");
1036 : }
1037 0 : aCssText.Cut(aCssText.Length() - 2, 1); // remove last ,
1038 :
1039 0 : return GroupRule::AppendRulesToCssText(aCssText);
1040 : }
1041 :
1042 : NS_IMETHODIMP
1043 0 : DocumentRule::SetCssText(const nsAString& aCssText)
1044 : {
1045 0 : return NS_ERROR_NOT_IMPLEMENTED;
1046 : }
1047 :
1048 : NS_IMETHODIMP
1049 0 : DocumentRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
1050 : {
1051 0 : return GroupRule::GetParentStyleSheet(aSheet);
1052 : }
1053 :
1054 : NS_IMETHODIMP
1055 0 : DocumentRule::GetParentRule(nsIDOMCSSRule** aParentRule)
1056 : {
1057 0 : return GroupRule::GetParentRule(aParentRule);
1058 : }
1059 :
1060 : NS_IMETHODIMP
1061 0 : DocumentRule::GetCssRules(nsIDOMCSSRuleList* *aRuleList)
1062 : {
1063 0 : return GroupRule::GetCssRules(aRuleList);
1064 : }
1065 :
1066 : NS_IMETHODIMP
1067 0 : DocumentRule::InsertRule(const nsAString & aRule, PRUint32 aIndex, PRUint32* _retval)
1068 : {
1069 0 : return GroupRule::InsertRule(aRule, aIndex, _retval);
1070 : }
1071 :
1072 : NS_IMETHODIMP
1073 0 : DocumentRule::DeleteRule(PRUint32 aIndex)
1074 : {
1075 0 : return GroupRule::DeleteRule(aIndex);
1076 : }
1077 :
1078 : // GroupRule interface
1079 : /* virtual */ bool
1080 0 : DocumentRule::UseForPresentation(nsPresContext* aPresContext,
1081 : nsMediaQueryResultCacheKey& aKey)
1082 : {
1083 0 : nsIDocument *doc = aPresContext->Document();
1084 0 : nsIURI *docURI = doc->GetDocumentURI();
1085 0 : nsCAutoString docURISpec;
1086 0 : if (docURI)
1087 0 : docURI->GetSpec(docURISpec);
1088 :
1089 0 : for (URL *url = mURLs; url; url = url->next) {
1090 0 : switch (url->func) {
1091 : case eURL: {
1092 0 : if (docURISpec == url->url)
1093 0 : return true;
1094 0 : } break;
1095 : case eURLPrefix: {
1096 0 : if (StringBeginsWith(docURISpec, url->url))
1097 0 : return true;
1098 0 : } break;
1099 : case eDomain: {
1100 0 : nsCAutoString host;
1101 0 : if (docURI)
1102 0 : docURI->GetHost(host);
1103 0 : PRInt32 lenDiff = host.Length() - url->url.Length();
1104 0 : if (lenDiff == 0) {
1105 0 : if (host == url->url)
1106 0 : return true;
1107 : } else {
1108 0 : if (StringEndsWith(host, url->url) &&
1109 0 : host.CharAt(lenDiff - 1) == '.')
1110 0 : return true;
1111 : }
1112 0 : } break;
1113 : case eRegExp: {
1114 0 : NS_ConvertUTF8toUTF16 spec(docURISpec);
1115 0 : NS_ConvertUTF8toUTF16 regex(url->url);
1116 0 : if (nsContentUtils::IsPatternMatching(spec, regex, doc)) {
1117 0 : return true;
1118 : }
1119 0 : } break;
1120 : }
1121 : }
1122 :
1123 0 : return false;
1124 : }
1125 :
1126 0 : DocumentRule::URL::~URL()
1127 : {
1128 0 : NS_CSS_DELETE_LIST_MEMBER(DocumentRule::URL, this, next);
1129 0 : }
1130 :
1131 : /* virtual */ size_t
1132 0 : DocumentRule::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const
1133 : {
1134 0 : size_t n = aMallocSizeOf(this);
1135 0 : n += GroupRule::SizeOfExcludingThis(aMallocSizeOf);
1136 :
1137 : // Measurement of the following members may be added later if DMD finds it is
1138 : // worthwhile:
1139 : // - mURLs
1140 :
1141 0 : return n;
1142 : }
1143 :
1144 : } // namespace css
1145 : } // namespace mozilla
1146 :
1147 : // Must be outside namespace
1148 : DOMCI_DATA(CSSMozDocumentRule, css::DocumentRule)
1149 :
1150 : // -------------------------------------------
1151 : // NameSpaceRule
1152 : //
1153 :
1154 : namespace mozilla {
1155 : namespace css {
1156 :
1157 0 : NameSpaceRule::NameSpaceRule(nsIAtom* aPrefix, const nsString& aURLSpec)
1158 : : Rule(),
1159 : mPrefix(aPrefix),
1160 0 : mURLSpec(aURLSpec)
1161 : {
1162 0 : }
1163 :
1164 0 : NameSpaceRule::NameSpaceRule(const NameSpaceRule& aCopy)
1165 : : Rule(aCopy),
1166 : mPrefix(aCopy.mPrefix),
1167 0 : mURLSpec(aCopy.mURLSpec)
1168 : {
1169 0 : }
1170 :
1171 0 : NameSpaceRule::~NameSpaceRule()
1172 : {
1173 0 : }
1174 :
1175 0 : NS_IMPL_ADDREF_INHERITED(NameSpaceRule, Rule)
1176 0 : NS_IMPL_RELEASE_INHERITED(NameSpaceRule, Rule)
1177 :
1178 : // QueryInterface implementation for NameSpaceRule
1179 0 : NS_INTERFACE_MAP_BEGIN(NameSpaceRule)
1180 0 : if (aIID.Equals(NS_GET_IID(css::NameSpaceRule))) {
1181 0 : *aInstancePtr = this;
1182 0 : NS_ADDREF_THIS();
1183 0 : return NS_OK;
1184 : }
1185 : else
1186 0 : NS_INTERFACE_MAP_ENTRY(nsIStyleRule)
1187 0 : NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
1188 0 : NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStyleRule)
1189 0 : NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSNameSpaceRule)
1190 0 : NS_INTERFACE_MAP_END
1191 :
1192 0 : IMPL_STYLE_RULE_INHERIT(NameSpaceRule, Rule)
1193 :
1194 : #ifdef DEBUG
1195 : /* virtual */ void
1196 0 : NameSpaceRule::List(FILE* out, PRInt32 aIndent) const
1197 : {
1198 0 : for (PRInt32 indent = aIndent; --indent >= 0; ) fputs(" ", out);
1199 :
1200 0 : nsAutoString buffer;
1201 :
1202 0 : fputs("@namespace ", out);
1203 :
1204 0 : if (mPrefix) {
1205 0 : mPrefix->ToString(buffer);
1206 0 : fputs(NS_LossyConvertUTF16toASCII(buffer).get(), out);
1207 0 : fputs(" ", out);
1208 : }
1209 :
1210 0 : fputs("url(", out);
1211 0 : fputs(NS_LossyConvertUTF16toASCII(mURLSpec).get(), out);
1212 0 : fputs(")\n", out);
1213 0 : }
1214 : #endif
1215 :
1216 : /* virtual */ PRInt32
1217 0 : NameSpaceRule::GetType() const
1218 : {
1219 0 : return Rule::NAMESPACE_RULE;
1220 : }
1221 :
1222 : /* virtual */ already_AddRefed<Rule>
1223 0 : NameSpaceRule::Clone() const
1224 : {
1225 0 : nsRefPtr<Rule> clone = new NameSpaceRule(*this);
1226 0 : return clone.forget();
1227 : }
1228 :
1229 : NS_IMETHODIMP
1230 0 : NameSpaceRule::GetType(PRUint16* aType)
1231 : {
1232 : // XXX What should really happen here?
1233 0 : *aType = nsIDOMCSSRule::UNKNOWN_RULE;
1234 0 : return NS_OK;
1235 : }
1236 :
1237 : NS_IMETHODIMP
1238 0 : NameSpaceRule::GetCssText(nsAString& aCssText)
1239 : {
1240 0 : aCssText.AssignLiteral("@namespace ");
1241 0 : if (mPrefix) {
1242 0 : aCssText.Append(nsDependentAtomString(mPrefix) + NS_LITERAL_STRING(" "));
1243 : }
1244 0 : aCssText.AppendLiteral("url(");
1245 0 : nsStyleUtil::AppendEscapedCSSString(mURLSpec, aCssText);
1246 0 : aCssText.Append(NS_LITERAL_STRING(");"));
1247 0 : return NS_OK;
1248 : }
1249 :
1250 : NS_IMETHODIMP
1251 0 : NameSpaceRule::SetCssText(const nsAString& aCssText)
1252 : {
1253 0 : return NS_ERROR_NOT_IMPLEMENTED;
1254 : }
1255 :
1256 : NS_IMETHODIMP
1257 0 : NameSpaceRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
1258 : {
1259 0 : return Rule::GetParentStyleSheet(aSheet);
1260 : }
1261 :
1262 : NS_IMETHODIMP
1263 0 : NameSpaceRule::GetParentRule(nsIDOMCSSRule** aParentRule)
1264 : {
1265 0 : return Rule::GetParentRule(aParentRule);
1266 : }
1267 :
1268 : /* virtual */ size_t
1269 0 : NameSpaceRule::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const
1270 : {
1271 0 : return aMallocSizeOf(this);
1272 :
1273 : // Measurement of the following members may be added later if DMD finds it is
1274 : // worthwhile:
1275 : // - mPrefix
1276 : // - mURLSpec
1277 : }
1278 :
1279 :
1280 : } // namespace css
1281 : } // namespace mozilla
1282 :
1283 : // Must be outside namespace
1284 : DOMCI_DATA(CSSNameSpaceRule, css::NameSpaceRule)
1285 :
1286 : // -------------------------------------------
1287 : // nsCSSFontFaceStyleDecl and related routines
1288 : //
1289 :
1290 : // A src: descriptor is represented as an array value; each entry in
1291 : // the array can be eCSSUnit_URL, eCSSUnit_Local_Font, or
1292 : // eCSSUnit_Font_Format. Blocks of eCSSUnit_Font_Format may appear
1293 : // only after one of the first two. (css3-fonts only contemplates
1294 : // annotating URLs with formats, but we handle the general case.)
1295 : static void
1296 0 : AppendSerializedFontSrc(const nsCSSValue& src, nsAString & aResult NS_OUTPARAM)
1297 : {
1298 0 : NS_PRECONDITION(src.GetUnit() == eCSSUnit_Array,
1299 : "improper value unit for src:");
1300 :
1301 0 : const nsCSSValue::Array& sources = *src.GetArrayValue();
1302 0 : size_t i = 0;
1303 :
1304 0 : while (i < sources.Count()) {
1305 0 : nsAutoString formats;
1306 :
1307 0 : if (sources[i].GetUnit() == eCSSUnit_URL) {
1308 0 : aResult.AppendLiteral("url(");
1309 0 : nsDependentString url(sources[i].GetOriginalURLValue());
1310 0 : nsStyleUtil::AppendEscapedCSSString(url, aResult);
1311 0 : aResult.AppendLiteral(")");
1312 0 : } else if (sources[i].GetUnit() == eCSSUnit_Local_Font) {
1313 0 : aResult.AppendLiteral("local(");
1314 0 : nsDependentString local(sources[i].GetStringBufferValue());
1315 0 : nsStyleUtil::AppendEscapedCSSString(local, aResult);
1316 0 : aResult.AppendLiteral(")");
1317 : } else {
1318 0 : NS_NOTREACHED("entry in src: descriptor with improper unit");
1319 0 : i++;
1320 0 : continue;
1321 : }
1322 :
1323 0 : i++;
1324 0 : formats.Truncate();
1325 0 : while (i < sources.Count() &&
1326 0 : sources[i].GetUnit() == eCSSUnit_Font_Format) {
1327 0 : formats.Append('"');
1328 0 : formats.Append(sources[i].GetStringBufferValue());
1329 0 : formats.AppendLiteral("\", ");
1330 0 : i++;
1331 : }
1332 0 : if (formats.Length() > 0) {
1333 0 : formats.Truncate(formats.Length() - 2); // remove the last comma
1334 0 : aResult.AppendLiteral(" format(");
1335 0 : aResult.Append(formats);
1336 0 : aResult.Append(')');
1337 : }
1338 0 : aResult.AppendLiteral(", ");
1339 : }
1340 0 : aResult.Truncate(aResult.Length() - 2); // remove the last comma-space
1341 0 : }
1342 :
1343 : // print all characters with at least four hex digits
1344 : static void
1345 0 : AppendSerializedUnicodePoint(PRUint32 aCode, nsACString &aBuf NS_OUTPARAM)
1346 : {
1347 0 : aBuf.Append(nsPrintfCString("%04X", aCode));
1348 0 : }
1349 :
1350 : // A unicode-range: descriptor is represented as an array of integers,
1351 : // to be interpreted as a sequence of pairs: min max min max ...
1352 : // It is in source order. (Possibly it should be sorted and overlaps
1353 : // consolidated, but right now we don't do that.)
1354 : static void
1355 0 : AppendSerializedUnicodeRange(nsCSSValue const & aValue,
1356 : nsAString & aResult NS_OUTPARAM)
1357 : {
1358 0 : NS_PRECONDITION(aValue.GetUnit() == eCSSUnit_Null ||
1359 : aValue.GetUnit() == eCSSUnit_Array,
1360 : "improper value unit for unicode-range:");
1361 0 : aResult.Truncate();
1362 0 : if (aValue.GetUnit() != eCSSUnit_Array)
1363 0 : return;
1364 :
1365 0 : nsCSSValue::Array const & sources = *aValue.GetArrayValue();
1366 0 : nsCAutoString buf;
1367 :
1368 0 : NS_ABORT_IF_FALSE(sources.Count() % 2 == 0,
1369 : "odd number of entries in a unicode-range: array");
1370 :
1371 0 : for (PRUint32 i = 0; i < sources.Count(); i += 2) {
1372 0 : PRUint32 min = sources[i].GetIntValue();
1373 0 : PRUint32 max = sources[i+1].GetIntValue();
1374 :
1375 : // We don't try to replicate the U+XX?? notation.
1376 0 : buf.AppendLiteral("U+");
1377 0 : AppendSerializedUnicodePoint(min, buf);
1378 :
1379 0 : if (min != max) {
1380 0 : buf.Append('-');
1381 0 : AppendSerializedUnicodePoint(max, buf);
1382 : }
1383 0 : buf.AppendLiteral(", ");
1384 : }
1385 0 : buf.Truncate(buf.Length() - 2); // remove the last comma-space
1386 0 : CopyASCIItoUTF16(buf, aResult);
1387 : }
1388 :
1389 : // Mapping from nsCSSFontDesc codes to nsCSSFontFaceStyleDecl fields.
1390 : nsCSSValue nsCSSFontFaceStyleDecl::* const
1391 : nsCSSFontFaceStyleDecl::Fields[] = {
1392 : #define CSS_FONT_DESC(name_, method_) &nsCSSFontFaceStyleDecl::m##method_,
1393 : #include "nsCSSFontDescList.h"
1394 : #undef CSS_FONT_DESC
1395 : };
1396 :
1397 : DOMCI_DATA(CSSFontFaceStyleDecl, nsCSSFontFaceStyleDecl)
1398 :
1399 : // QueryInterface implementation for nsCSSFontFaceStyleDecl
1400 0 : NS_INTERFACE_MAP_BEGIN(nsCSSFontFaceStyleDecl)
1401 0 : NS_INTERFACE_MAP_ENTRY(nsIDOMCSSStyleDeclaration)
1402 0 : NS_INTERFACE_MAP_ENTRY(nsISupports)
1403 0 : NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSFontFaceStyleDecl)
1404 0 : NS_INTERFACE_MAP_END
1405 :
1406 0 : NS_IMPL_ADDREF_USING_AGGREGATOR(nsCSSFontFaceStyleDecl, ContainingRule())
1407 0 : NS_IMPL_RELEASE_USING_AGGREGATOR(nsCSSFontFaceStyleDecl, ContainingRule())
1408 :
1409 : // helper for string GetPropertyValue and RemovePropertyValue
1410 : nsresult
1411 0 : nsCSSFontFaceStyleDecl::GetPropertyValue(nsCSSFontDesc aFontDescID,
1412 : nsAString & aResult NS_OUTPARAM) const
1413 : {
1414 0 : NS_ENSURE_ARG_RANGE(aFontDescID, eCSSFontDesc_UNKNOWN,
1415 : eCSSFontDesc_COUNT - 1);
1416 :
1417 0 : aResult.Truncate();
1418 0 : if (aFontDescID == eCSSFontDesc_UNKNOWN)
1419 0 : return NS_OK;
1420 :
1421 0 : const nsCSSValue& val = this->*nsCSSFontFaceStyleDecl::Fields[aFontDescID];
1422 :
1423 0 : if (val.GetUnit() == eCSSUnit_Null) {
1424 : // Avoid having to check no-value in the Family and Src cases below.
1425 0 : return NS_OK;
1426 : }
1427 :
1428 0 : switch (aFontDescID) {
1429 : case eCSSFontDesc_Family: {
1430 : // we don't use nsCSSValue::AppendToString here because it doesn't
1431 : // canonicalize the way we want, and anyway it's overkill when
1432 : // we know we have eCSSUnit_String
1433 0 : NS_ASSERTION(val.GetUnit() == eCSSUnit_String, "unexpected unit");
1434 0 : nsDependentString family(val.GetStringBufferValue());
1435 0 : nsStyleUtil::AppendEscapedCSSString(family, aResult);
1436 0 : return NS_OK;
1437 : }
1438 :
1439 : case eCSSFontDesc_Style:
1440 0 : val.AppendToString(eCSSProperty_font_style, aResult);
1441 0 : return NS_OK;
1442 :
1443 : case eCSSFontDesc_Weight:
1444 0 : val.AppendToString(eCSSProperty_font_weight, aResult);
1445 0 : return NS_OK;
1446 :
1447 : case eCSSFontDesc_Stretch:
1448 0 : val.AppendToString(eCSSProperty_font_stretch, aResult);
1449 0 : return NS_OK;
1450 :
1451 : case eCSSFontDesc_FontFeatureSettings:
1452 0 : val.AppendToString(eCSSProperty_font_feature_settings, aResult);
1453 0 : return NS_OK;
1454 :
1455 : case eCSSFontDesc_FontLanguageOverride:
1456 0 : val.AppendToString(eCSSProperty_font_language_override, aResult);
1457 0 : return NS_OK;
1458 :
1459 : case eCSSFontDesc_Src:
1460 0 : AppendSerializedFontSrc(val, aResult);
1461 0 : return NS_OK;
1462 :
1463 : case eCSSFontDesc_UnicodeRange:
1464 0 : AppendSerializedUnicodeRange(val, aResult);
1465 0 : return NS_OK;
1466 :
1467 : case eCSSFontDesc_UNKNOWN:
1468 : case eCSSFontDesc_COUNT:
1469 : ;
1470 : }
1471 : NS_NOTREACHED("nsCSSFontFaceStyleDecl::GetPropertyValue: "
1472 0 : "out-of-range value got to the switch");
1473 0 : return NS_ERROR_INVALID_ARG;
1474 : }
1475 :
1476 :
1477 : // attribute DOMString cssText;
1478 : NS_IMETHODIMP
1479 0 : nsCSSFontFaceStyleDecl::GetCssText(nsAString & aCssText)
1480 : {
1481 0 : nsAutoString descStr;
1482 :
1483 0 : aCssText.Truncate();
1484 0 : for (nsCSSFontDesc id = nsCSSFontDesc(eCSSFontDesc_UNKNOWN + 1);
1485 : id < eCSSFontDesc_COUNT;
1486 : id = nsCSSFontDesc(id + 1)) {
1487 0 : if ((this->*nsCSSFontFaceStyleDecl::Fields[id]).GetUnit()
1488 : != eCSSUnit_Null &&
1489 0 : NS_SUCCEEDED(GetPropertyValue(id, descStr))) {
1490 0 : NS_ASSERTION(descStr.Length() > 0,
1491 : "GetCssText: non-null unit, empty property value");
1492 0 : aCssText.AppendLiteral(" ");
1493 0 : aCssText.AppendASCII(nsCSSProps::GetStringValue(id).get());
1494 0 : aCssText.AppendLiteral(": ");
1495 0 : aCssText.Append(descStr);
1496 0 : aCssText.AppendLiteral(";\n");
1497 : }
1498 : }
1499 0 : return NS_OK;
1500 : }
1501 :
1502 : NS_IMETHODIMP
1503 0 : nsCSSFontFaceStyleDecl::SetCssText(const nsAString & aCssText)
1504 : {
1505 0 : return NS_ERROR_NOT_IMPLEMENTED; // bug 443978
1506 : }
1507 :
1508 : // DOMString getPropertyValue (in DOMString propertyName);
1509 : NS_IMETHODIMP
1510 0 : nsCSSFontFaceStyleDecl::GetPropertyValue(const nsAString & propertyName,
1511 : nsAString & aResult NS_OUTPARAM)
1512 : {
1513 0 : return GetPropertyValue(nsCSSProps::LookupFontDesc(propertyName), aResult);
1514 : }
1515 :
1516 : // nsIDOMCSSValue getPropertyCSSValue (in DOMString propertyName);
1517 : NS_IMETHODIMP
1518 0 : nsCSSFontFaceStyleDecl::GetPropertyCSSValue(const nsAString & propertyName,
1519 : nsIDOMCSSValue **aResult NS_OUTPARAM)
1520 : {
1521 : // ??? nsDOMCSSDeclaration returns null/NS_OK, but that seems wrong.
1522 0 : return NS_ERROR_NOT_IMPLEMENTED;
1523 : }
1524 :
1525 : // DOMString removeProperty (in DOMString propertyName) raises (DOMException);
1526 : NS_IMETHODIMP
1527 0 : nsCSSFontFaceStyleDecl::RemoveProperty(const nsAString & propertyName,
1528 : nsAString & aResult NS_OUTPARAM)
1529 : {
1530 0 : nsCSSFontDesc descID = nsCSSProps::LookupFontDesc(propertyName);
1531 0 : NS_ASSERTION(descID >= eCSSFontDesc_UNKNOWN &&
1532 : descID < eCSSFontDesc_COUNT,
1533 : "LookupFontDesc returned value out of range");
1534 :
1535 0 : if (descID == eCSSFontDesc_UNKNOWN) {
1536 0 : aResult.Truncate();
1537 : } else {
1538 0 : nsresult rv = GetPropertyValue(descID, aResult);
1539 0 : NS_ENSURE_SUCCESS(rv, rv);
1540 0 : (this->*nsCSSFontFaceStyleDecl::Fields[descID]).Reset();
1541 : }
1542 0 : return NS_OK;
1543 : }
1544 :
1545 : // DOMString getPropertyPriority (in DOMString propertyName);
1546 : NS_IMETHODIMP
1547 0 : nsCSSFontFaceStyleDecl::GetPropertyPriority(const nsAString & propertyName,
1548 : nsAString & aResult NS_OUTPARAM)
1549 : {
1550 : // font descriptors do not have priorities at present
1551 0 : aResult.Truncate();
1552 0 : return NS_OK;
1553 : }
1554 :
1555 : // void setProperty (in DOMString propertyName, in DOMString value,
1556 : // in DOMString priority) raises (DOMException);
1557 : NS_IMETHODIMP
1558 0 : nsCSSFontFaceStyleDecl::SetProperty(const nsAString & propertyName,
1559 : const nsAString & value,
1560 : const nsAString & priority)
1561 : {
1562 0 : return NS_ERROR_NOT_IMPLEMENTED; // bug 443978
1563 : }
1564 :
1565 : // readonly attribute unsigned long length;
1566 : NS_IMETHODIMP
1567 0 : nsCSSFontFaceStyleDecl::GetLength(PRUint32 *aLength)
1568 : {
1569 0 : PRUint32 len = 0;
1570 0 : for (nsCSSFontDesc id = nsCSSFontDesc(eCSSFontDesc_UNKNOWN + 1);
1571 : id < eCSSFontDesc_COUNT;
1572 : id = nsCSSFontDesc(id + 1))
1573 0 : if ((this->*nsCSSFontFaceStyleDecl::Fields[id]).GetUnit() != eCSSUnit_Null)
1574 0 : len++;
1575 :
1576 0 : *aLength = len;
1577 0 : return NS_OK;
1578 : }
1579 :
1580 : // DOMString item (in unsigned long index);
1581 : NS_IMETHODIMP
1582 0 : nsCSSFontFaceStyleDecl::Item(PRUint32 index, nsAString & aResult NS_OUTPARAM)
1583 : {
1584 0 : PRInt32 nset = -1;
1585 0 : for (nsCSSFontDesc id = nsCSSFontDesc(eCSSFontDesc_UNKNOWN + 1);
1586 : id < eCSSFontDesc_COUNT;
1587 : id = nsCSSFontDesc(id + 1)) {
1588 0 : if ((this->*nsCSSFontFaceStyleDecl::Fields[id]).GetUnit()
1589 : != eCSSUnit_Null) {
1590 0 : nset++;
1591 0 : if (nset == PRInt32(index)) {
1592 0 : aResult.AssignASCII(nsCSSProps::GetStringValue(id).get());
1593 0 : return NS_OK;
1594 : }
1595 : }
1596 : }
1597 0 : aResult.Truncate();
1598 0 : return NS_OK;
1599 : }
1600 :
1601 : // readonly attribute nsIDOMCSSRule parentRule;
1602 : NS_IMETHODIMP
1603 0 : nsCSSFontFaceStyleDecl::GetParentRule(nsIDOMCSSRule** aParentRule)
1604 : {
1605 0 : NS_IF_ADDREF(*aParentRule = ContainingRule()->GetDOMRule());
1606 0 : return NS_OK;
1607 : }
1608 :
1609 :
1610 : // -------------------------------------------
1611 : // nsCSSFontFaceRule
1612 : //
1613 :
1614 : /* virtual */ already_AddRefed<css::Rule>
1615 0 : nsCSSFontFaceRule::Clone() const
1616 : {
1617 0 : nsRefPtr<css::Rule> clone = new nsCSSFontFaceRule(*this);
1618 0 : return clone.forget();
1619 : }
1620 :
1621 0 : NS_IMPL_ADDREF_INHERITED(nsCSSFontFaceRule, Rule)
1622 0 : NS_IMPL_RELEASE_INHERITED(nsCSSFontFaceRule, Rule)
1623 :
1624 : DOMCI_DATA(CSSFontFaceRule, nsCSSFontFaceRule)
1625 :
1626 : // QueryInterface implementation for nsCSSFontFaceRule
1627 0 : NS_INTERFACE_MAP_BEGIN(nsCSSFontFaceRule)
1628 0 : NS_INTERFACE_MAP_ENTRY(nsIStyleRule)
1629 0 : NS_INTERFACE_MAP_ENTRY(nsIDOMCSSFontFaceRule)
1630 0 : NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
1631 0 : NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStyleRule)
1632 0 : NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSFontFaceRule)
1633 0 : NS_INTERFACE_MAP_END
1634 :
1635 0 : IMPL_STYLE_RULE_INHERIT(nsCSSFontFaceRule, Rule)
1636 :
1637 : #ifdef DEBUG
1638 : void
1639 0 : nsCSSFontFaceRule::List(FILE* out, PRInt32 aIndent) const
1640 : {
1641 0 : nsCString baseInd, descInd;
1642 0 : for (PRInt32 indent = aIndent; --indent >= 0; ) {
1643 0 : baseInd.AppendLiteral(" ");
1644 0 : descInd.AppendLiteral(" ");
1645 : }
1646 0 : descInd.AppendLiteral(" ");
1647 :
1648 0 : nsString descStr;
1649 :
1650 0 : fprintf(out, "%s@font-face {\n", baseInd.get());
1651 0 : for (nsCSSFontDesc id = nsCSSFontDesc(eCSSFontDesc_UNKNOWN + 1);
1652 : id < eCSSFontDesc_COUNT;
1653 : id = nsCSSFontDesc(id + 1))
1654 0 : if ((mDecl.*nsCSSFontFaceStyleDecl::Fields[id]).GetUnit()
1655 : != eCSSUnit_Null) {
1656 0 : if (NS_FAILED(mDecl.GetPropertyValue(id, descStr)))
1657 0 : descStr.AssignLiteral("#<serialization error>");
1658 0 : else if (descStr.Length() == 0)
1659 0 : descStr.AssignLiteral("#<serialization missing>");
1660 : fprintf(out, "%s%s: %s\n",
1661 0 : descInd.get(), nsCSSProps::GetStringValue(id).get(),
1662 0 : NS_ConvertUTF16toUTF8(descStr).get());
1663 : }
1664 0 : fprintf(out, "%s}\n", baseInd.get());
1665 0 : }
1666 : #endif
1667 :
1668 : /* virtual */ PRInt32
1669 0 : nsCSSFontFaceRule::GetType() const
1670 : {
1671 0 : return Rule::FONT_FACE_RULE;
1672 : }
1673 :
1674 : NS_IMETHODIMP
1675 0 : nsCSSFontFaceRule::GetType(PRUint16* aType)
1676 : {
1677 0 : *aType = nsIDOMCSSRule::FONT_FACE_RULE;
1678 0 : return NS_OK;
1679 : }
1680 :
1681 : NS_IMETHODIMP
1682 0 : nsCSSFontFaceRule::GetCssText(nsAString& aCssText)
1683 : {
1684 0 : nsAutoString propText;
1685 0 : mDecl.GetCssText(propText);
1686 :
1687 0 : aCssText.AssignLiteral("@font-face {\n");
1688 0 : aCssText.Append(propText);
1689 0 : aCssText.Append('}');
1690 0 : return NS_OK;
1691 : }
1692 :
1693 : NS_IMETHODIMP
1694 0 : nsCSSFontFaceRule::SetCssText(const nsAString& aCssText)
1695 : {
1696 0 : return NS_ERROR_NOT_IMPLEMENTED; // bug 443978
1697 : }
1698 :
1699 : NS_IMETHODIMP
1700 0 : nsCSSFontFaceRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
1701 : {
1702 0 : return Rule::GetParentStyleSheet(aSheet);
1703 : }
1704 :
1705 : NS_IMETHODIMP
1706 0 : nsCSSFontFaceRule::GetParentRule(nsIDOMCSSRule** aParentRule)
1707 : {
1708 0 : return Rule::GetParentRule(aParentRule);
1709 : }
1710 :
1711 : NS_IMETHODIMP
1712 0 : nsCSSFontFaceRule::GetStyle(nsIDOMCSSStyleDeclaration** aStyle)
1713 : {
1714 0 : NS_IF_ADDREF(*aStyle = &mDecl);
1715 0 : return NS_OK;
1716 : }
1717 :
1718 : // Arguably these should forward to nsCSSFontFaceStyleDecl methods.
1719 : void
1720 0 : nsCSSFontFaceRule::SetDesc(nsCSSFontDesc aDescID, nsCSSValue const & aValue)
1721 : {
1722 0 : NS_PRECONDITION(aDescID > eCSSFontDesc_UNKNOWN &&
1723 : aDescID < eCSSFontDesc_COUNT,
1724 : "aDescID out of range in nsCSSFontFaceRule::SetDesc");
1725 :
1726 : // FIXME: handle dynamic changes
1727 :
1728 0 : mDecl.*nsCSSFontFaceStyleDecl::Fields[aDescID] = aValue;
1729 0 : }
1730 :
1731 : void
1732 0 : nsCSSFontFaceRule::GetDesc(nsCSSFontDesc aDescID, nsCSSValue & aValue)
1733 : {
1734 0 : NS_PRECONDITION(aDescID > eCSSFontDesc_UNKNOWN &&
1735 : aDescID < eCSSFontDesc_COUNT,
1736 : "aDescID out of range in nsCSSFontFaceRule::GetDesc");
1737 :
1738 0 : aValue = mDecl.*nsCSSFontFaceStyleDecl::Fields[aDescID];
1739 0 : }
1740 :
1741 : /* virtual */ size_t
1742 0 : nsCSSFontFaceRule::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const
1743 : {
1744 0 : return aMallocSizeOf(this);
1745 :
1746 : // Measurement of the following members may be added later if DMD finds it is
1747 : // worthwhile:
1748 : // - mDecl
1749 : }
1750 :
1751 :
1752 : // -------------------------------------------
1753 : // nsCSSKeyframeStyleDeclaration
1754 : //
1755 :
1756 0 : nsCSSKeyframeStyleDeclaration::nsCSSKeyframeStyleDeclaration(nsCSSKeyframeRule *aRule)
1757 0 : : mRule(aRule)
1758 : {
1759 0 : }
1760 :
1761 0 : nsCSSKeyframeStyleDeclaration::~nsCSSKeyframeStyleDeclaration()
1762 : {
1763 0 : NS_ASSERTION(!mRule, "DropReference not called.");
1764 0 : }
1765 :
1766 0 : NS_IMPL_ADDREF(nsCSSKeyframeStyleDeclaration)
1767 0 : NS_IMPL_RELEASE(nsCSSKeyframeStyleDeclaration)
1768 :
1769 : css::Declaration*
1770 0 : nsCSSKeyframeStyleDeclaration::GetCSSDeclaration(bool aAllocate)
1771 : {
1772 0 : if (mRule) {
1773 0 : return mRule->Declaration();
1774 : } else {
1775 0 : return nsnull;
1776 : }
1777 : }
1778 :
1779 : void
1780 0 : nsCSSKeyframeStyleDeclaration::GetCSSParsingEnvironment(CSSParsingEnvironment& aCSSParseEnv)
1781 : {
1782 0 : GetCSSParsingEnvironmentForRule(mRule, aCSSParseEnv);
1783 0 : }
1784 :
1785 : NS_IMETHODIMP
1786 0 : nsCSSKeyframeStyleDeclaration::GetParentRule(nsIDOMCSSRule **aParent)
1787 : {
1788 0 : NS_ENSURE_ARG_POINTER(aParent);
1789 :
1790 0 : NS_IF_ADDREF(*aParent = mRule);
1791 0 : return NS_OK;
1792 : }
1793 :
1794 : nsresult
1795 0 : nsCSSKeyframeStyleDeclaration::SetCSSDeclaration(css::Declaration* aDecl)
1796 : {
1797 0 : NS_ABORT_IF_FALSE(aDecl, "must be non-null");
1798 0 : mRule->ChangeDeclaration(aDecl);
1799 0 : return NS_OK;
1800 : }
1801 :
1802 : nsIDocument*
1803 0 : nsCSSKeyframeStyleDeclaration::DocToUpdate()
1804 : {
1805 0 : return nsnull;
1806 : }
1807 :
1808 : // -------------------------------------------
1809 : // nsCSSKeyframeRule
1810 : //
1811 :
1812 0 : nsCSSKeyframeRule::nsCSSKeyframeRule(const nsCSSKeyframeRule& aCopy)
1813 : // copy everything except our reference count and mDOMDeclaration
1814 : : Rule(aCopy)
1815 : , mKeys(aCopy.mKeys)
1816 0 : , mDeclaration(new css::Declaration(*aCopy.mDeclaration))
1817 : {
1818 0 : }
1819 :
1820 0 : nsCSSKeyframeRule::~nsCSSKeyframeRule()
1821 : {
1822 0 : if (mDOMDeclaration) {
1823 0 : mDOMDeclaration->DropReference();
1824 : }
1825 0 : }
1826 :
1827 : /* virtual */ already_AddRefed<css::Rule>
1828 0 : nsCSSKeyframeRule::Clone() const
1829 : {
1830 0 : nsRefPtr<css::Rule> clone = new nsCSSKeyframeRule(*this);
1831 0 : return clone.forget();
1832 : }
1833 :
1834 0 : NS_IMPL_ADDREF_INHERITED(nsCSSKeyframeRule, Rule)
1835 0 : NS_IMPL_RELEASE_INHERITED(nsCSSKeyframeRule, Rule)
1836 :
1837 : DOMCI_DATA(MozCSSKeyframeRule, nsCSSKeyframeRule)
1838 :
1839 : // QueryInterface implementation for nsCSSKeyframeRule
1840 0 : NS_INTERFACE_MAP_BEGIN(nsCSSKeyframeRule)
1841 0 : NS_INTERFACE_MAP_ENTRY(nsIStyleRule)
1842 0 : NS_INTERFACE_MAP_ENTRY(nsIDOMMozCSSKeyframeRule)
1843 0 : NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
1844 0 : NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStyleRule)
1845 0 : NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MozCSSKeyframeRule)
1846 0 : NS_INTERFACE_MAP_END
1847 :
1848 0 : IMPL_STYLE_RULE_INHERIT_GET_DOM_RULE_WEAK(nsCSSKeyframeRule, Rule)
1849 :
1850 : /* virtual */ void
1851 0 : nsCSSKeyframeRule::MapRuleInfoInto(nsRuleData* aRuleData)
1852 : {
1853 : // We need to implement MapRuleInfoInto because the animation manager
1854 : // constructs a rule node pointing to us in order to compute the
1855 : // styles it needs to animate.
1856 :
1857 : // FIXME (spec): The spec doesn't say what to do with !important.
1858 : // We'll just map them.
1859 0 : if (mDeclaration->HasImportantData()) {
1860 0 : mDeclaration->MapImportantRuleInfoInto(aRuleData);
1861 : }
1862 0 : mDeclaration->MapNormalRuleInfoInto(aRuleData);
1863 0 : }
1864 :
1865 : #ifdef DEBUG
1866 : void
1867 0 : nsCSSKeyframeRule::List(FILE* out, PRInt32 aIndent) const
1868 : {
1869 : // FIXME: WRITE ME
1870 0 : }
1871 : #endif
1872 :
1873 : /* virtual */ PRInt32
1874 0 : nsCSSKeyframeRule::GetType() const
1875 : {
1876 0 : return Rule::KEYFRAME_RULE;
1877 : }
1878 :
1879 : NS_IMETHODIMP
1880 0 : nsCSSKeyframeRule::GetType(PRUint16* aType)
1881 : {
1882 0 : *aType = nsIDOMCSSRule::MOZ_KEYFRAME_RULE;
1883 0 : return NS_OK;
1884 : }
1885 :
1886 : NS_IMETHODIMP
1887 0 : nsCSSKeyframeRule::GetCssText(nsAString& aCssText)
1888 : {
1889 0 : nsCSSKeyframeRule::GetKeyText(aCssText);
1890 0 : aCssText.AppendLiteral(" { ");
1891 0 : nsAutoString tmp;
1892 0 : mDeclaration->ToString(tmp);
1893 0 : aCssText.Append(tmp);
1894 0 : aCssText.AppendLiteral(" }");
1895 0 : return NS_OK;
1896 : }
1897 :
1898 : NS_IMETHODIMP
1899 0 : nsCSSKeyframeRule::SetCssText(const nsAString& aCssText)
1900 : {
1901 : // FIXME: implement???
1902 0 : return NS_ERROR_NOT_IMPLEMENTED;
1903 : }
1904 :
1905 : NS_IMETHODIMP
1906 0 : nsCSSKeyframeRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
1907 : {
1908 0 : return Rule::GetParentStyleSheet(aSheet);
1909 : }
1910 :
1911 : NS_IMETHODIMP
1912 0 : nsCSSKeyframeRule::GetParentRule(nsIDOMCSSRule** aParentRule)
1913 : {
1914 0 : return Rule::GetParentRule(aParentRule);
1915 : }
1916 :
1917 : NS_IMETHODIMP
1918 0 : nsCSSKeyframeRule::GetKeyText(nsAString& aKeyText)
1919 : {
1920 0 : aKeyText.Truncate();
1921 0 : PRUint32 i = 0, i_end = mKeys.Length();
1922 0 : NS_ABORT_IF_FALSE(i_end != 0, "must have some keys");
1923 0 : for (;;) {
1924 0 : aKeyText.AppendFloat(mKeys[i] * 100.0f);
1925 0 : aKeyText.Append(PRUnichar('%'));
1926 0 : if (++i == i_end) {
1927 : break;
1928 : }
1929 0 : aKeyText.AppendLiteral(", ");
1930 : }
1931 0 : return NS_OK;
1932 : }
1933 :
1934 : NS_IMETHODIMP
1935 0 : nsCSSKeyframeRule::SetKeyText(const nsAString& aKeyText)
1936 : {
1937 0 : nsCSSParser parser;
1938 :
1939 0 : InfallibleTArray<float> newSelectors;
1940 : // FIXME: pass filename and line number
1941 0 : if (parser.ParseKeyframeSelectorString(aKeyText, nsnull, 0, newSelectors)) {
1942 0 : newSelectors.SwapElements(mKeys);
1943 : } else {
1944 : // for now, we don't do anything if the parse fails
1945 : }
1946 :
1947 0 : if (mSheet) {
1948 0 : mSheet->SetModifiedByChildRule();
1949 : }
1950 :
1951 0 : return NS_OK;
1952 : }
1953 :
1954 : NS_IMETHODIMP
1955 0 : nsCSSKeyframeRule::GetStyle(nsIDOMCSSStyleDeclaration** aStyle)
1956 : {
1957 0 : if (!mDOMDeclaration) {
1958 0 : mDOMDeclaration = new nsCSSKeyframeStyleDeclaration(this);
1959 : }
1960 0 : NS_ADDREF(*aStyle = mDOMDeclaration);
1961 0 : return NS_OK;
1962 : }
1963 :
1964 : void
1965 0 : nsCSSKeyframeRule::ChangeDeclaration(css::Declaration* aDeclaration)
1966 : {
1967 : // Be careful to not assign to an nsAutoPtr if we would be assigning
1968 : // the thing it already holds.
1969 0 : if (aDeclaration != mDeclaration) {
1970 0 : mDeclaration = aDeclaration;
1971 : }
1972 :
1973 0 : if (mSheet) {
1974 0 : mSheet->SetModifiedByChildRule();
1975 : }
1976 0 : }
1977 :
1978 : /* virtual */ size_t
1979 0 : nsCSSKeyframeRule::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const
1980 : {
1981 0 : return aMallocSizeOf(this);
1982 :
1983 : // Measurement of the following members may be added later if DMD finds it is
1984 : // worthwhile:
1985 : // - mKeys
1986 : // - mDeclaration
1987 : // - mDOMDeclaration
1988 : }
1989 :
1990 :
1991 : // -------------------------------------------
1992 : // nsCSSKeyframesRule
1993 : //
1994 :
1995 0 : nsCSSKeyframesRule::nsCSSKeyframesRule(const nsCSSKeyframesRule& aCopy)
1996 : // copy everything except our reference count. GroupRule's copy
1997 : // constructor also doesn't copy the lazily-constructed
1998 : // mRuleCollection.
1999 : : GroupRule(aCopy),
2000 0 : mName(aCopy.mName)
2001 : {
2002 0 : }
2003 :
2004 0 : nsCSSKeyframesRule::~nsCSSKeyframesRule()
2005 : {
2006 0 : }
2007 :
2008 : /* virtual */ already_AddRefed<css::Rule>
2009 0 : nsCSSKeyframesRule::Clone() const
2010 : {
2011 0 : nsRefPtr<css::Rule> clone = new nsCSSKeyframesRule(*this);
2012 0 : return clone.forget();
2013 : }
2014 :
2015 0 : NS_IMPL_ADDREF_INHERITED(nsCSSKeyframesRule, css::GroupRule)
2016 0 : NS_IMPL_RELEASE_INHERITED(nsCSSKeyframesRule, css::GroupRule)
2017 :
2018 : DOMCI_DATA(MozCSSKeyframesRule, nsCSSKeyframesRule)
2019 :
2020 : // QueryInterface implementation for nsCSSKeyframesRule
2021 0 : NS_INTERFACE_MAP_BEGIN(nsCSSKeyframesRule)
2022 0 : NS_INTERFACE_MAP_ENTRY(nsIStyleRule)
2023 0 : NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
2024 0 : NS_INTERFACE_MAP_ENTRY(nsIDOMMozCSSKeyframesRule)
2025 0 : NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStyleRule)
2026 0 : NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MozCSSKeyframesRule)
2027 0 : NS_INTERFACE_MAP_END
2028 :
2029 : #ifdef DEBUG
2030 : void
2031 0 : nsCSSKeyframesRule::List(FILE* out, PRInt32 aIndent) const
2032 : {
2033 : // FIXME: WRITE ME
2034 0 : }
2035 : #endif
2036 :
2037 : /* virtual */ PRInt32
2038 0 : nsCSSKeyframesRule::GetType() const
2039 : {
2040 0 : return Rule::KEYFRAMES_RULE;
2041 : }
2042 :
2043 : NS_IMETHODIMP
2044 0 : nsCSSKeyframesRule::GetType(PRUint16* aType)
2045 : {
2046 0 : *aType = nsIDOMCSSRule::MOZ_KEYFRAMES_RULE;
2047 0 : return NS_OK;
2048 : }
2049 :
2050 : NS_IMETHODIMP
2051 0 : nsCSSKeyframesRule::GetCssText(nsAString& aCssText)
2052 : {
2053 0 : aCssText.AssignLiteral("@-moz-keyframes ");
2054 0 : aCssText.Append(mName);
2055 0 : aCssText.AppendLiteral(" {\n");
2056 0 : nsAutoString tmp;
2057 0 : for (PRUint32 i = 0, i_end = mRules.Count(); i != i_end; ++i) {
2058 0 : static_cast<nsCSSKeyframeRule*>(mRules[i])->GetCssText(tmp);
2059 0 : aCssText.Append(tmp);
2060 0 : aCssText.AppendLiteral("\n");
2061 : }
2062 0 : aCssText.AppendLiteral("}");
2063 0 : return NS_OK;
2064 : }
2065 :
2066 : NS_IMETHODIMP
2067 0 : nsCSSKeyframesRule::SetCssText(const nsAString& aCssText)
2068 : {
2069 : // FIXME: implement???
2070 0 : return NS_ERROR_NOT_IMPLEMENTED;
2071 : }
2072 :
2073 : NS_IMETHODIMP
2074 0 : nsCSSKeyframesRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
2075 : {
2076 0 : return GroupRule::GetParentStyleSheet(aSheet);
2077 : }
2078 :
2079 : NS_IMETHODIMP
2080 0 : nsCSSKeyframesRule::GetParentRule(nsIDOMCSSRule** aParentRule)
2081 : {
2082 0 : return GroupRule::GetParentRule(aParentRule);
2083 : }
2084 :
2085 : NS_IMETHODIMP
2086 0 : nsCSSKeyframesRule::GetName(nsAString& aName)
2087 : {
2088 0 : aName = mName;
2089 0 : return NS_OK;
2090 : }
2091 :
2092 : NS_IMETHODIMP
2093 0 : nsCSSKeyframesRule::SetName(const nsAString& aName)
2094 : {
2095 0 : mName = aName;
2096 :
2097 0 : if (mSheet) {
2098 0 : mSheet->SetModifiedByChildRule();
2099 : }
2100 :
2101 0 : return NS_OK;
2102 : }
2103 :
2104 : NS_IMETHODIMP
2105 0 : nsCSSKeyframesRule::GetCssRules(nsIDOMCSSRuleList* *aRuleList)
2106 : {
2107 0 : return GroupRule::GetCssRules(aRuleList);
2108 : }
2109 :
2110 : NS_IMETHODIMP
2111 0 : nsCSSKeyframesRule::InsertRule(const nsAString& aRule)
2112 : {
2113 : // The spec is confusing, and I think we should just append the rule,
2114 : // which also turns out to match WebKit:
2115 : // http://lists.w3.org/Archives/Public/www-style/2011Apr/0034.html
2116 0 : nsCSSParser parser;
2117 :
2118 : // FIXME: pass filename and line number
2119 : nsRefPtr<nsCSSKeyframeRule> rule =
2120 0 : parser.ParseKeyframeRule(aRule, nsnull, 0);
2121 0 : if (rule) {
2122 0 : AppendStyleRule(rule);
2123 : }
2124 :
2125 0 : return NS_OK;
2126 : }
2127 :
2128 : static const PRUint32 RULE_NOT_FOUND = PRUint32(-1);
2129 :
2130 : PRUint32
2131 0 : nsCSSKeyframesRule::FindRuleIndexForKey(const nsAString& aKey)
2132 : {
2133 0 : nsCSSParser parser;
2134 :
2135 0 : InfallibleTArray<float> keys;
2136 : // FIXME: pass filename and line number
2137 0 : if (parser.ParseKeyframeSelectorString(aKey, nsnull, 0, keys)) {
2138 : // The spec isn't clear, but we'll match on the key list, which
2139 : // mostly matches what WebKit does, except we'll do last-match
2140 : // instead of first-match, and handling parsing differences better.
2141 : // http://lists.w3.org/Archives/Public/www-style/2011Apr/0036.html
2142 : // http://lists.w3.org/Archives/Public/www-style/2011Apr/0037.html
2143 0 : for (PRUint32 i = mRules.Count(); i-- != 0; ) {
2144 0 : if (static_cast<nsCSSKeyframeRule*>(mRules[i])->GetKeys() == keys) {
2145 0 : return i;
2146 : }
2147 : }
2148 : }
2149 :
2150 0 : return RULE_NOT_FOUND;
2151 : }
2152 :
2153 : NS_IMETHODIMP
2154 0 : nsCSSKeyframesRule::DeleteRule(const nsAString& aKey)
2155 : {
2156 0 : PRUint32 index = FindRuleIndexForKey(aKey);
2157 0 : if (index != RULE_NOT_FOUND) {
2158 0 : mRules.RemoveObjectAt(index);
2159 0 : if (mSheet) {
2160 0 : mSheet->SetModifiedByChildRule();
2161 : }
2162 : }
2163 0 : return NS_OK;
2164 : }
2165 :
2166 : NS_IMETHODIMP
2167 0 : nsCSSKeyframesRule::FindRule(const nsAString& aKey,
2168 : nsIDOMMozCSSKeyframeRule** aResult)
2169 : {
2170 0 : PRUint32 index = FindRuleIndexForKey(aKey);
2171 0 : if (index == RULE_NOT_FOUND) {
2172 0 : *aResult = nsnull;
2173 : } else {
2174 0 : NS_ADDREF(*aResult = static_cast<nsCSSKeyframeRule*>(mRules[index]));
2175 : }
2176 0 : return NS_OK;
2177 : }
2178 :
2179 : // GroupRule interface
2180 : /* virtual */ bool
2181 0 : nsCSSKeyframesRule::UseForPresentation(nsPresContext* aPresContext,
2182 : nsMediaQueryResultCacheKey& aKey)
2183 : {
2184 0 : NS_ABORT_IF_FALSE(false, "should not be called");
2185 0 : return false;
2186 : }
2187 :
2188 : /* virtual */ size_t
2189 0 : nsCSSKeyframesRule::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const
2190 : {
2191 0 : size_t n = aMallocSizeOf(this);
2192 0 : n += GroupRule::SizeOfExcludingThis(aMallocSizeOf);
2193 :
2194 : // Measurement of the following members may be added later if DMD finds it is
2195 : // worthwhile:
2196 : // - mName
2197 :
2198 0 : return n;
2199 : }
2200 :
2201 :
|