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 "nsCSSStyleSheet.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 "mozilla/css/Declaration.h"
74 #include "nsPrintfCString.h"
76 #define IMPL_STYLE_RULE_INHERIT(_class, super) \
77 /* virtual */ already_AddRefed<nsIStyleSheet> _class::GetStyleSheet() const { return super::GetStyleSheet(); } \
78 /* virtual */ void _class::SetStyleSheet(nsCSSStyleSheet* aSheet) { super::SetStyleSheet(aSheet); } \
79 /* virtual */ void _class::SetParentRule(nsICSSGroupRule* aRule) { super::SetParentRule(aRule); } \
80 nsIDOMCSSRule* _class::GetDOMRuleWeak(nsresult *aResult) { *aResult = NS_OK; return this; } \
81 /* virtual */ void _class::MapRuleInfoInto(nsRuleData* aRuleData) { }
83 #define IMPL_STYLE_RULE_INHERIT2(_class, super) \
84 /* virtual */ already_AddRefed<nsIStyleSheet> _class::GetStyleSheet() const { return super::GetStyleSheet(); } \
85 /* virtual */ void _class::SetParentRule(nsICSSGroupRule* aRule) { super::SetParentRule(aRule); } \
86 /* virtual */ void _class::MapRuleInfoInto(nsRuleData* aRuleData) { }
88 // -------------------------------
89 // Style Rule List for group rules
91 class CSSGroupRuleRuleListImpl
: public nsICSSRuleList
94 CSSGroupRuleRuleListImpl(nsICSSGroupRule
*aGroupRule
);
98 NS_DECL_NSIDOMCSSRULELIST
100 virtual nsIDOMCSSRule
* GetItemAt(PRUint32 aIndex
, nsresult
* aResult
);
102 void DropReference() { mGroupRule
= nsnull
; }
105 virtual ~CSSGroupRuleRuleListImpl(void);
108 nsICSSGroupRule
* mGroupRule
;
111 CSSGroupRuleRuleListImpl::CSSGroupRuleRuleListImpl(nsICSSGroupRule
*aGroupRule
)
113 // Not reference counted to avoid circular references.
114 // The rule will tell us when its going away.
115 mGroupRule
= aGroupRule
;
118 CSSGroupRuleRuleListImpl::~CSSGroupRuleRuleListImpl()
122 DOMCI_DATA(CSSGroupRuleRuleList
, CSSGroupRuleRuleListImpl
)
124 // QueryInterface implementation for CSSGroupRuleRuleList
125 NS_INTERFACE_MAP_BEGIN(CSSGroupRuleRuleListImpl
)
126 NS_INTERFACE_MAP_ENTRY(nsICSSRuleList
)
127 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRuleList
)
128 NS_INTERFACE_MAP_ENTRY(nsISupports
)
129 NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSGroupRuleRuleList
)
133 NS_IMPL_ADDREF(CSSGroupRuleRuleListImpl
)
134 NS_IMPL_RELEASE(CSSGroupRuleRuleListImpl
)
137 CSSGroupRuleRuleListImpl::GetLength(PRUint32
* aLength
)
141 mGroupRule
->StyleRuleCount(count
);
142 *aLength
= (PRUint32
)count
;
151 CSSGroupRuleRuleListImpl::GetItemAt(PRUint32 aIndex
, nsresult
* aResult
)
153 nsresult result
= NS_OK
;
156 nsCOMPtr
<nsICSSRule
> rule
;
158 result
= mGroupRule
->GetStyleRuleAt(aIndex
, *getter_AddRefs(rule
));
160 return rule
->GetDOMRuleWeak(aResult
);
162 if (result
== NS_ERROR_ILLEGAL_VALUE
) {
163 result
= NS_OK
; // per spec: "Return Value ... null if ... not a valid index."
173 CSSGroupRuleRuleListImpl::Item(PRUint32 aIndex
, nsIDOMCSSRule
** aReturn
)
176 nsIDOMCSSRule
* rule
= GetItemAt(aIndex
, &rv
);
182 NS_ADDREF(*aReturn
= rule
);
186 // -------------------------------------------
189 class NS_FINAL_CLASS CSSCharsetRuleImpl
: public nsCSSRule
,
191 public nsIDOMCSSCharsetRule
194 CSSCharsetRuleImpl(const nsAString
& aEncoding
);
195 CSSCharsetRuleImpl(const CSSCharsetRuleImpl
& aCopy
);
197 ~CSSCharsetRuleImpl() {}
201 DECL_STYLE_RULE_INHERIT
203 // nsIStyleRule methods
205 virtual void List(FILE* out
= stdout
, PRInt32 aIndent
= 0) const;
208 // nsICSSRule methods
209 virtual PRInt32
GetType() const;
210 virtual already_AddRefed
<nsICSSRule
> Clone() const;
212 // nsIDOMCSSRule interface
213 NS_DECL_NSIDOMCSSRULE
215 // nsIDOMCSSCharsetRule methods
216 NS_IMETHOD
GetEncoding(nsAString
& aEncoding
);
217 NS_IMETHOD
SetEncoding(const nsAString
& aEncoding
);
223 CSSCharsetRuleImpl::CSSCharsetRuleImpl(const nsAString
& aEncoding
)
229 CSSCharsetRuleImpl::CSSCharsetRuleImpl(const CSSCharsetRuleImpl
& aCopy
)
231 mEncoding(aCopy
.mEncoding
)
235 NS_IMPL_ADDREF(CSSCharsetRuleImpl
)
236 NS_IMPL_RELEASE(CSSCharsetRuleImpl
)
238 DOMCI_DATA(CSSCharsetRule
, CSSCharsetRuleImpl
)
240 // QueryInterface implementation for CSSCharsetRuleImpl
241 NS_INTERFACE_MAP_BEGIN(CSSCharsetRuleImpl
)
242 NS_INTERFACE_MAP_ENTRY(nsICSSRule
)
243 NS_INTERFACE_MAP_ENTRY(nsIStyleRule
)
244 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule
)
245 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSCharsetRule
)
246 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports
, nsICSSRule
)
247 NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSCharsetRule
)
250 IMPL_STYLE_RULE_INHERIT(CSSCharsetRuleImpl
, nsCSSRule
)
254 CSSCharsetRuleImpl::List(FILE* out
, PRInt32 aIndent
) const
257 for (PRInt32 indent
= aIndent
; --indent
>= 0; ) fputs(" ", out
);
259 fputs("@charset \"", out
);
260 fputs(NS_LossyConvertUTF16toASCII(mEncoding
).get(), out
);
265 /* virtual */ PRInt32
266 CSSCharsetRuleImpl::GetType() const
268 return nsICSSRule::CHARSET_RULE
;
271 /* virtual */ already_AddRefed
<nsICSSRule
>
272 CSSCharsetRuleImpl::Clone() const
274 nsCOMPtr
<nsICSSRule
> clone
= new CSSCharsetRuleImpl(*this);
275 return clone
.forget();
279 CSSCharsetRuleImpl::GetEncoding(nsAString
& aEncoding
)
281 aEncoding
= mEncoding
;
286 CSSCharsetRuleImpl::SetEncoding(const nsAString
& aEncoding
)
288 mEncoding
= aEncoding
;
294 NS_NewCSSCharsetRule(nsICSSRule
** aInstancePtrResult
, const nsAString
& aEncoding
)
296 if (! aInstancePtrResult
) {
297 return NS_ERROR_NULL_POINTER
;
300 CSSCharsetRuleImpl
* it
= new CSSCharsetRuleImpl(aEncoding
);
303 return NS_ERROR_OUT_OF_MEMORY
;
306 NS_ADDREF(*aInstancePtrResult
= it
);
311 CSSCharsetRuleImpl::GetType(PRUint16
* aType
)
313 *aType
= nsIDOMCSSRule::CHARSET_RULE
;
318 CSSCharsetRuleImpl::GetCssText(nsAString
& aCssText
)
320 aCssText
.AssignLiteral("@charset \"");
321 aCssText
.Append(mEncoding
);
322 aCssText
.AppendLiteral("\";");
327 CSSCharsetRuleImpl::SetCssText(const nsAString
& aCssText
)
329 return NS_ERROR_NOT_IMPLEMENTED
;
333 CSSCharsetRuleImpl::GetParentStyleSheet(nsIDOMCSSStyleSheet
** aSheet
)
335 NS_ENSURE_ARG_POINTER(aSheet
);
337 NS_IF_ADDREF(*aSheet
= mSheet
);
342 CSSCharsetRuleImpl::GetParentRule(nsIDOMCSSRule
** aParentRule
)
345 return mParentRule
->GetDOMRule(aParentRule
);
347 *aParentRule
= nsnull
;
353 // -------------------------------------------
356 class NS_FINAL_CLASS CSSImportRuleImpl
: public nsCSSRule
,
357 public nsICSSImportRule
,
358 public nsIDOMCSSImportRule
361 CSSImportRuleImpl(nsMediaList
* aMedia
);
362 CSSImportRuleImpl(const CSSImportRuleImpl
& aCopy
);
364 ~CSSImportRuleImpl();
369 DECL_STYLE_RULE_INHERIT
371 // nsIStyleRule methods
373 virtual void List(FILE* out
= stdout
, PRInt32 aIndent
= 0) const;
376 // nsICSSRule methods
377 virtual PRInt32
GetType() const;
378 virtual already_AddRefed
<nsICSSRule
> Clone() const;
380 // nsICSSImportRule methods
381 NS_IMETHOD
SetURLSpec(const nsString
& aURLSpec
);
382 NS_IMETHOD
GetURLSpec(nsString
& aURLSpec
) const;
384 NS_IMETHOD
SetMedia(const nsString
& aMedia
);
385 NS_IMETHOD
GetMedia(nsString
& aMedia
) const;
387 NS_IMETHOD
SetSheet(nsCSSStyleSheet
*);
389 // nsIDOMCSSRule interface
390 NS_DECL_NSIDOMCSSRULE
392 // nsIDOMCSSImportRule interface
393 NS_DECL_NSIDOMCSSIMPORTRULE
397 nsRefPtr
<nsMediaList
> mMedia
;
398 nsRefPtr
<nsCSSStyleSheet
> mChildSheet
;
401 CSSImportRuleImpl::CSSImportRuleImpl(nsMediaList
* aMedia
)
406 // XXXbz This is really silly.... the mMedia here will be replaced
407 // with itself if we manage to load a sheet. Which should really
408 // never fail nowadays, in sane cases.
411 CSSImportRuleImpl::CSSImportRuleImpl(const CSSImportRuleImpl
& aCopy
)
413 mURLSpec(aCopy
.mURLSpec
)
415 nsRefPtr
<nsCSSStyleSheet
> sheet
;
416 if (aCopy
.mChildSheet
) {
417 sheet
= aCopy
.mChildSheet
->Clone(nsnull
, this, nsnull
, nsnull
);
420 // SetSheet sets mMedia appropriately
423 CSSImportRuleImpl::~CSSImportRuleImpl()
426 mChildSheet
->SetOwnerRule(nsnull
);
430 NS_IMPL_ADDREF(CSSImportRuleImpl
)
431 NS_IMPL_RELEASE(CSSImportRuleImpl
)
433 DOMCI_DATA(CSSImportRule
, CSSImportRuleImpl
)
435 // QueryInterface implementation for CSSImportRuleImpl
436 NS_INTERFACE_MAP_BEGIN(CSSImportRuleImpl
)
437 NS_INTERFACE_MAP_ENTRY(nsICSSImportRule
)
438 NS_INTERFACE_MAP_ENTRY(nsICSSRule
)
439 NS_INTERFACE_MAP_ENTRY(nsIStyleRule
)
440 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule
)
441 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSImportRule
)
442 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports
, nsICSSImportRule
)
443 NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSImportRule
)
446 IMPL_STYLE_RULE_INHERIT(CSSImportRuleImpl
, nsCSSRule
)
450 CSSImportRuleImpl::List(FILE* out
, PRInt32 aIndent
) const
453 for (PRInt32 indent
= aIndent
; --indent
>= 0; ) fputs(" ", out
);
455 fputs("@import \"", out
);
456 fputs(NS_LossyConvertUTF16toASCII(mURLSpec
).get(), out
);
459 nsAutoString mediaText
;
460 mMedia
->GetText(mediaText
);
461 fputs(NS_LossyConvertUTF16toASCII(mediaText
).get(), out
);
466 /* virtual */ PRInt32
467 CSSImportRuleImpl::GetType() const
469 return nsICSSRule::IMPORT_RULE
;
472 /* virtual */ already_AddRefed
<nsICSSRule
>
473 CSSImportRuleImpl::Clone() const
475 nsCOMPtr
<nsICSSRule
> clone
= new CSSImportRuleImpl(*this);
476 return clone
.forget();
480 CSSImportRuleImpl::SetURLSpec(const nsString
& aURLSpec
)
487 CSSImportRuleImpl::GetURLSpec(nsString
& aURLSpec
) const
494 CSSImportRuleImpl::SetMedia(const nsString
& aMedia
)
497 return mMedia
->SetText(aMedia
);
504 CSSImportRuleImpl::GetMedia(nsString
& aMedia
) const
507 return mMedia
->GetText(aMedia
);
515 CSSImportRuleImpl::SetSheet(nsCSSStyleSheet
* aSheet
)
518 NS_ENSURE_ARG_POINTER(aSheet
);
521 mChildSheet
= aSheet
;
522 aSheet
->SetOwnerRule(this);
524 // set our medialist to be the same as the sheet's medialist
525 nsCOMPtr
<nsIDOMMediaList
> mediaList
;
526 rv
= mChildSheet
->GetMedia(getter_AddRefs(mediaList
));
527 NS_ENSURE_SUCCESS(rv
, rv
);
528 mMedia
= static_cast<nsMediaList
*>(mediaList
.get());
534 NS_NewCSSImportRule(nsICSSImportRule
** aInstancePtrResult
,
535 const nsString
& aURLSpec
,
538 NS_ENSURE_ARG_POINTER(aInstancePtrResult
);
540 CSSImportRuleImpl
* it
= new CSSImportRuleImpl(aMedia
);
543 return NS_ERROR_OUT_OF_MEMORY
;
546 it
->SetURLSpec(aURLSpec
);
547 NS_ADDREF(*aInstancePtrResult
= it
);
552 CSSImportRuleImpl::GetType(PRUint16
* aType
)
554 NS_ENSURE_ARG_POINTER(aType
);
555 *aType
= nsIDOMCSSRule::IMPORT_RULE
;
560 CSSImportRuleImpl::GetCssText(nsAString
& aCssText
)
562 aCssText
.AssignLiteral("@import url(");
563 nsStyleUtil::AppendEscapedCSSString(mURLSpec
, aCssText
);
564 aCssText
.Append(NS_LITERAL_STRING(")"));
566 nsAutoString mediaText
;
567 mMedia
->GetText(mediaText
);
568 if (!mediaText
.IsEmpty()) {
569 aCssText
.AppendLiteral(" ");
570 aCssText
.Append(mediaText
);
573 aCssText
.AppendLiteral(";");
578 CSSImportRuleImpl::SetCssText(const nsAString
& aCssText
)
580 return NS_ERROR_NOT_IMPLEMENTED
;
584 CSSImportRuleImpl::GetParentStyleSheet(nsIDOMCSSStyleSheet
** aSheet
)
586 NS_ENSURE_ARG_POINTER(aSheet
);
588 NS_IF_ADDREF(*aSheet
= mSheet
);
593 CSSImportRuleImpl::GetParentRule(nsIDOMCSSRule
** aParentRule
)
596 return mParentRule
->GetDOMRule(aParentRule
);
598 *aParentRule
= nsnull
;
603 CSSImportRuleImpl::GetHref(nsAString
& aHref
)
610 CSSImportRuleImpl::GetMedia(nsIDOMMediaList
* *aMedia
)
612 NS_ENSURE_ARG_POINTER(aMedia
);
614 NS_IF_ADDREF(*aMedia
= mMedia
);
619 CSSImportRuleImpl::GetStyleSheet(nsIDOMCSSStyleSheet
* *aStyleSheet
)
621 NS_ENSURE_ARG_POINTER(aStyleSheet
);
623 NS_IF_ADDREF(*aStyleSheet
= mChildSheet
);
627 nsCSSGroupRule::nsCSSGroupRule()
629 , mRuleCollection(nsnull
)
634 CloneRuleInto(nsICSSRule
* aRule
, void* aArray
)
636 nsCOMPtr
<nsICSSRule
> clone
= aRule
->Clone();
637 static_cast<nsCOMArray
<nsICSSRule
>*>(aArray
)->AppendObject(clone
);
642 SetParentRuleReference(nsICSSRule
* aRule
, void* aParentRule
)
644 nsCSSGroupRule
* parentRule
= static_cast<nsCSSGroupRule
*>(aParentRule
);
645 aRule
->SetParentRule(parentRule
);
649 nsCSSGroupRule::nsCSSGroupRule(const nsCSSGroupRule
& aCopy
)
651 , mRuleCollection(nsnull
) // lazily constructed
653 const_cast<nsCSSGroupRule
&>(aCopy
).mRules
.EnumerateForwards(CloneRuleInto
, &mRules
);
654 mRules
.EnumerateForwards(SetParentRuleReference
, this);
657 nsCSSGroupRule::~nsCSSGroupRule()
659 mRules
.EnumerateForwards(SetParentRuleReference
, nsnull
);
660 if (mRuleCollection
) {
661 mRuleCollection
->DropReference();
662 NS_RELEASE(mRuleCollection
);
666 NS_IMPL_ADDREF(nsCSSGroupRule
)
667 NS_IMPL_RELEASE(nsCSSGroupRule
)
669 IMPL_STYLE_RULE_INHERIT2(nsCSSGroupRule
, nsCSSRule
)
672 SetStyleSheetReference(nsICSSRule
* aRule
, void* aSheet
)
674 nsCSSStyleSheet
* sheet
= (nsCSSStyleSheet
*)aSheet
;
675 aRule
->SetStyleSheet(sheet
);
680 nsCSSGroupRule::SetStyleSheet(nsCSSStyleSheet
* aSheet
)
682 mRules
.EnumerateForwards(SetStyleSheetReference
, aSheet
);
683 nsCSSRule::SetStyleSheet(aSheet
);
688 nsCSSGroupRule::List(FILE* out
, PRInt32 aIndent
) const
692 for (PRInt32 index
= 0, count
= mRules
.Count(); index
< count
; ++index
) {
693 mRules
.ObjectAt(index
)->List(out
, aIndent
+ 1);
700 nsCSSGroupRule::AppendStyleRule(nsICSSRule
* aRule
)
702 mRules
.AppendObject(aRule
);
703 aRule
->SetStyleSheet(mSheet
);
704 aRule
->SetParentRule(this);
706 // XXXldb Shouldn't we be using |WillDirty| and |DidDirty| (and
707 // shouldn't |SetModified| be removed?
708 mSheet
->SetModified(PR_TRUE
);
714 nsCSSGroupRule::StyleRuleCount(PRInt32
& aCount
) const
716 aCount
= mRules
.Count();
721 nsCSSGroupRule::GetStyleRuleAt(PRInt32 aIndex
, nsICSSRule
*& aRule
) const
723 if (aIndex
< 0 || aIndex
>= mRules
.Count()) {
725 return NS_ERROR_ILLEGAL_VALUE
;
728 NS_ADDREF(aRule
= mRules
.ObjectAt(aIndex
));
732 NS_IMETHODIMP_(PRBool
)
733 nsCSSGroupRule::EnumerateRulesForwards(RuleEnumFunc aFunc
, void * aData
) const
736 const_cast<nsCSSGroupRule
*>(this)->mRules
.EnumerateForwards(aFunc
, aData
);
740 * The next two methods (DeleteStyleRuleAt and InsertStyleRulesAt)
741 * should never be called unless you have first called WillDirty() on
742 * the parents tylesheet. After they are called, DidDirty() needs to
743 * be called on the sheet
746 nsCSSGroupRule::DeleteStyleRuleAt(PRUint32 aIndex
)
748 nsICSSRule
* rule
= mRules
.SafeObjectAt(aIndex
);
750 rule
->SetStyleSheet(nsnull
);
751 rule
->SetParentRule(nsnull
);
753 return mRules
.RemoveObjectAt(aIndex
) ? NS_OK
: NS_ERROR_ILLEGAL_VALUE
;
757 nsCSSGroupRule::InsertStyleRulesAt(PRUint32 aIndex
,
758 nsCOMArray
<nsICSSRule
>& aRules
)
760 aRules
.EnumerateForwards(SetStyleSheetReference
, mSheet
);
761 aRules
.EnumerateForwards(SetParentRuleReference
, this);
762 if (! mRules
.InsertObjectsAt(aRules
, aIndex
)) {
763 return NS_ERROR_FAILURE
;
769 nsCSSGroupRule::ReplaceStyleRule(nsICSSRule
* aOld
, nsICSSRule
* aNew
)
771 PRInt32 index
= mRules
.IndexOf(aOld
);
772 NS_ENSURE_TRUE(index
!= -1, NS_ERROR_UNEXPECTED
);
773 mRules
.ReplaceObjectAt(aNew
, index
);
774 aNew
->SetStyleSheet(mSheet
);
775 aNew
->SetParentRule(this);
776 aOld
->SetStyleSheet(nsnull
);
777 aOld
->SetParentRule(nsnull
);
782 nsCSSGroupRule::AppendRulesToCssText(nsAString
& aCssText
)
784 aCssText
.AppendLiteral(" {\n");
787 for (PRInt32 index
= 0, count
= mRules
.Count(); index
< count
; ++index
) {
788 nsICSSRule
* rule
= mRules
.ObjectAt(index
);
789 nsCOMPtr
<nsIDOMCSSRule
> domRule
;
790 rule
->GetDOMRule(getter_AddRefs(domRule
));
792 nsAutoString cssText
;
793 domRule
->GetCssText(cssText
);
794 aCssText
.Append(NS_LITERAL_STRING(" ") +
796 NS_LITERAL_STRING("\n"));
800 aCssText
.AppendLiteral("}");
806 nsCSSGroupRule::GetParentStyleSheet(nsIDOMCSSStyleSheet
** aSheet
)
808 NS_IF_ADDREF(*aSheet
= mSheet
);
813 nsCSSGroupRule::GetParentRule(nsIDOMCSSRule
** aParentRule
)
816 return mParentRule
->GetDOMRule(aParentRule
);
818 *aParentRule
= nsnull
;
822 // nsIDOMCSSMediaRule or nsIDOMCSSMozDocumentRule methods
824 nsCSSGroupRule::GetCssRules(nsIDOMCSSRuleList
* *aRuleList
)
826 if (!mRuleCollection
) {
827 mRuleCollection
= new CSSGroupRuleRuleListImpl(this);
828 if (!mRuleCollection
) {
829 return NS_ERROR_OUT_OF_MEMORY
;
831 NS_ADDREF(mRuleCollection
);
834 NS_ADDREF(*aRuleList
= mRuleCollection
);
839 nsCSSGroupRule::InsertRule(const nsAString
& aRule
, PRUint32 aIndex
, PRUint32
* _retval
)
841 NS_ENSURE_TRUE(mSheet
, NS_ERROR_FAILURE
);
843 if (aIndex
> PRUint32(mRules
.Count()))
844 return NS_ERROR_DOM_INDEX_SIZE_ERR
;
846 NS_ASSERTION(PRUint32(mRules
.Count()) <= PR_INT32_MAX
,
847 "Too many style rules!");
849 return mSheet
->InsertRuleIntoGroup(aRule
, this, aIndex
, _retval
);
853 nsCSSGroupRule::DeleteRule(PRUint32 aIndex
)
855 NS_ENSURE_TRUE(mSheet
, NS_ERROR_FAILURE
);
857 if (aIndex
>= PRUint32(mRules
.Count()))
858 return NS_ERROR_DOM_INDEX_SIZE_ERR
;
860 NS_ASSERTION(PRUint32(mRules
.Count()) <= PR_INT32_MAX
,
861 "Too many style rules!");
863 return mSheet
->DeleteRuleFromGroup(this, aIndex
);
866 // -------------------------------------------
869 nsCSSMediaRule::nsCSSMediaRule()
873 nsCSSMediaRule::nsCSSMediaRule(const nsCSSMediaRule
& aCopy
)
874 : nsCSSGroupRule(aCopy
)
877 aCopy
.mMedia
->Clone(getter_AddRefs(mMedia
));
879 // XXXldb This doesn't really make sense.
880 mMedia
->SetStyleSheet(aCopy
.mSheet
);
885 nsCSSMediaRule::~nsCSSMediaRule()
888 mMedia
->SetStyleSheet(nsnull
);
892 NS_IMPL_ADDREF_INHERITED(nsCSSMediaRule
, nsCSSGroupRule
)
893 NS_IMPL_RELEASE_INHERITED(nsCSSMediaRule
, nsCSSGroupRule
)
895 DOMCI_DATA(CSSMediaRule
, nsCSSMediaRule
)
897 // QueryInterface implementation for nsCSSMediaRule
898 NS_INTERFACE_MAP_BEGIN(nsCSSMediaRule
)
899 NS_INTERFACE_MAP_ENTRY(nsICSSGroupRule
)
900 NS_INTERFACE_MAP_ENTRY(nsICSSRule
)
901 NS_INTERFACE_MAP_ENTRY(nsIStyleRule
)
902 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule
)
903 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSMediaRule
)
904 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports
, nsCSSGroupRule
)
905 NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSMediaRule
)
909 nsCSSMediaRule::SetStyleSheet(nsCSSStyleSheet
* aSheet
)
912 // Set to null so it knows it's leaving one sheet and joining another.
913 mMedia
->SetStyleSheet(nsnull
);
914 mMedia
->SetStyleSheet(aSheet
);
917 nsCSSGroupRule::SetStyleSheet(aSheet
);
922 nsCSSMediaRule::List(FILE* out
, PRInt32 aIndent
) const
924 for (PRInt32 indent
= aIndent
; --indent
>= 0; ) fputs(" ", out
);
928 fputs("@media ", out
);
931 nsAutoString mediaText
;
932 mMedia
->GetText(mediaText
);
933 fputs(NS_LossyConvertUTF16toASCII(mediaText
).get(), out
);
936 nsCSSGroupRule::List(out
, aIndent
);
940 /* virtual */ PRInt32
941 nsCSSMediaRule::GetType() const
943 return nsICSSRule::MEDIA_RULE
;
946 /* virtual */ already_AddRefed
<nsICSSRule
>
947 nsCSSMediaRule::Clone() const
949 nsCOMPtr
<nsICSSRule
> clone
= new nsCSSMediaRule(*this);
950 return clone
.forget();
954 nsCSSMediaRule::SetMedia(nsMediaList
* aMedia
)
958 mMedia
->SetStyleSheet(mSheet
);
962 // nsIDOMCSSRule methods
964 nsCSSMediaRule::GetType(PRUint16
* aType
)
966 *aType
= nsIDOMCSSRule::MEDIA_RULE
;
971 nsCSSMediaRule::GetCssText(nsAString
& aCssText
)
973 aCssText
.AssignLiteral("@media ");
976 nsAutoString mediaText
;
977 mMedia
->GetText(mediaText
);
978 aCssText
.Append(mediaText
);
981 return nsCSSGroupRule::AppendRulesToCssText(aCssText
);
985 nsCSSMediaRule::SetCssText(const nsAString
& aCssText
)
987 return NS_ERROR_NOT_IMPLEMENTED
;
991 nsCSSMediaRule::GetParentStyleSheet(nsIDOMCSSStyleSheet
** aSheet
)
993 return nsCSSGroupRule::GetParentStyleSheet(aSheet
);
997 nsCSSMediaRule::GetParentRule(nsIDOMCSSRule
** aParentRule
)
999 return nsCSSGroupRule::GetParentRule(aParentRule
);
1002 // nsIDOMCSSMediaRule methods
1004 nsCSSMediaRule::GetMedia(nsIDOMMediaList
* *aMedia
)
1006 NS_ENSURE_ARG_POINTER(aMedia
);
1007 NS_IF_ADDREF(*aMedia
= mMedia
);
1012 nsCSSMediaRule::GetCssRules(nsIDOMCSSRuleList
* *aRuleList
)
1014 return nsCSSGroupRule::GetCssRules(aRuleList
);
1018 nsCSSMediaRule::InsertRule(const nsAString
& aRule
, PRUint32 aIndex
, PRUint32
* _retval
)
1020 return nsCSSGroupRule::InsertRule(aRule
, aIndex
, _retval
);
1024 nsCSSMediaRule::DeleteRule(PRUint32 aIndex
)
1026 return nsCSSGroupRule::DeleteRule(aIndex
);
1029 // nsICSSGroupRule interface
1030 NS_IMETHODIMP_(PRBool
)
1031 nsCSSMediaRule::UseForPresentation(nsPresContext
* aPresContext
,
1032 nsMediaQueryResultCacheKey
& aKey
)
1035 return mMedia
->Matches(aPresContext
, aKey
);
1041 nsCSSDocumentRule::nsCSSDocumentRule(void)
1045 nsCSSDocumentRule::nsCSSDocumentRule(const nsCSSDocumentRule
& aCopy
)
1046 : nsCSSGroupRule(aCopy
)
1047 , mURLs(new URL(*aCopy
.mURLs
))
1051 nsCSSDocumentRule::~nsCSSDocumentRule(void)
1055 NS_IMPL_ADDREF_INHERITED(nsCSSDocumentRule
, nsCSSGroupRule
)
1056 NS_IMPL_RELEASE_INHERITED(nsCSSDocumentRule
, nsCSSGroupRule
)
1058 DOMCI_DATA(CSSMozDocumentRule
, nsCSSDocumentRule
)
1060 // QueryInterface implementation for nsCSSDocumentRule
1061 NS_INTERFACE_MAP_BEGIN(nsCSSDocumentRule
)
1062 NS_INTERFACE_MAP_ENTRY(nsICSSGroupRule
)
1063 NS_INTERFACE_MAP_ENTRY(nsICSSRule
)
1064 NS_INTERFACE_MAP_ENTRY(nsIStyleRule
)
1065 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule
)
1066 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSMozDocumentRule
)
1067 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports
, nsCSSGroupRule
)
1068 NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSMozDocumentRule
)
1069 NS_INTERFACE_MAP_END
1073 nsCSSDocumentRule::List(FILE* out
, PRInt32 aIndent
) const
1075 for (PRInt32 indent
= aIndent
; --indent
>= 0; ) fputs(" ", out
);
1078 str
.AssignLiteral("@-moz-document ");
1079 for (URL
*url
= mURLs
; url
; url
= url
->next
) {
1080 switch (url
->func
) {
1082 str
.AppendLiteral("url(\"");
1085 str
.AppendLiteral("url-prefix(\"");
1088 str
.AppendLiteral("domain(\"");
1091 nsCAutoString
escapedURL(url
->url
);
1092 escapedURL
.ReplaceSubstring("\"", "\\\""); // escape quotes
1093 str
.Append(escapedURL
);
1094 str
.AppendLiteral("\"), ");
1096 str
.Cut(str
.Length() - 2, 1); // remove last ,
1097 fputs(str
.get(), out
);
1099 nsCSSGroupRule::List(out
, aIndent
);
1103 /* virtual */ PRInt32
1104 nsCSSDocumentRule::GetType() const
1106 return nsICSSRule::DOCUMENT_RULE
;
1109 /* virtual */ already_AddRefed
<nsICSSRule
>
1110 nsCSSDocumentRule::Clone() const
1112 nsCOMPtr
<nsICSSRule
> clone
= new nsCSSDocumentRule(*this);
1113 return clone
.forget();
1116 // nsIDOMCSSRule methods
1118 nsCSSDocumentRule::GetType(PRUint16
* aType
)
1120 // XXX What should really happen here?
1121 *aType
= nsIDOMCSSRule::UNKNOWN_RULE
;
1126 nsCSSDocumentRule::GetCssText(nsAString
& aCssText
)
1128 aCssText
.AssignLiteral("@-moz-document ");
1129 for (URL
*url
= mURLs
; url
; url
= url
->next
) {
1130 switch (url
->func
) {
1132 aCssText
.AppendLiteral("url(");
1135 aCssText
.AppendLiteral("url-prefix(");
1138 aCssText
.AppendLiteral("domain(");
1141 nsStyleUtil::AppendEscapedCSSString(NS_ConvertUTF8toUTF16(url
->url
),
1143 aCssText
.AppendLiteral("), ");
1145 aCssText
.Cut(aCssText
.Length() - 2, 1); // remove last ,
1147 return nsCSSGroupRule::AppendRulesToCssText(aCssText
);
1151 nsCSSDocumentRule::SetCssText(const nsAString
& aCssText
)
1153 return NS_ERROR_NOT_IMPLEMENTED
;
1157 nsCSSDocumentRule::GetParentStyleSheet(nsIDOMCSSStyleSheet
** aSheet
)
1159 return nsCSSGroupRule::GetParentStyleSheet(aSheet
);
1163 nsCSSDocumentRule::GetParentRule(nsIDOMCSSRule
** aParentRule
)
1165 return nsCSSGroupRule::GetParentRule(aParentRule
);
1169 nsCSSDocumentRule::GetCssRules(nsIDOMCSSRuleList
* *aRuleList
)
1171 return nsCSSGroupRule::GetCssRules(aRuleList
);
1175 nsCSSDocumentRule::InsertRule(const nsAString
& aRule
, PRUint32 aIndex
, PRUint32
* _retval
)
1177 return nsCSSGroupRule::InsertRule(aRule
, aIndex
, _retval
);
1181 nsCSSDocumentRule::DeleteRule(PRUint32 aIndex
)
1183 return nsCSSGroupRule::DeleteRule(aIndex
);
1186 // nsICSSGroupRule interface
1187 NS_IMETHODIMP_(PRBool
)
1188 nsCSSDocumentRule::UseForPresentation(nsPresContext
* aPresContext
,
1189 nsMediaQueryResultCacheKey
& aKey
)
1191 nsIURI
*docURI
= aPresContext
->Document()->GetDocumentURI();
1192 nsCAutoString docURISpec
;
1194 docURI
->GetSpec(docURISpec
);
1196 for (URL
*url
= mURLs
; url
; url
= url
->next
) {
1197 switch (url
->func
) {
1199 if (docURISpec
== url
->url
)
1203 if (StringBeginsWith(docURISpec
, url
->url
))
1209 docURI
->GetHost(host
);
1210 PRInt32 lenDiff
= host
.Length() - url
->url
.Length();
1212 if (host
== url
->url
)
1215 if (StringEndsWith(host
, url
->url
) &&
1216 host
.CharAt(lenDiff
- 1) == '.')
1226 nsCSSDocumentRule::URL::~URL()
1228 NS_CSS_DELETE_LIST_MEMBER(nsCSSDocumentRule::URL
, this, next
);
1231 // -------------------------------------------
1232 // nsICSSNameSpaceRule
1234 class NS_FINAL_CLASS CSSNameSpaceRuleImpl
: public nsCSSRule
,
1235 public nsICSSNameSpaceRule
,
1236 public nsIDOMCSSRule
1239 CSSNameSpaceRuleImpl(void);
1240 CSSNameSpaceRuleImpl(const CSSNameSpaceRuleImpl
& aCopy
);
1242 ~CSSNameSpaceRuleImpl();
1246 DECL_STYLE_RULE_INHERIT
1248 // nsIStyleRule methods
1250 virtual void List(FILE* out
= stdout
, PRInt32 aIndent
= 0) const;
1253 // nsICSSRule methods
1254 virtual PRInt32
GetType() const;
1255 virtual already_AddRefed
<nsICSSRule
> Clone() const;
1257 // nsICSSNameSpaceRule methods
1258 NS_IMETHOD
GetPrefix(nsIAtom
*& aPrefix
) const;
1259 NS_IMETHOD
SetPrefix(nsIAtom
* aPrefix
);
1261 NS_IMETHOD
GetURLSpec(nsString
& aURLSpec
) const;
1262 NS_IMETHOD
SetURLSpec(const nsString
& aURLSpec
);
1264 // nsIDOMCSSRule interface
1265 NS_DECL_NSIDOMCSSRULE
1272 CSSNameSpaceRuleImpl::CSSNameSpaceRuleImpl(void)
1279 CSSNameSpaceRuleImpl::CSSNameSpaceRuleImpl(const CSSNameSpaceRuleImpl
& aCopy
)
1281 mPrefix(aCopy
.mPrefix
),
1282 mURLSpec(aCopy
.mURLSpec
)
1284 NS_IF_ADDREF(mPrefix
);
1287 CSSNameSpaceRuleImpl::~CSSNameSpaceRuleImpl()
1289 NS_IF_RELEASE(mPrefix
);
1292 NS_IMPL_ADDREF(CSSNameSpaceRuleImpl
)
1293 NS_IMPL_RELEASE(CSSNameSpaceRuleImpl
)
1295 DOMCI_DATA(CSSNameSpaceRule
, CSSNameSpaceRuleImpl
)
1297 // QueryInterface implementation for CSSNameSpaceRuleImpl
1298 NS_INTERFACE_MAP_BEGIN(CSSNameSpaceRuleImpl
)
1299 NS_INTERFACE_MAP_ENTRY(nsICSSNameSpaceRule
)
1300 NS_INTERFACE_MAP_ENTRY(nsICSSRule
)
1301 NS_INTERFACE_MAP_ENTRY(nsIStyleRule
)
1302 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule
)
1303 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports
, nsICSSNameSpaceRule
)
1304 NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSNameSpaceRule
)
1305 NS_INTERFACE_MAP_END
1307 IMPL_STYLE_RULE_INHERIT(CSSNameSpaceRuleImpl
, nsCSSRule
)
1311 CSSNameSpaceRuleImpl::List(FILE* out
, PRInt32 aIndent
) const
1313 for (PRInt32 indent
= aIndent
; --indent
>= 0; ) fputs(" ", out
);
1315 nsAutoString buffer
;
1317 fputs("@namespace ", out
);
1320 mPrefix
->ToString(buffer
);
1321 fputs(NS_LossyConvertUTF16toASCII(buffer
).get(), out
);
1326 fputs(NS_LossyConvertUTF16toASCII(mURLSpec
).get(), out
);
1331 /* virtual */ PRInt32
1332 CSSNameSpaceRuleImpl::GetType() const
1334 return nsICSSRule::NAMESPACE_RULE
;
1337 /* virtual */ already_AddRefed
<nsICSSRule
>
1338 CSSNameSpaceRuleImpl::Clone() const
1340 nsCOMPtr
<nsICSSRule
> clone
= new CSSNameSpaceRuleImpl(*this);
1341 return clone
.forget();
1345 CSSNameSpaceRuleImpl::GetPrefix(nsIAtom
*& aPrefix
) const
1348 NS_IF_ADDREF(aPrefix
);
1353 CSSNameSpaceRuleImpl::SetPrefix(nsIAtom
* aPrefix
)
1355 NS_IF_RELEASE(mPrefix
);
1357 NS_IF_ADDREF(mPrefix
);
1362 CSSNameSpaceRuleImpl::GetURLSpec(nsString
& aURLSpec
) const
1364 aURLSpec
= mURLSpec
;
1369 CSSNameSpaceRuleImpl::SetURLSpec(const nsString
& aURLSpec
)
1371 mURLSpec
= aURLSpec
;
1376 NS_NewCSSNameSpaceRule(nsICSSNameSpaceRule
** aInstancePtrResult
,
1377 nsIAtom
* aPrefix
, const nsString
& aURLSpec
)
1379 if (! aInstancePtrResult
) {
1380 return NS_ERROR_NULL_POINTER
;
1383 CSSNameSpaceRuleImpl
* it
= new CSSNameSpaceRuleImpl();
1386 return NS_ERROR_OUT_OF_MEMORY
;
1389 it
->SetPrefix(aPrefix
);
1390 it
->SetURLSpec(aURLSpec
);
1391 NS_ADDREF(*aInstancePtrResult
= it
);
1396 CSSNameSpaceRuleImpl::GetType(PRUint16
* aType
)
1398 // XXX What should really happen here?
1399 *aType
= nsIDOMCSSRule::UNKNOWN_RULE
;
1404 CSSNameSpaceRuleImpl::GetCssText(nsAString
& aCssText
)
1406 aCssText
.AssignLiteral("@namespace ");
1408 aCssText
.Append(nsDependentAtomString(mPrefix
) + NS_LITERAL_STRING(" "));
1410 aCssText
.AppendLiteral("url(");
1411 nsStyleUtil::AppendEscapedCSSString(mURLSpec
, aCssText
);
1412 aCssText
.Append(NS_LITERAL_STRING(");"));
1417 CSSNameSpaceRuleImpl::SetCssText(const nsAString
& aCssText
)
1419 return NS_ERROR_NOT_IMPLEMENTED
;
1423 CSSNameSpaceRuleImpl::GetParentStyleSheet(nsIDOMCSSStyleSheet
** aSheet
)
1425 NS_IF_ADDREF(*aSheet
= mSheet
);
1430 CSSNameSpaceRuleImpl::GetParentRule(nsIDOMCSSRule
** aParentRule
)
1433 return mParentRule
->GetDOMRule(aParentRule
);
1435 *aParentRule
= nsnull
;
1439 // -------------------------------------------
1440 // nsCSSFontFaceStyleDecl and related routines
1443 // A src: descriptor is represented as an array value; each entry in
1444 // the array can be eCSSUnit_URL, eCSSUnit_Local_Font, or
1445 // eCSSUnit_Font_Format. Blocks of eCSSUnit_Font_Format may appear
1446 // only after one of the first two. (css3-fonts only contemplates
1447 // annotating URLs with formats, but we handle the general case.)
1449 AppendSerializedFontSrc(const nsCSSValue
& src
, nsAString
& aResult NS_OUTPARAM
)
1451 NS_PRECONDITION(src
.GetUnit() == eCSSUnit_Array
,
1452 "improper value unit for src:");
1454 const nsCSSValue::Array
& sources
= *src
.GetArrayValue();
1457 while (i
< sources
.Count()) {
1458 nsAutoString formats
;
1460 if (sources
[i
].GetUnit() == eCSSUnit_URL
) {
1461 aResult
.AppendLiteral("url(");
1462 nsDependentString
url(sources
[i
].GetOriginalURLValue());
1463 nsStyleUtil::AppendEscapedCSSString(url
, aResult
);
1464 aResult
.AppendLiteral(")");
1465 } else if (sources
[i
].GetUnit() == eCSSUnit_Local_Font
) {
1466 aResult
.AppendLiteral("local(");
1467 nsDependentString
local(sources
[i
].GetStringBufferValue());
1468 nsStyleUtil::AppendEscapedCSSString(local
, aResult
);
1469 aResult
.AppendLiteral(")");
1471 NS_NOTREACHED("entry in src: descriptor with improper unit");
1478 while (i
< sources
.Count() &&
1479 sources
[i
].GetUnit() == eCSSUnit_Font_Format
) {
1480 formats
.Append('"');
1481 formats
.Append(sources
[i
].GetStringBufferValue());
1482 formats
.AppendLiteral("\", ");
1485 if (formats
.Length() > 0) {
1486 formats
.Truncate(formats
.Length() - 2); // remove the last comma
1487 aResult
.AppendLiteral(" format(");
1488 aResult
.Append(formats
);
1489 aResult
.Append(')');
1491 aResult
.AppendLiteral(", ");
1493 aResult
.Truncate(aResult
.Length() - 2); // remove the last comma-space
1496 // print all characters with at least four hex digits
1498 AppendSerializedUnicodePoint(PRUint32 aCode
, nsACString
&aBuf NS_OUTPARAM
)
1500 aBuf
.Append(nsPrintfCString("%04X", aCode
));
1503 // A unicode-range: descriptor is represented as an array of integers,
1504 // to be interpreted as a sequence of pairs: min max min max ...
1505 // It is in source order. (Possibly it should be sorted and overlaps
1506 // consolidated, but right now we don't do that.)
1508 AppendSerializedUnicodeRange(nsCSSValue
const & aValue
,
1509 nsAString
& aResult NS_OUTPARAM
)
1511 NS_PRECONDITION(aValue
.GetUnit() == eCSSUnit_Null
||
1512 aValue
.GetUnit() == eCSSUnit_Array
,
1513 "improper value unit for unicode-range:");
1515 if (aValue
.GetUnit() != eCSSUnit_Array
)
1518 nsCSSValue::Array
const & sources
= *aValue
.GetArrayValue();
1521 NS_ABORT_IF_FALSE(sources
.Count() % 2 == 0,
1522 "odd number of entries in a unicode-range: array");
1524 for (PRUint32 i
= 0; i
< sources
.Count(); i
+= 2) {
1525 PRUint32 min
= sources
[i
].GetIntValue();
1526 PRUint32 max
= sources
[i
+1].GetIntValue();
1528 // We don't try to replicate the U+XX?? notation.
1529 buf
.AppendLiteral("U+");
1530 AppendSerializedUnicodePoint(min
, buf
);
1534 AppendSerializedUnicodePoint(max
, buf
);
1536 buf
.AppendLiteral(", ");
1538 buf
.Truncate(buf
.Length() - 2); // remove the last comma-space
1539 CopyASCIItoUTF16(buf
, aResult
);
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
,
1552 &nsCSSFontFaceStyleDecl::mFontFeatureSettings
,
1553 &nsCSSFontFaceStyleDecl::mFontLanguageOverride
1556 DOMCI_DATA(CSSFontFaceStyleDecl
, nsCSSFontFaceStyleDecl
)
1558 // QueryInterface implementation for nsCSSFontFaceStyleDecl
1559 NS_INTERFACE_MAP_BEGIN(nsCSSFontFaceStyleDecl
)
1560 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSStyleDeclaration
)
1561 NS_INTERFACE_MAP_ENTRY(nsISupports
)
1562 NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSFontFaceStyleDecl
)
1563 NS_INTERFACE_MAP_END
1565 NS_IMPL_ADDREF_USING_AGGREGATOR(nsCSSFontFaceStyleDecl
, ContainingRule())
1566 NS_IMPL_RELEASE_USING_AGGREGATOR(nsCSSFontFaceStyleDecl
, ContainingRule())
1568 // helper for string GetPropertyValue and RemovePropertyValue
1570 nsCSSFontFaceStyleDecl::GetPropertyValue(nsCSSFontDesc aFontDescID
,
1571 nsAString
& aResult NS_OUTPARAM
) const
1573 NS_ENSURE_ARG_RANGE(aFontDescID
, eCSSFontDesc_UNKNOWN
,
1574 eCSSFontDesc_COUNT
- 1);
1577 if (aFontDescID
== eCSSFontDesc_UNKNOWN
)
1580 const nsCSSValue
& val
= this->*nsCSSFontFaceStyleDecl::Fields
[aFontDescID
];
1582 if (val
.GetUnit() == eCSSUnit_Null
) {
1583 // Avoid having to check no-value in the Family and Src cases below.
1587 switch (aFontDescID
) {
1588 case eCSSFontDesc_Family
: {
1589 // we don't use nsCSSValue::AppendToString here because it doesn't
1590 // canonicalize the way we want, and anyway it's overkill when
1591 // we know we have eCSSUnit_String
1592 NS_ASSERTION(val
.GetUnit() == eCSSUnit_String
, "unexpected unit");
1593 nsDependentString
family(val
.GetStringBufferValue());
1594 nsStyleUtil::AppendEscapedCSSString(family
, aResult
);
1598 case eCSSFontDesc_Style
:
1599 val
.AppendToString(eCSSProperty_font_style
, aResult
);
1602 case eCSSFontDesc_Weight
:
1603 val
.AppendToString(eCSSProperty_font_weight
, aResult
);
1606 case eCSSFontDesc_Stretch
:
1607 val
.AppendToString(eCSSProperty_font_stretch
, aResult
);
1610 case eCSSFontDesc_FontFeatureSettings
:
1611 val
.AppendToString(eCSSProperty_font_feature_settings
, aResult
);
1614 case eCSSFontDesc_FontLanguageOverride
:
1615 val
.AppendToString(eCSSProperty_font_language_override
, aResult
);
1618 case eCSSFontDesc_Src
:
1619 AppendSerializedFontSrc(val
, aResult
);
1622 case eCSSFontDesc_UnicodeRange
:
1623 AppendSerializedUnicodeRange(val
, aResult
);
1626 case eCSSFontDesc_UNKNOWN
:
1627 case eCSSFontDesc_COUNT
:
1630 NS_NOTREACHED("nsCSSFontFaceStyleDecl::GetPropertyValue: "
1631 "out-of-range value got to the switch");
1632 return NS_ERROR_INVALID_ARG
;
1636 // attribute DOMString cssText;
1638 nsCSSFontFaceStyleDecl::GetCssText(nsAString
& aCssText
)
1640 nsAutoString descStr
;
1642 aCssText
.Truncate();
1643 for (nsCSSFontDesc id
= nsCSSFontDesc(eCSSFontDesc_UNKNOWN
+ 1);
1644 id
< eCSSFontDesc_COUNT
;
1645 id
= nsCSSFontDesc(id
+ 1)) {
1646 if ((this->*nsCSSFontFaceStyleDecl::Fields
[id
]).GetUnit()
1648 NS_SUCCEEDED(GetPropertyValue(id
, descStr
))) {
1649 NS_ASSERTION(descStr
.Length() > 0,
1650 "GetCssText: non-null unit, empty property value");
1651 aCssText
.AppendLiteral(" ");
1652 aCssText
.AppendASCII(nsCSSProps::GetStringValue(id
).get());
1653 aCssText
.AppendLiteral(": ");
1654 aCssText
.Append(descStr
);
1655 aCssText
.AppendLiteral(";\n");
1662 nsCSSFontFaceStyleDecl::SetCssText(const nsAString
& aCssText
)
1664 return NS_ERROR_NOT_IMPLEMENTED
; // bug 443978
1667 // DOMString getPropertyValue (in DOMString propertyName);
1669 nsCSSFontFaceStyleDecl::GetPropertyValue(const nsAString
& propertyName
,
1670 nsAString
& aResult NS_OUTPARAM
)
1672 return GetPropertyValue(nsCSSProps::LookupFontDesc(propertyName
), aResult
);
1675 // nsIDOMCSSValue getPropertyCSSValue (in DOMString propertyName);
1677 nsCSSFontFaceStyleDecl::GetPropertyCSSValue(const nsAString
& propertyName
,
1678 nsIDOMCSSValue
**aResult NS_OUTPARAM
)
1680 // ??? nsDOMCSSDeclaration returns null/NS_OK, but that seems wrong.
1681 return NS_ERROR_NOT_IMPLEMENTED
;
1684 // DOMString removeProperty (in DOMString propertyName) raises (DOMException);
1686 nsCSSFontFaceStyleDecl::RemoveProperty(const nsAString
& propertyName
,
1687 nsAString
& aResult NS_OUTPARAM
)
1689 nsCSSFontDesc descID
= nsCSSProps::LookupFontDesc(propertyName
);
1690 NS_ASSERTION(descID
>= eCSSFontDesc_UNKNOWN
&&
1691 descID
< eCSSFontDesc_COUNT
,
1692 "LookupFontDesc returned value out of range");
1694 if (descID
== eCSSFontDesc_UNKNOWN
) {
1697 nsresult rv
= GetPropertyValue(descID
, aResult
);
1698 NS_ENSURE_SUCCESS(rv
, rv
);
1699 (this->*nsCSSFontFaceStyleDecl::Fields
[descID
]).Reset();
1704 // DOMString getPropertyPriority (in DOMString propertyName);
1706 nsCSSFontFaceStyleDecl::GetPropertyPriority(const nsAString
& propertyName
,
1707 nsAString
& aResult NS_OUTPARAM
)
1709 // font descriptors do not have priorities at present
1714 // void setProperty (in DOMString propertyName, in DOMString value,
1715 // in DOMString priority) raises (DOMException);
1717 nsCSSFontFaceStyleDecl::SetProperty(const nsAString
& propertyName
,
1718 const nsAString
& value
,
1719 const nsAString
& priority
)
1721 return NS_ERROR_NOT_IMPLEMENTED
; // bug 443978
1724 // readonly attribute unsigned long length;
1726 nsCSSFontFaceStyleDecl::GetLength(PRUint32
*aLength
)
1729 for (nsCSSFontDesc id
= nsCSSFontDesc(eCSSFontDesc_UNKNOWN
+ 1);
1730 id
< eCSSFontDesc_COUNT
;
1731 id
= nsCSSFontDesc(id
+ 1))
1732 if ((this->*nsCSSFontFaceStyleDecl::Fields
[id
]).GetUnit() != eCSSUnit_Null
)
1739 // DOMString item (in unsigned long index);
1741 nsCSSFontFaceStyleDecl::Item(PRUint32 index
, nsAString
& aResult NS_OUTPARAM
)
1744 for (nsCSSFontDesc id
= nsCSSFontDesc(eCSSFontDesc_UNKNOWN
+ 1);
1745 id
< eCSSFontDesc_COUNT
;
1746 id
= nsCSSFontDesc(id
+ 1)) {
1747 if ((this->*nsCSSFontFaceStyleDecl::Fields
[id
]).GetUnit()
1750 if (nset
== PRInt32(index
)) {
1751 aResult
.AssignASCII(nsCSSProps::GetStringValue(id
).get());
1760 // readonly attribute nsIDOMCSSRule parentRule;
1762 nsCSSFontFaceStyleDecl::GetParentRule(nsIDOMCSSRule
** aParentRule
)
1764 return ContainingRule()->GetDOMRule(aParentRule
);
1768 // -------------------------------------------
1769 // nsCSSFontFaceRule
1772 /* virtual */ already_AddRefed
<nsICSSRule
>
1773 nsCSSFontFaceRule::Clone() const
1775 nsCOMPtr
<nsICSSRule
> clone
= new nsCSSFontFaceRule(*this);
1776 return clone
.forget();
1779 NS_IMPL_ADDREF(nsCSSFontFaceRule
)
1780 NS_IMPL_RELEASE(nsCSSFontFaceRule
)
1782 DOMCI_DATA(CSSFontFaceRule
, nsCSSFontFaceRule
)
1784 // QueryInterface implementation for nsCSSFontFaceRule
1785 NS_INTERFACE_MAP_BEGIN(nsCSSFontFaceRule
)
1786 NS_INTERFACE_MAP_ENTRY(nsICSSRule
)
1787 NS_INTERFACE_MAP_ENTRY(nsIStyleRule
)
1788 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSFontFaceRule
)
1789 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule
)
1790 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports
, nsICSSRule
)
1791 NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSFontFaceRule
)
1792 NS_INTERFACE_MAP_END
1794 IMPL_STYLE_RULE_INHERIT(nsCSSFontFaceRule
, nsCSSRule
)
1798 nsCSSFontFaceRule::List(FILE* out
, PRInt32 aIndent
) const
1800 nsCString baseInd
, descInd
;
1801 for (PRInt32 indent
= aIndent
; --indent
>= 0; ) {
1802 baseInd
.AppendLiteral(" ");
1803 descInd
.AppendLiteral(" ");
1805 descInd
.AppendLiteral(" ");
1809 fprintf(out
, "%s@font-face {\n", baseInd
.get());
1810 for (nsCSSFontDesc id
= nsCSSFontDesc(eCSSFontDesc_UNKNOWN
+ 1);
1811 id
< eCSSFontDesc_COUNT
;
1812 id
= nsCSSFontDesc(id
+ 1))
1813 if ((mDecl
.*nsCSSFontFaceStyleDecl::Fields
[id
]).GetUnit()
1815 if (NS_FAILED(mDecl
.GetPropertyValue(id
, descStr
)))
1816 descStr
.AssignLiteral("#<serialization error>");
1817 else if (descStr
.Length() == 0)
1818 descStr
.AssignLiteral("#<serialization missing>");
1819 fprintf(out
, "%s%s: %s\n",
1820 descInd
.get(), nsCSSProps::GetStringValue(id
).get(),
1821 NS_ConvertUTF16toUTF8(descStr
).get());
1823 fprintf(out
, "%s}\n", baseInd
.get());
1827 /* virtual */ PRInt32
1828 nsCSSFontFaceRule::GetType() const
1830 return nsICSSRule::FONT_FACE_RULE
;
1834 nsCSSFontFaceRule::GetType(PRUint16
* aType
)
1836 *aType
= nsIDOMCSSRule::FONT_FACE_RULE
;
1841 nsCSSFontFaceRule::GetCssText(nsAString
& aCssText
)
1843 nsAutoString propText
;
1844 mDecl
.GetCssText(propText
);
1846 aCssText
.AssignLiteral("@font-face {\n");
1847 aCssText
.Append(propText
);
1848 aCssText
.Append('}');
1853 nsCSSFontFaceRule::SetCssText(const nsAString
& aCssText
)
1855 return NS_ERROR_NOT_IMPLEMENTED
; // bug 443978
1859 nsCSSFontFaceRule::GetParentStyleSheet(nsIDOMCSSStyleSheet
** aSheet
)
1861 NS_IF_ADDREF(*aSheet
= mSheet
);
1866 nsCSSFontFaceRule::GetParentRule(nsIDOMCSSRule
** aParentRule
)
1869 return mParentRule
->GetDOMRule(aParentRule
);
1871 *aParentRule
= nsnull
;
1876 nsCSSFontFaceRule::GetStyle(nsIDOMCSSStyleDeclaration
** aStyle
)
1878 NS_IF_ADDREF(*aStyle
= &mDecl
);
1882 // Arguably these should forward to nsCSSFontFaceStyleDecl methods.
1884 nsCSSFontFaceRule::SetDesc(nsCSSFontDesc aDescID
, nsCSSValue
const & aValue
)
1886 NS_PRECONDITION(aDescID
> eCSSFontDesc_UNKNOWN
&&
1887 aDescID
< eCSSFontDesc_COUNT
,
1888 "aDescID out of range in nsCSSFontFaceRule::SetDesc");
1890 mDecl
.*nsCSSFontFaceStyleDecl::Fields
[aDescID
] = aValue
;
1894 nsCSSFontFaceRule::GetDesc(nsCSSFontDesc aDescID
, nsCSSValue
& aValue
)
1896 NS_PRECONDITION(aDescID
> eCSSFontDesc_UNKNOWN
&&
1897 aDescID
< eCSSFontDesc_COUNT
,
1898 "aDescID out of range in nsCSSFontFaceRule::GetDesc");
1900 aValue
= mDecl
.*nsCSSFontFaceStyleDecl::Fields
[aDescID
];