Back to index

lightning-sunbird  0.9+nobinonly
nsSVGStyleElement.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 the Mozilla SVG project.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * IBM Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 2004
00020  * IBM Corporation. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   IBM Corporation (original author)
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either the GNU General Public License Version 2 or later (the "GPL"), or
00027  * 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 
00039 #include "nsSVGElement.h"
00040 #include "nsSVGAtoms.h"
00041 #include "nsIDOMSVGStyleElement.h"
00042 #include "nsUnicharUtils.h"
00043 #include "nsIDocument.h"
00044 #include "nsStyleLinkElement.h"
00045 
00046 typedef nsSVGElement nsSVGStyleElementBase;
00047 
00048 class nsSVGStyleElement : public nsSVGStyleElementBase,
00049                           public nsIDOMSVGStyleElement,
00050                           public nsStyleLinkElement
00051 {
00052 protected:
00053   friend nsresult NS_NewSVGStyleElement(nsIContent **aResult,
00054                                         nsINodeInfo *aNodeInfo);
00055   nsSVGStyleElement(nsINodeInfo *aNodeInfo);
00056   virtual ~nsSVGStyleElement();
00057   
00058 public:
00059   NS_DECL_ISUPPORTS_INHERITED
00060   NS_DECL_NSIDOMSVGSTYLEELEMENT
00061 
00062   // xxx I wish we could use virtual inheritance
00063   NS_FORWARD_NSIDOMNODE_NO_CLONENODE(nsSVGStyleElementBase::)
00064   NS_FORWARD_NSIDOMELEMENT(nsSVGStyleElementBase::)
00065   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGStyleElementBase::)
00066 
00067   // nsIContent
00068   virtual nsresult InsertChildAt(nsIContent* aKid, PRUint32 aIndex,
00069                                  PRBool aNotify);
00070   virtual nsresult AppendChildTo(nsIContent* aKid, PRBool aNotify);
00071   virtual nsresult RemoveChildAt(PRUint32 aIndex, PRBool aNotify);
00072   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
00073                               nsIContent* aBindingParent,
00074                               PRBool aCompileEventHandlers);
00075   virtual void UnbindFromTree(PRBool aDeep = PR_TRUE,
00076                               PRBool aNullParent = PR_TRUE);
00077   nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
00078                    const nsAString& aValue, PRBool aNotify)
00079   {
00080     return SetAttr(aNameSpaceID, aName, nsnull, aValue, aNotify);
00081   }
00082   virtual nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
00083                            nsIAtom* aPrefix, const nsAString& aValue,
00084                            PRBool aNotify);
00085   virtual nsresult UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
00086                              PRBool aNotify);
00087 protected:
00088   // Dummy init method to make the NS_IMPL_NS_NEW_SVG_ELEMENT and
00089   // NS_IMPL_SVG_DOM_CLONENODE usable with this class. This should be
00090   // completely optimized away.
00091   inline nsresult Init()
00092   {
00093     return NS_OK;
00094   }
00095 
00096   // nsStyleLinkElement overrides
00097   void GetStyleSheetURL(PRBool* aIsInline,
00098                         nsIURI** aURI);
00099   void GetStyleSheetInfo(nsAString& aTitle,
00100                          nsAString& aType,
00101                          nsAString& aMedia,
00102                          PRBool* aIsAlternate);
00103 };
00104 
00105 
00106 NS_IMPL_NS_NEW_SVG_ELEMENT(Style)
00107 
00108 
00109 //----------------------------------------------------------------------
00110 // nsISupports methods
00111 
00112 NS_IMPL_ADDREF_INHERITED(nsSVGStyleElement,nsSVGStyleElementBase)
00113 NS_IMPL_RELEASE_INHERITED(nsSVGStyleElement,nsSVGStyleElementBase)
00114 
00115 NS_INTERFACE_MAP_BEGIN(nsSVGStyleElement)
00116   NS_INTERFACE_MAP_ENTRY(nsIDOMNode)
00117   NS_INTERFACE_MAP_ENTRY(nsIDOMElement)
00118   NS_INTERFACE_MAP_ENTRY(nsIDOMSVGElement)
00119   NS_INTERFACE_MAP_ENTRY(nsIDOMSVGStyleElement)
00120   NS_INTERFACE_MAP_ENTRY(nsIDOMLinkStyle)
00121   NS_INTERFACE_MAP_ENTRY(nsIStyleSheetLinkingElement)
00122   NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(SVGStyleElement)
00123 NS_INTERFACE_MAP_END_INHERITING(nsSVGStyleElementBase)
00124 
00125 //----------------------------------------------------------------------
00126 // Implementation
00127 
00128 nsSVGStyleElement::nsSVGStyleElement(nsINodeInfo *aNodeInfo)
00129   : nsSVGStyleElementBase(aNodeInfo)
00130 {
00131 
00132 }
00133 
00134 nsSVGStyleElement::~nsSVGStyleElement()
00135 {
00136 }
00137 
00138 //----------------------------------------------------------------------
00139 // nsIDOMNode methods
00140 
00141 
00142 NS_IMPL_DOM_CLONENODE_WITH_INIT(nsSVGStyleElement)
00143 
00144 
00145 //----------------------------------------------------------------------
00146 // nsIContent methods
00147 
00148 nsresult
00149 nsSVGStyleElement::InsertChildAt(nsIContent* aKid, PRUint32 aIndex,
00150                                  PRBool aNotify)
00151 {
00152   nsresult rv = nsSVGStyleElementBase::InsertChildAt(aKid, aIndex, aNotify);
00153   if (NS_SUCCEEDED(rv)) {
00154     UpdateStyleSheet();
00155   }
00156 
00157   return rv;
00158 }
00159 
00160 nsresult
00161 nsSVGStyleElement::AppendChildTo(nsIContent* aKid, PRBool aNotify)
00162 {
00163   nsresult rv = nsSVGStyleElementBase::AppendChildTo(aKid, aNotify);
00164   if (NS_SUCCEEDED(rv)) {
00165     UpdateStyleSheet();
00166   }
00167 
00168   return rv;
00169 }
00170 
00171 nsresult
00172 nsSVGStyleElement::RemoveChildAt(PRUint32 aIndex, PRBool aNotify)
00173 {
00174   nsresult rv = nsSVGStyleElementBase::RemoveChildAt(aIndex, aNotify);
00175   if (NS_SUCCEEDED(rv)) {
00176     UpdateStyleSheet();
00177   }
00178 
00179   return rv;
00180 }
00181 
00182 nsresult
00183 nsSVGStyleElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
00184                               nsIContent* aBindingParent,
00185                               PRBool aCompileEventHandlers)
00186 {
00187   nsresult rv = nsSVGStyleElementBase::BindToTree(aDocument, aParent,
00188                                                   aBindingParent,
00189                                                   aCompileEventHandlers);
00190   NS_ENSURE_SUCCESS(rv, rv);
00191 
00192   UpdateStyleSheet(nsnull);
00193 
00194   return rv;  
00195 }
00196 
00197 void
00198 nsSVGStyleElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
00199 {
00200   nsCOMPtr<nsIDocument> oldDoc = GetCurrentDoc();
00201 
00202   nsSVGStyleElementBase::UnbindFromTree(aDeep, aNullParent);
00203   UpdateStyleSheet(oldDoc);
00204 }
00205 
00206 nsresult
00207 nsSVGStyleElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
00208                            nsIAtom* aPrefix, const nsAString& aValue,
00209                            PRBool aNotify)
00210 {
00211   nsresult rv = nsSVGStyleElementBase::SetAttr(aNameSpaceID, aName, aPrefix,
00212                                                aValue, aNotify);
00213   if (NS_SUCCEEDED(rv)) {
00214     UpdateStyleSheet();
00215   }
00216 
00217   return rv;
00218 }
00219 
00220 nsresult
00221 nsSVGStyleElement::UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
00222                               PRBool aNotify)
00223 {
00224   nsresult rv = nsSVGStyleElementBase::UnsetAttr(aNameSpaceID, aAttribute,
00225                                                  aNotify);
00226   if (NS_SUCCEEDED(rv)) {
00227     UpdateStyleSheet();
00228   }
00229 
00230   return rv;
00231 }
00232 
00233 //----------------------------------------------------------------------
00234 // nsIDOMSVGStyleElement methods
00235 
00236 /* attribute DOMString xmlspace; */
00237 NS_IMETHODIMP nsSVGStyleElement::GetXmlspace(nsAString & aXmlspace)
00238 {
00239   GetAttr(kNameSpaceID_XML, nsSVGAtoms::space, aXmlspace);
00240 
00241   return NS_OK;
00242 }
00243 NS_IMETHODIMP nsSVGStyleElement::SetXmlspace(const nsAString & aXmlspace)
00244 {
00245   return SetAttr(kNameSpaceID_XML, nsSVGAtoms::space, aXmlspace, PR_TRUE);
00246 }
00247 
00248 /* attribute DOMString type; */
00249 NS_IMETHODIMP nsSVGStyleElement::GetType(nsAString & aType)
00250 {
00251   GetAttr(kNameSpaceID_None, nsSVGAtoms::type, aType);
00252 
00253   return NS_OK;
00254 }
00255 NS_IMETHODIMP nsSVGStyleElement::SetType(const nsAString & aType)
00256 {
00257   return SetAttr(kNameSpaceID_None, nsSVGAtoms::type, aType, PR_TRUE);
00258 }
00259 
00260 /* attribute DOMString media; */
00261 NS_IMETHODIMP nsSVGStyleElement::GetMedia(nsAString & aMedia)
00262 {
00263   GetAttr(kNameSpaceID_None, nsSVGAtoms::media, aMedia);
00264 
00265   return NS_OK;
00266 }
00267 NS_IMETHODIMP nsSVGStyleElement::SetMedia(const nsAString & aMedia)
00268 {
00269   return SetAttr(kNameSpaceID_XML, nsSVGAtoms::media, aMedia, PR_TRUE);
00270 }
00271 
00272 /* attribute DOMString title; */
00273 NS_IMETHODIMP nsSVGStyleElement::GetTitle(nsAString & aTitle)
00274 {
00275   GetAttr(kNameSpaceID_None, nsSVGAtoms::title, aTitle);
00276 
00277   return NS_OK;
00278 }
00279 NS_IMETHODIMP nsSVGStyleElement::SetTitle(const nsAString & aTitle)
00280 {
00281   return SetAttr(kNameSpaceID_XML, nsSVGAtoms::title, aTitle, PR_TRUE);
00282 }
00283 
00284 //----------------------------------------------------------------------
00285 // nsStyleLinkElement methods
00286 
00287 void
00288 nsSVGStyleElement::GetStyleSheetURL(PRBool* aIsInline,
00289                                     nsIURI** aURI)
00290 {
00291   *aURI = nsnull;
00292   *aIsInline = PR_TRUE;
00293 
00294   return;
00295 }
00296 
00297 void
00298 nsSVGStyleElement::GetStyleSheetInfo(nsAString& aTitle,
00299                                      nsAString& aType,
00300                                      nsAString& aMedia,
00301                                      PRBool* aIsAlternate)
00302 {
00303   *aIsAlternate = PR_FALSE;
00304 
00305   nsAutoString title;
00306   GetAttr(kNameSpaceID_None, nsSVGAtoms::title, title);
00307   title.CompressWhitespace();
00308   aTitle.Assign(title);
00309 
00310   GetAttr(kNameSpaceID_None, nsSVGAtoms::media, aMedia);
00311   // SVG spec refers to the HTML4.0 spec which is inconsistent, make it
00312   // case INSENSITIVE
00313   ToLowerCase(aMedia);
00314 
00315   GetAttr(kNameSpaceID_None, nsSVGAtoms::type, aType);
00316 
00317   return;
00318 }