Bug 451040 ? Passwords Manager Empty after convert to MozStorage. r=gavin
[wine-gecko.git] / layout / style / nsCSSRules.cpp
bloba952423d1f57dcc7c112c2bffbdbd6413acbc23e
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
13 * License.
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.
22 * Contributor(s):
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"
46 #include "nsString.h"
47 #include "nsIAtom.h"
48 #include "nsIURL.h"
50 #include "nsCSSRule.h"
51 #include "nsCSSProps.h"
52 #include "nsICSSStyleSheet.h"
54 #include "nsCOMPtr.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 "nsIDOMCSSRuleList.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 NS_IMETHODIMP _class::GetDOMRule(nsIDOMCSSRule** aDOMRule) { return CallQueryInterface(this, aDOMRule); } \
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::GetDOMRule(nsIDOMCSSRule** aDOMRule) { return CallQueryInterface(this, aDOMRule); } \
86 NS_IMETHODIMP _class::MapRuleInfoInto(nsRuleData* aRuleData) { return NS_OK; }
88 // -------------------------------
89 // Style Rule List for group rules
91 class CSSGroupRuleRuleListImpl : public nsIDOMCSSRuleList
93 public:
94 CSSGroupRuleRuleListImpl(nsICSSGroupRule *aGroupRule);
96 NS_DECL_ISUPPORTS
98 NS_DECL_NSIDOMCSSRULELIST
100 void DropReference() { mGroupRule = nsnull; }
102 protected:
103 virtual ~CSSGroupRuleRuleListImpl(void);
105 private:
106 nsICSSGroupRule* mGroupRule;
109 CSSGroupRuleRuleListImpl::CSSGroupRuleRuleListImpl(nsICSSGroupRule *aGroupRule)
111 // Not reference counted to avoid circular references.
112 // The rule will tell us when its going away.
113 mGroupRule = aGroupRule;
116 CSSGroupRuleRuleListImpl::~CSSGroupRuleRuleListImpl()
120 // QueryInterface implementation for CSSGroupRuleRuleList
121 NS_INTERFACE_MAP_BEGIN(CSSGroupRuleRuleListImpl)
122 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRuleList)
123 NS_INTERFACE_MAP_ENTRY(nsISupports)
124 NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(CSSGroupRuleRuleList)
125 NS_INTERFACE_MAP_END
128 NS_IMPL_ADDREF(CSSGroupRuleRuleListImpl)
129 NS_IMPL_RELEASE(CSSGroupRuleRuleListImpl)
131 NS_IMETHODIMP
132 CSSGroupRuleRuleListImpl::GetLength(PRUint32* aLength)
134 if (mGroupRule) {
135 PRInt32 count;
136 mGroupRule->StyleRuleCount(count);
137 *aLength = (PRUint32)count;
138 } else {
139 *aLength = 0;
142 return NS_OK;
145 NS_IMETHODIMP
146 CSSGroupRuleRuleListImpl::Item(PRUint32 aIndex, nsIDOMCSSRule** aReturn)
148 nsresult result = NS_OK;
150 *aReturn = nsnull;
151 if (mGroupRule) {
152 nsCOMPtr<nsICSSRule> rule;
154 result = mGroupRule->GetStyleRuleAt(aIndex, *getter_AddRefs(rule));
155 if (rule) {
156 result = rule->GetDOMRule(aReturn);
157 } else if (result == NS_ERROR_ILLEGAL_VALUE) {
158 result = NS_OK; // per spec: "Return Value ... null if ... not a valid index."
162 return result;
165 // -------------------------------------------
166 // CharsetRule
168 class CSSCharsetRuleImpl : public nsCSSRule,
169 public nsICSSRule,
170 public nsIDOMCSSCharsetRule
172 public:
173 CSSCharsetRuleImpl(const nsAString& aEncoding);
174 CSSCharsetRuleImpl(const CSSCharsetRuleImpl& aCopy);
175 virtual ~CSSCharsetRuleImpl(void);
177 NS_DECL_ISUPPORTS_INHERITED
179 DECL_STYLE_RULE_INHERIT
181 // nsIStyleRule methods
182 #ifdef DEBUG
183 NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const;
184 #endif
186 // nsICSSRule methods
187 NS_IMETHOD GetType(PRInt32& aType) const;
188 NS_IMETHOD Clone(nsICSSRule*& aClone) const;
190 // nsIDOMCSSRule interface
191 NS_DECL_NSIDOMCSSRULE
193 // nsIDOMCSSCharsetRule methods
194 NS_IMETHOD GetEncoding(nsAString& aEncoding);
195 NS_IMETHOD SetEncoding(const nsAString& aEncoding);
197 protected:
198 nsString mEncoding;
201 CSSCharsetRuleImpl::CSSCharsetRuleImpl(const nsAString& aEncoding)
202 : nsCSSRule(),
203 mEncoding(aEncoding)
207 CSSCharsetRuleImpl::CSSCharsetRuleImpl(const CSSCharsetRuleImpl& aCopy)
208 : nsCSSRule(aCopy),
209 mEncoding(aCopy.mEncoding)
213 CSSCharsetRuleImpl::~CSSCharsetRuleImpl(void)
217 NS_IMPL_ADDREF_INHERITED(CSSCharsetRuleImpl, nsCSSRule)
218 NS_IMPL_RELEASE_INHERITED(CSSCharsetRuleImpl, nsCSSRule)
220 // QueryInterface implementation for CSSCharsetRuleImpl
221 NS_INTERFACE_MAP_BEGIN(CSSCharsetRuleImpl)
222 NS_INTERFACE_MAP_ENTRY(nsICSSRule)
223 NS_INTERFACE_MAP_ENTRY(nsIStyleRule)
224 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
225 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSCharsetRule)
226 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsICSSRule)
227 NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(CSSCharsetRule)
228 NS_INTERFACE_MAP_END
230 IMPL_STYLE_RULE_INHERIT(CSSCharsetRuleImpl, nsCSSRule)
232 #ifdef DEBUG
233 NS_IMETHODIMP
234 CSSCharsetRuleImpl::List(FILE* out, PRInt32 aIndent) const
236 // Indent
237 for (PRInt32 indent = aIndent; --indent >= 0; ) fputs(" ", out);
239 fputs("@charset \"", out);
240 fputs(NS_LossyConvertUTF16toASCII(mEncoding).get(), out);
241 fputs("\"\n", out);
243 return NS_OK;
245 #endif
247 NS_IMETHODIMP
248 CSSCharsetRuleImpl::GetType(PRInt32& aType) const
250 aType = nsICSSRule::CHARSET_RULE;
251 return NS_OK;
254 NS_IMETHODIMP
255 CSSCharsetRuleImpl::Clone(nsICSSRule*& aClone) const
257 CSSCharsetRuleImpl* clone = new CSSCharsetRuleImpl(*this);
258 if (clone) {
259 return CallQueryInterface(clone, &aClone);
261 aClone = nsnull;
262 return NS_ERROR_OUT_OF_MEMORY;
265 NS_IMETHODIMP
266 CSSCharsetRuleImpl::GetEncoding(nsAString& aEncoding)
268 aEncoding = mEncoding;
269 return NS_OK;
272 NS_IMETHODIMP
273 CSSCharsetRuleImpl::SetEncoding(const nsAString& aEncoding)
275 mEncoding = aEncoding;
276 return NS_OK;
280 nsresult
281 NS_NewCSSCharsetRule(nsICSSRule** aInstancePtrResult, const nsAString& aEncoding)
283 if (! aInstancePtrResult) {
284 return NS_ERROR_NULL_POINTER;
287 CSSCharsetRuleImpl* it = new CSSCharsetRuleImpl(aEncoding);
289 if (! it) {
290 return NS_ERROR_OUT_OF_MEMORY;
293 return CallQueryInterface(it, aInstancePtrResult);
296 NS_IMETHODIMP
297 CSSCharsetRuleImpl::GetType(PRUint16* aType)
299 *aType = nsIDOMCSSRule::CHARSET_RULE;
300 return NS_OK;
303 NS_IMETHODIMP
304 CSSCharsetRuleImpl::GetCssText(nsAString& aCssText)
306 aCssText.AssignLiteral("@charset \"");
307 aCssText.Append(mEncoding);
308 aCssText.AppendLiteral("\";");
309 return NS_OK;
312 NS_IMETHODIMP
313 CSSCharsetRuleImpl::SetCssText(const nsAString& aCssText)
315 return NS_ERROR_NOT_IMPLEMENTED;
318 NS_IMETHODIMP
319 CSSCharsetRuleImpl::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
321 NS_ENSURE_ARG_POINTER(aSheet);
323 if (mSheet) {
324 return CallQueryInterface(mSheet, aSheet);
326 *aSheet = nsnull;
327 return NS_OK;
330 NS_IMETHODIMP
331 CSSCharsetRuleImpl::GetParentRule(nsIDOMCSSRule** aParentRule)
333 if (mParentRule) {
334 return mParentRule->GetDOMRule(aParentRule);
336 *aParentRule = nsnull;
337 return NS_OK;
342 // -------------------------------------------
343 // nsICSSImportRule
345 class CSSImportRuleImpl : public nsCSSRule,
346 public nsICSSImportRule,
347 public nsIDOMCSSImportRule
349 public:
350 CSSImportRuleImpl(nsMediaList* aMedia);
351 CSSImportRuleImpl(const CSSImportRuleImpl& aCopy);
352 virtual ~CSSImportRuleImpl(void);
354 NS_DECL_ISUPPORTS_INHERITED
356 DECL_STYLE_RULE_INHERIT
358 // nsIStyleRule methods
359 #ifdef DEBUG
360 NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const;
361 #endif
363 // nsICSSRule methods
364 NS_IMETHOD GetType(PRInt32& aType) const;
365 NS_IMETHOD Clone(nsICSSRule*& aClone) const;
367 // nsICSSImportRule methods
368 NS_IMETHOD SetURLSpec(const nsString& aURLSpec);
369 NS_IMETHOD GetURLSpec(nsString& aURLSpec) const;
371 NS_IMETHOD SetMedia(const nsString& aMedia);
372 NS_IMETHOD GetMedia(nsString& aMedia) const;
374 NS_IMETHOD SetSheet(nsICSSStyleSheet*);
376 // nsIDOMCSSRule interface
377 NS_DECL_NSIDOMCSSRULE
379 // nsIDOMCSSImportRule interface
380 NS_DECL_NSIDOMCSSIMPORTRULE
382 protected:
383 nsString mURLSpec;
384 nsRefPtr<nsMediaList> mMedia;
385 nsCOMPtr<nsICSSStyleSheet> mChildSheet;
388 CSSImportRuleImpl::CSSImportRuleImpl(nsMediaList* aMedia)
389 : nsCSSRule()
390 , mURLSpec()
391 , mMedia(aMedia)
393 // XXXbz This is really silly.... the mMedia here will be replaced
394 // with itself if we manage to load a sheet. Which should really
395 // never fail nowadays, in sane cases.
398 CSSImportRuleImpl::CSSImportRuleImpl(const CSSImportRuleImpl& aCopy)
399 : nsCSSRule(aCopy),
400 mURLSpec(aCopy.mURLSpec)
402 nsCOMPtr<nsICSSStyleSheet> sheet;
403 if (aCopy.mChildSheet) {
404 aCopy.mChildSheet->Clone(nsnull, this, nsnull, nsnull,
405 getter_AddRefs(sheet));
407 SetSheet(sheet);
408 // SetSheet sets mMedia appropriately
411 CSSImportRuleImpl::~CSSImportRuleImpl(void)
413 if (mChildSheet) {
414 mChildSheet->SetOwnerRule(nsnull);
418 NS_IMPL_ADDREF_INHERITED(CSSImportRuleImpl, nsCSSRule)
419 NS_IMPL_RELEASE_INHERITED(CSSImportRuleImpl, nsCSSRule)
421 // QueryInterface implementation for CSSImportRuleImpl
422 NS_INTERFACE_MAP_BEGIN(CSSImportRuleImpl)
423 NS_INTERFACE_MAP_ENTRY(nsICSSImportRule)
424 NS_INTERFACE_MAP_ENTRY(nsICSSRule)
425 NS_INTERFACE_MAP_ENTRY(nsIStyleRule)
426 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
427 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSImportRule)
428 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsICSSImportRule)
429 NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(CSSImportRule)
430 NS_INTERFACE_MAP_END
432 IMPL_STYLE_RULE_INHERIT(CSSImportRuleImpl, nsCSSRule)
434 #ifdef DEBUG
435 NS_IMETHODIMP
436 CSSImportRuleImpl::List(FILE* out, PRInt32 aIndent) const
438 // Indent
439 for (PRInt32 indent = aIndent; --indent >= 0; ) fputs(" ", out);
441 fputs("@import \"", out);
442 fputs(NS_LossyConvertUTF16toASCII(mURLSpec).get(), out);
443 fputs("\" ", out);
445 nsAutoString mediaText;
446 mMedia->GetText(mediaText);
447 fputs(NS_LossyConvertUTF16toASCII(mediaText).get(), out);
448 fputs("\n", out);
450 return NS_OK;
452 #endif
454 NS_IMETHODIMP
455 CSSImportRuleImpl::GetType(PRInt32& aType) const
457 aType = nsICSSRule::IMPORT_RULE;
458 return NS_OK;
461 NS_IMETHODIMP
462 CSSImportRuleImpl::Clone(nsICSSRule*& aClone) const
464 CSSImportRuleImpl* clone = new CSSImportRuleImpl(*this);
465 if (clone) {
466 return CallQueryInterface(clone, &aClone);
468 aClone = nsnull;
469 return NS_ERROR_OUT_OF_MEMORY;
472 NS_IMETHODIMP
473 CSSImportRuleImpl::SetURLSpec(const nsString& aURLSpec)
475 mURLSpec = aURLSpec;
476 return NS_OK;
479 NS_IMETHODIMP
480 CSSImportRuleImpl::GetURLSpec(nsString& aURLSpec) const
482 aURLSpec = mURLSpec;
483 return NS_OK;
486 NS_IMETHODIMP
487 CSSImportRuleImpl::SetMedia(const nsString& aMedia)
489 if (mMedia) {
490 return mMedia->SetText(aMedia);
491 } else {
492 return NS_OK;
496 NS_IMETHODIMP
497 CSSImportRuleImpl::GetMedia(nsString& aMedia) const
499 if (mMedia) {
500 return mMedia->GetText(aMedia);
501 } else {
502 aMedia.Truncate();
503 return NS_OK;
507 NS_IMETHODIMP
508 CSSImportRuleImpl::SetSheet(nsICSSStyleSheet* aSheet)
510 nsresult rv;
511 NS_ENSURE_ARG_POINTER(aSheet);
513 // set the new sheet
514 mChildSheet = aSheet;
515 aSheet->SetOwnerRule(this);
517 // set our medialist to be the same as the sheet's medialist
518 nsCOMPtr<nsIDOMStyleSheet> sheet(do_QueryInterface(mChildSheet, &rv));
519 NS_ENSURE_SUCCESS(rv, rv);
520 nsCOMPtr<nsIDOMMediaList> mediaList;
521 rv = sheet->GetMedia(getter_AddRefs(mediaList));
522 NS_ENSURE_SUCCESS(rv, rv);
523 mMedia = static_cast<nsMediaList*>(mediaList.get());
525 return NS_OK;
528 nsresult
529 NS_NewCSSImportRule(nsICSSImportRule** aInstancePtrResult,
530 const nsString& aURLSpec,
531 nsMediaList* aMedia)
533 NS_ENSURE_ARG_POINTER(aInstancePtrResult);
535 CSSImportRuleImpl* it = new CSSImportRuleImpl(aMedia);
537 if (! it) {
538 return NS_ERROR_OUT_OF_MEMORY;
541 it->SetURLSpec(aURLSpec);
542 return CallQueryInterface(it, aInstancePtrResult);
545 NS_IMETHODIMP
546 CSSImportRuleImpl::GetType(PRUint16* aType)
548 NS_ENSURE_ARG_POINTER(aType);
549 *aType = nsIDOMCSSRule::IMPORT_RULE;
550 return NS_OK;
553 NS_IMETHODIMP
554 CSSImportRuleImpl::GetCssText(nsAString& aCssText)
556 aCssText.AssignLiteral("@import url(");
557 aCssText.Append(mURLSpec);
558 aCssText.Append(NS_LITERAL_STRING(")"));
559 if (mMedia) {
560 nsAutoString mediaText;
561 mMedia->GetText(mediaText);
562 if (!mediaText.IsEmpty()) {
563 aCssText.AppendLiteral(" ");
564 aCssText.Append(mediaText);
567 aCssText.AppendLiteral(";");
568 return NS_OK;
571 NS_IMETHODIMP
572 CSSImportRuleImpl::SetCssText(const nsAString& aCssText)
574 return NS_ERROR_NOT_IMPLEMENTED;
577 NS_IMETHODIMP
578 CSSImportRuleImpl::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
580 NS_ENSURE_ARG_POINTER(aSheet);
581 if (mSheet) {
582 return CallQueryInterface(mSheet, aSheet);
584 *aSheet = nsnull;
585 return NS_OK;
588 NS_IMETHODIMP
589 CSSImportRuleImpl::GetParentRule(nsIDOMCSSRule** aParentRule)
591 if (mParentRule) {
592 return mParentRule->GetDOMRule(aParentRule);
594 *aParentRule = nsnull;
595 return NS_OK;
598 NS_IMETHODIMP
599 CSSImportRuleImpl::GetHref(nsAString & aHref)
601 aHref = mURLSpec;
602 return NS_OK;
605 NS_IMETHODIMP
606 CSSImportRuleImpl::GetMedia(nsIDOMMediaList * *aMedia)
608 NS_ENSURE_ARG_POINTER(aMedia);
609 if (!mMedia) {
610 *aMedia = nsnull;
611 return NS_OK;
614 return CallQueryInterface(mMedia.get(), aMedia);
617 NS_IMETHODIMP
618 CSSImportRuleImpl::GetStyleSheet(nsIDOMCSSStyleSheet * *aStyleSheet)
620 NS_ENSURE_ARG_POINTER(aStyleSheet);
621 if (!mChildSheet) {
622 *aStyleSheet = nsnull;
623 return NS_OK;
626 return CallQueryInterface(mChildSheet, aStyleSheet);
629 nsCSSGroupRule::nsCSSGroupRule()
630 : nsCSSRule()
631 , mRuleCollection(nsnull)
635 static PRBool
636 CloneRuleInto(nsICSSRule* aRule, void* aArray)
638 nsICSSRule* clone = nsnull;
639 aRule->Clone(clone);
640 if (clone) {
641 static_cast<nsCOMArray<nsICSSRule>*>(aArray)->AppendObject(clone);
642 NS_RELEASE(clone);
644 return PR_TRUE;
647 static PRBool
648 SetParentRuleReference(nsICSSRule* aRule, void* aParentRule)
650 nsCSSGroupRule* parentRule = static_cast<nsCSSGroupRule*>(aParentRule);
651 aRule->SetParentRule(parentRule);
652 return PR_TRUE;
655 nsCSSGroupRule::nsCSSGroupRule(const nsCSSGroupRule& aCopy)
656 : nsCSSRule(aCopy)
657 , mRuleCollection(nsnull) // lazily constructed
659 const_cast<nsCSSGroupRule&>(aCopy).mRules.EnumerateForwards(CloneRuleInto, &mRules);
660 mRules.EnumerateForwards(SetParentRuleReference, this);
663 nsCSSGroupRule::~nsCSSGroupRule()
665 mRules.EnumerateForwards(SetParentRuleReference, nsnull);
666 if (mRuleCollection) {
667 mRuleCollection->DropReference();
668 NS_RELEASE(mRuleCollection);
672 IMPL_STYLE_RULE_INHERIT2(nsCSSGroupRule, nsCSSRule)
674 static PRBool
675 SetStyleSheetReference(nsICSSRule* aRule, void* aSheet)
677 nsICSSStyleSheet* sheet = (nsICSSStyleSheet*)aSheet;
678 aRule->SetStyleSheet(sheet);
679 return PR_TRUE;
682 NS_IMETHODIMP
683 nsCSSGroupRule::SetStyleSheet(nsICSSStyleSheet* aSheet)
685 mRules.EnumerateForwards(SetStyleSheetReference, aSheet);
686 return nsCSSRule::SetStyleSheet(aSheet);
689 #ifdef DEBUG
690 NS_IMETHODIMP
691 nsCSSGroupRule::List(FILE* out, PRInt32 aIndent) const
693 fputs(" {\n", out);
695 for (PRInt32 index = 0, count = mRules.Count(); index < count; ++index) {
696 mRules.ObjectAt(index)->List(out, aIndent + 1);
698 fputs("}\n", out);
699 return NS_OK;
701 #endif
703 NS_IMETHODIMP
704 nsCSSGroupRule::AppendStyleRule(nsICSSRule* aRule)
706 mRules.AppendObject(aRule);
707 aRule->SetStyleSheet(mSheet);
708 aRule->SetParentRule(this);
709 if (mSheet) {
710 // XXXldb Shouldn't we be using |WillDirty| and |DidDirty| (and
711 // shouldn't |SetModified| be removed?
712 mSheet->SetModified(PR_TRUE);
714 return NS_OK;
717 NS_IMETHODIMP
718 nsCSSGroupRule::StyleRuleCount(PRInt32& aCount) const
720 aCount = mRules.Count();
721 return NS_OK;
724 NS_IMETHODIMP
725 nsCSSGroupRule::GetStyleRuleAt(PRInt32 aIndex, nsICSSRule*& aRule) const
727 if (aIndex < 0 || aIndex >= mRules.Count()) {
728 aRule = nsnull;
729 return NS_ERROR_ILLEGAL_VALUE;
732 NS_ADDREF(aRule = mRules.ObjectAt(aIndex));
733 return NS_OK;
736 NS_IMETHODIMP_(PRBool)
737 nsCSSGroupRule::EnumerateRulesForwards(RuleEnumFunc aFunc, void * aData) const
739 return
740 const_cast<nsCSSGroupRule*>(this)->mRules.EnumerateForwards(aFunc, aData);
744 * The next two methods (DeleteStyleRuleAt and InsertStyleRulesAt)
745 * should never be called unless you have first called WillDirty() on
746 * the parents tylesheet. After they are called, DidDirty() needs to
747 * be called on the sheet
749 NS_IMETHODIMP
750 nsCSSGroupRule::DeleteStyleRuleAt(PRUint32 aIndex)
752 nsICSSRule* rule = mRules.SafeObjectAt(aIndex);
753 if (rule) {
754 rule->SetStyleSheet(nsnull);
755 rule->SetParentRule(nsnull);
757 return mRules.RemoveObjectAt(aIndex) ? NS_OK : NS_ERROR_ILLEGAL_VALUE;
760 NS_IMETHODIMP
761 nsCSSGroupRule::InsertStyleRulesAt(PRUint32 aIndex,
762 nsCOMArray<nsICSSRule>& aRules)
764 aRules.EnumerateForwards(SetStyleSheetReference, mSheet);
765 aRules.EnumerateForwards(SetParentRuleReference, this);
766 if (! mRules.InsertObjectsAt(aRules, aIndex)) {
767 return NS_ERROR_FAILURE;
769 return NS_OK;
772 NS_IMETHODIMP
773 nsCSSGroupRule::ReplaceStyleRule(nsICSSRule* aOld, nsICSSRule* aNew)
775 PRInt32 index = mRules.IndexOf(aOld);
776 NS_ENSURE_TRUE(index != -1, NS_ERROR_UNEXPECTED);
777 mRules.ReplaceObjectAt(aNew, index);
778 aNew->SetStyleSheet(mSheet);
779 aNew->SetParentRule(this);
780 aOld->SetStyleSheet(nsnull);
781 aOld->SetParentRule(nsnull);
782 return NS_OK;
785 nsresult
786 nsCSSGroupRule::AppendRulesToCssText(nsAString& aCssText)
788 aCssText.AppendLiteral(" {\n");
790 // get all the rules
791 for (PRInt32 index = 0, count = mRules.Count(); index < count; ++index) {
792 nsICSSRule* rule = mRules.ObjectAt(index);
793 nsCOMPtr<nsIDOMCSSRule> domRule;
794 rule->GetDOMRule(getter_AddRefs(domRule));
795 if (domRule) {
796 nsAutoString cssText;
797 domRule->GetCssText(cssText);
798 aCssText.Append(NS_LITERAL_STRING(" ") +
799 cssText +
800 NS_LITERAL_STRING("\n"));
804 aCssText.AppendLiteral("}");
806 return NS_OK;
809 nsresult
810 nsCSSGroupRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
812 if (mSheet) {
813 return CallQueryInterface(mSheet, aSheet);
815 *aSheet = nsnull;
816 return NS_OK;
819 nsresult
820 nsCSSGroupRule::GetParentRule(nsIDOMCSSRule** aParentRule)
822 if (mParentRule) {
823 return mParentRule->GetDOMRule(aParentRule);
825 *aParentRule = nsnull;
826 return NS_OK;
829 // nsIDOMCSSMediaRule or nsIDOMCSSMozDocumentRule methods
830 nsresult
831 nsCSSGroupRule::GetCssRules(nsIDOMCSSRuleList* *aRuleList)
833 if (!mRuleCollection) {
834 mRuleCollection = new CSSGroupRuleRuleListImpl(this);
835 if (!mRuleCollection) {
836 return NS_ERROR_OUT_OF_MEMORY;
838 NS_ADDREF(mRuleCollection);
841 return CallQueryInterface(mRuleCollection, aRuleList);
844 nsresult
845 nsCSSGroupRule::InsertRule(const nsAString & aRule, PRUint32 aIndex, PRUint32* _retval)
847 NS_ENSURE_TRUE(mSheet, NS_ERROR_FAILURE);
849 if (aIndex > PRUint32(mRules.Count()))
850 return NS_ERROR_DOM_INDEX_SIZE_ERR;
852 NS_ASSERTION(PRUint32(mRules.Count()) <= PR_INT32_MAX,
853 "Too many style rules!");
855 return mSheet->InsertRuleIntoGroup(aRule, this, aIndex, _retval);
858 nsresult
859 nsCSSGroupRule::DeleteRule(PRUint32 aIndex)
861 NS_ENSURE_TRUE(mSheet, NS_ERROR_FAILURE);
863 if (aIndex >= PRUint32(mRules.Count()))
864 return NS_ERROR_DOM_INDEX_SIZE_ERR;
866 NS_ASSERTION(PRUint32(mRules.Count()) <= PR_INT32_MAX,
867 "Too many style rules!");
869 return mSheet->DeleteRuleFromGroup(this, aIndex);
872 // -------------------------------------------
873 // nsICSSMediaRule
875 nsCSSMediaRule::nsCSSMediaRule()
879 nsCSSMediaRule::nsCSSMediaRule(const nsCSSMediaRule& aCopy)
880 : nsCSSGroupRule(aCopy)
882 if (aCopy.mMedia) {
883 aCopy.mMedia->Clone(getter_AddRefs(mMedia));
884 if (mMedia) {
885 // XXXldb This doesn't really make sense.
886 mMedia->SetStyleSheet(aCopy.mSheet);
891 nsCSSMediaRule::~nsCSSMediaRule()
893 if (mMedia) {
894 mMedia->SetStyleSheet(nsnull);
898 NS_IMPL_ADDREF_INHERITED(nsCSSMediaRule, nsCSSRule)
899 NS_IMPL_RELEASE_INHERITED(nsCSSMediaRule, nsCSSRule)
901 // QueryInterface implementation for nsCSSMediaRule
902 NS_INTERFACE_MAP_BEGIN(nsCSSMediaRule)
903 NS_INTERFACE_MAP_ENTRY(nsICSSGroupRule)
904 NS_INTERFACE_MAP_ENTRY(nsICSSRule)
905 NS_INTERFACE_MAP_ENTRY(nsIStyleRule)
906 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
907 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSMediaRule)
908 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsCSSGroupRule)
909 NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(CSSMediaRule)
910 NS_INTERFACE_MAP_END
912 NS_IMETHODIMP
913 nsCSSMediaRule::SetStyleSheet(nsICSSStyleSheet* aSheet)
915 if (mMedia) {
916 // Set to null so it knows it's leaving one sheet and joining another.
917 mMedia->SetStyleSheet(nsnull);
918 mMedia->SetStyleSheet(aSheet);
921 return nsCSSGroupRule::SetStyleSheet(aSheet);
924 #ifdef DEBUG
925 NS_IMETHODIMP
926 nsCSSMediaRule::List(FILE* out, PRInt32 aIndent) const
928 for (PRInt32 indent = aIndent; --indent >= 0; ) fputs(" ", out);
930 nsAutoString buffer;
932 fputs("@media ", out);
934 if (mMedia) {
935 nsAutoString mediaText;
936 mMedia->GetText(mediaText);
937 fputs(NS_LossyConvertUTF16toASCII(mediaText).get(), out);
940 return nsCSSGroupRule::List(out, aIndent);
942 #endif
944 NS_IMETHODIMP
945 nsCSSMediaRule::GetType(PRInt32& aType) const
947 aType = nsICSSRule::MEDIA_RULE;
948 return NS_OK;
951 NS_IMETHODIMP
952 nsCSSMediaRule::Clone(nsICSSRule*& aClone) const
954 nsCSSMediaRule* clone = new nsCSSMediaRule(*this);
955 if (clone) {
956 return CallQueryInterface(clone, &aClone);
958 aClone = nsnull;
959 return NS_ERROR_OUT_OF_MEMORY;
962 nsresult
963 nsCSSMediaRule::SetMedia(nsMediaList* aMedia)
965 mMedia = aMedia;
966 if (aMedia)
967 mMedia->SetStyleSheet(mSheet);
968 return NS_OK;
971 // nsIDOMCSSRule methods
972 NS_IMETHODIMP
973 nsCSSMediaRule::GetType(PRUint16* aType)
975 *aType = nsIDOMCSSRule::MEDIA_RULE;
976 return NS_OK;
979 NS_IMETHODIMP
980 nsCSSMediaRule::GetCssText(nsAString& aCssText)
982 aCssText.AssignLiteral("@media ");
983 // get all the media
984 if (mMedia) {
985 nsAutoString mediaText;
986 mMedia->GetText(mediaText);
987 aCssText.Append(mediaText);
990 return nsCSSGroupRule::AppendRulesToCssText(aCssText);
993 NS_IMETHODIMP
994 nsCSSMediaRule::SetCssText(const nsAString& aCssText)
996 return NS_ERROR_NOT_IMPLEMENTED;
999 NS_IMETHODIMP
1000 nsCSSMediaRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
1002 return nsCSSGroupRule::GetParentStyleSheet(aSheet);
1005 NS_IMETHODIMP
1006 nsCSSMediaRule::GetParentRule(nsIDOMCSSRule** aParentRule)
1008 return nsCSSGroupRule::GetParentRule(aParentRule);
1011 // nsIDOMCSSMediaRule methods
1012 NS_IMETHODIMP
1013 nsCSSMediaRule::GetMedia(nsIDOMMediaList* *aMedia)
1015 NS_ENSURE_ARG_POINTER(aMedia);
1016 if (!mMedia) {
1017 *aMedia = nsnull;
1018 return NS_OK;
1021 return CallQueryInterface(mMedia.get(), aMedia);
1024 NS_IMETHODIMP
1025 nsCSSMediaRule::GetCssRules(nsIDOMCSSRuleList* *aRuleList)
1027 return nsCSSGroupRule::GetCssRules(aRuleList);
1030 NS_IMETHODIMP
1031 nsCSSMediaRule::InsertRule(const nsAString & aRule, PRUint32 aIndex, PRUint32* _retval)
1033 return nsCSSGroupRule::InsertRule(aRule, aIndex, _retval);
1036 NS_IMETHODIMP
1037 nsCSSMediaRule::DeleteRule(PRUint32 aIndex)
1039 return nsCSSGroupRule::DeleteRule(aIndex);
1042 // nsICSSGroupRule interface
1043 NS_IMETHODIMP_(PRBool)
1044 nsCSSMediaRule::UseForPresentation(nsPresContext* aPresContext,
1045 nsMediaQueryResultCacheKey& aKey)
1047 if (mMedia) {
1048 return mMedia->Matches(aPresContext, aKey);
1050 return PR_TRUE;
1054 nsCSSDocumentRule::nsCSSDocumentRule(void)
1058 nsCSSDocumentRule::nsCSSDocumentRule(const nsCSSDocumentRule& aCopy)
1059 : nsCSSGroupRule(aCopy)
1060 , mURLs(new URL(*aCopy.mURLs))
1064 nsCSSDocumentRule::~nsCSSDocumentRule(void)
1068 NS_IMPL_ADDREF_INHERITED(nsCSSDocumentRule, nsCSSRule)
1069 NS_IMPL_RELEASE_INHERITED(nsCSSDocumentRule, nsCSSRule)
1071 // QueryInterface implementation for nsCSSDocumentRule
1072 NS_INTERFACE_MAP_BEGIN(nsCSSDocumentRule)
1073 NS_INTERFACE_MAP_ENTRY(nsICSSGroupRule)
1074 NS_INTERFACE_MAP_ENTRY(nsICSSRule)
1075 NS_INTERFACE_MAP_ENTRY(nsIStyleRule)
1076 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
1077 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSMozDocumentRule)
1078 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsCSSGroupRule)
1079 NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(CSSMozDocumentRule)
1080 NS_INTERFACE_MAP_END
1082 #ifdef DEBUG
1083 NS_IMETHODIMP
1084 nsCSSDocumentRule::List(FILE* out, PRInt32 aIndent) const
1086 for (PRInt32 indent = aIndent; --indent >= 0; ) fputs(" ", out);
1088 nsCAutoString str;
1089 str.AssignLiteral("@-moz-document ");
1090 for (URL *url = mURLs; url; url = url->next) {
1091 switch (url->func) {
1092 case eURL:
1093 str.AppendLiteral("url(\"");
1094 break;
1095 case eURLPrefix:
1096 str.AppendLiteral("url-prefix(\"");
1097 break;
1098 case eDomain:
1099 str.AppendLiteral("domain(\"");
1100 break;
1102 nsCAutoString escapedURL(url->url);
1103 escapedURL.ReplaceSubstring("\"", "\\\""); // escape quotes
1104 str.Append(escapedURL);
1105 str.AppendLiteral("\"), ");
1107 str.Cut(str.Length() - 2, 1); // remove last ,
1108 fputs(str.get(), out);
1110 return nsCSSGroupRule::List(out, aIndent);
1112 #endif
1114 NS_IMETHODIMP
1115 nsCSSDocumentRule::GetType(PRInt32& aType) const
1117 aType = nsICSSRule::DOCUMENT_RULE;
1118 return NS_OK;
1121 NS_IMETHODIMP
1122 nsCSSDocumentRule::Clone(nsICSSRule*& aClone) const
1124 nsCSSDocumentRule* clone = new nsCSSDocumentRule(*this);
1125 if (clone) {
1126 return CallQueryInterface(clone, &aClone);
1128 aClone = nsnull;
1129 return NS_ERROR_OUT_OF_MEMORY;
1132 // nsIDOMCSSRule methods
1133 NS_IMETHODIMP
1134 nsCSSDocumentRule::GetType(PRUint16* aType)
1136 // XXX What should really happen here?
1137 *aType = nsIDOMCSSRule::UNKNOWN_RULE;
1138 return NS_OK;
1141 NS_IMETHODIMP
1142 nsCSSDocumentRule::GetCssText(nsAString& aCssText)
1144 aCssText.AssignLiteral("@-moz-document ");
1145 for (URL *url = mURLs; url; url = url->next) {
1146 switch (url->func) {
1147 case eURL:
1148 aCssText.AppendLiteral("url(\"");
1149 break;
1150 case eURLPrefix:
1151 aCssText.AppendLiteral("url-prefix(\"");
1152 break;
1153 case eDomain:
1154 aCssText.AppendLiteral("domain(\"");
1155 break;
1157 nsCAutoString escapedURL(url->url);
1158 escapedURL.ReplaceSubstring("\"", "\\\""); // escape quotes
1159 AppendUTF8toUTF16(escapedURL, aCssText);
1160 aCssText.AppendLiteral("\"), ");
1162 aCssText.Cut(aCssText.Length() - 2, 1); // remove last ,
1164 return nsCSSGroupRule::AppendRulesToCssText(aCssText);
1167 NS_IMETHODIMP
1168 nsCSSDocumentRule::SetCssText(const nsAString& aCssText)
1170 return NS_ERROR_NOT_IMPLEMENTED;
1173 NS_IMETHODIMP
1174 nsCSSDocumentRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
1176 return nsCSSGroupRule::GetParentStyleSheet(aSheet);
1179 NS_IMETHODIMP
1180 nsCSSDocumentRule::GetParentRule(nsIDOMCSSRule** aParentRule)
1182 return nsCSSGroupRule::GetParentRule(aParentRule);
1185 NS_IMETHODIMP
1186 nsCSSDocumentRule::GetCssRules(nsIDOMCSSRuleList* *aRuleList)
1188 return nsCSSGroupRule::GetCssRules(aRuleList);
1191 NS_IMETHODIMP
1192 nsCSSDocumentRule::InsertRule(const nsAString & aRule, PRUint32 aIndex, PRUint32* _retval)
1194 return nsCSSGroupRule::InsertRule(aRule, aIndex, _retval);
1197 NS_IMETHODIMP
1198 nsCSSDocumentRule::DeleteRule(PRUint32 aIndex)
1200 return nsCSSGroupRule::DeleteRule(aIndex);
1203 // nsICSSGroupRule interface
1204 NS_IMETHODIMP_(PRBool)
1205 nsCSSDocumentRule::UseForPresentation(nsPresContext* aPresContext,
1206 nsMediaQueryResultCacheKey& aKey)
1208 nsIURI *docURI = aPresContext->Document()->GetDocumentURI();
1209 nsCAutoString docURISpec;
1210 if (docURI)
1211 docURI->GetSpec(docURISpec);
1213 for (URL *url = mURLs; url; url = url->next) {
1214 switch (url->func) {
1215 case eURL: {
1216 if (docURISpec == url->url)
1217 return PR_TRUE;
1218 } break;
1219 case eURLPrefix: {
1220 if (StringBeginsWith(docURISpec, url->url))
1221 return PR_TRUE;
1222 } break;
1223 case eDomain: {
1224 nsCAutoString host;
1225 if (docURI)
1226 docURI->GetHost(host);
1227 PRInt32 lenDiff = host.Length() - url->url.Length();
1228 if (lenDiff == 0) {
1229 if (host == url->url)
1230 return PR_TRUE;
1231 } else {
1232 if (StringEndsWith(host, url->url) &&
1233 host.CharAt(lenDiff - 1) == '.')
1234 return PR_TRUE;
1236 } break;
1240 return PR_FALSE;
1244 // -------------------------------------------
1245 // nsICSSNameSpaceRule
1247 class CSSNameSpaceRuleImpl : public nsCSSRule,
1248 public nsICSSNameSpaceRule,
1249 public nsIDOMCSSRule
1251 public:
1252 CSSNameSpaceRuleImpl(void);
1253 CSSNameSpaceRuleImpl(const CSSNameSpaceRuleImpl& aCopy);
1254 virtual ~CSSNameSpaceRuleImpl(void);
1256 NS_DECL_ISUPPORTS_INHERITED
1258 DECL_STYLE_RULE_INHERIT
1260 // nsIStyleRule methods
1261 #ifdef DEBUG
1262 NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const;
1263 #endif
1265 // nsICSSRule methods
1266 NS_IMETHOD GetType(PRInt32& aType) const;
1267 NS_IMETHOD Clone(nsICSSRule*& aClone) const;
1269 // nsICSSNameSpaceRule methods
1270 NS_IMETHOD GetPrefix(nsIAtom*& aPrefix) const;
1271 NS_IMETHOD SetPrefix(nsIAtom* aPrefix);
1273 NS_IMETHOD GetURLSpec(nsString& aURLSpec) const;
1274 NS_IMETHOD SetURLSpec(const nsString& aURLSpec);
1276 // nsIDOMCSSRule interface
1277 NS_DECL_NSIDOMCSSRULE
1279 protected:
1280 nsIAtom* mPrefix;
1281 nsString mURLSpec;
1284 CSSNameSpaceRuleImpl::CSSNameSpaceRuleImpl(void)
1285 : nsCSSRule(),
1286 mPrefix(nsnull),
1287 mURLSpec()
1291 CSSNameSpaceRuleImpl::CSSNameSpaceRuleImpl(const CSSNameSpaceRuleImpl& aCopy)
1292 : nsCSSRule(aCopy),
1293 mPrefix(aCopy.mPrefix),
1294 mURLSpec(aCopy.mURLSpec)
1296 NS_IF_ADDREF(mPrefix);
1299 CSSNameSpaceRuleImpl::~CSSNameSpaceRuleImpl(void)
1301 NS_IF_RELEASE(mPrefix);
1304 NS_IMPL_ADDREF_INHERITED(CSSNameSpaceRuleImpl, nsCSSRule)
1305 NS_IMPL_RELEASE_INHERITED(CSSNameSpaceRuleImpl, nsCSSRule)
1307 // QueryInterface implementation for CSSNameSpaceRuleImpl
1308 NS_INTERFACE_MAP_BEGIN(CSSNameSpaceRuleImpl)
1309 NS_INTERFACE_MAP_ENTRY(nsICSSNameSpaceRule)
1310 NS_INTERFACE_MAP_ENTRY(nsICSSRule)
1311 NS_INTERFACE_MAP_ENTRY(nsIStyleRule)
1312 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
1313 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsICSSNameSpaceRule)
1314 NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(CSSNameSpaceRule)
1315 NS_INTERFACE_MAP_END
1317 IMPL_STYLE_RULE_INHERIT(CSSNameSpaceRuleImpl, nsCSSRule)
1319 #ifdef DEBUG
1320 NS_IMETHODIMP
1321 CSSNameSpaceRuleImpl::List(FILE* out, PRInt32 aIndent) const
1323 for (PRInt32 indent = aIndent; --indent >= 0; ) fputs(" ", out);
1325 nsAutoString buffer;
1327 fputs("@namespace ", out);
1329 if (mPrefix) {
1330 mPrefix->ToString(buffer);
1331 fputs(NS_LossyConvertUTF16toASCII(buffer).get(), out);
1332 fputs(" ", out);
1335 fputs("url(", out);
1336 fputs(NS_LossyConvertUTF16toASCII(mURLSpec).get(), out);
1337 fputs(")\n", out);
1338 return NS_OK;
1340 #endif
1342 NS_IMETHODIMP
1343 CSSNameSpaceRuleImpl::GetType(PRInt32& aType) const
1345 aType = nsICSSRule::NAMESPACE_RULE;
1346 return NS_OK;
1349 NS_IMETHODIMP
1350 CSSNameSpaceRuleImpl::Clone(nsICSSRule*& aClone) const
1352 CSSNameSpaceRuleImpl* clone = new CSSNameSpaceRuleImpl(*this);
1353 if (clone) {
1354 return CallQueryInterface(clone, &aClone);
1356 aClone = nsnull;
1357 return NS_ERROR_OUT_OF_MEMORY;
1360 NS_IMETHODIMP
1361 CSSNameSpaceRuleImpl::GetPrefix(nsIAtom*& aPrefix) const
1363 aPrefix = mPrefix;
1364 NS_IF_ADDREF(aPrefix);
1365 return NS_OK;
1368 NS_IMETHODIMP
1369 CSSNameSpaceRuleImpl::SetPrefix(nsIAtom* aPrefix)
1371 NS_IF_RELEASE(mPrefix);
1372 mPrefix = aPrefix;
1373 NS_IF_ADDREF(mPrefix);
1374 return NS_OK;
1377 NS_IMETHODIMP
1378 CSSNameSpaceRuleImpl::GetURLSpec(nsString& aURLSpec) const
1380 aURLSpec = mURLSpec;
1381 return NS_OK;
1384 NS_IMETHODIMP
1385 CSSNameSpaceRuleImpl::SetURLSpec(const nsString& aURLSpec)
1387 mURLSpec = aURLSpec;
1388 return NS_OK;
1391 nsresult
1392 NS_NewCSSNameSpaceRule(nsICSSNameSpaceRule** aInstancePtrResult,
1393 nsIAtom* aPrefix, const nsString& aURLSpec)
1395 if (! aInstancePtrResult) {
1396 return NS_ERROR_NULL_POINTER;
1399 CSSNameSpaceRuleImpl* it = new CSSNameSpaceRuleImpl();
1401 if (! it) {
1402 return NS_ERROR_OUT_OF_MEMORY;
1405 it->SetPrefix(aPrefix);
1406 it->SetURLSpec(aURLSpec);
1407 return CallQueryInterface(it, aInstancePtrResult);
1410 NS_IMETHODIMP
1411 CSSNameSpaceRuleImpl::GetType(PRUint16* aType)
1413 // XXX What should really happen here?
1414 *aType = nsIDOMCSSRule::UNKNOWN_RULE;
1415 return NS_OK;
1418 NS_IMETHODIMP
1419 CSSNameSpaceRuleImpl::GetCssText(nsAString& aCssText)
1421 aCssText.AssignLiteral("@namespace ");
1422 if (mPrefix) {
1423 nsString atomStr;
1424 mPrefix->ToString(atomStr);
1425 aCssText.Append(atomStr);
1426 aCssText.AppendLiteral(" ");
1428 aCssText.AppendLiteral("url(");
1429 aCssText.Append(mURLSpec);
1430 aCssText.Append(NS_LITERAL_STRING(");"));
1431 return NS_OK;
1434 NS_IMETHODIMP
1435 CSSNameSpaceRuleImpl::SetCssText(const nsAString& aCssText)
1437 return NS_ERROR_NOT_IMPLEMENTED;
1440 NS_IMETHODIMP
1441 CSSNameSpaceRuleImpl::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
1443 if (mSheet) {
1444 return CallQueryInterface(mSheet, aSheet);
1446 *aSheet = nsnull;
1447 return NS_OK;
1450 NS_IMETHODIMP
1451 CSSNameSpaceRuleImpl::GetParentRule(nsIDOMCSSRule** aParentRule)
1453 if (mParentRule) {
1454 return mParentRule->GetDOMRule(aParentRule);
1456 *aParentRule = nsnull;
1457 return NS_OK;
1460 // -------------------------------------------
1461 // nsCSSFontFaceStyleDecl and related routines
1464 // A src: descriptor is represented as an array value; each entry in
1465 // the array can be eCSSUnit_URL, eCSSUnit_Local_Font, or
1466 // eCSSUnit_Font_Format. Blocks of eCSSUnit_Font_Format may appear
1467 // only after one of the first two. (css3-fonts only contemplates
1468 // annotating URLs with formats, but we handle the general case.)
1469 static void
1470 SerializeFontSrc(const nsCSSValue& src, nsAString & aResult NS_OUTPARAM)
1472 NS_PRECONDITION(src.GetUnit() == eCSSUnit_Null ||
1473 src.GetUnit() == eCSSUnit_Array,
1474 "improper value unit for src:");
1475 aResult.Truncate();
1476 if (src.GetUnit() != eCSSUnit_Array)
1477 return;
1479 const nsCSSValue::Array& sources = *src.GetArrayValue();
1480 PRUint32 i = 0;
1482 while (i < sources.Count()) {
1483 nsAutoString formats;
1485 if (sources[i].GetUnit() == eCSSUnit_URL) {
1486 nsDependentString url(sources[i].GetOriginalURLValue());
1487 nsAutoString escapedUrl;
1488 nsStyleUtil::EscapeCSSString(url, escapedUrl);
1489 aResult.AppendLiteral("url(\"");
1490 aResult.Append(escapedUrl);
1491 aResult.AppendLiteral("\")");
1492 } else if (sources[i].GetUnit() == eCSSUnit_Local_Font) {
1493 nsDependentString local(sources[i].GetStringBufferValue());
1494 nsAutoString escapedLocal;
1495 nsStyleUtil::EscapeCSSString(local, escapedLocal);
1496 aResult.AppendLiteral("local(\"");
1497 aResult.Append(escapedLocal);
1498 aResult.AppendLiteral("\")");
1499 } else {
1500 NS_NOTREACHED("entry in src: descriptor with improper unit");
1501 i++;
1502 continue;
1505 i++;
1506 formats.Truncate();
1507 while (i < sources.Count() &&
1508 sources[i].GetUnit() == eCSSUnit_Font_Format) {
1509 formats.Append('"');
1510 formats.Append(sources[i].GetStringBufferValue());
1511 formats.AppendLiteral("\", ");
1512 i++;
1514 if (formats.Length() > 0) {
1515 formats.Truncate(formats.Length() - 2); // remove the last comma
1516 aResult.AppendLiteral(" format(");
1517 aResult.Append(formats);
1518 aResult.Append(')');
1520 aResult.AppendLiteral(", ");
1522 aResult.Truncate(aResult.Length() - 2); // remove the last comma-space
1525 // Mapping from nsCSSFontDesc codes to nsCSSFontFaceStyleDecl fields.
1526 // Keep this in sync with enum nsCSSFontDesc in nsCSSProperty.h.
1527 nsCSSValue nsCSSFontFaceStyleDecl::* const
1528 nsCSSFontFaceStyleDecl::Fields[] = {
1529 &nsCSSFontFaceStyleDecl::mFamily,
1530 &nsCSSFontFaceStyleDecl::mStyle,
1531 &nsCSSFontFaceStyleDecl::mWeight,
1532 &nsCSSFontFaceStyleDecl::mStretch,
1533 &nsCSSFontFaceStyleDecl::mSrc,
1534 &nsCSSFontFaceStyleDecl::mUnicodeRange
1537 // QueryInterface implementation for nsCSSFontFaceStyleDecl
1538 NS_INTERFACE_MAP_BEGIN(nsCSSFontFaceStyleDecl)
1539 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSStyleDeclaration)
1540 NS_INTERFACE_MAP_ENTRY(nsISupports)
1541 NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(CSSFontFaceStyleDecl)
1542 NS_INTERFACE_MAP_END
1544 NS_IMPL_ADDREF_USING_AGGREGATOR(nsCSSFontFaceStyleDecl, ContainingRule())
1545 NS_IMPL_RELEASE_USING_AGGREGATOR(nsCSSFontFaceStyleDecl, ContainingRule())
1547 // helper for string GetPropertyValue and RemovePropertyValue
1548 nsresult
1549 nsCSSFontFaceStyleDecl::GetPropertyValue(nsCSSFontDesc aFontDescID,
1550 nsAString & aResult NS_OUTPARAM) const
1552 NS_ENSURE_ARG_RANGE(aFontDescID, eCSSFontDesc_UNKNOWN,
1553 eCSSFontDesc_COUNT - 1);
1555 aResult.Truncate();
1556 if (aFontDescID == eCSSFontDesc_UNKNOWN)
1557 return NS_OK;
1559 const nsCSSValue& val = this->*nsCSSFontFaceStyleDecl::Fields[aFontDescID];
1561 switch (aFontDescID) {
1562 case eCSSFontDesc_Family: {
1563 // we don't use AppendCSSValueToString here because it doesn't
1564 // canonicalize the way we want, and anyway it's overkill when
1565 // we know we have eCSSUnit_String
1566 nsDependentString family(val.GetStringBufferValue());
1567 nsAutoString escapedFamily;
1568 nsStyleUtil::EscapeCSSString(family, escapedFamily);
1569 aResult.Append('"');
1570 aResult.Append(escapedFamily);
1571 aResult.Append('"');
1572 return NS_OK;
1575 case eCSSFontDesc_Style:
1576 nsCSSDeclaration::AppendCSSValueToString(eCSSProperty_font_style, val,
1577 aResult);
1578 return NS_OK;
1580 case eCSSFontDesc_Weight:
1581 nsCSSDeclaration::AppendCSSValueToString(eCSSProperty_font_weight, val,
1582 aResult);
1583 return NS_OK;
1585 case eCSSFontDesc_Stretch:
1586 nsCSSDeclaration::AppendCSSValueToString(eCSSProperty_font_stretch, val,
1587 aResult);
1588 return NS_OK;
1590 case eCSSFontDesc_Src:
1591 SerializeFontSrc(val, aResult);
1592 return NS_OK;
1594 case eCSSFontDesc_UnicodeRange:
1595 // these are not implemented, so always return an empty string
1596 return NS_OK;
1598 case eCSSFontDesc_UNKNOWN:
1599 case eCSSFontDesc_COUNT:
1602 NS_NOTREACHED("nsCSSFontFaceStyleDecl::GetPropertyValue: "
1603 "out-of-range value got to the switch");
1604 return NS_ERROR_INVALID_ARG;
1608 // attribute DOMString cssText;
1609 NS_IMETHODIMP
1610 nsCSSFontFaceStyleDecl::GetCssText(nsAString & aCssText)
1612 nsAutoString descStr;
1614 aCssText.Truncate();
1615 for (nsCSSFontDesc id = nsCSSFontDesc(eCSSFontDesc_UNKNOWN + 1);
1616 id < eCSSFontDesc_COUNT;
1617 id = nsCSSFontDesc(id + 1)) {
1618 if ((this->*nsCSSFontFaceStyleDecl::Fields[id]).GetUnit()
1619 != eCSSUnit_Null &&
1620 NS_SUCCEEDED(GetPropertyValue(id, descStr))) {
1621 NS_ASSERTION(descStr.Length() > 0,
1622 "GetCssText: non-null unit, empty property value");
1623 aCssText.AppendLiteral(" ");
1624 aCssText.AppendASCII(nsCSSProps::GetStringValue(id).get());
1625 aCssText.AppendLiteral(": ");
1626 aCssText.Append(descStr);
1627 aCssText.AppendLiteral(";\n");
1630 return NS_OK;
1633 NS_IMETHODIMP
1634 nsCSSFontFaceStyleDecl::SetCssText(const nsAString & aCssText)
1636 return NS_ERROR_NOT_IMPLEMENTED; // bug 443978
1639 // DOMString getPropertyValue (in DOMString propertyName);
1640 NS_IMETHODIMP
1641 nsCSSFontFaceStyleDecl::GetPropertyValue(const nsAString & propertyName,
1642 nsAString & aResult NS_OUTPARAM)
1644 return GetPropertyValue(nsCSSProps::LookupFontDesc(propertyName), aResult);
1647 // nsIDOMCSSValue getPropertyCSSValue (in DOMString propertyName);
1648 NS_IMETHODIMP
1649 nsCSSFontFaceStyleDecl::GetPropertyCSSValue(const nsAString & propertyName,
1650 nsIDOMCSSValue **aResult NS_OUTPARAM)
1652 // ??? nsDOMCSSDeclaration returns null/NS_OK, but that seems wrong.
1653 return NS_ERROR_NOT_IMPLEMENTED;
1656 // DOMString removeProperty (in DOMString propertyName) raises (DOMException);
1657 NS_IMETHODIMP
1658 nsCSSFontFaceStyleDecl::RemoveProperty(const nsAString & propertyName,
1659 nsAString & aResult NS_OUTPARAM)
1661 nsCSSFontDesc descID = nsCSSProps::LookupFontDesc(propertyName);
1662 NS_ASSERTION(descID >= eCSSFontDesc_UNKNOWN &&
1663 descID < eCSSFontDesc_COUNT,
1664 "LookupFontDesc returned value out of range");
1666 if (descID == eCSSFontDesc_UNKNOWN) {
1667 aResult.Truncate();
1668 } else {
1669 nsresult rv = GetPropertyValue(descID, aResult);
1670 NS_ENSURE_SUCCESS(rv, rv);
1671 (this->*nsCSSFontFaceStyleDecl::Fields[descID]).Reset();
1673 return NS_OK;
1676 // DOMString getPropertyPriority (in DOMString propertyName);
1677 NS_IMETHODIMP
1678 nsCSSFontFaceStyleDecl::GetPropertyPriority(const nsAString & propertyName,
1679 nsAString & aResult NS_OUTPARAM)
1681 // font descriptors do not have priorities at present
1682 aResult.Truncate();
1683 return NS_OK;
1686 // void setProperty (in DOMString propertyName, in DOMString value,
1687 // in DOMString priority) raises (DOMException);
1688 NS_IMETHODIMP
1689 nsCSSFontFaceStyleDecl::SetProperty(const nsAString & propertyName,
1690 const nsAString & value,
1691 const nsAString & priority)
1693 return NS_ERROR_NOT_IMPLEMENTED; // bug 443978
1696 // readonly attribute unsigned long length;
1697 NS_IMETHODIMP
1698 nsCSSFontFaceStyleDecl::GetLength(PRUint32 *aLength)
1700 PRUint32 len = 0;
1701 for (nsCSSFontDesc id = nsCSSFontDesc(eCSSFontDesc_UNKNOWN + 1);
1702 id < eCSSFontDesc_COUNT;
1703 id = nsCSSFontDesc(id + 1))
1704 if ((this->*nsCSSFontFaceStyleDecl::Fields[id]).GetUnit() != eCSSUnit_Null)
1705 len++;
1707 *aLength = len;
1708 return NS_OK;
1711 // DOMString item (in unsigned long index);
1712 NS_IMETHODIMP
1713 nsCSSFontFaceStyleDecl::Item(PRUint32 index, nsAString & aResult NS_OUTPARAM)
1715 PRInt32 nset = -1;
1716 for (nsCSSFontDesc id = nsCSSFontDesc(eCSSFontDesc_UNKNOWN + 1);
1717 id < eCSSFontDesc_COUNT;
1718 id = nsCSSFontDesc(id + 1)) {
1719 if ((this->*nsCSSFontFaceStyleDecl::Fields[id]).GetUnit()
1720 != eCSSUnit_Null) {
1721 nset++;
1722 if (nset == PRInt32(index)) {
1723 aResult.AssignASCII(nsCSSProps::GetStringValue(id).get());
1724 return NS_OK;
1728 aResult.Truncate();
1729 return NS_OK;
1732 // readonly attribute nsIDOMCSSRule parentRule;
1733 NS_IMETHODIMP
1734 nsCSSFontFaceStyleDecl::GetParentRule(nsIDOMCSSRule** aParentRule)
1736 return ContainingRule()->GetDOMRule(aParentRule);
1740 // -------------------------------------------
1741 // nsCSSFontFaceRule
1744 NS_IMETHODIMP
1745 nsCSSFontFaceRule::Clone(nsICSSRule*& aClone) const
1747 nsCSSFontFaceRule* clone = new nsCSSFontFaceRule(*this);
1748 if (clone) {
1749 return CallQueryInterface(clone, &aClone);
1751 aClone = nsnull;
1752 return NS_ERROR_OUT_OF_MEMORY;
1755 NS_IMPL_ADDREF_INHERITED(nsCSSFontFaceRule, nsCSSRule)
1756 NS_IMPL_RELEASE_INHERITED(nsCSSFontFaceRule, nsCSSRule)
1758 // QueryInterface implementation for nsCSSFontFaceRule
1759 NS_INTERFACE_MAP_BEGIN(nsCSSFontFaceRule)
1760 NS_INTERFACE_MAP_ENTRY(nsICSSRule)
1761 NS_INTERFACE_MAP_ENTRY(nsIStyleRule)
1762 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSFontFaceRule)
1763 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
1764 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsICSSRule)
1765 NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(CSSFontFaceRule)
1766 NS_INTERFACE_MAP_END
1768 IMPL_STYLE_RULE_INHERIT(nsCSSFontFaceRule, nsCSSRule)
1770 #ifdef DEBUG
1771 NS_IMETHODIMP
1772 nsCSSFontFaceRule::List(FILE* out, PRInt32 aIndent) const
1774 nsCString baseInd, descInd;
1775 for (PRInt32 indent = aIndent; --indent >= 0; ) {
1776 baseInd.AppendLiteral(" ");
1777 descInd.AppendLiteral(" ");
1779 descInd.AppendLiteral(" ");
1781 nsString descStr;
1783 fprintf(out, "%s@font-face {\n", baseInd.get());
1784 for (nsCSSFontDesc id = nsCSSFontDesc(eCSSFontDesc_UNKNOWN + 1);
1785 id < eCSSFontDesc_COUNT;
1786 id = nsCSSFontDesc(id + 1))
1787 if ((mDecl.*nsCSSFontFaceStyleDecl::Fields[id]).GetUnit()
1788 != eCSSUnit_Null) {
1789 if (NS_FAILED(mDecl.GetPropertyValue(id, descStr)))
1790 descStr.AssignLiteral("#<serialization error>");
1791 else if (descStr.Length() == 0)
1792 descStr.AssignLiteral("#<serialization missing>");
1793 fprintf(out, "%s%s: %s\n",
1794 descInd.get(), nsCSSProps::GetStringValue(id).get(),
1795 NS_ConvertUTF16toUTF8(descStr).get());
1797 fprintf(out, "%s}\n", baseInd.get());
1798 return NS_OK;
1800 #endif
1802 NS_IMETHODIMP
1803 nsCSSFontFaceRule::GetType(PRInt32& aType) const
1805 aType = nsICSSRule::FONT_FACE_RULE;
1806 return NS_OK;
1809 NS_IMETHODIMP
1810 nsCSSFontFaceRule::GetType(PRUint16* aType)
1812 *aType = nsIDOMCSSRule::FONT_FACE_RULE;
1813 return NS_OK;
1816 NS_IMETHODIMP
1817 nsCSSFontFaceRule::GetCssText(nsAString& aCssText)
1819 nsAutoString propText;
1820 mDecl.GetCssText(propText);
1822 aCssText.AssignLiteral("@font-face {\n");
1823 aCssText.Append(propText);
1824 aCssText.Append('}');
1825 return NS_OK;
1828 NS_IMETHODIMP
1829 nsCSSFontFaceRule::SetCssText(const nsAString& aCssText)
1831 return NS_ERROR_NOT_IMPLEMENTED; // bug 443978
1834 NS_IMETHODIMP
1835 nsCSSFontFaceRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
1837 if (mSheet) {
1838 return CallQueryInterface(mSheet, aSheet);
1840 *aSheet = nsnull;
1841 return NS_OK;
1844 NS_IMETHODIMP
1845 nsCSSFontFaceRule::GetParentRule(nsIDOMCSSRule** aParentRule)
1847 if (mParentRule) {
1848 return mParentRule->GetDOMRule(aParentRule);
1850 *aParentRule = nsnull;
1851 return NS_OK;
1854 NS_IMETHODIMP
1855 nsCSSFontFaceRule::GetStyle(nsIDOMCSSStyleDeclaration** aStyle)
1857 return CallQueryInterface(&mDecl, aStyle);
1860 // Arguably these should forward to nsCSSFontFaceStyleDecl methods.
1861 void
1862 nsCSSFontFaceRule::SetDesc(nsCSSFontDesc aDescID, nsCSSValue const & aValue)
1864 NS_PRECONDITION(aDescID > eCSSFontDesc_UNKNOWN &&
1865 aDescID < eCSSFontDesc_COUNT,
1866 "aDescID out of range in nsCSSFontFaceRule::SetDesc");
1868 mDecl.*nsCSSFontFaceStyleDecl::Fields[aDescID] = aValue;
1871 void
1872 nsCSSFontFaceRule::GetDesc(nsCSSFontDesc aDescID, nsCSSValue & aValue)
1874 NS_PRECONDITION(aDescID > eCSSFontDesc_UNKNOWN &&
1875 aDescID < eCSSFontDesc_COUNT,
1876 "aDescID out of range in nsCSSFontFaceRule::GetDesc");
1878 aValue = mDecl.*nsCSSFontFaceStyleDecl::Fields[aDescID];