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
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/
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
15 * The Original Code is mozilla.org code.
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.
23 * Boris Zbarsky <bzbarsky@mit.edu>
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.
37 * ***** END LICENSE BLOCK ***** */
39 /* rules in a CSS stylesheet other than style rules (e.g., @import rules) */
41 #include "nsCSSRules.h"
42 #include "nsCSSValue.h"
43 #include "nsICSSImportRule.h"
44 #include "nsICSSNameSpaceRule.h"
50 #include "nsCSSRule.h"
51 #include "nsCSSProps.h"
52 #include "nsICSSStyleSheet.h"
55 #include "nsIDOMCSSStyleSheet.h"
56 #include "nsIDOMCSSRule.h"
57 #include "nsIDOMCSSImportRule.h"
58 #include "nsIDOMCSSMediaRule.h"
59 #include "nsIDOMCSSMozDocumentRule.h"
60 #include "nsIDOMCSSCharsetRule.h"
61 #include "nsIDOMCSSStyleDeclaration.h"
62 #include "nsIMediaList.h"
63 #include "nsIDOMMediaList.h"
64 #include "nsICSSRuleList.h"
65 #include "nsIDOMStyleSheet.h"
66 #include "nsIDocument.h"
67 #include "nsPresContext.h"
69 #include "nsContentUtils.h"
70 #include "nsStyleConsts.h"
71 #include "nsDOMError.h"
72 #include "nsStyleUtil.h"
73 #include "nsCSSDeclaration.h"
75 #define IMPL_STYLE_RULE_INHERIT(_class, super) \
76 NS_IMETHODIMP _class::GetStyleSheet(nsIStyleSheet*& aSheet) const { return super::GetStyleSheet(aSheet); } \
77 NS_IMETHODIMP _class::SetStyleSheet(nsICSSStyleSheet* aSheet) { return super::SetStyleSheet(aSheet); } \
78 NS_IMETHODIMP _class::SetParentRule(nsICSSGroupRule* aRule) { return super::SetParentRule(aRule); } \
79 nsIDOMCSSRule* _class::GetDOMRuleWeak(nsresult *aResult) { *aResult = NS_OK; return this; } \
80 NS_IMETHODIMP _class::MapRuleInfoInto(nsRuleData* aRuleData) { return NS_OK; }
82 #define IMPL_STYLE_RULE_INHERIT2(_class, super) \
83 NS_IMETHODIMP _class::GetStyleSheet(nsIStyleSheet*& aSheet) const { return super::GetStyleSheet(aSheet); } \
84 NS_IMETHODIMP _class::SetParentRule(nsICSSGroupRule* aRule) { return super::SetParentRule(aRule); } \
85 NS_IMETHODIMP _class::MapRuleInfoInto(nsRuleData* aRuleData) { return NS_OK; }
87 // -------------------------------
88 // Style Rule List for group rules
90 class CSSGroupRuleRuleListImpl
: public nsICSSRuleList
93 CSSGroupRuleRuleListImpl(nsICSSGroupRule
*aGroupRule
);
97 NS_DECL_NSIDOMCSSRULELIST
99 virtual nsIDOMCSSRule
* GetItemAt(PRUint32 aIndex
, nsresult
* aResult
);
101 void DropReference() { mGroupRule
= nsnull
; }
104 virtual ~CSSGroupRuleRuleListImpl(void);
107 nsICSSGroupRule
* mGroupRule
;
110 CSSGroupRuleRuleListImpl::CSSGroupRuleRuleListImpl(nsICSSGroupRule
*aGroupRule
)
112 // Not reference counted to avoid circular references.
113 // The rule will tell us when its going away.
114 mGroupRule
= aGroupRule
;
117 CSSGroupRuleRuleListImpl::~CSSGroupRuleRuleListImpl()
121 // QueryInterface implementation for CSSGroupRuleRuleList
122 NS_INTERFACE_MAP_BEGIN(CSSGroupRuleRuleListImpl
)
123 NS_INTERFACE_MAP_ENTRY(nsICSSRuleList
)
124 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRuleList
)
125 NS_INTERFACE_MAP_ENTRY(nsISupports
)
126 NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(CSSGroupRuleRuleList
)
130 NS_IMPL_ADDREF(CSSGroupRuleRuleListImpl
)
131 NS_IMPL_RELEASE(CSSGroupRuleRuleListImpl
)
134 CSSGroupRuleRuleListImpl::GetLength(PRUint32
* aLength
)
138 mGroupRule
->StyleRuleCount(count
);
139 *aLength
= (PRUint32
)count
;
148 CSSGroupRuleRuleListImpl::GetItemAt(PRUint32 aIndex
, nsresult
* aResult
)
150 nsresult result
= NS_OK
;
153 nsCOMPtr
<nsICSSRule
> rule
;
155 result
= mGroupRule
->GetStyleRuleAt(aIndex
, *getter_AddRefs(rule
));
157 return rule
->GetDOMRuleWeak(aResult
);
159 if (result
== NS_ERROR_ILLEGAL_VALUE
) {
160 result
= NS_OK
; // per spec: "Return Value ... null if ... not a valid index."
170 CSSGroupRuleRuleListImpl::Item(PRUint32 aIndex
, nsIDOMCSSRule
** aReturn
)
173 nsIDOMCSSRule
* rule
= GetItemAt(aIndex
, &rv
);
179 return CallQueryInterface(rule
, aReturn
);
182 // -------------------------------------------
185 class CSSCharsetRuleImpl
: public nsCSSRule
,
187 public nsIDOMCSSCharsetRule
190 CSSCharsetRuleImpl(const nsAString
& aEncoding
);
191 CSSCharsetRuleImpl(const CSSCharsetRuleImpl
& aCopy
);
192 virtual ~CSSCharsetRuleImpl(void);
194 NS_DECL_ISUPPORTS_INHERITED
196 DECL_STYLE_RULE_INHERIT
198 // nsIStyleRule methods
200 NS_IMETHOD
List(FILE* out
= stdout
, PRInt32 aIndent
= 0) const;
203 // nsICSSRule methods
204 NS_IMETHOD
GetType(PRInt32
& aType
) const;
205 NS_IMETHOD
Clone(nsICSSRule
*& aClone
) const;
207 // nsIDOMCSSRule interface
208 NS_DECL_NSIDOMCSSRULE
210 // nsIDOMCSSCharsetRule methods
211 NS_IMETHOD
GetEncoding(nsAString
& aEncoding
);
212 NS_IMETHOD
SetEncoding(const nsAString
& aEncoding
);
218 CSSCharsetRuleImpl::CSSCharsetRuleImpl(const nsAString
& aEncoding
)
224 CSSCharsetRuleImpl::CSSCharsetRuleImpl(const CSSCharsetRuleImpl
& aCopy
)
226 mEncoding(aCopy
.mEncoding
)
230 CSSCharsetRuleImpl::~CSSCharsetRuleImpl(void)
234 NS_IMPL_ADDREF_INHERITED(CSSCharsetRuleImpl
, nsCSSRule
)
235 NS_IMPL_RELEASE_INHERITED(CSSCharsetRuleImpl
, nsCSSRule
)
237 // QueryInterface implementation for CSSCharsetRuleImpl
238 NS_INTERFACE_MAP_BEGIN(CSSCharsetRuleImpl
)
239 NS_INTERFACE_MAP_ENTRY(nsICSSRule
)
240 NS_INTERFACE_MAP_ENTRY(nsIStyleRule
)
241 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule
)
242 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSCharsetRule
)
243 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports
, nsICSSRule
)
244 NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(CSSCharsetRule
)
247 IMPL_STYLE_RULE_INHERIT(CSSCharsetRuleImpl
, nsCSSRule
)
251 CSSCharsetRuleImpl::List(FILE* out
, PRInt32 aIndent
) const
254 for (PRInt32 indent
= aIndent
; --indent
>= 0; ) fputs(" ", out
);
256 fputs("@charset \"", out
);
257 fputs(NS_LossyConvertUTF16toASCII(mEncoding
).get(), out
);
265 CSSCharsetRuleImpl::GetType(PRInt32
& aType
) const
267 aType
= nsICSSRule::CHARSET_RULE
;
272 CSSCharsetRuleImpl::Clone(nsICSSRule
*& aClone
) const
274 CSSCharsetRuleImpl
* clone
= new CSSCharsetRuleImpl(*this);
276 return CallQueryInterface(clone
, &aClone
);
279 return NS_ERROR_OUT_OF_MEMORY
;
283 CSSCharsetRuleImpl::GetEncoding(nsAString
& aEncoding
)
285 aEncoding
= mEncoding
;
290 CSSCharsetRuleImpl::SetEncoding(const nsAString
& aEncoding
)
292 mEncoding
= aEncoding
;
298 NS_NewCSSCharsetRule(nsICSSRule
** aInstancePtrResult
, const nsAString
& aEncoding
)
300 if (! aInstancePtrResult
) {
301 return NS_ERROR_NULL_POINTER
;
304 CSSCharsetRuleImpl
* it
= new CSSCharsetRuleImpl(aEncoding
);
307 return NS_ERROR_OUT_OF_MEMORY
;
310 return CallQueryInterface(it
, aInstancePtrResult
);
314 CSSCharsetRuleImpl::GetType(PRUint16
* aType
)
316 *aType
= nsIDOMCSSRule::CHARSET_RULE
;
321 CSSCharsetRuleImpl::GetCssText(nsAString
& aCssText
)
323 aCssText
.AssignLiteral("@charset \"");
324 aCssText
.Append(mEncoding
);
325 aCssText
.AppendLiteral("\";");
330 CSSCharsetRuleImpl::SetCssText(const nsAString
& aCssText
)
332 return NS_ERROR_NOT_IMPLEMENTED
;
336 CSSCharsetRuleImpl::GetParentStyleSheet(nsIDOMCSSStyleSheet
** aSheet
)
338 NS_ENSURE_ARG_POINTER(aSheet
);
341 return CallQueryInterface(mSheet
, aSheet
);
348 CSSCharsetRuleImpl::GetParentRule(nsIDOMCSSRule
** aParentRule
)
351 return mParentRule
->GetDOMRule(aParentRule
);
353 *aParentRule
= nsnull
;
359 // -------------------------------------------
362 class CSSImportRuleImpl
: public nsCSSRule
,
363 public nsICSSImportRule
,
364 public nsIDOMCSSImportRule
367 CSSImportRuleImpl(nsMediaList
* aMedia
);
368 CSSImportRuleImpl(const CSSImportRuleImpl
& aCopy
);
369 virtual ~CSSImportRuleImpl(void);
371 NS_DECL_ISUPPORTS_INHERITED
373 DECL_STYLE_RULE_INHERIT
375 // nsIStyleRule methods
377 NS_IMETHOD
List(FILE* out
= stdout
, PRInt32 aIndent
= 0) const;
380 // nsICSSRule methods
381 NS_IMETHOD
GetType(PRInt32
& aType
) const;
382 NS_IMETHOD
Clone(nsICSSRule
*& aClone
) const;
384 // nsICSSImportRule methods
385 NS_IMETHOD
SetURLSpec(const nsString
& aURLSpec
);
386 NS_IMETHOD
GetURLSpec(nsString
& aURLSpec
) const;
388 NS_IMETHOD
SetMedia(const nsString
& aMedia
);
389 NS_IMETHOD
GetMedia(nsString
& aMedia
) const;
391 NS_IMETHOD
SetSheet(nsICSSStyleSheet
*);
393 // nsIDOMCSSRule interface
394 NS_DECL_NSIDOMCSSRULE
396 // nsIDOMCSSImportRule interface
397 NS_DECL_NSIDOMCSSIMPORTRULE
401 nsRefPtr
<nsMediaList
> mMedia
;
402 nsCOMPtr
<nsICSSStyleSheet
> mChildSheet
;
405 CSSImportRuleImpl::CSSImportRuleImpl(nsMediaList
* aMedia
)
410 // XXXbz This is really silly.... the mMedia here will be replaced
411 // with itself if we manage to load a sheet. Which should really
412 // never fail nowadays, in sane cases.
415 CSSImportRuleImpl::CSSImportRuleImpl(const CSSImportRuleImpl
& aCopy
)
417 mURLSpec(aCopy
.mURLSpec
)
419 nsCOMPtr
<nsICSSStyleSheet
> sheet
;
420 if (aCopy
.mChildSheet
) {
421 aCopy
.mChildSheet
->Clone(nsnull
, this, nsnull
, nsnull
,
422 getter_AddRefs(sheet
));
425 // SetSheet sets mMedia appropriately
428 CSSImportRuleImpl::~CSSImportRuleImpl(void)
431 mChildSheet
->SetOwnerRule(nsnull
);
435 NS_IMPL_ADDREF_INHERITED(CSSImportRuleImpl
, nsCSSRule
)
436 NS_IMPL_RELEASE_INHERITED(CSSImportRuleImpl
, nsCSSRule
)
438 // QueryInterface implementation for CSSImportRuleImpl
439 NS_INTERFACE_MAP_BEGIN(CSSImportRuleImpl
)
440 NS_INTERFACE_MAP_ENTRY(nsICSSImportRule
)
441 NS_INTERFACE_MAP_ENTRY(nsICSSRule
)
442 NS_INTERFACE_MAP_ENTRY(nsIStyleRule
)
443 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule
)
444 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSImportRule
)
445 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports
, nsICSSImportRule
)
446 NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(CSSImportRule
)
449 IMPL_STYLE_RULE_INHERIT(CSSImportRuleImpl
, nsCSSRule
)
453 CSSImportRuleImpl::List(FILE* out
, PRInt32 aIndent
) const
456 for (PRInt32 indent
= aIndent
; --indent
>= 0; ) fputs(" ", out
);
458 fputs("@import \"", out
);
459 fputs(NS_LossyConvertUTF16toASCII(mURLSpec
).get(), out
);
462 nsAutoString mediaText
;
463 mMedia
->GetText(mediaText
);
464 fputs(NS_LossyConvertUTF16toASCII(mediaText
).get(), out
);
472 CSSImportRuleImpl::GetType(PRInt32
& aType
) const
474 aType
= nsICSSRule::IMPORT_RULE
;
479 CSSImportRuleImpl::Clone(nsICSSRule
*& aClone
) const
481 CSSImportRuleImpl
* clone
= new CSSImportRuleImpl(*this);
483 return CallQueryInterface(clone
, &aClone
);
486 return NS_ERROR_OUT_OF_MEMORY
;
490 CSSImportRuleImpl::SetURLSpec(const nsString
& aURLSpec
)
497 CSSImportRuleImpl::GetURLSpec(nsString
& aURLSpec
) const
504 CSSImportRuleImpl::SetMedia(const nsString
& aMedia
)
507 return mMedia
->SetText(aMedia
);
514 CSSImportRuleImpl::GetMedia(nsString
& aMedia
) const
517 return mMedia
->GetText(aMedia
);
525 CSSImportRuleImpl::SetSheet(nsICSSStyleSheet
* aSheet
)
528 NS_ENSURE_ARG_POINTER(aSheet
);
531 mChildSheet
= aSheet
;
532 aSheet
->SetOwnerRule(this);
534 // set our medialist to be the same as the sheet's medialist
535 nsCOMPtr
<nsIDOMStyleSheet
> sheet(do_QueryInterface(mChildSheet
, &rv
));
536 NS_ENSURE_SUCCESS(rv
, rv
);
537 nsCOMPtr
<nsIDOMMediaList
> mediaList
;
538 rv
= sheet
->GetMedia(getter_AddRefs(mediaList
));
539 NS_ENSURE_SUCCESS(rv
, rv
);
540 mMedia
= static_cast<nsMediaList
*>(mediaList
.get());
546 NS_NewCSSImportRule(nsICSSImportRule
** aInstancePtrResult
,
547 const nsString
& aURLSpec
,
550 NS_ENSURE_ARG_POINTER(aInstancePtrResult
);
552 CSSImportRuleImpl
* it
= new CSSImportRuleImpl(aMedia
);
555 return NS_ERROR_OUT_OF_MEMORY
;
558 it
->SetURLSpec(aURLSpec
);
559 return CallQueryInterface(it
, aInstancePtrResult
);
563 CSSImportRuleImpl::GetType(PRUint16
* aType
)
565 NS_ENSURE_ARG_POINTER(aType
);
566 *aType
= nsIDOMCSSRule::IMPORT_RULE
;
571 CSSImportRuleImpl::GetCssText(nsAString
& aCssText
)
573 aCssText
.AssignLiteral("@import url(");
574 aCssText
.Append(mURLSpec
);
575 aCssText
.Append(NS_LITERAL_STRING(")"));
577 nsAutoString mediaText
;
578 mMedia
->GetText(mediaText
);
579 if (!mediaText
.IsEmpty()) {
580 aCssText
.AppendLiteral(" ");
581 aCssText
.Append(mediaText
);
584 aCssText
.AppendLiteral(";");
589 CSSImportRuleImpl::SetCssText(const nsAString
& aCssText
)
591 return NS_ERROR_NOT_IMPLEMENTED
;
595 CSSImportRuleImpl::GetParentStyleSheet(nsIDOMCSSStyleSheet
** aSheet
)
597 NS_ENSURE_ARG_POINTER(aSheet
);
599 return CallQueryInterface(mSheet
, aSheet
);
606 CSSImportRuleImpl::GetParentRule(nsIDOMCSSRule
** aParentRule
)
609 return mParentRule
->GetDOMRule(aParentRule
);
611 *aParentRule
= nsnull
;
616 CSSImportRuleImpl::GetHref(nsAString
& aHref
)
623 CSSImportRuleImpl::GetMedia(nsIDOMMediaList
* *aMedia
)
625 NS_ENSURE_ARG_POINTER(aMedia
);
631 return CallQueryInterface(mMedia
.get(), aMedia
);
635 CSSImportRuleImpl::GetStyleSheet(nsIDOMCSSStyleSheet
* *aStyleSheet
)
637 NS_ENSURE_ARG_POINTER(aStyleSheet
);
639 *aStyleSheet
= nsnull
;
643 return CallQueryInterface(mChildSheet
, aStyleSheet
);
646 nsCSSGroupRule::nsCSSGroupRule()
648 , mRuleCollection(nsnull
)
653 CloneRuleInto(nsICSSRule
* aRule
, void* aArray
)
655 nsICSSRule
* clone
= nsnull
;
658 static_cast<nsCOMArray
<nsICSSRule
>*>(aArray
)->AppendObject(clone
);
665 SetParentRuleReference(nsICSSRule
* aRule
, void* aParentRule
)
667 nsCSSGroupRule
* parentRule
= static_cast<nsCSSGroupRule
*>(aParentRule
);
668 aRule
->SetParentRule(parentRule
);
672 nsCSSGroupRule::nsCSSGroupRule(const nsCSSGroupRule
& aCopy
)
674 , mRuleCollection(nsnull
) // lazily constructed
676 const_cast<nsCSSGroupRule
&>(aCopy
).mRules
.EnumerateForwards(CloneRuleInto
, &mRules
);
677 mRules
.EnumerateForwards(SetParentRuleReference
, this);
680 nsCSSGroupRule::~nsCSSGroupRule()
682 mRules
.EnumerateForwards(SetParentRuleReference
, nsnull
);
683 if (mRuleCollection
) {
684 mRuleCollection
->DropReference();
685 NS_RELEASE(mRuleCollection
);
689 IMPL_STYLE_RULE_INHERIT2(nsCSSGroupRule
, nsCSSRule
)
692 SetStyleSheetReference(nsICSSRule
* aRule
, void* aSheet
)
694 nsICSSStyleSheet
* sheet
= (nsICSSStyleSheet
*)aSheet
;
695 aRule
->SetStyleSheet(sheet
);
700 nsCSSGroupRule::SetStyleSheet(nsICSSStyleSheet
* aSheet
)
702 mRules
.EnumerateForwards(SetStyleSheetReference
, aSheet
);
703 return nsCSSRule::SetStyleSheet(aSheet
);
708 nsCSSGroupRule::List(FILE* out
, PRInt32 aIndent
) const
712 for (PRInt32 index
= 0, count
= mRules
.Count(); index
< count
; ++index
) {
713 mRules
.ObjectAt(index
)->List(out
, aIndent
+ 1);
721 nsCSSGroupRule::AppendStyleRule(nsICSSRule
* aRule
)
723 mRules
.AppendObject(aRule
);
724 aRule
->SetStyleSheet(mSheet
);
725 aRule
->SetParentRule(this);
727 // XXXldb Shouldn't we be using |WillDirty| and |DidDirty| (and
728 // shouldn't |SetModified| be removed?
729 mSheet
->SetModified(PR_TRUE
);
735 nsCSSGroupRule::StyleRuleCount(PRInt32
& aCount
) const
737 aCount
= mRules
.Count();
742 nsCSSGroupRule::GetStyleRuleAt(PRInt32 aIndex
, nsICSSRule
*& aRule
) const
744 if (aIndex
< 0 || aIndex
>= mRules
.Count()) {
746 return NS_ERROR_ILLEGAL_VALUE
;
749 NS_ADDREF(aRule
= mRules
.ObjectAt(aIndex
));
753 NS_IMETHODIMP_(PRBool
)
754 nsCSSGroupRule::EnumerateRulesForwards(RuleEnumFunc aFunc
, void * aData
) const
757 const_cast<nsCSSGroupRule
*>(this)->mRules
.EnumerateForwards(aFunc
, aData
);
761 * The next two methods (DeleteStyleRuleAt and InsertStyleRulesAt)
762 * should never be called unless you have first called WillDirty() on
763 * the parents tylesheet. After they are called, DidDirty() needs to
764 * be called on the sheet
767 nsCSSGroupRule::DeleteStyleRuleAt(PRUint32 aIndex
)
769 nsICSSRule
* rule
= mRules
.SafeObjectAt(aIndex
);
771 rule
->SetStyleSheet(nsnull
);
772 rule
->SetParentRule(nsnull
);
774 return mRules
.RemoveObjectAt(aIndex
) ? NS_OK
: NS_ERROR_ILLEGAL_VALUE
;
778 nsCSSGroupRule::InsertStyleRulesAt(PRUint32 aIndex
,
779 nsCOMArray
<nsICSSRule
>& aRules
)
781 aRules
.EnumerateForwards(SetStyleSheetReference
, mSheet
);
782 aRules
.EnumerateForwards(SetParentRuleReference
, this);
783 if (! mRules
.InsertObjectsAt(aRules
, aIndex
)) {
784 return NS_ERROR_FAILURE
;
790 nsCSSGroupRule::ReplaceStyleRule(nsICSSRule
* aOld
, nsICSSRule
* aNew
)
792 PRInt32 index
= mRules
.IndexOf(aOld
);
793 NS_ENSURE_TRUE(index
!= -1, NS_ERROR_UNEXPECTED
);
794 mRules
.ReplaceObjectAt(aNew
, index
);
795 aNew
->SetStyleSheet(mSheet
);
796 aNew
->SetParentRule(this);
797 aOld
->SetStyleSheet(nsnull
);
798 aOld
->SetParentRule(nsnull
);
803 nsCSSGroupRule::AppendRulesToCssText(nsAString
& aCssText
)
805 aCssText
.AppendLiteral(" {\n");
808 for (PRInt32 index
= 0, count
= mRules
.Count(); index
< count
; ++index
) {
809 nsICSSRule
* rule
= mRules
.ObjectAt(index
);
810 nsCOMPtr
<nsIDOMCSSRule
> domRule
;
811 rule
->GetDOMRule(getter_AddRefs(domRule
));
813 nsAutoString cssText
;
814 domRule
->GetCssText(cssText
);
815 aCssText
.Append(NS_LITERAL_STRING(" ") +
817 NS_LITERAL_STRING("\n"));
821 aCssText
.AppendLiteral("}");
827 nsCSSGroupRule::GetParentStyleSheet(nsIDOMCSSStyleSheet
** aSheet
)
830 return CallQueryInterface(mSheet
, aSheet
);
837 nsCSSGroupRule::GetParentRule(nsIDOMCSSRule
** aParentRule
)
840 return mParentRule
->GetDOMRule(aParentRule
);
842 *aParentRule
= nsnull
;
846 // nsIDOMCSSMediaRule or nsIDOMCSSMozDocumentRule methods
848 nsCSSGroupRule::GetCssRules(nsIDOMCSSRuleList
* *aRuleList
)
850 if (!mRuleCollection
) {
851 mRuleCollection
= new CSSGroupRuleRuleListImpl(this);
852 if (!mRuleCollection
) {
853 return NS_ERROR_OUT_OF_MEMORY
;
855 NS_ADDREF(mRuleCollection
);
858 return CallQueryInterface(mRuleCollection
, aRuleList
);
862 nsCSSGroupRule::InsertRule(const nsAString
& aRule
, PRUint32 aIndex
, PRUint32
* _retval
)
864 NS_ENSURE_TRUE(mSheet
, NS_ERROR_FAILURE
);
866 if (aIndex
> PRUint32(mRules
.Count()))
867 return NS_ERROR_DOM_INDEX_SIZE_ERR
;
869 NS_ASSERTION(PRUint32(mRules
.Count()) <= PR_INT32_MAX
,
870 "Too many style rules!");
872 return mSheet
->InsertRuleIntoGroup(aRule
, this, aIndex
, _retval
);
876 nsCSSGroupRule::DeleteRule(PRUint32 aIndex
)
878 NS_ENSURE_TRUE(mSheet
, NS_ERROR_FAILURE
);
880 if (aIndex
>= PRUint32(mRules
.Count()))
881 return NS_ERROR_DOM_INDEX_SIZE_ERR
;
883 NS_ASSERTION(PRUint32(mRules
.Count()) <= PR_INT32_MAX
,
884 "Too many style rules!");
886 return mSheet
->DeleteRuleFromGroup(this, aIndex
);
889 // -------------------------------------------
892 nsCSSMediaRule::nsCSSMediaRule()
896 nsCSSMediaRule::nsCSSMediaRule(const nsCSSMediaRule
& aCopy
)
897 : nsCSSGroupRule(aCopy
)
900 aCopy
.mMedia
->Clone(getter_AddRefs(mMedia
));
902 // XXXldb This doesn't really make sense.
903 mMedia
->SetStyleSheet(aCopy
.mSheet
);
908 nsCSSMediaRule::~nsCSSMediaRule()
911 mMedia
->SetStyleSheet(nsnull
);
915 NS_IMPL_ADDREF_INHERITED(nsCSSMediaRule
, nsCSSRule
)
916 NS_IMPL_RELEASE_INHERITED(nsCSSMediaRule
, nsCSSRule
)
918 // QueryInterface implementation for nsCSSMediaRule
919 NS_INTERFACE_MAP_BEGIN(nsCSSMediaRule
)
920 NS_INTERFACE_MAP_ENTRY(nsICSSGroupRule
)
921 NS_INTERFACE_MAP_ENTRY(nsICSSRule
)
922 NS_INTERFACE_MAP_ENTRY(nsIStyleRule
)
923 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule
)
924 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSMediaRule
)
925 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports
, nsCSSGroupRule
)
926 NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(CSSMediaRule
)
930 nsCSSMediaRule::SetStyleSheet(nsICSSStyleSheet
* aSheet
)
933 // Set to null so it knows it's leaving one sheet and joining another.
934 mMedia
->SetStyleSheet(nsnull
);
935 mMedia
->SetStyleSheet(aSheet
);
938 return nsCSSGroupRule::SetStyleSheet(aSheet
);
943 nsCSSMediaRule::List(FILE* out
, PRInt32 aIndent
) const
945 for (PRInt32 indent
= aIndent
; --indent
>= 0; ) fputs(" ", out
);
949 fputs("@media ", out
);
952 nsAutoString mediaText
;
953 mMedia
->GetText(mediaText
);
954 fputs(NS_LossyConvertUTF16toASCII(mediaText
).get(), out
);
957 return nsCSSGroupRule::List(out
, aIndent
);
962 nsCSSMediaRule::GetType(PRInt32
& aType
) const
964 aType
= nsICSSRule::MEDIA_RULE
;
969 nsCSSMediaRule::Clone(nsICSSRule
*& aClone
) const
971 nsCSSMediaRule
* clone
= new nsCSSMediaRule(*this);
973 return CallQueryInterface(clone
, &aClone
);
976 return NS_ERROR_OUT_OF_MEMORY
;
980 nsCSSMediaRule::SetMedia(nsMediaList
* aMedia
)
984 mMedia
->SetStyleSheet(mSheet
);
988 // nsIDOMCSSRule methods
990 nsCSSMediaRule::GetType(PRUint16
* aType
)
992 *aType
= nsIDOMCSSRule::MEDIA_RULE
;
997 nsCSSMediaRule::GetCssText(nsAString
& aCssText
)
999 aCssText
.AssignLiteral("@media ");
1000 // get all the media
1002 nsAutoString mediaText
;
1003 mMedia
->GetText(mediaText
);
1004 aCssText
.Append(mediaText
);
1007 return nsCSSGroupRule::AppendRulesToCssText(aCssText
);
1011 nsCSSMediaRule::SetCssText(const nsAString
& aCssText
)
1013 return NS_ERROR_NOT_IMPLEMENTED
;
1017 nsCSSMediaRule::GetParentStyleSheet(nsIDOMCSSStyleSheet
** aSheet
)
1019 return nsCSSGroupRule::GetParentStyleSheet(aSheet
);
1023 nsCSSMediaRule::GetParentRule(nsIDOMCSSRule
** aParentRule
)
1025 return nsCSSGroupRule::GetParentRule(aParentRule
);
1028 // nsIDOMCSSMediaRule methods
1030 nsCSSMediaRule::GetMedia(nsIDOMMediaList
* *aMedia
)
1032 NS_ENSURE_ARG_POINTER(aMedia
);
1038 return CallQueryInterface(mMedia
.get(), aMedia
);
1042 nsCSSMediaRule::GetCssRules(nsIDOMCSSRuleList
* *aRuleList
)
1044 return nsCSSGroupRule::GetCssRules(aRuleList
);
1048 nsCSSMediaRule::InsertRule(const nsAString
& aRule
, PRUint32 aIndex
, PRUint32
* _retval
)
1050 return nsCSSGroupRule::InsertRule(aRule
, aIndex
, _retval
);
1054 nsCSSMediaRule::DeleteRule(PRUint32 aIndex
)
1056 return nsCSSGroupRule::DeleteRule(aIndex
);
1059 // nsICSSGroupRule interface
1060 NS_IMETHODIMP_(PRBool
)
1061 nsCSSMediaRule::UseForPresentation(nsPresContext
* aPresContext
,
1062 nsMediaQueryResultCacheKey
& aKey
)
1065 return mMedia
->Matches(aPresContext
, aKey
);
1071 nsCSSDocumentRule::nsCSSDocumentRule(void)
1075 nsCSSDocumentRule::nsCSSDocumentRule(const nsCSSDocumentRule
& aCopy
)
1076 : nsCSSGroupRule(aCopy
)
1077 , mURLs(new URL(*aCopy
.mURLs
))
1081 nsCSSDocumentRule::~nsCSSDocumentRule(void)
1085 NS_IMPL_ADDREF_INHERITED(nsCSSDocumentRule
, nsCSSRule
)
1086 NS_IMPL_RELEASE_INHERITED(nsCSSDocumentRule
, nsCSSRule
)
1088 // QueryInterface implementation for nsCSSDocumentRule
1089 NS_INTERFACE_MAP_BEGIN(nsCSSDocumentRule
)
1090 NS_INTERFACE_MAP_ENTRY(nsICSSGroupRule
)
1091 NS_INTERFACE_MAP_ENTRY(nsICSSRule
)
1092 NS_INTERFACE_MAP_ENTRY(nsIStyleRule
)
1093 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule
)
1094 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSMozDocumentRule
)
1095 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports
, nsCSSGroupRule
)
1096 NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(CSSMozDocumentRule
)
1097 NS_INTERFACE_MAP_END
1101 nsCSSDocumentRule::List(FILE* out
, PRInt32 aIndent
) const
1103 for (PRInt32 indent
= aIndent
; --indent
>= 0; ) fputs(" ", out
);
1106 str
.AssignLiteral("@-moz-document ");
1107 for (URL
*url
= mURLs
; url
; url
= url
->next
) {
1108 switch (url
->func
) {
1110 str
.AppendLiteral("url(\"");
1113 str
.AppendLiteral("url-prefix(\"");
1116 str
.AppendLiteral("domain(\"");
1119 nsCAutoString
escapedURL(url
->url
);
1120 escapedURL
.ReplaceSubstring("\"", "\\\""); // escape quotes
1121 str
.Append(escapedURL
);
1122 str
.AppendLiteral("\"), ");
1124 str
.Cut(str
.Length() - 2, 1); // remove last ,
1125 fputs(str
.get(), out
);
1127 return nsCSSGroupRule::List(out
, aIndent
);
1132 nsCSSDocumentRule::GetType(PRInt32
& aType
) const
1134 aType
= nsICSSRule::DOCUMENT_RULE
;
1139 nsCSSDocumentRule::Clone(nsICSSRule
*& aClone
) const
1141 nsCSSDocumentRule
* clone
= new nsCSSDocumentRule(*this);
1143 return CallQueryInterface(clone
, &aClone
);
1146 return NS_ERROR_OUT_OF_MEMORY
;
1149 // nsIDOMCSSRule methods
1151 nsCSSDocumentRule::GetType(PRUint16
* aType
)
1153 // XXX What should really happen here?
1154 *aType
= nsIDOMCSSRule::UNKNOWN_RULE
;
1159 nsCSSDocumentRule::GetCssText(nsAString
& aCssText
)
1161 aCssText
.AssignLiteral("@-moz-document ");
1162 for (URL
*url
= mURLs
; url
; url
= url
->next
) {
1163 switch (url
->func
) {
1165 aCssText
.AppendLiteral("url(\"");
1168 aCssText
.AppendLiteral("url-prefix(\"");
1171 aCssText
.AppendLiteral("domain(\"");
1174 nsCAutoString
escapedURL(url
->url
);
1175 escapedURL
.ReplaceSubstring("\"", "\\\""); // escape quotes
1176 AppendUTF8toUTF16(escapedURL
, aCssText
);
1177 aCssText
.AppendLiteral("\"), ");
1179 aCssText
.Cut(aCssText
.Length() - 2, 1); // remove last ,
1181 return nsCSSGroupRule::AppendRulesToCssText(aCssText
);
1185 nsCSSDocumentRule::SetCssText(const nsAString
& aCssText
)
1187 return NS_ERROR_NOT_IMPLEMENTED
;
1191 nsCSSDocumentRule::GetParentStyleSheet(nsIDOMCSSStyleSheet
** aSheet
)
1193 return nsCSSGroupRule::GetParentStyleSheet(aSheet
);
1197 nsCSSDocumentRule::GetParentRule(nsIDOMCSSRule
** aParentRule
)
1199 return nsCSSGroupRule::GetParentRule(aParentRule
);
1203 nsCSSDocumentRule::GetCssRules(nsIDOMCSSRuleList
* *aRuleList
)
1205 return nsCSSGroupRule::GetCssRules(aRuleList
);
1209 nsCSSDocumentRule::InsertRule(const nsAString
& aRule
, PRUint32 aIndex
, PRUint32
* _retval
)
1211 return nsCSSGroupRule::InsertRule(aRule
, aIndex
, _retval
);
1215 nsCSSDocumentRule::DeleteRule(PRUint32 aIndex
)
1217 return nsCSSGroupRule::DeleteRule(aIndex
);
1220 // nsICSSGroupRule interface
1221 NS_IMETHODIMP_(PRBool
)
1222 nsCSSDocumentRule::UseForPresentation(nsPresContext
* aPresContext
,
1223 nsMediaQueryResultCacheKey
& aKey
)
1225 nsIURI
*docURI
= aPresContext
->Document()->GetDocumentURI();
1226 nsCAutoString docURISpec
;
1228 docURI
->GetSpec(docURISpec
);
1230 for (URL
*url
= mURLs
; url
; url
= url
->next
) {
1231 switch (url
->func
) {
1233 if (docURISpec
== url
->url
)
1237 if (StringBeginsWith(docURISpec
, url
->url
))
1243 docURI
->GetHost(host
);
1244 PRInt32 lenDiff
= host
.Length() - url
->url
.Length();
1246 if (host
== url
->url
)
1249 if (StringEndsWith(host
, url
->url
) &&
1250 host
.CharAt(lenDiff
- 1) == '.')
1261 // -------------------------------------------
1262 // nsICSSNameSpaceRule
1264 class CSSNameSpaceRuleImpl
: public nsCSSRule
,
1265 public nsICSSNameSpaceRule
,
1266 public nsIDOMCSSRule
1269 CSSNameSpaceRuleImpl(void);
1270 CSSNameSpaceRuleImpl(const CSSNameSpaceRuleImpl
& aCopy
);
1271 virtual ~CSSNameSpaceRuleImpl(void);
1273 NS_DECL_ISUPPORTS_INHERITED
1275 DECL_STYLE_RULE_INHERIT
1277 // nsIStyleRule methods
1279 NS_IMETHOD
List(FILE* out
= stdout
, PRInt32 aIndent
= 0) const;
1282 // nsICSSRule methods
1283 NS_IMETHOD
GetType(PRInt32
& aType
) const;
1284 NS_IMETHOD
Clone(nsICSSRule
*& aClone
) const;
1286 // nsICSSNameSpaceRule methods
1287 NS_IMETHOD
GetPrefix(nsIAtom
*& aPrefix
) const;
1288 NS_IMETHOD
SetPrefix(nsIAtom
* aPrefix
);
1290 NS_IMETHOD
GetURLSpec(nsString
& aURLSpec
) const;
1291 NS_IMETHOD
SetURLSpec(const nsString
& aURLSpec
);
1293 // nsIDOMCSSRule interface
1294 NS_DECL_NSIDOMCSSRULE
1301 CSSNameSpaceRuleImpl::CSSNameSpaceRuleImpl(void)
1308 CSSNameSpaceRuleImpl::CSSNameSpaceRuleImpl(const CSSNameSpaceRuleImpl
& aCopy
)
1310 mPrefix(aCopy
.mPrefix
),
1311 mURLSpec(aCopy
.mURLSpec
)
1313 NS_IF_ADDREF(mPrefix
);
1316 CSSNameSpaceRuleImpl::~CSSNameSpaceRuleImpl(void)
1318 NS_IF_RELEASE(mPrefix
);
1321 NS_IMPL_ADDREF_INHERITED(CSSNameSpaceRuleImpl
, nsCSSRule
)
1322 NS_IMPL_RELEASE_INHERITED(CSSNameSpaceRuleImpl
, nsCSSRule
)
1324 // QueryInterface implementation for CSSNameSpaceRuleImpl
1325 NS_INTERFACE_MAP_BEGIN(CSSNameSpaceRuleImpl
)
1326 NS_INTERFACE_MAP_ENTRY(nsICSSNameSpaceRule
)
1327 NS_INTERFACE_MAP_ENTRY(nsICSSRule
)
1328 NS_INTERFACE_MAP_ENTRY(nsIStyleRule
)
1329 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule
)
1330 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports
, nsICSSNameSpaceRule
)
1331 NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(CSSNameSpaceRule
)
1332 NS_INTERFACE_MAP_END
1334 IMPL_STYLE_RULE_INHERIT(CSSNameSpaceRuleImpl
, nsCSSRule
)
1338 CSSNameSpaceRuleImpl::List(FILE* out
, PRInt32 aIndent
) const
1340 for (PRInt32 indent
= aIndent
; --indent
>= 0; ) fputs(" ", out
);
1342 nsAutoString buffer
;
1344 fputs("@namespace ", out
);
1347 mPrefix
->ToString(buffer
);
1348 fputs(NS_LossyConvertUTF16toASCII(buffer
).get(), out
);
1353 fputs(NS_LossyConvertUTF16toASCII(mURLSpec
).get(), out
);
1360 CSSNameSpaceRuleImpl::GetType(PRInt32
& aType
) const
1362 aType
= nsICSSRule::NAMESPACE_RULE
;
1367 CSSNameSpaceRuleImpl::Clone(nsICSSRule
*& aClone
) const
1369 CSSNameSpaceRuleImpl
* clone
= new CSSNameSpaceRuleImpl(*this);
1371 return CallQueryInterface(clone
, &aClone
);
1374 return NS_ERROR_OUT_OF_MEMORY
;
1378 CSSNameSpaceRuleImpl::GetPrefix(nsIAtom
*& aPrefix
) const
1381 NS_IF_ADDREF(aPrefix
);
1386 CSSNameSpaceRuleImpl::SetPrefix(nsIAtom
* aPrefix
)
1388 NS_IF_RELEASE(mPrefix
);
1390 NS_IF_ADDREF(mPrefix
);
1395 CSSNameSpaceRuleImpl::GetURLSpec(nsString
& aURLSpec
) const
1397 aURLSpec
= mURLSpec
;
1402 CSSNameSpaceRuleImpl::SetURLSpec(const nsString
& aURLSpec
)
1404 mURLSpec
= aURLSpec
;
1409 NS_NewCSSNameSpaceRule(nsICSSNameSpaceRule
** aInstancePtrResult
,
1410 nsIAtom
* aPrefix
, const nsString
& aURLSpec
)
1412 if (! aInstancePtrResult
) {
1413 return NS_ERROR_NULL_POINTER
;
1416 CSSNameSpaceRuleImpl
* it
= new CSSNameSpaceRuleImpl();
1419 return NS_ERROR_OUT_OF_MEMORY
;
1422 it
->SetPrefix(aPrefix
);
1423 it
->SetURLSpec(aURLSpec
);
1424 return CallQueryInterface(it
, aInstancePtrResult
);
1428 CSSNameSpaceRuleImpl::GetType(PRUint16
* aType
)
1430 // XXX What should really happen here?
1431 *aType
= nsIDOMCSSRule::UNKNOWN_RULE
;
1436 CSSNameSpaceRuleImpl::GetCssText(nsAString
& aCssText
)
1438 aCssText
.AssignLiteral("@namespace ");
1441 mPrefix
->ToString(atomStr
);
1442 aCssText
.Append(atomStr
);
1443 aCssText
.AppendLiteral(" ");
1445 aCssText
.AppendLiteral("url(");
1446 aCssText
.Append(mURLSpec
);
1447 aCssText
.Append(NS_LITERAL_STRING(");"));
1452 CSSNameSpaceRuleImpl::SetCssText(const nsAString
& aCssText
)
1454 return NS_ERROR_NOT_IMPLEMENTED
;
1458 CSSNameSpaceRuleImpl::GetParentStyleSheet(nsIDOMCSSStyleSheet
** aSheet
)
1461 return CallQueryInterface(mSheet
, aSheet
);
1468 CSSNameSpaceRuleImpl::GetParentRule(nsIDOMCSSRule
** aParentRule
)
1471 return mParentRule
->GetDOMRule(aParentRule
);
1473 *aParentRule
= nsnull
;
1477 // -------------------------------------------
1478 // nsCSSFontFaceStyleDecl and related routines
1481 // A src: descriptor is represented as an array value; each entry in
1482 // the array can be eCSSUnit_URL, eCSSUnit_Local_Font, or
1483 // eCSSUnit_Font_Format. Blocks of eCSSUnit_Font_Format may appear
1484 // only after one of the first two. (css3-fonts only contemplates
1485 // annotating URLs with formats, but we handle the general case.)
1487 SerializeFontSrc(const nsCSSValue
& src
, nsAString
& aResult NS_OUTPARAM
)
1489 NS_PRECONDITION(src
.GetUnit() == eCSSUnit_Null
||
1490 src
.GetUnit() == eCSSUnit_Array
,
1491 "improper value unit for src:");
1493 if (src
.GetUnit() != eCSSUnit_Array
)
1496 const nsCSSValue::Array
& sources
= *src
.GetArrayValue();
1499 while (i
< sources
.Count()) {
1500 nsAutoString formats
;
1502 if (sources
[i
].GetUnit() == eCSSUnit_URL
) {
1503 nsDependentString
url(sources
[i
].GetOriginalURLValue());
1504 nsAutoString escapedUrl
;
1505 nsStyleUtil::EscapeCSSString(url
, escapedUrl
);
1506 aResult
.AppendLiteral("url(\"");
1507 aResult
.Append(escapedUrl
);
1508 aResult
.AppendLiteral("\")");
1509 } else if (sources
[i
].GetUnit() == eCSSUnit_Local_Font
) {
1510 nsDependentString
local(sources
[i
].GetStringBufferValue());
1511 nsAutoString escapedLocal
;
1512 nsStyleUtil::EscapeCSSString(local
, escapedLocal
);
1513 aResult
.AppendLiteral("local(\"");
1514 aResult
.Append(escapedLocal
);
1515 aResult
.AppendLiteral("\")");
1517 NS_NOTREACHED("entry in src: descriptor with improper unit");
1524 while (i
< sources
.Count() &&
1525 sources
[i
].GetUnit() == eCSSUnit_Font_Format
) {
1526 formats
.Append('"');
1527 formats
.Append(sources
[i
].GetStringBufferValue());
1528 formats
.AppendLiteral("\", ");
1531 if (formats
.Length() > 0) {
1532 formats
.Truncate(formats
.Length() - 2); // remove the last comma
1533 aResult
.AppendLiteral(" format(");
1534 aResult
.Append(formats
);
1535 aResult
.Append(')');
1537 aResult
.AppendLiteral(", ");
1539 aResult
.Truncate(aResult
.Length() - 2); // remove the last comma-space
1542 // Mapping from nsCSSFontDesc codes to nsCSSFontFaceStyleDecl fields.
1543 // Keep this in sync with enum nsCSSFontDesc in nsCSSProperty.h.
1544 nsCSSValue
nsCSSFontFaceStyleDecl::* const
1545 nsCSSFontFaceStyleDecl::Fields
[] = {
1546 &nsCSSFontFaceStyleDecl::mFamily
,
1547 &nsCSSFontFaceStyleDecl::mStyle
,
1548 &nsCSSFontFaceStyleDecl::mWeight
,
1549 &nsCSSFontFaceStyleDecl::mStretch
,
1550 &nsCSSFontFaceStyleDecl::mSrc
,
1551 &nsCSSFontFaceStyleDecl::mUnicodeRange
1554 // QueryInterface implementation for nsCSSFontFaceStyleDecl
1555 NS_INTERFACE_MAP_BEGIN(nsCSSFontFaceStyleDecl
)
1556 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSStyleDeclaration
)
1557 NS_INTERFACE_MAP_ENTRY(nsISupports
)
1558 NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(CSSFontFaceStyleDecl
)
1559 NS_INTERFACE_MAP_END
1561 NS_IMPL_ADDREF_USING_AGGREGATOR(nsCSSFontFaceStyleDecl
, ContainingRule())
1562 NS_IMPL_RELEASE_USING_AGGREGATOR(nsCSSFontFaceStyleDecl
, ContainingRule())
1564 // helper for string GetPropertyValue and RemovePropertyValue
1566 nsCSSFontFaceStyleDecl::GetPropertyValue(nsCSSFontDesc aFontDescID
,
1567 nsAString
& aResult NS_OUTPARAM
) const
1569 NS_ENSURE_ARG_RANGE(aFontDescID
, eCSSFontDesc_UNKNOWN
,
1570 eCSSFontDesc_COUNT
- 1);
1573 if (aFontDescID
== eCSSFontDesc_UNKNOWN
)
1576 const nsCSSValue
& val
= this->*nsCSSFontFaceStyleDecl::Fields
[aFontDescID
];
1578 switch (aFontDescID
) {
1579 case eCSSFontDesc_Family
: {
1580 // we don't use AppendCSSValueToString here because it doesn't
1581 // canonicalize the way we want, and anyway it's overkill when
1582 // we know we have eCSSUnit_String
1583 nsDependentString
family(val
.GetStringBufferValue());
1584 nsAutoString escapedFamily
;
1585 nsStyleUtil::EscapeCSSString(family
, escapedFamily
);
1586 aResult
.Append('"');
1587 aResult
.Append(escapedFamily
);
1588 aResult
.Append('"');
1592 case eCSSFontDesc_Style
:
1593 nsCSSDeclaration::AppendCSSValueToString(eCSSProperty_font_style
, val
,
1597 case eCSSFontDesc_Weight
:
1598 nsCSSDeclaration::AppendCSSValueToString(eCSSProperty_font_weight
, val
,
1602 case eCSSFontDesc_Stretch
:
1603 nsCSSDeclaration::AppendCSSValueToString(eCSSProperty_font_stretch
, val
,
1607 case eCSSFontDesc_Src
:
1608 SerializeFontSrc(val
, aResult
);
1611 case eCSSFontDesc_UnicodeRange
:
1612 // these are not implemented, so always return an empty string
1615 case eCSSFontDesc_UNKNOWN
:
1616 case eCSSFontDesc_COUNT
:
1619 NS_NOTREACHED("nsCSSFontFaceStyleDecl::GetPropertyValue: "
1620 "out-of-range value got to the switch");
1621 return NS_ERROR_INVALID_ARG
;
1625 // attribute DOMString cssText;
1627 nsCSSFontFaceStyleDecl::GetCssText(nsAString
& aCssText
)
1629 nsAutoString descStr
;
1631 aCssText
.Truncate();
1632 for (nsCSSFontDesc id
= nsCSSFontDesc(eCSSFontDesc_UNKNOWN
+ 1);
1633 id
< eCSSFontDesc_COUNT
;
1634 id
= nsCSSFontDesc(id
+ 1)) {
1635 if ((this->*nsCSSFontFaceStyleDecl::Fields
[id
]).GetUnit()
1637 NS_SUCCEEDED(GetPropertyValue(id
, descStr
))) {
1638 NS_ASSERTION(descStr
.Length() > 0,
1639 "GetCssText: non-null unit, empty property value");
1640 aCssText
.AppendLiteral(" ");
1641 aCssText
.AppendASCII(nsCSSProps::GetStringValue(id
).get());
1642 aCssText
.AppendLiteral(": ");
1643 aCssText
.Append(descStr
);
1644 aCssText
.AppendLiteral(";\n");
1651 nsCSSFontFaceStyleDecl::SetCssText(const nsAString
& aCssText
)
1653 return NS_ERROR_NOT_IMPLEMENTED
; // bug 443978
1656 // DOMString getPropertyValue (in DOMString propertyName);
1658 nsCSSFontFaceStyleDecl::GetPropertyValue(const nsAString
& propertyName
,
1659 nsAString
& aResult NS_OUTPARAM
)
1661 return GetPropertyValue(nsCSSProps::LookupFontDesc(propertyName
), aResult
);
1664 // nsIDOMCSSValue getPropertyCSSValue (in DOMString propertyName);
1666 nsCSSFontFaceStyleDecl::GetPropertyCSSValue(const nsAString
& propertyName
,
1667 nsIDOMCSSValue
**aResult NS_OUTPARAM
)
1669 // ??? nsDOMCSSDeclaration returns null/NS_OK, but that seems wrong.
1670 return NS_ERROR_NOT_IMPLEMENTED
;
1673 // DOMString removeProperty (in DOMString propertyName) raises (DOMException);
1675 nsCSSFontFaceStyleDecl::RemoveProperty(const nsAString
& propertyName
,
1676 nsAString
& aResult NS_OUTPARAM
)
1678 nsCSSFontDesc descID
= nsCSSProps::LookupFontDesc(propertyName
);
1679 NS_ASSERTION(descID
>= eCSSFontDesc_UNKNOWN
&&
1680 descID
< eCSSFontDesc_COUNT
,
1681 "LookupFontDesc returned value out of range");
1683 if (descID
== eCSSFontDesc_UNKNOWN
) {
1686 nsresult rv
= GetPropertyValue(descID
, aResult
);
1687 NS_ENSURE_SUCCESS(rv
, rv
);
1688 (this->*nsCSSFontFaceStyleDecl::Fields
[descID
]).Reset();
1693 // DOMString getPropertyPriority (in DOMString propertyName);
1695 nsCSSFontFaceStyleDecl::GetPropertyPriority(const nsAString
& propertyName
,
1696 nsAString
& aResult NS_OUTPARAM
)
1698 // font descriptors do not have priorities at present
1703 // void setProperty (in DOMString propertyName, in DOMString value,
1704 // in DOMString priority) raises (DOMException);
1706 nsCSSFontFaceStyleDecl::SetProperty(const nsAString
& propertyName
,
1707 const nsAString
& value
,
1708 const nsAString
& priority
)
1710 return NS_ERROR_NOT_IMPLEMENTED
; // bug 443978
1713 // readonly attribute unsigned long length;
1715 nsCSSFontFaceStyleDecl::GetLength(PRUint32
*aLength
)
1718 for (nsCSSFontDesc id
= nsCSSFontDesc(eCSSFontDesc_UNKNOWN
+ 1);
1719 id
< eCSSFontDesc_COUNT
;
1720 id
= nsCSSFontDesc(id
+ 1))
1721 if ((this->*nsCSSFontFaceStyleDecl::Fields
[id
]).GetUnit() != eCSSUnit_Null
)
1728 // DOMString item (in unsigned long index);
1730 nsCSSFontFaceStyleDecl::Item(PRUint32 index
, nsAString
& aResult NS_OUTPARAM
)
1733 for (nsCSSFontDesc id
= nsCSSFontDesc(eCSSFontDesc_UNKNOWN
+ 1);
1734 id
< eCSSFontDesc_COUNT
;
1735 id
= nsCSSFontDesc(id
+ 1)) {
1736 if ((this->*nsCSSFontFaceStyleDecl::Fields
[id
]).GetUnit()
1739 if (nset
== PRInt32(index
)) {
1740 aResult
.AssignASCII(nsCSSProps::GetStringValue(id
).get());
1749 // readonly attribute nsIDOMCSSRule parentRule;
1751 nsCSSFontFaceStyleDecl::GetParentRule(nsIDOMCSSRule
** aParentRule
)
1753 return ContainingRule()->GetDOMRule(aParentRule
);
1757 // -------------------------------------------
1758 // nsCSSFontFaceRule
1762 nsCSSFontFaceRule::Clone(nsICSSRule
*& aClone
) const
1764 nsCSSFontFaceRule
* clone
= new nsCSSFontFaceRule(*this);
1766 return CallQueryInterface(clone
, &aClone
);
1769 return NS_ERROR_OUT_OF_MEMORY
;
1772 NS_IMPL_ADDREF_INHERITED(nsCSSFontFaceRule
, nsCSSRule
)
1773 NS_IMPL_RELEASE_INHERITED(nsCSSFontFaceRule
, nsCSSRule
)
1775 // QueryInterface implementation for nsCSSFontFaceRule
1776 NS_INTERFACE_MAP_BEGIN(nsCSSFontFaceRule
)
1777 NS_INTERFACE_MAP_ENTRY(nsICSSRule
)
1778 NS_INTERFACE_MAP_ENTRY(nsIStyleRule
)
1779 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSFontFaceRule
)
1780 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule
)
1781 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports
, nsICSSRule
)
1782 NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(CSSFontFaceRule
)
1783 NS_INTERFACE_MAP_END
1785 IMPL_STYLE_RULE_INHERIT(nsCSSFontFaceRule
, nsCSSRule
)
1789 nsCSSFontFaceRule::List(FILE* out
, PRInt32 aIndent
) const
1791 nsCString baseInd
, descInd
;
1792 for (PRInt32 indent
= aIndent
; --indent
>= 0; ) {
1793 baseInd
.AppendLiteral(" ");
1794 descInd
.AppendLiteral(" ");
1796 descInd
.AppendLiteral(" ");
1800 fprintf(out
, "%s@font-face {\n", baseInd
.get());
1801 for (nsCSSFontDesc id
= nsCSSFontDesc(eCSSFontDesc_UNKNOWN
+ 1);
1802 id
< eCSSFontDesc_COUNT
;
1803 id
= nsCSSFontDesc(id
+ 1))
1804 if ((mDecl
.*nsCSSFontFaceStyleDecl::Fields
[id
]).GetUnit()
1806 if (NS_FAILED(mDecl
.GetPropertyValue(id
, descStr
)))
1807 descStr
.AssignLiteral("#<serialization error>");
1808 else if (descStr
.Length() == 0)
1809 descStr
.AssignLiteral("#<serialization missing>");
1810 fprintf(out
, "%s%s: %s\n",
1811 descInd
.get(), nsCSSProps::GetStringValue(id
).get(),
1812 NS_ConvertUTF16toUTF8(descStr
).get());
1814 fprintf(out
, "%s}\n", baseInd
.get());
1820 nsCSSFontFaceRule::GetType(PRInt32
& aType
) const
1822 aType
= nsICSSRule::FONT_FACE_RULE
;
1827 nsCSSFontFaceRule::GetType(PRUint16
* aType
)
1829 *aType
= nsIDOMCSSRule::FONT_FACE_RULE
;
1834 nsCSSFontFaceRule::GetCssText(nsAString
& aCssText
)
1836 nsAutoString propText
;
1837 mDecl
.GetCssText(propText
);
1839 aCssText
.AssignLiteral("@font-face {\n");
1840 aCssText
.Append(propText
);
1841 aCssText
.Append('}');
1846 nsCSSFontFaceRule::SetCssText(const nsAString
& aCssText
)
1848 return NS_ERROR_NOT_IMPLEMENTED
; // bug 443978
1852 nsCSSFontFaceRule::GetParentStyleSheet(nsIDOMCSSStyleSheet
** aSheet
)
1855 return CallQueryInterface(mSheet
, aSheet
);
1862 nsCSSFontFaceRule::GetParentRule(nsIDOMCSSRule
** aParentRule
)
1865 return mParentRule
->GetDOMRule(aParentRule
);
1867 *aParentRule
= nsnull
;
1872 nsCSSFontFaceRule::GetStyle(nsIDOMCSSStyleDeclaration
** aStyle
)
1874 return CallQueryInterface(&mDecl
, aStyle
);
1877 // Arguably these should forward to nsCSSFontFaceStyleDecl methods.
1879 nsCSSFontFaceRule::SetDesc(nsCSSFontDesc aDescID
, nsCSSValue
const & aValue
)
1881 NS_PRECONDITION(aDescID
> eCSSFontDesc_UNKNOWN
&&
1882 aDescID
< eCSSFontDesc_COUNT
,
1883 "aDescID out of range in nsCSSFontFaceRule::SetDesc");
1885 mDecl
.*nsCSSFontFaceStyleDecl::Fields
[aDescID
] = aValue
;
1889 nsCSSFontFaceRule::GetDesc(nsCSSFontDesc aDescID
, nsCSSValue
& aValue
)
1891 NS_PRECONDITION(aDescID
> eCSSFontDesc_UNKNOWN
&&
1892 aDescID
< eCSSFontDesc_COUNT
,
1893 "aDescID out of range in nsCSSFontFaceRule::GetDesc");
1895 aValue
= mDecl
.*nsCSSFontFaceStyleDecl::Fields
[aDescID
];