Back to index

lightning-sunbird  0.9+nobinonly
nsHTMLStyleElement.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 Communicator client 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) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Daniel Glazman <glazman@netscape.com>
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 "nsIDOMHTMLStyleElement.h"
00039 #include "nsIDOMLinkStyle.h"
00040 #include "nsIDOMEventReceiver.h"
00041 #include "nsGenericHTMLElement.h"
00042 #include "nsHTMLAtoms.h"
00043 #include "nsStyleConsts.h"
00044 #include "nsPresContext.h"
00045 #include "nsIDOMStyleSheet.h"
00046 #include "nsIStyleSheet.h"
00047 #include "nsStyleLinkElement.h"
00048 #include "nsNetUtil.h"
00049 #include "nsIDocument.h"
00050 #include "nsUnicharUtils.h"
00051 #include "nsParserUtils.h"
00052 
00053 
00054 class nsHTMLStyleElement : public nsGenericHTMLElement,
00055                            public nsIDOMHTMLStyleElement,
00056                            public nsStyleLinkElement
00057 {
00058 public:
00059   nsHTMLStyleElement(nsINodeInfo *aNodeInfo);
00060   virtual ~nsHTMLStyleElement();
00061 
00062   // nsISupports
00063   NS_DECL_ISUPPORTS_INHERITED
00064 
00065   // nsIDOMNode
00066   NS_FORWARD_NSIDOMNODE_NO_CLONENODE(nsGenericHTMLElement::)
00067 
00068   // nsIDOMElement
00069   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
00070 
00071   // nsIDOMHTMLElement
00072   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
00073 
00074   // nsIDOMHTMLStyleElement
00075   NS_DECL_NSIDOMHTMLSTYLEELEMENT
00076 
00077   virtual nsresult InsertChildAt(nsIContent* aKid, PRUint32 aIndex,
00078                                  PRBool aNotify);
00079   virtual nsresult AppendChildTo(nsIContent* aKid, PRBool aNotify);
00080   virtual nsresult RemoveChildAt(PRUint32 aIndex, PRBool aNotify);
00081   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
00082                               nsIContent* aBindingParent,
00083                               PRBool aCompileEventHandlers);
00084   virtual void UnbindFromTree(PRBool aDeep = PR_TRUE,
00085                               PRBool aNullParent = PR_TRUE);
00086   nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
00087                    const nsAString& aValue, PRBool aNotify)
00088   {
00089     return SetAttr(aNameSpaceID, aName, nsnull, aValue, aNotify);
00090   }
00091   virtual nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
00092                            nsIAtom* aPrefix, const nsAString& aValue,
00093                            PRBool aNotify);
00094   virtual nsresult UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
00095                              PRBool aNotify);
00096 
00097   virtual nsresult GetInnerHTML(nsAString& aInnerHTML);
00098   virtual nsresult SetInnerHTML(const nsAString& aInnerHTML);
00099 
00100 protected:
00101   void GetStyleSheetURL(PRBool* aIsInline,
00102                         nsIURI** aURI);
00103   void GetStyleSheetInfo(nsAString& aTitle,
00104                          nsAString& aType,
00105                          nsAString& aMedia,
00106                          PRBool* aIsAlternate);
00107 };
00108 
00109 
00110 NS_IMPL_NS_NEW_HTML_ELEMENT(Style)
00111 
00112 
00113 nsHTMLStyleElement::nsHTMLStyleElement(nsINodeInfo *aNodeInfo)
00114   : nsGenericHTMLElement(aNodeInfo)
00115 {
00116 }
00117 
00118 nsHTMLStyleElement::~nsHTMLStyleElement()
00119 {
00120 }
00121 
00122 
00123 NS_IMPL_ADDREF_INHERITED(nsHTMLStyleElement, nsGenericElement) 
00124 NS_IMPL_RELEASE_INHERITED(nsHTMLStyleElement, nsGenericElement) 
00125 
00126 
00127 // QueryInterface implementation for nsHTMLStyleElement
00128 NS_HTML_CONTENT_INTERFACE_MAP_BEGIN(nsHTMLStyleElement, nsGenericHTMLElement)
00129   NS_INTERFACE_MAP_ENTRY(nsIDOMHTMLStyleElement)
00130   NS_INTERFACE_MAP_ENTRY(nsIDOMLinkStyle)
00131   NS_INTERFACE_MAP_ENTRY(nsIStyleSheetLinkingElement)
00132   NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(HTMLStyleElement)
00133 NS_HTML_CONTENT_INTERFACE_MAP_END
00134 
00135 
00136 NS_IMPL_DOM_CLONENODE(nsHTMLStyleElement)
00137 
00138 
00139 NS_IMETHODIMP
00140 nsHTMLStyleElement::GetDisabled(PRBool* aDisabled)
00141 {
00142   nsresult result = NS_OK;
00143   
00144   if (mStyleSheet) {
00145     nsCOMPtr<nsIDOMStyleSheet> ss(do_QueryInterface(mStyleSheet));
00146 
00147     if (ss) {
00148       result = ss->GetDisabled(aDisabled);
00149     }
00150   }
00151   else {
00152     *aDisabled = PR_FALSE;
00153   }
00154 
00155   return result;
00156 }
00157 
00158 NS_IMETHODIMP 
00159 nsHTMLStyleElement::SetDisabled(PRBool aDisabled)
00160 {
00161   nsresult result = NS_OK;
00162   
00163   if (mStyleSheet) {
00164     nsCOMPtr<nsIDOMStyleSheet> ss(do_QueryInterface(mStyleSheet));
00165 
00166     if (ss) {
00167       result = ss->SetDisabled(aDisabled);
00168     }
00169   }
00170 
00171   return result;
00172 }
00173 
00174 NS_IMPL_STRING_ATTR(nsHTMLStyleElement, Media, media)
00175 NS_IMPL_STRING_ATTR(nsHTMLStyleElement, Type, type)
00176 
00177 nsresult
00178 nsHTMLStyleElement::InsertChildAt(nsIContent* aKid, PRUint32 aIndex,
00179                                   PRBool aNotify)
00180 {
00181   nsresult rv = nsGenericHTMLElement::InsertChildAt(aKid, aIndex, aNotify);
00182   if (NS_SUCCEEDED(rv)) {
00183     UpdateStyleSheet();
00184   }
00185 
00186   return rv;
00187 }
00188 
00189 nsresult
00190 nsHTMLStyleElement::AppendChildTo(nsIContent* aKid, PRBool aNotify)
00191 {
00192   nsresult rv = nsGenericHTMLElement::AppendChildTo(aKid, aNotify);
00193   if (NS_SUCCEEDED(rv)) {
00194     UpdateStyleSheet();
00195   }
00196 
00197   return rv;
00198 }
00199 
00200 nsresult
00201 nsHTMLStyleElement::RemoveChildAt(PRUint32 aIndex, PRBool aNotify)
00202 {
00203   nsresult rv = nsGenericHTMLElement::RemoveChildAt(aIndex, aNotify);
00204   if (NS_SUCCEEDED(rv)) {
00205     UpdateStyleSheet();
00206   }
00207 
00208   return rv;
00209 }
00210 
00211 nsresult
00212 nsHTMLStyleElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
00213                                nsIContent* aBindingParent,
00214                                PRBool aCompileEventHandlers)
00215 {
00216   nsresult rv = nsGenericHTMLElement::BindToTree(aDocument, aParent,
00217                                                  aBindingParent,
00218                                                  aCompileEventHandlers);
00219   NS_ENSURE_SUCCESS(rv, rv);
00220 
00221   UpdateStyleSheet(nsnull);
00222 
00223   return rv;  
00224 }
00225 
00226 void
00227 nsHTMLStyleElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
00228 {
00229   nsCOMPtr<nsIDocument> oldDoc = GetCurrentDoc();
00230 
00231   nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
00232   UpdateStyleSheet(oldDoc);
00233 }
00234 
00235 nsresult
00236 nsHTMLStyleElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
00237                             nsIAtom* aPrefix, const nsAString& aValue,
00238                             PRBool aNotify)
00239 {
00240   nsresult rv = nsGenericHTMLElement::SetAttr(aNameSpaceID, aName, aPrefix,
00241                                               aValue, aNotify);
00242   if (NS_SUCCEEDED(rv)) {
00243     UpdateStyleSheet();
00244   }
00245 
00246   return rv;
00247 }
00248 
00249 nsresult
00250 nsHTMLStyleElement::UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
00251                               PRBool aNotify)
00252 {
00253   nsresult rv = nsGenericHTMLElement::UnsetAttr(aNameSpaceID, aAttribute,
00254                                                 aNotify);
00255   if (NS_SUCCEEDED(rv)) {
00256     UpdateStyleSheet();
00257   }
00258 
00259   return rv;
00260 }
00261 
00262 nsresult
00263 nsHTMLStyleElement::GetInnerHTML(nsAString& aInnerHTML)
00264 {
00265   GetContentsAsText(aInnerHTML);
00266   return NS_OK;
00267 }
00268 
00269 nsresult
00270 nsHTMLStyleElement::SetInnerHTML(const nsAString& aInnerHTML)
00271 {
00272   SetEnableUpdates(PR_FALSE);
00273 
00274   nsresult rv = ReplaceContentsWithText(aInnerHTML, PR_TRUE);
00275   
00276   SetEnableUpdates(PR_TRUE);
00277   
00278   UpdateStyleSheet();
00279   return rv;
00280 }
00281 
00282 void
00283 nsHTMLStyleElement::GetStyleSheetURL(PRBool* aIsInline,
00284                                      nsIURI** aURI)
00285 {
00286   *aURI = nsnull;
00287   *aIsInline = !HasAttr(kNameSpaceID_None, nsHTMLAtoms::src);
00288   if (*aIsInline) {
00289     return;
00290   }
00291   if (mNodeInfo->NamespaceEquals(kNameSpaceID_XHTML)) {
00292     // We stopped supporting <style src="..."> for XHTML as it is
00293     // non-standard.
00294     *aIsInline = PR_TRUE;
00295     return;
00296   }
00297 
00298   GetHrefURIForAnchors(aURI);
00299   return;
00300 }
00301 
00302 void
00303 nsHTMLStyleElement::GetStyleSheetInfo(nsAString& aTitle,
00304                                       nsAString& aType,
00305                                       nsAString& aMedia,
00306                                       PRBool* aIsAlternate)
00307 {
00308   aTitle.Truncate();
00309   aType.Truncate();
00310   aMedia.Truncate();
00311   *aIsAlternate = PR_FALSE;
00312 
00313   nsAutoString title;
00314   GetAttr(kNameSpaceID_None, nsHTMLAtoms::title, title);
00315   title.CompressWhitespace();
00316   aTitle.Assign(title);
00317 
00318   GetAttr(kNameSpaceID_None, nsHTMLAtoms::media, aMedia);
00319   ToLowerCase(aMedia); // HTML4.0 spec is inconsistent, make it case INSENSITIVE
00320 
00321   GetAttr(kNameSpaceID_None, nsHTMLAtoms::type, aType);
00322 
00323   nsAutoString mimeType;
00324   nsAutoString notUsed;
00325   nsParserUtils::SplitMimeType(aType, mimeType, notUsed);
00326   if (!mimeType.IsEmpty() && !mimeType.LowerCaseEqualsLiteral("text/css")) {
00327     return;
00328   }
00329 
00330   // If we get here we assume that we're loading a css file, so set the
00331   // type to 'text/css'
00332   aType.AssignLiteral("text/css");
00333 
00334   return;
00335 }