Back to index

lightning-sunbird  0.9+nobinonly
nsCSSRules.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1999
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Boris Zbarsky <bzbarsky@mit.edu>
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either of the GNU General Public License Version 2 or later (the "GPL"),
00027  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 #include "nsCSSRules.h"
00039 #include "nsICSSImportRule.h"
00040 #include "nsICSSNameSpaceRule.h"
00041 
00042 #include "nsString.h"
00043 #include "nsIAtom.h"
00044 #include "nsISupportsArray.h"
00045 #include "nsIURL.h"
00046 
00047 #include "nsCSSRule.h"
00048 #include "nsLayoutAtoms.h"
00049 #include "nsICSSStyleSheet.h"
00050 
00051 #include "nsCOMPtr.h"
00052 #include "nsIDOMCSSStyleSheet.h"
00053 #include "nsIDOMCSSRule.h"
00054 #include "nsIDOMCSSImportRule.h"
00055 #include "nsIDOMCSSMediaRule.h"
00056 #include "nsIDOMCSSMozDocumentRule.h"
00057 #include "nsIDOMCSSCharsetRule.h"
00058 #include "nsIMediaList.h"
00059 #include "nsIDOMMediaList.h"
00060 #include "nsIDOMCSSRuleList.h"
00061 #include "nsIDOMStyleSheet.h"
00062 #include "nsIDocument.h"
00063 #include "nsPresContext.h"
00064 
00065 #include "nsContentUtils.h"
00066 #include "nsStyleConsts.h"
00067 #include "nsDOMError.h"
00068 
00069 #define IMPL_STYLE_RULE_INHERIT(_class, super) \
00070 NS_IMETHODIMP _class::GetStyleSheet(nsIStyleSheet*& aSheet) const { return super::GetStyleSheet(aSheet); }  \
00071 NS_IMETHODIMP _class::SetStyleSheet(nsICSSStyleSheet* aSheet) { return super::SetStyleSheet(aSheet); }  \
00072 NS_IMETHODIMP _class::SetParentRule(nsICSSGroupRule* aRule) { return super::SetParentRule(aRule); }  \
00073 NS_IMETHODIMP _class::GetDOMRule(nsIDOMCSSRule** aDOMRule) { return CallQueryInterface(this, aDOMRule); }  \
00074 NS_IMETHODIMP _class::MapRuleInfoInto(nsRuleData* aRuleData) { return NS_OK; } 
00075 
00076 #define IMPL_STYLE_RULE_INHERIT2(_class, super) \
00077 NS_IMETHODIMP _class::GetStyleSheet(nsIStyleSheet*& aSheet) const { return super::GetStyleSheet(aSheet); }  \
00078 NS_IMETHODIMP _class::SetParentRule(nsICSSGroupRule* aRule) { return super::SetParentRule(aRule); }  \
00079 NS_IMETHODIMP _class::GetDOMRule(nsIDOMCSSRule** aDOMRule) { return CallQueryInterface(this, aDOMRule); }  \
00080 NS_IMETHODIMP _class::MapRuleInfoInto(nsRuleData* aRuleData) { return NS_OK; } 
00081 
00082 // -------------------------------
00083 // Style Rule List for group rules
00084 //
00085 class CSSGroupRuleRuleListImpl : public nsIDOMCSSRuleList
00086 {
00087 public:
00088   CSSGroupRuleRuleListImpl(nsICSSGroupRule *aGroupRule);
00089 
00090   NS_DECL_ISUPPORTS
00091 
00092   NS_DECL_NSIDOMCSSRULELIST
00093 
00094   void DropReference() { mGroupRule = nsnull; }
00095 
00096 protected:
00097   virtual ~CSSGroupRuleRuleListImpl(void);
00098 
00099 private:
00100   nsICSSGroupRule* mGroupRule;
00101 };
00102 
00103 CSSGroupRuleRuleListImpl::CSSGroupRuleRuleListImpl(nsICSSGroupRule *aGroupRule)
00104 {
00105   // Not reference counted to avoid circular references.
00106   // The rule will tell us when its going away.
00107   mGroupRule = aGroupRule;
00108 }
00109 
00110 CSSGroupRuleRuleListImpl::~CSSGroupRuleRuleListImpl()
00111 {
00112 }
00113 
00114 // QueryInterface implementation for CSSGroupRuleRuleList
00115 NS_INTERFACE_MAP_BEGIN(CSSGroupRuleRuleListImpl)
00116   NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRuleList)
00117   NS_INTERFACE_MAP_ENTRY(nsISupports)
00118   NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(CSSGroupRuleRuleList)
00119 NS_INTERFACE_MAP_END
00120 
00121 
00122 NS_IMPL_ADDREF(CSSGroupRuleRuleListImpl)
00123 NS_IMPL_RELEASE(CSSGroupRuleRuleListImpl)
00124 
00125 NS_IMETHODIMP    
00126 CSSGroupRuleRuleListImpl::GetLength(PRUint32* aLength)
00127 {
00128   if (mGroupRule) {
00129     PRInt32 count;
00130     mGroupRule->StyleRuleCount(count);
00131     *aLength = (PRUint32)count;
00132   } else {
00133     *aLength = 0;
00134   }
00135 
00136   return NS_OK;
00137 }
00138 
00139 NS_IMETHODIMP    
00140 CSSGroupRuleRuleListImpl::Item(PRUint32 aIndex, nsIDOMCSSRule** aReturn)
00141 {
00142   nsresult result = NS_OK;
00143 
00144   *aReturn = nsnull;
00145   if (mGroupRule) {
00146     nsCOMPtr<nsICSSRule> rule;
00147 
00148     result = mGroupRule->GetStyleRuleAt(aIndex, *getter_AddRefs(rule));
00149     if (rule) {
00150       result = rule->GetDOMRule(aReturn);
00151     } else if (result == NS_ERROR_ILLEGAL_VALUE) {
00152       result = NS_OK; // per spec: "Return Value ... null if ... not a valid index."
00153     }
00154   }
00155   
00156   return result;
00157 }
00158 
00159 // -------------------------------------------
00160 // CharsetRule
00161 //
00162 class CSSCharsetRuleImpl : public nsCSSRule,
00163                            public nsICSSRule,
00164                            public nsIDOMCSSCharsetRule
00165 {
00166 public:
00167   CSSCharsetRuleImpl(const nsAString& aEncoding);
00168   CSSCharsetRuleImpl(const CSSCharsetRuleImpl& aCopy);
00169   virtual ~CSSCharsetRuleImpl(void);
00170 
00171   NS_DECL_ISUPPORTS_INHERITED
00172 
00173   DECL_STYLE_RULE_INHERIT
00174 
00175   // nsIStyleRule methods
00176 #ifdef DEBUG
00177   NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const;
00178 #endif
00179 
00180   // nsICSSRule methods
00181   NS_IMETHOD GetType(PRInt32& aType) const;
00182   NS_IMETHOD Clone(nsICSSRule*& aClone) const;
00183 
00184   // nsIDOMCSSRule interface
00185   NS_DECL_NSIDOMCSSRULE
00186   
00187   // nsIDOMCSSCharsetRule methods
00188   NS_IMETHOD GetEncoding(nsAString& aEncoding);
00189   NS_IMETHOD SetEncoding(const nsAString& aEncoding);
00190 
00191 protected:
00192   nsString  mEncoding;
00193 };
00194 
00195 CSSCharsetRuleImpl::CSSCharsetRuleImpl(const nsAString& aEncoding)
00196   : nsCSSRule(),
00197     mEncoding(aEncoding)
00198 {
00199 }
00200 
00201 CSSCharsetRuleImpl::CSSCharsetRuleImpl(const CSSCharsetRuleImpl& aCopy)
00202   : nsCSSRule(aCopy),
00203     mEncoding(aCopy.mEncoding)
00204 {
00205 }
00206 
00207 CSSCharsetRuleImpl::~CSSCharsetRuleImpl(void)
00208 {
00209 }
00210 
00211 NS_IMPL_ADDREF_INHERITED(CSSCharsetRuleImpl, nsCSSRule)
00212 NS_IMPL_RELEASE_INHERITED(CSSCharsetRuleImpl, nsCSSRule)
00213 
00214 // QueryInterface implementation for CSSCharsetRuleImpl
00215 NS_INTERFACE_MAP_BEGIN(CSSCharsetRuleImpl)
00216   NS_INTERFACE_MAP_ENTRY(nsICSSRule)
00217   NS_INTERFACE_MAP_ENTRY(nsIStyleRule)
00218   NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
00219   NS_INTERFACE_MAP_ENTRY(nsIDOMCSSCharsetRule)
00220   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsICSSRule)
00221   NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(CSSCharsetRule)
00222 NS_INTERFACE_MAP_END
00223 
00224 IMPL_STYLE_RULE_INHERIT(CSSCharsetRuleImpl, nsCSSRule)
00225 
00226 #ifdef DEBUG
00227 NS_IMETHODIMP
00228 CSSCharsetRuleImpl::List(FILE* out, PRInt32 aIndent) const
00229 {
00230   // Indent
00231   for (PRInt32 indent = aIndent; --indent >= 0; ) fputs("  ", out);
00232 
00233   fputs("@charset \"", out);
00234   fputs(NS_LossyConvertUCS2toASCII(mEncoding).get(), out);
00235   fputs("\"\n", out);
00236 
00237   return NS_OK;
00238 }
00239 #endif
00240 
00241 NS_IMETHODIMP
00242 CSSCharsetRuleImpl::GetType(PRInt32& aType) const
00243 {
00244   aType = nsICSSRule::CHARSET_RULE;
00245   return NS_OK;
00246 }
00247 
00248 NS_IMETHODIMP
00249 CSSCharsetRuleImpl::Clone(nsICSSRule*& aClone) const
00250 {
00251   CSSCharsetRuleImpl* clone = new CSSCharsetRuleImpl(*this);
00252   if (clone) {
00253     return CallQueryInterface(clone, &aClone);
00254   }
00255   aClone = nsnull;
00256   return NS_ERROR_OUT_OF_MEMORY;
00257 }
00258 
00259 NS_IMETHODIMP
00260 CSSCharsetRuleImpl::GetEncoding(nsAString& aEncoding)
00261 {
00262   aEncoding = mEncoding;
00263   return NS_OK;
00264 }
00265 
00266 NS_IMETHODIMP
00267 CSSCharsetRuleImpl::SetEncoding(const nsAString& aEncoding)
00268 {
00269   mEncoding = aEncoding;
00270   return NS_OK;
00271 }
00272 
00273 
00274 nsresult
00275 NS_NewCSSCharsetRule(nsICSSRule** aInstancePtrResult, const nsAString& aEncoding)
00276 {
00277   if (! aInstancePtrResult) {
00278     return NS_ERROR_NULL_POINTER;
00279   }
00280 
00281   CSSCharsetRuleImpl* it = new CSSCharsetRuleImpl(aEncoding);
00282 
00283   if (! it) {
00284     return NS_ERROR_OUT_OF_MEMORY;
00285   }
00286 
00287   return CallQueryInterface(it, aInstancePtrResult);
00288 }
00289 
00290 NS_IMETHODIMP
00291 CSSCharsetRuleImpl::GetType(PRUint16* aType)
00292 {
00293   *aType = nsIDOMCSSRule::CHARSET_RULE;
00294   return NS_OK;
00295 }
00296 
00297 NS_IMETHODIMP
00298 CSSCharsetRuleImpl::GetCssText(nsAString& aCssText)
00299 {
00300   aCssText.AssignLiteral("@charset \"");
00301   aCssText.Append(mEncoding);
00302   aCssText.AppendLiteral("\";");
00303   return NS_OK;
00304 }
00305 
00306 NS_IMETHODIMP
00307 CSSCharsetRuleImpl::SetCssText(const nsAString& aCssText)
00308 {
00309   return NS_ERROR_NOT_IMPLEMENTED;
00310 }
00311 
00312 NS_IMETHODIMP
00313 CSSCharsetRuleImpl::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
00314 {
00315   NS_ENSURE_ARG_POINTER(aSheet);
00316 
00317   if (mSheet) {
00318     return CallQueryInterface(mSheet, aSheet);
00319   }
00320   *aSheet = nsnull;
00321   return NS_OK;
00322 }
00323 
00324 NS_IMETHODIMP
00325 CSSCharsetRuleImpl::GetParentRule(nsIDOMCSSRule** aParentRule)
00326 {
00327   if (mParentRule) {
00328     return mParentRule->GetDOMRule(aParentRule);
00329   }
00330   *aParentRule = nsnull;
00331   return NS_OK;
00332 }
00333 
00334 
00335 
00336 // -------------------------------------------
00337 // nsICSSImportRule
00338 //
00339 class CSSImportRuleImpl : public nsCSSRule,
00340                           public nsICSSImportRule,
00341                           public nsIDOMCSSImportRule
00342 {
00343 public:
00344   CSSImportRuleImpl(nsMediaList* aMedia);
00345   CSSImportRuleImpl(const CSSImportRuleImpl& aCopy);
00346   virtual ~CSSImportRuleImpl(void);
00347 
00348   NS_DECL_ISUPPORTS_INHERITED
00349 
00350   DECL_STYLE_RULE_INHERIT
00351 
00352   // nsIStyleRule methods
00353 #ifdef DEBUG
00354   NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const;
00355 #endif
00356 
00357   // nsICSSRule methods
00358   NS_IMETHOD GetType(PRInt32& aType) const;
00359   NS_IMETHOD Clone(nsICSSRule*& aClone) const;
00360 
00361   // nsICSSImportRule methods
00362   NS_IMETHOD SetURLSpec(const nsString& aURLSpec);
00363   NS_IMETHOD GetURLSpec(nsString& aURLSpec) const;
00364 
00365   NS_IMETHOD SetMedia(const nsString& aMedia);
00366   NS_IMETHOD GetMedia(nsString& aMedia) const;
00367 
00368   NS_IMETHOD SetSheet(nsICSSStyleSheet*);
00369   
00370   // nsIDOMCSSRule interface
00371   NS_DECL_NSIDOMCSSRULE
00372 
00373   // nsIDOMCSSImportRule interface
00374   NS_DECL_NSIDOMCSSIMPORTRULE
00375 
00376 protected:
00377   nsString  mURLSpec;
00378   nsCOMPtr<nsMediaList> mMedia;
00379   nsCOMPtr<nsICSSStyleSheet> mChildSheet;
00380 };
00381 
00382 CSSImportRuleImpl::CSSImportRuleImpl(nsMediaList* aMedia)
00383   : nsCSSRule()
00384   , mURLSpec()
00385   , mMedia(aMedia)
00386 {
00387   // XXXbz This is really silly.... the mMedia here will be replaced
00388   // with itself if we manage to load a sheet.  Which should really
00389   // never fail nowadays, in sane cases.
00390 }
00391 
00392 CSSImportRuleImpl::CSSImportRuleImpl(const CSSImportRuleImpl& aCopy)
00393   : nsCSSRule(aCopy),
00394     mURLSpec(aCopy.mURLSpec)
00395 {
00396   nsCOMPtr<nsICSSStyleSheet> sheet;
00397   if (aCopy.mChildSheet) {
00398     aCopy.mChildSheet->Clone(nsnull, this, nsnull, nsnull,
00399                              getter_AddRefs(sheet));
00400   }
00401   SetSheet(sheet);
00402   // SetSheet sets mMedia appropriately
00403 }
00404 
00405 CSSImportRuleImpl::~CSSImportRuleImpl(void)
00406 {
00407   if (mChildSheet) {
00408     mChildSheet->SetOwnerRule(nsnull);
00409   }
00410 }
00411 
00412 NS_IMPL_ADDREF_INHERITED(CSSImportRuleImpl, nsCSSRule)
00413 NS_IMPL_RELEASE_INHERITED(CSSImportRuleImpl, nsCSSRule)
00414 
00415 // QueryInterface implementation for CSSImportRuleImpl
00416 NS_INTERFACE_MAP_BEGIN(CSSImportRuleImpl)
00417   NS_INTERFACE_MAP_ENTRY(nsICSSImportRule)
00418   NS_INTERFACE_MAP_ENTRY(nsICSSRule)
00419   NS_INTERFACE_MAP_ENTRY(nsIStyleRule)
00420   NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
00421   NS_INTERFACE_MAP_ENTRY(nsIDOMCSSImportRule)
00422   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsICSSImportRule)
00423   NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(CSSImportRule)
00424 NS_INTERFACE_MAP_END
00425 
00426 IMPL_STYLE_RULE_INHERIT(CSSImportRuleImpl, nsCSSRule)
00427 
00428 #ifdef DEBUG
00429 NS_IMETHODIMP
00430 CSSImportRuleImpl::List(FILE* out, PRInt32 aIndent) const
00431 {
00432   // Indent
00433   for (PRInt32 indent = aIndent; --indent >= 0; ) fputs("  ", out);
00434 
00435   fputs("@import \"", out);
00436   fputs(NS_LossyConvertUCS2toASCII(mURLSpec).get(), out);
00437   fputs("\" ", out);
00438 
00439   nsAutoString mediaText;
00440   mMedia->GetText(mediaText);
00441   fputs(NS_LossyConvertUCS2toASCII(mediaText).get(), out);
00442   fputs("\n", out);
00443 
00444   return NS_OK;
00445 }
00446 #endif
00447 
00448 NS_IMETHODIMP
00449 CSSImportRuleImpl::GetType(PRInt32& aType) const
00450 {
00451   aType = nsICSSRule::IMPORT_RULE;
00452   return NS_OK;
00453 }
00454 
00455 NS_IMETHODIMP
00456 CSSImportRuleImpl::Clone(nsICSSRule*& aClone) const
00457 {
00458   CSSImportRuleImpl* clone = new CSSImportRuleImpl(*this);
00459   if (clone) {
00460     return CallQueryInterface(clone, &aClone);
00461   }
00462   aClone = nsnull;
00463   return NS_ERROR_OUT_OF_MEMORY;
00464 }
00465 
00466 NS_IMETHODIMP
00467 CSSImportRuleImpl::SetURLSpec(const nsString& aURLSpec)
00468 {
00469   mURLSpec = aURLSpec;
00470   return NS_OK;
00471 }
00472 
00473 NS_IMETHODIMP
00474 CSSImportRuleImpl::GetURLSpec(nsString& aURLSpec) const
00475 {
00476   aURLSpec = mURLSpec;
00477   return NS_OK;
00478 }
00479 
00480 NS_IMETHODIMP
00481 CSSImportRuleImpl::SetMedia(const nsString& aMedia)
00482 {
00483   if (mMedia) {
00484     return mMedia->SetText(aMedia);
00485   } else {
00486     return NS_OK;
00487   }
00488 }
00489 
00490 NS_IMETHODIMP
00491 CSSImportRuleImpl::GetMedia(nsString& aMedia) const
00492 {
00493   if (mMedia) {
00494     return mMedia->GetText(aMedia);
00495   } else {
00496     aMedia.Truncate();
00497     return NS_OK;
00498   }
00499 }
00500 
00501 NS_IMETHODIMP
00502 CSSImportRuleImpl::SetSheet(nsICSSStyleSheet* aSheet)
00503 {
00504   nsresult rv;
00505   NS_ENSURE_ARG_POINTER(aSheet);
00506   
00507   // set the new sheet
00508   mChildSheet = aSheet;
00509   aSheet->SetOwnerRule(this);
00510 
00511   // set our medialist to be the same as the sheet's medialist
00512   nsCOMPtr<nsIDOMStyleSheet> sheet(do_QueryInterface(mChildSheet, &rv));
00513   NS_ENSURE_SUCCESS(rv, rv);
00514   nsCOMPtr<nsIDOMMediaList> mediaList;
00515   rv = sheet->GetMedia(getter_AddRefs(mediaList));
00516   NS_ENSURE_SUCCESS(rv, rv);
00517   mMedia = do_QueryInterface(mediaList);
00518   
00519   return NS_OK;
00520 }
00521 
00522 nsresult
00523 NS_NewCSSImportRule(nsICSSImportRule** aInstancePtrResult, 
00524                     const nsString& aURLSpec,
00525                     nsMediaList* aMedia)
00526 {
00527   NS_ENSURE_ARG_POINTER(aInstancePtrResult);
00528 
00529   CSSImportRuleImpl* it = new CSSImportRuleImpl(aMedia);
00530 
00531   if (! it) {
00532     return NS_ERROR_OUT_OF_MEMORY;
00533   }
00534 
00535   it->SetURLSpec(aURLSpec);
00536   return CallQueryInterface(it, aInstancePtrResult);
00537 }
00538 
00539 NS_IMETHODIMP
00540 CSSImportRuleImpl::GetType(PRUint16* aType)
00541 {
00542   NS_ENSURE_ARG_POINTER(aType);
00543   *aType = nsIDOMCSSRule::IMPORT_RULE;
00544   return NS_OK;
00545 }
00546 
00547 NS_IMETHODIMP
00548 CSSImportRuleImpl::GetCssText(nsAString& aCssText)
00549 {
00550   aCssText.AssignLiteral("@import url(");
00551   aCssText.Append(mURLSpec);
00552   aCssText.Append(NS_LITERAL_STRING(")"));
00553   if (mMedia) {
00554     nsAutoString mediaText;
00555     mMedia->GetText(mediaText);
00556     if (!mediaText.IsEmpty()) {
00557       aCssText.AppendLiteral(" ");
00558       aCssText.Append(mediaText);
00559     }
00560   }
00561   aCssText.AppendLiteral(";");
00562   return NS_OK;
00563 }
00564 
00565 NS_IMETHODIMP
00566 CSSImportRuleImpl::SetCssText(const nsAString& aCssText)
00567 {
00568   return NS_ERROR_NOT_IMPLEMENTED;
00569 }
00570 
00571 NS_IMETHODIMP
00572 CSSImportRuleImpl::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
00573 {
00574   NS_ENSURE_ARG_POINTER(aSheet);
00575   if (mSheet) {
00576     return CallQueryInterface(mSheet, aSheet);
00577   }
00578   *aSheet = nsnull;
00579   return NS_OK;
00580 }
00581 
00582 NS_IMETHODIMP
00583 CSSImportRuleImpl::GetParentRule(nsIDOMCSSRule** aParentRule)
00584 {
00585   if (mParentRule) {
00586     return mParentRule->GetDOMRule(aParentRule);
00587   }
00588   *aParentRule = nsnull;
00589   return NS_OK;
00590 }
00591 
00592 NS_IMETHODIMP
00593 CSSImportRuleImpl::GetHref(nsAString & aHref)
00594 {
00595   aHref = mURLSpec;
00596   return NS_OK;
00597 }
00598 
00599 NS_IMETHODIMP
00600 CSSImportRuleImpl::GetMedia(nsIDOMMediaList * *aMedia)
00601 {
00602   NS_ENSURE_ARG_POINTER(aMedia);
00603   if (!mMedia) {
00604     *aMedia = nsnull;
00605     return NS_OK;
00606   }
00607 
00608   return CallQueryInterface(mMedia, aMedia);
00609 }
00610 
00611 NS_IMETHODIMP
00612 CSSImportRuleImpl::GetStyleSheet(nsIDOMCSSStyleSheet * *aStyleSheet)
00613 {
00614   NS_ENSURE_ARG_POINTER(aStyleSheet);
00615   if (!mChildSheet) {
00616     *aStyleSheet = nsnull;
00617     return NS_OK;
00618   }
00619 
00620   return CallQueryInterface(mChildSheet, aStyleSheet);
00621 }
00622 
00623 nsCSSGroupRule::nsCSSGroupRule()
00624   : nsCSSRule()
00625   , mRuleCollection(nsnull)
00626 {
00627 }
00628 
00629 static PRBool
00630 CloneRuleInto(nsISupports* aRule, void* aArray)
00631 {
00632   nsICSSRule* rule = (nsICSSRule*)aRule;
00633   nsICSSRule* clone = nsnull;
00634   rule->Clone(clone);
00635   if (clone) {
00636     nsISupportsArray* array = (nsISupportsArray*)aArray;
00637     array->AppendElement(clone);
00638     NS_RELEASE(clone);
00639   }
00640   return PR_TRUE;
00641 }
00642 
00643 static PRBool
00644 SetParentRuleReference(nsISupports* aRule, void* aParentRule)
00645 {
00646   nsICSSRule* rule = NS_STATIC_CAST(nsICSSRule*, aRule);
00647   nsCSSGroupRule* parentRule = NS_STATIC_CAST(nsCSSGroupRule*, aParentRule);
00648   rule->SetParentRule(parentRule);
00649   return PR_TRUE;
00650 }
00651 
00652 nsCSSGroupRule::nsCSSGroupRule(const nsCSSGroupRule& aCopy)
00653   : nsCSSRule(aCopy)
00654   , mRuleCollection(nsnull) // lazily constructed
00655 {
00656   if (aCopy.mRules) {
00657     NS_NewISupportsArray(getter_AddRefs(mRules));
00658     if (mRules) {
00659       aCopy.mRules->EnumerateForwards(CloneRuleInto, mRules);
00660       mRules->EnumerateForwards(SetParentRuleReference, this);
00661     }
00662   }
00663 }
00664 
00665 nsCSSGroupRule::~nsCSSGroupRule()
00666 {
00667   if (mRules) {
00668     mRules->EnumerateForwards(SetParentRuleReference, nsnull);
00669   }
00670   if (mRuleCollection) {
00671     mRuleCollection->DropReference();
00672     NS_RELEASE(mRuleCollection);
00673   }
00674 }
00675 
00676 IMPL_STYLE_RULE_INHERIT2(nsCSSGroupRule, nsCSSRule)
00677 
00678 static PRBool
00679 SetStyleSheetReference(nsISupports* aRule, void* aSheet)
00680 {
00681   nsICSSRule* rule = (nsICSSRule*)aRule;
00682   nsICSSStyleSheet* sheet = (nsICSSStyleSheet*)aSheet;
00683   rule->SetStyleSheet(sheet);
00684   return PR_TRUE;
00685 }
00686 
00687 NS_IMETHODIMP
00688 nsCSSGroupRule::SetStyleSheet(nsICSSStyleSheet* aSheet)
00689 {
00690   if (mRules) {
00691     mRules->EnumerateForwards(SetStyleSheetReference, aSheet);
00692   }
00693 
00694   return nsCSSRule::SetStyleSheet(aSheet);
00695 }
00696 
00697 #ifdef DEBUG
00698 NS_IMETHODIMP
00699 nsCSSGroupRule::List(FILE* out, PRInt32 aIndent) const
00700 {
00701   fputs(" {\n", out);
00702 
00703   if (mRules) {
00704     PRUint32 index = 0;
00705     PRUint32 count;
00706     mRules->Count(&count);
00707     while (index < count) {
00708       nsCOMPtr<nsICSSRule> rule = dont_AddRef((nsICSSRule*)mRules->ElementAt(index++));
00709       rule->List(out, aIndent + 1);
00710     }
00711   }
00712   fputs("}\n", out);
00713   return NS_OK;
00714 }
00715 #endif
00716 
00717 NS_IMETHODIMP
00718 nsCSSGroupRule::AppendStyleRule(nsICSSRule* aRule)
00719 {
00720   nsresult result = NS_OK;
00721   if (!mRules) {
00722     result = NS_NewISupportsArray(getter_AddRefs(mRules));
00723   }
00724   if (NS_SUCCEEDED(result) && mRules) {
00725     mRules->AppendElement(aRule);
00726     aRule->SetStyleSheet(mSheet);
00727     aRule->SetParentRule(this);
00728     if (mSheet) {
00729       // XXXldb Shouldn't we be using |WillDirty| and |DidDirty| (and
00730       // shouldn't |SetModified| be removed?
00731       mSheet->SetModified(PR_TRUE);
00732     }
00733   }
00734   return result;
00735 }
00736 
00737 NS_IMETHODIMP
00738 nsCSSGroupRule::StyleRuleCount(PRInt32& aCount) const
00739 {
00740   if (mRules) {
00741     PRUint32 count;
00742     mRules->Count(&count);
00743     aCount = (PRInt32)count;
00744   }
00745   else {
00746     aCount = 0;
00747   }
00748   return NS_OK;
00749 }
00750 
00751 NS_IMETHODIMP
00752 nsCSSGroupRule::GetStyleRuleAt(PRInt32 aIndex, nsICSSRule*& aRule) const
00753 {
00754   if (mRules) {
00755     PRInt32 count = 0;
00756     nsresult rv = StyleRuleCount(count);
00757     NS_ENSURE_SUCCESS(rv, rv);
00758     if (aIndex >= count) {
00759       aRule = nsnull;
00760       return NS_ERROR_ILLEGAL_VALUE;
00761     }      
00762     aRule = (nsICSSRule*)mRules->ElementAt(aIndex);
00763     return NS_OK;
00764   }
00765   return NS_ERROR_ILLEGAL_VALUE;
00766 }
00767 
00768 NS_IMETHODIMP
00769 nsCSSGroupRule::EnumerateRulesForwards(nsISupportsArrayEnumFunc aFunc, void * aData) const
00770 {
00771   if (mRules) {
00772     return ((mRules->EnumerateForwards(aFunc, aData)) ? NS_OK : NS_ENUMERATOR_FALSE);
00773   }
00774   return NS_OK;
00775 }
00776 
00777 /*
00778  * The next two methods (DeleteStyleRuleAt and InsertStyleRulesAt)
00779  * should never be called unless you have first called WillDirty() on
00780  * the parents tylesheet.  After they are called, DidDirty() needs to
00781  * be called on the sheet
00782  */
00783 NS_IMETHODIMP
00784 nsCSSGroupRule::DeleteStyleRuleAt(PRUint32 aIndex)
00785 {
00786   NS_ENSURE_TRUE(mRules, NS_ERROR_FAILURE);
00787 
00788   nsCOMPtr<nsICSSRule> rule = dont_AddRef((nsICSSRule*)mRules->ElementAt(aIndex));
00789   if (rule) {
00790     rule->SetStyleSheet(nsnull);
00791     rule->SetParentRule(nsnull);
00792   }
00793   return mRules->DeleteElementAt(aIndex);
00794 }
00795 
00796 NS_IMETHODIMP
00797 nsCSSGroupRule::InsertStyleRulesAt(PRUint32 aIndex, nsISupportsArray* aRules)
00798 {
00799   NS_ENSURE_TRUE(mRules, NS_ERROR_FAILURE);
00800 
00801   aRules->EnumerateForwards(SetStyleSheetReference, mSheet);
00802   aRules->EnumerateForwards(SetParentRuleReference, this);
00803   // There is no xpcom-compatible version of InsertElementsAt.... :(
00804   if (! mRules->InsertElementsAt(aRules, aIndex)) {
00805     return NS_ERROR_FAILURE;
00806   }
00807   return NS_OK;
00808 }
00809 
00810 NS_IMETHODIMP
00811 nsCSSGroupRule::ReplaceStyleRule(nsICSSRule* aOld, nsICSSRule* aNew)
00812 {
00813   PRInt32 index = mRules->IndexOf(aOld);
00814   NS_ENSURE_TRUE(index != -1, NS_ERROR_UNEXPECTED);
00815   mRules->ReplaceElementAt(aNew, index);
00816   aNew->SetStyleSheet(mSheet);
00817   aNew->SetParentRule(this);
00818   aOld->SetStyleSheet(nsnull);
00819   aOld->SetParentRule(nsnull);
00820   return NS_OK;
00821 }
00822 
00823 nsresult
00824 nsCSSGroupRule::AppendRulesToCssText(nsAString& aCssText)
00825 {
00826   aCssText.AppendLiteral(" {\n");
00827 
00828   // get all the rules
00829   if (mRules) {
00830     PRUint32 count;
00831     mRules->Count(&count);
00832     for (PRUint32 index = 0; index < count; index++) {
00833       nsCOMPtr<nsICSSRule> rule;
00834       mRules->GetElementAt(index, getter_AddRefs(rule));
00835       nsCOMPtr<nsIDOMCSSRule> domRule;
00836       rule->GetDOMRule(getter_AddRefs(domRule));
00837       if (domRule) {
00838         nsAutoString cssText;
00839         domRule->GetCssText(cssText);
00840         aCssText.Append(NS_LITERAL_STRING("  ") +
00841                         cssText +
00842                         NS_LITERAL_STRING("\n"));
00843       }
00844     }
00845   }
00846 
00847   aCssText.AppendLiteral("}");
00848   
00849   return NS_OK;
00850 }
00851 
00852 nsresult
00853 nsCSSGroupRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
00854 {
00855   if (mSheet) {
00856     return CallQueryInterface(mSheet, aSheet);
00857   }
00858   *aSheet = nsnull;
00859   return NS_OK;
00860 }
00861 
00862 nsresult
00863 nsCSSGroupRule::GetParentRule(nsIDOMCSSRule** aParentRule)
00864 {
00865   if (mParentRule) {
00866     return mParentRule->GetDOMRule(aParentRule);
00867   }
00868   *aParentRule = nsnull;
00869   return NS_OK;
00870 }
00871 
00872 // nsIDOMCSSMediaRule or nsIDOMCSSMozDocumentRule methods
00873 nsresult
00874 nsCSSGroupRule::GetCssRules(nsIDOMCSSRuleList* *aRuleList)
00875 {
00876   if (!mRuleCollection) {
00877     mRuleCollection = new CSSGroupRuleRuleListImpl(this);
00878     if (!mRuleCollection) {
00879       return NS_ERROR_OUT_OF_MEMORY;
00880     }
00881     NS_ADDREF(mRuleCollection);
00882   }
00883 
00884   return CallQueryInterface(mRuleCollection, aRuleList);
00885 }
00886 
00887 nsresult
00888 nsCSSGroupRule::InsertRule(const nsAString & aRule, PRUint32 aIndex, PRUint32* _retval)
00889 {
00890   NS_ENSURE_TRUE(mSheet, NS_ERROR_FAILURE);
00891   
00892   if (!mRules) {
00893     nsresult rv = NS_NewISupportsArray(getter_AddRefs(mRules));
00894     if (NS_FAILED(rv))
00895       return rv;
00896   }
00897 
00898   PRUint32 count;
00899   mRules->Count(&count);
00900   if (aIndex > count)
00901     return NS_ERROR_DOM_INDEX_SIZE_ERR;
00902   
00903   return mSheet->InsertRuleIntoGroup(aRule, this, aIndex, _retval);
00904 }
00905 
00906 nsresult
00907 nsCSSGroupRule::DeleteRule(PRUint32 aIndex)
00908 {
00909   NS_ENSURE_TRUE(mSheet, NS_ERROR_FAILURE);
00910   if (!mRules)  {
00911     return NS_ERROR_DOM_INDEX_SIZE_ERR;
00912   }
00913   
00914   PRUint32 count;
00915   mRules->Count(&count);
00916   if (aIndex >= count)
00917     return NS_ERROR_DOM_INDEX_SIZE_ERR;
00918 
00919   return mSheet->DeleteRuleFromGroup(this, aIndex);
00920 }
00921 
00922 // -------------------------------------------
00923 // nsICSSMediaRule
00924 //
00925 nsCSSMediaRule::nsCSSMediaRule()
00926 {
00927 }
00928 
00929 nsCSSMediaRule::nsCSSMediaRule(const nsCSSMediaRule& aCopy)
00930   : nsCSSGroupRule(aCopy)
00931 {
00932   if (aCopy.mMedia) {
00933     aCopy.mMedia->Clone(getter_AddRefs(mMedia));
00934     if (mMedia) {
00935       // XXXldb This doesn't really make sense.
00936       mMedia->SetStyleSheet(aCopy.mSheet);
00937     }
00938   }
00939 }
00940 
00941 nsCSSMediaRule::~nsCSSMediaRule()
00942 {
00943   if (mMedia) {
00944     mMedia->SetStyleSheet(nsnull);
00945   }
00946 }
00947 
00948 NS_IMPL_ADDREF_INHERITED(nsCSSMediaRule, nsCSSRule)
00949 NS_IMPL_RELEASE_INHERITED(nsCSSMediaRule, nsCSSRule)
00950 
00951 // QueryInterface implementation for nsCSSMediaRule
00952 NS_INTERFACE_MAP_BEGIN(nsCSSMediaRule)
00953   NS_INTERFACE_MAP_ENTRY(nsICSSGroupRule)
00954   NS_INTERFACE_MAP_ENTRY(nsICSSRule)
00955   NS_INTERFACE_MAP_ENTRY(nsIStyleRule)
00956   NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
00957   NS_INTERFACE_MAP_ENTRY(nsIDOMCSSMediaRule)
00958   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsCSSGroupRule)
00959   NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(CSSMediaRule)
00960 NS_INTERFACE_MAP_END
00961 
00962 NS_IMETHODIMP
00963 nsCSSMediaRule::SetStyleSheet(nsICSSStyleSheet* aSheet)
00964 {
00965   if (mMedia) {
00966     // Set to null so it knows it's leaving one sheet and joining another.
00967     mMedia->SetStyleSheet(nsnull);
00968     mMedia->SetStyleSheet(aSheet);
00969   }
00970 
00971   return nsCSSGroupRule::SetStyleSheet(aSheet);
00972 }
00973 
00974 #ifdef DEBUG
00975 NS_IMETHODIMP
00976 nsCSSMediaRule::List(FILE* out, PRInt32 aIndent) const
00977 {
00978   for (PRInt32 indent = aIndent; --indent >= 0; ) fputs("  ", out);
00979 
00980   nsAutoString  buffer;
00981 
00982   fputs("@media ", out);
00983 
00984   if (mMedia) {
00985     nsAutoString mediaText;
00986     mMedia->GetText(mediaText);
00987     fputs(NS_LossyConvertUCS2toASCII(mediaText).get(), out);
00988   }
00989 
00990   return nsCSSGroupRule::List(out, aIndent);
00991 }
00992 #endif
00993 
00994 NS_IMETHODIMP
00995 nsCSSMediaRule::GetType(PRInt32& aType) const
00996 {
00997   aType = nsICSSRule::MEDIA_RULE;
00998   return NS_OK;
00999 }
01000 
01001 NS_IMETHODIMP
01002 nsCSSMediaRule::Clone(nsICSSRule*& aClone) const
01003 {
01004   nsCSSMediaRule* clone = new nsCSSMediaRule(*this);
01005   if (clone) {
01006     return CallQueryInterface(clone, &aClone);
01007   }
01008   aClone = nsnull;
01009   return NS_ERROR_OUT_OF_MEMORY;
01010 }
01011 
01012 nsresult
01013 nsCSSMediaRule::SetMedia(nsMediaList* aMedia)
01014 {
01015   mMedia = aMedia;
01016   if (aMedia)
01017     mMedia->SetStyleSheet(mSheet);
01018   return NS_OK;
01019 }
01020 
01021 // nsIDOMCSSRule methods
01022 NS_IMETHODIMP
01023 nsCSSMediaRule::GetType(PRUint16* aType)
01024 {
01025   *aType = nsIDOMCSSRule::MEDIA_RULE;
01026   return NS_OK;
01027 }
01028 
01029 NS_IMETHODIMP
01030 nsCSSMediaRule::GetCssText(nsAString& aCssText)
01031 {
01032   aCssText.AssignLiteral("@media ");
01033   // get all the media
01034   if (mMedia) {
01035     nsAutoString mediaText;
01036     mMedia->GetText(mediaText);
01037     aCssText.Append(mediaText);
01038   }
01039 
01040   return nsCSSGroupRule::AppendRulesToCssText(aCssText);
01041 }
01042 
01043 NS_IMETHODIMP
01044 nsCSSMediaRule::SetCssText(const nsAString& aCssText)
01045 {
01046   return NS_ERROR_NOT_IMPLEMENTED;
01047 }
01048 
01049 NS_IMETHODIMP
01050 nsCSSMediaRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
01051 {
01052   return nsCSSGroupRule::GetParentStyleSheet(aSheet);
01053 }
01054 
01055 NS_IMETHODIMP
01056 nsCSSMediaRule::GetParentRule(nsIDOMCSSRule** aParentRule)
01057 {
01058   return nsCSSGroupRule::GetParentRule(aParentRule);
01059 }
01060 
01061 // nsIDOMCSSMediaRule methods
01062 NS_IMETHODIMP
01063 nsCSSMediaRule::GetMedia(nsIDOMMediaList* *aMedia)
01064 {
01065   NS_ENSURE_ARG_POINTER(aMedia);
01066   if (!mMedia) {
01067     *aMedia = nsnull;
01068     return NS_OK;
01069   }
01070 
01071   return CallQueryInterface(mMedia, aMedia);
01072 }
01073 
01074 NS_IMETHODIMP
01075 nsCSSMediaRule::GetCssRules(nsIDOMCSSRuleList* *aRuleList)
01076 {
01077   return nsCSSGroupRule::GetCssRules(aRuleList);
01078 }
01079 
01080 NS_IMETHODIMP
01081 nsCSSMediaRule::InsertRule(const nsAString & aRule, PRUint32 aIndex, PRUint32* _retval)
01082 {
01083   return nsCSSGroupRule::InsertRule(aRule, aIndex, _retval);
01084 }
01085 
01086 NS_IMETHODIMP
01087 nsCSSMediaRule::DeleteRule(PRUint32 aIndex)
01088 {
01089   return nsCSSGroupRule::DeleteRule(aIndex);
01090 }
01091 
01092 // nsICSSGroupRule interface
01093 NS_IMETHODIMP_(PRBool)
01094 nsCSSMediaRule::UseForPresentation(nsPresContext* aPresContext)
01095 {
01096   if (mMedia) {
01097     return mMedia->Matches(aPresContext);
01098   }
01099   return PR_TRUE;
01100 }
01101 
01102 
01103 nsCSSDocumentRule::nsCSSDocumentRule(void)
01104 {
01105 }
01106 
01107 nsCSSDocumentRule::nsCSSDocumentRule(const nsCSSDocumentRule& aCopy)
01108   : nsCSSGroupRule(aCopy)
01109   , mURLs(new URL(*aCopy.mURLs))
01110 {
01111 }
01112 
01113 nsCSSDocumentRule::~nsCSSDocumentRule(void)
01114 {
01115 }
01116 
01117 NS_IMPL_ADDREF_INHERITED(nsCSSDocumentRule, nsCSSRule)
01118 NS_IMPL_RELEASE_INHERITED(nsCSSDocumentRule, nsCSSRule)
01119 
01120 // QueryInterface implementation for nsCSSDocumentRule
01121 NS_INTERFACE_MAP_BEGIN(nsCSSDocumentRule)
01122   NS_INTERFACE_MAP_ENTRY(nsICSSGroupRule)
01123   NS_INTERFACE_MAP_ENTRY(nsICSSRule)
01124   NS_INTERFACE_MAP_ENTRY(nsIStyleRule)
01125   NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
01126   NS_INTERFACE_MAP_ENTRY(nsIDOMCSSMozDocumentRule)
01127   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsCSSGroupRule)
01128   NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(CSSMozDocumentRule)
01129 NS_INTERFACE_MAP_END
01130 
01131 #ifdef DEBUG
01132 NS_IMETHODIMP
01133 nsCSSDocumentRule::List(FILE* out, PRInt32 aIndent) const
01134 {
01135   for (PRInt32 indent = aIndent; --indent >= 0; ) fputs("  ", out);
01136 
01137   nsCAutoString str;
01138   str.AssignLiteral("@-moz-document ");
01139   for (URL *url = mURLs; url; url = url->next) {
01140     switch (url->func) {
01141       case eURL:
01142         str.AppendLiteral("url(\"");
01143         break;
01144       case eURLPrefix:
01145         str.AppendLiteral("url-prefix(\"");
01146         break;
01147       case eDomain:
01148         str.AppendLiteral("domain(\"");
01149         break;
01150     }
01151     nsCAutoString escapedURL(url->url);
01152     escapedURL.ReplaceSubstring("\"", "\\\""); // escape quotes
01153     str.Append(escapedURL);
01154     str.AppendLiteral("\"), ");
01155   }
01156   str.Cut(str.Length() - 2, 1); // remove last ,
01157   fputs(str.get(), out);
01158 
01159   return nsCSSGroupRule::List(out, aIndent);
01160 }
01161 #endif
01162 
01163 NS_IMETHODIMP
01164 nsCSSDocumentRule::GetType(PRInt32& aType) const
01165 {
01166   aType = nsICSSRule::DOCUMENT_RULE;
01167   return NS_OK;
01168 }
01169 
01170 NS_IMETHODIMP
01171 nsCSSDocumentRule::Clone(nsICSSRule*& aClone) const
01172 {
01173   nsCSSDocumentRule* clone = new nsCSSDocumentRule(*this);
01174   if (clone) {
01175     return CallQueryInterface(clone, &aClone);
01176   }
01177   aClone = nsnull;
01178   return NS_ERROR_OUT_OF_MEMORY;
01179 }
01180 
01181 // nsIDOMCSSRule methods
01182 NS_IMETHODIMP
01183 nsCSSDocumentRule::GetType(PRUint16* aType)
01184 {
01185   // XXX What should really happen here?
01186   *aType = nsIDOMCSSRule::UNKNOWN_RULE;
01187   return NS_OK;
01188 }
01189 
01190 NS_IMETHODIMP
01191 nsCSSDocumentRule::GetCssText(nsAString& aCssText)
01192 {
01193   aCssText.AssignLiteral("@-moz-document ");
01194   for (URL *url = mURLs; url; url = url->next) {
01195     switch (url->func) {
01196       case eURL:
01197         aCssText.AppendLiteral("url(\"");
01198         break;
01199       case eURLPrefix:
01200         aCssText.AppendLiteral("url-prefix(\"");
01201         break;
01202       case eDomain:
01203         aCssText.AppendLiteral("domain(\"");
01204         break;
01205     }
01206     nsCAutoString escapedURL(url->url);
01207     escapedURL.ReplaceSubstring("\"", "\\\""); // escape quotes
01208     AppendUTF8toUTF16(escapedURL, aCssText);
01209     aCssText.AppendLiteral("\"), ");
01210   }
01211   aCssText.Cut(aCssText.Length() - 2, 1); // remove last ,
01212 
01213   return nsCSSGroupRule::AppendRulesToCssText(aCssText);
01214 }
01215 
01216 NS_IMETHODIMP
01217 nsCSSDocumentRule::SetCssText(const nsAString& aCssText)
01218 {
01219   return NS_ERROR_NOT_IMPLEMENTED;
01220 }
01221 
01222 NS_IMETHODIMP
01223 nsCSSDocumentRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
01224 {
01225   return nsCSSGroupRule::GetParentStyleSheet(aSheet);
01226 }
01227 
01228 NS_IMETHODIMP
01229 nsCSSDocumentRule::GetParentRule(nsIDOMCSSRule** aParentRule)
01230 {
01231   return nsCSSGroupRule::GetParentRule(aParentRule);
01232 }
01233 
01234 NS_IMETHODIMP
01235 nsCSSDocumentRule::GetCssRules(nsIDOMCSSRuleList* *aRuleList)
01236 {
01237   return nsCSSGroupRule::GetCssRules(aRuleList);
01238 }
01239 
01240 NS_IMETHODIMP
01241 nsCSSDocumentRule::InsertRule(const nsAString & aRule, PRUint32 aIndex, PRUint32* _retval)
01242 {
01243   return nsCSSGroupRule::InsertRule(aRule, aIndex, _retval);
01244 }
01245 
01246 NS_IMETHODIMP
01247 nsCSSDocumentRule::DeleteRule(PRUint32 aIndex)
01248 {
01249   return nsCSSGroupRule::DeleteRule(aIndex);
01250 }
01251 
01252 // nsICSSGroupRule interface
01253 NS_IMETHODIMP_(PRBool)
01254 nsCSSDocumentRule::UseForPresentation(nsPresContext* aPresContext)
01255 {
01256   nsIURI *docURI = aPresContext->GetDocument()->GetDocumentURI();
01257   nsCAutoString docURISpec;
01258   if (docURI)
01259     docURI->GetSpec(docURISpec);
01260 
01261   for (URL *url = mURLs; url; url = url->next) {
01262     switch (url->func) {
01263       case eURL: {
01264         if (docURISpec == url->url)
01265           return PR_TRUE;
01266       } break;
01267       case eURLPrefix: {
01268         if (StringBeginsWith(docURISpec, url->url))
01269           return PR_TRUE;
01270       } break;
01271       case eDomain: {
01272         nsCAutoString host;
01273         if (docURI)
01274           docURI->GetHost(host);
01275         PRInt32 lenDiff = host.Length() - url->url.Length();
01276         if (lenDiff == 0) {
01277           if (host == url->url)
01278             return PR_TRUE;
01279         } else {
01280           if (StringEndsWith(host, url->url) &&
01281               host.CharAt(lenDiff - 1) == '.')
01282             return PR_TRUE;
01283         }
01284       } break;
01285     }
01286   }
01287 
01288   return PR_FALSE;
01289 }
01290 
01291 
01292 // -------------------------------------------
01293 // nsICSSNameSpaceRule
01294 //
01295 class CSSNameSpaceRuleImpl : public nsCSSRule,
01296                              public nsICSSNameSpaceRule,
01297                              public nsIDOMCSSRule
01298 {
01299 public:
01300   CSSNameSpaceRuleImpl(void);
01301   CSSNameSpaceRuleImpl(const CSSNameSpaceRuleImpl& aCopy);
01302   virtual ~CSSNameSpaceRuleImpl(void);
01303 
01304   NS_DECL_ISUPPORTS_INHERITED
01305 
01306   DECL_STYLE_RULE_INHERIT
01307 
01308   // nsIStyleRule methods
01309 #ifdef DEBUG
01310   NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const;
01311 #endif
01312 
01313   // nsICSSRule methods
01314   NS_IMETHOD GetType(PRInt32& aType) const;
01315   NS_IMETHOD Clone(nsICSSRule*& aClone) const;
01316 
01317   // nsICSSNameSpaceRule methods
01318   NS_IMETHOD GetPrefix(nsIAtom*& aPrefix) const;
01319   NS_IMETHOD SetPrefix(nsIAtom* aPrefix);
01320 
01321   NS_IMETHOD GetURLSpec(nsString& aURLSpec) const;
01322   NS_IMETHOD SetURLSpec(const nsString& aURLSpec);
01323 
01324   // nsIDOMCSSRule interface
01325   NS_DECL_NSIDOMCSSRULE
01326   
01327 protected:
01328   nsIAtom*  mPrefix;
01329   nsString  mURLSpec;
01330 };
01331 
01332 CSSNameSpaceRuleImpl::CSSNameSpaceRuleImpl(void)
01333   : nsCSSRule(),
01334     mPrefix(nsnull),
01335     mURLSpec()
01336 {
01337 }
01338 
01339 CSSNameSpaceRuleImpl::CSSNameSpaceRuleImpl(const CSSNameSpaceRuleImpl& aCopy)
01340   : nsCSSRule(aCopy),
01341     mPrefix(aCopy.mPrefix),
01342     mURLSpec(aCopy.mURLSpec)
01343 {
01344   NS_IF_ADDREF(mPrefix);
01345 }
01346 
01347 CSSNameSpaceRuleImpl::~CSSNameSpaceRuleImpl(void)
01348 {
01349   NS_IF_RELEASE(mPrefix);
01350 }
01351 
01352 NS_IMPL_ADDREF_INHERITED(CSSNameSpaceRuleImpl, nsCSSRule)
01353 NS_IMPL_RELEASE_INHERITED(CSSNameSpaceRuleImpl, nsCSSRule)
01354 
01355 // QueryInterface implementation for CSSNameSpaceRuleImpl
01356 NS_INTERFACE_MAP_BEGIN(CSSNameSpaceRuleImpl)
01357   NS_INTERFACE_MAP_ENTRY(nsICSSNameSpaceRule)
01358   NS_INTERFACE_MAP_ENTRY(nsICSSRule)
01359   NS_INTERFACE_MAP_ENTRY(nsIStyleRule)
01360   NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
01361   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsICSSNameSpaceRule)
01362   NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(CSSNameSpaceRule)
01363 NS_INTERFACE_MAP_END
01364 
01365 IMPL_STYLE_RULE_INHERIT(CSSNameSpaceRuleImpl, nsCSSRule)
01366 
01367 #ifdef DEBUG
01368 NS_IMETHODIMP
01369 CSSNameSpaceRuleImpl::List(FILE* out, PRInt32 aIndent) const
01370 {
01371   for (PRInt32 indent = aIndent; --indent >= 0; ) fputs("  ", out);
01372 
01373   nsAutoString  buffer;
01374 
01375   fputs("@namespace ", out);
01376 
01377   if (mPrefix) {
01378     mPrefix->ToString(buffer);
01379     fputs(NS_LossyConvertUCS2toASCII(buffer).get(), out);
01380     fputs(" ", out);
01381   }
01382 
01383   fputs("url(", out);
01384   fputs(NS_LossyConvertUCS2toASCII(mURLSpec).get(), out);
01385   fputs(")\n", out);
01386   return NS_OK;
01387 }
01388 #endif
01389 
01390 NS_IMETHODIMP
01391 CSSNameSpaceRuleImpl::GetType(PRInt32& aType) const
01392 {
01393   aType = nsICSSRule::NAMESPACE_RULE;
01394   return NS_OK;
01395 }
01396 
01397 NS_IMETHODIMP
01398 CSSNameSpaceRuleImpl::Clone(nsICSSRule*& aClone) const
01399 {
01400   CSSNameSpaceRuleImpl* clone = new CSSNameSpaceRuleImpl(*this);
01401   if (clone) {
01402     return CallQueryInterface(clone, &aClone);
01403   }
01404   aClone = nsnull;
01405   return NS_ERROR_OUT_OF_MEMORY;
01406 }
01407 
01408 NS_IMETHODIMP
01409 CSSNameSpaceRuleImpl::GetPrefix(nsIAtom*& aPrefix) const
01410 {
01411   aPrefix = mPrefix;
01412   NS_IF_ADDREF(aPrefix);
01413   return NS_OK;
01414 }
01415 
01416 NS_IMETHODIMP
01417 CSSNameSpaceRuleImpl::SetPrefix(nsIAtom* aPrefix)
01418 {
01419   NS_IF_RELEASE(mPrefix);
01420   mPrefix = aPrefix;
01421   NS_IF_ADDREF(mPrefix);
01422   return NS_OK;
01423 }
01424 
01425 NS_IMETHODIMP
01426 CSSNameSpaceRuleImpl::GetURLSpec(nsString& aURLSpec) const
01427 {
01428   aURLSpec = mURLSpec;
01429   return NS_OK;
01430 }
01431 
01432 NS_IMETHODIMP
01433 CSSNameSpaceRuleImpl::SetURLSpec(const nsString& aURLSpec)
01434 {
01435   mURLSpec = aURLSpec;
01436   return NS_OK;
01437 }
01438 
01439 nsresult
01440 NS_NewCSSNameSpaceRule(nsICSSNameSpaceRule** aInstancePtrResult, 
01441                        nsIAtom* aPrefix, const nsString& aURLSpec)
01442 {
01443   if (! aInstancePtrResult) {
01444     return NS_ERROR_NULL_POINTER;
01445   }
01446 
01447   CSSNameSpaceRuleImpl* it = new CSSNameSpaceRuleImpl();
01448 
01449   if (! it) {
01450     return NS_ERROR_OUT_OF_MEMORY;
01451   }
01452 
01453   it->SetPrefix(aPrefix);
01454   it->SetURLSpec(aURLSpec);
01455   return CallQueryInterface(it, aInstancePtrResult);
01456 }
01457 
01458 NS_IMETHODIMP
01459 CSSNameSpaceRuleImpl::GetType(PRUint16* aType)
01460 {
01461   // XXX What should really happen here?
01462   *aType = nsIDOMCSSRule::UNKNOWN_RULE;
01463   return NS_OK;
01464 }
01465 
01466 NS_IMETHODIMP
01467 CSSNameSpaceRuleImpl::GetCssText(nsAString& aCssText)
01468 {
01469   aCssText.AssignLiteral("@namespace ");
01470   if (mPrefix) {
01471     nsString atomStr;
01472     mPrefix->ToString(atomStr);
01473     aCssText.Append(atomStr);
01474     aCssText.AppendLiteral(" ");
01475   }
01476   aCssText.AppendLiteral("url(");
01477   aCssText.Append(mURLSpec);
01478   aCssText.Append(NS_LITERAL_STRING(");"));
01479   return NS_OK;
01480 }
01481 
01482 NS_IMETHODIMP
01483 CSSNameSpaceRuleImpl::SetCssText(const nsAString& aCssText)
01484 {
01485   return NS_ERROR_NOT_IMPLEMENTED;
01486 }
01487 
01488 NS_IMETHODIMP
01489 CSSNameSpaceRuleImpl::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
01490 {
01491   if (mSheet) {
01492     return CallQueryInterface(mSheet, aSheet);
01493   }
01494   *aSheet = nsnull;
01495   return NS_OK;
01496 }
01497 
01498 NS_IMETHODIMP
01499 CSSNameSpaceRuleImpl::GetParentRule(nsIDOMCSSRule** aParentRule)
01500 {
01501   if (mParentRule) {
01502     return mParentRule->GetDOMRule(aParentRule);
01503   }
01504   *aParentRule = nsnull;
01505   return NS_OK;
01506 }
01507