Back to index

lightning-sunbird  0.9+nobinonly
nsCSSLoader.h
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
00002   * vim: ft=cpp tw=78 sw=2 et ts=2
00003  *
00004  * ***** BEGIN LICENSE BLOCK *****
00005  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00006  *
00007  * The contents of this file are subject to the Mozilla Public License Version
00008  * 1.1 (the "License"); you may not use this file except in compliance with
00009  * the License. You may obtain a copy of the License at
00010  * http://www.mozilla.org/MPL/
00011  *
00012  * Software distributed under the License is distributed on an "AS IS" basis,
00013  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00014  * for the specific language governing rights and limitations under the
00015  * License.
00016  *
00017  * The Original Code is mozilla.org code.
00018  *
00019  * The Initial Developer of the Original Code is
00020  * Netscape Communications Corporation.
00021  * Portions created by the Initial Developer are Copyright (C) 1999
00022  * the Initial Developer. All Rights Reserved.
00023  *
00024  * Contributor(s):
00025  *   Boris Zbarsky <bzbarsky@mit.edu>
00026  *
00027  * Alternatively, the contents of this file may be used under the terms of
00028  * either of the GNU General Public License Version 2 or later (the "GPL"),
00029  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00030  * in which case the provisions of the GPL or the LGPL are applicable instead
00031  * of those above. If you wish to allow use of your version of this file only
00032  * under the terms of either the GPL or the LGPL, and not to allow others to
00033  * use your version of this file under the terms of the MPL, indicate your
00034  * decision by deleting the provisions above and replace them with the notice
00035  * and other provisions required by the GPL or the LGPL. If you do not delete
00036  * the provisions above, a recipient may use your version of this file under
00037  * the terms of any one of the MPL, the GPL or the LGPL.
00038  *
00039  * ***** END LICENSE BLOCK *****
00040  *
00041  * This Original Code has been modified by IBM Corporation. Modifications made by IBM 
00042  * described herein are Copyright (c) International Business Machines Corporation, 2000.
00043  * Modifications to Mozilla code or documentation identified per MPL Section 3.3
00044  *
00045  * Date             Modified by     Description of modification
00046  * 04/20/2000       IBM Corp.      OS/2 VisualAge build.
00047  */
00048 
00049 #ifndef nsCSSLoader_h__
00050 #define nsCSSLoader_h__
00051 
00052 class CSSLoaderImpl;
00053 class nsIURI;
00054 class nsIParser;
00055 class nsICSSStyleSheet;
00056 class nsIStyleSheetLinkingElement;
00057 class nsICSSLoaderObserver;
00058 class nsICSSParser;
00059 class nsICSSImportRule;
00060 class nsMediaList;
00061 
00062 #include "nsICSSLoader.h"
00063 #include "nsIUnicharStreamLoader.h"
00064 #include "nsCOMPtr.h"
00065 #include "nsCOMArray.h"
00066 #include "nsString.h"
00067 #include "nsURIHashKey.h"
00068 #include "nsInterfaceHashtable.h"
00069 #include "nsDataHashtable.h"
00070 
00099 /*********************************************
00100  * Data needed to properly load a stylesheet *
00101  *********************************************/
00102 
00103 class SheetLoadData : public nsIUnicharStreamLoaderObserver
00104 {
00105 public:
00106   virtual ~SheetLoadData(void);
00107   // Data for loading a sheet linked from a document
00108   SheetLoadData(CSSLoaderImpl* aLoader,
00109                 const nsSubstring& aTitle,
00110                 nsIParser* aParserToUnblock,
00111                 nsIURI* aURI,
00112                 nsICSSStyleSheet* aSheet,
00113                 nsIStyleSheetLinkingElement* aOwningElement,
00114                 nsICSSLoaderObserver* aObserver);                 
00115 
00116   // Data for loading a sheet linked from an @import rule
00117   SheetLoadData(CSSLoaderImpl* aLoader,
00118                 nsIURI* aURI,
00119                 nsICSSStyleSheet* aSheet,
00120                 SheetLoadData* aParentData,
00121                 nsICSSLoaderObserver* aObserver);                 
00122 
00123   // Data for loading an agent sheet
00124   SheetLoadData(CSSLoaderImpl* aLoader,
00125                 nsIURI* aURI,
00126                 nsICSSStyleSheet* aSheet,
00127                 PRBool aSyncLoad,
00128                 PRBool aAllowUnsafeRules,
00129                 nsICSSLoaderObserver* aObserver);
00130 
00131   already_AddRefed<nsIURI> GetReferrerURI();
00132   
00133   NS_DECL_ISUPPORTS
00134   NS_DECL_NSIUNICHARSTREAMLOADEROBSERVER
00135 
00136   // Hold a ref to the CSSLoader so we can call back to it to let it
00137   // know the load finished
00138   CSSLoaderImpl*             mLoader; // strong ref
00139 
00140   // Title needed to pull datas out of the pending datas table when
00141   // the preferred title is changed
00142   nsString                   mTitle;
00143 
00144   // Charset we decided to use for the sheet
00145   nsCString                  mCharset;
00146 
00147   // Parser to be told to continue parsing once the load completes
00148   nsCOMPtr<nsIParser>        mParserToUnblock;
00149 
00150   // URI we're loading.  Null for inline sheets
00151   nsCOMPtr<nsIURI>           mURI;
00152 
00153   // Should be 1 for non-inline sheets.
00154   PRUint32                   mLineNumber;
00155 
00156   // The sheet we're loading data for
00157   nsCOMPtr<nsICSSStyleSheet> mSheet;
00158 
00159   // Linked list of datas for the same URI as us
00160   SheetLoadData*             mNext;  // strong ref
00161 
00162   // Load data for the sheet that @import-ed us if we were @import-ed
00163   // during the parse
00164   SheetLoadData*             mParentData;  // strong ref
00165 
00166   // Number of sheets we @import-ed that are still loading
00167   PRUint32                   mPendingChildren;
00168 
00169   // mSyncLoad is true when the load needs to be synchronous -- right
00170   // now only for LoadAgentSheet with no observer
00171   PRPackedBool               mSyncLoad;
00172 
00173   // mIsAgent is true if the load was triggered by LoadAgentSheet or
00174   // an @import from an agent sheet.  Agent loads can proceed even if
00175   // we have no document.
00176   PRPackedBool               mIsAgent;
00177 
00178   // mIsLoading is true from the moment we are placed in the loader's
00179   // "loading datas" table (right after the async channel is opened)
00180   // to the moment we are removed from said table (due to the load
00181   // completing or being cancelled).
00182   PRPackedBool               mIsLoading; // Set once the data is in the "loading" table
00183 
00184   // mIsCancelled is set to true when a sheet load is stopped by
00185   // Stop() or StopLoadingSheet().  SheetLoadData::OnStreamComplete()
00186   // checks this to avoid parsing sheets that have been cancelled and
00187   // such.
00188   PRPackedBool               mIsCancelled;
00189   
00190   // mAllowUnsafeRules is true if we should allow unsafe rules to be parsed
00191   // in the loaded sheet.
00192   PRPackedBool               mAllowUnsafeRules;
00193 
00194   // This is the element that imported the sheet.  Needed to get the
00195   // charset set on it.
00196   nsCOMPtr<nsIStyleSheetLinkingElement> mOwningElement;
00197 
00198   // The observer that wishes to be notified of load completion
00199   nsCOMPtr<nsICSSLoaderObserver>        mObserver;
00200 };
00201 
00202 
00203 /***********************************************************************
00204  * Enum that describes the state of the sheet returned by CreateSheet. *
00205  ***********************************************************************/
00206 enum StyleSheetState {
00207   eSheetStateUnknown = 0,
00208   eSheetNeedsParser,
00209   eSheetPending,
00210   eSheetLoading,
00211   eSheetComplete
00212 };
00213 
00214 
00215 /**********************
00216  * Loader Declaration *
00217  **********************/
00218 
00219 class CSSLoaderImpl : public nsICSSLoader,
00220                       public nsICSSLoader_MOZILLA_1_8_BRANCH
00221 {
00222 public:
00223   CSSLoaderImpl(void);
00224   virtual ~CSSLoaderImpl(void);
00225 
00226   NS_DECL_ISUPPORTS
00227 
00228   static void Shutdown(); // called at app shutdown
00229   
00230   // nsICSSLoader methods
00231   NS_IMETHOD Init(nsIDocument* aDocument);
00232   NS_IMETHOD DropDocumentReference(void);
00233 
00234   NS_IMETHOD SetCaseSensitive(PRBool aCaseSensitive);
00235   NS_IMETHOD SetCompatibilityMode(nsCompatibility aCompatMode);
00236   NS_IMETHOD SetPreferredSheet(const nsAString& aTitle);
00237   NS_IMETHOD GetPreferredSheet(nsAString& aTitle);
00238 
00239   NS_IMETHOD GetParserFor(nsICSSStyleSheet* aSheet,
00240                           nsICSSParser** aParser);
00241   NS_IMETHOD RecycleParser(nsICSSParser* aParser);
00242 
00243   NS_IMETHOD LoadInlineStyle(nsIContent* aElement,
00244                              nsIUnicharInputStream* aStream, 
00245                              PRUint32 aLineNumber,
00246                              const nsSubstring& aTitle, 
00247                              const nsSubstring& aMedia, 
00248                              nsIParser* aParserToUnblock,
00249                              PRBool& aCompleted,
00250                              nsICSSLoaderObserver* aObserver);
00251 
00252   NS_IMETHOD LoadStyleLink(nsIContent* aElement,
00253                            nsIURI* aURL, 
00254                            const nsSubstring& aTitle, 
00255                            const nsSubstring& aMedia, 
00256                            nsIParser* aParserToUnblock,
00257                            PRBool& aCompleted,
00258                            nsICSSLoaderObserver* aObserver);
00259 
00260   NS_IMETHOD LoadChildSheet(nsICSSStyleSheet* aParentSheet,
00261                             nsIURI* aURL, 
00262                             nsMediaList* aMedia,
00263                             nsICSSImportRule* aRule);
00264 
00265   // nsICSSLoader_MOZILLA_1_8_BRANCH
00266   NS_IMETHOD LoadSheetSync(nsIURI* aURL, PRBool aAllowUnsafeRules, nsICSSStyleSheet** aSheet);
00267 
00268   NS_IMETHOD LoadAgentSheet(nsIURI* aURL, nsICSSStyleSheet** aSheet);
00269 
00270   NS_IMETHOD LoadAgentSheet(nsIURI* aURL, nsICSSLoaderObserver* aObserver);
00271 
00272   // stop loading all sheets
00273   NS_IMETHOD Stop(void);
00274 
00275   // stop loading one sheet
00276   NS_IMETHOD StopLoadingSheet(nsIURI* aURL);
00277 
00285   NS_IMETHOD GetEnabled(PRBool *aEnabled);
00286   NS_IMETHOD SetEnabled(PRBool aEnabled);
00287 
00288   // local helper methods (some are public for access from statics)
00289   PRBool IsAlternate(const nsAString& aTitle);
00290 
00291 private:
00292   nsresult CheckLoadAllowed(nsIURI* aSourceURI,
00293                             nsIURI* aTargetURI,
00294                             nsISupports* aContext);
00295 
00296 
00297   // For inline style, the aURI param is null, but the aLinkingContent
00298   // must be non-null then.
00299   nsresult CreateSheet(nsIURI* aURI,
00300                        nsIContent* aLinkingContent,
00301                        PRBool aSyncLoad,
00302                        StyleSheetState& aSheetState,
00303                        nsICSSStyleSheet** aSheet);
00304 
00305   // Pass in either a media string or the nsMediaList from the
00306   // CSSParser.  Don't pass both.
00307   nsresult PrepareSheet(nsICSSStyleSheet* aSheet,
00308                         const nsSubstring& aTitle,
00309                         const nsSubstring& aMediaString,
00310                         nsMediaList* aMediaList);
00311 
00312   nsresult InsertSheetInDoc(nsICSSStyleSheet* aSheet,
00313                             nsIContent* aLinkingContent,
00314                             nsIDocument* aDocument);
00315 
00316   nsresult InsertChildSheet(nsICSSStyleSheet* aSheet,
00317                             nsICSSStyleSheet* aParentSheet,
00318                             nsICSSImportRule* aParentRule);
00319 
00320   nsresult InternalLoadAgentSheet(nsIURI* aURL,
00321                                   nsICSSStyleSheet** aSheet,
00322                                   PRBool aAllowUnsafeRules,
00323                                   nsICSSLoaderObserver* aObserver);
00324   
00325 public:
00326   nsresult LoadSheet(SheetLoadData* aLoadData, StyleSheetState aSheetState);
00327 
00328 protected:
00329   friend class SheetLoadData;
00330 
00331   // Protected functions and members are ones that SheetLoadData needs
00332   // access to
00333   nsresult ParseSheet(nsIUnicharInputStream* aStream,
00334                       SheetLoadData* aLoadData,
00335                       PRBool& aCompleted);
00336 
00337 public:
00338   void SheetComplete(SheetLoadData* aLoadData, PRBool aSucceeded);
00339 
00340   static nsCOMArray<nsICSSParser>* gParsers;  // array of idle CSS parsers
00341 
00342 protected:
00343   // the load data needs access to the document...
00344   nsIDocument*      mDocument;  // the document we live for
00345 
00346 #ifdef DEBUG
00347   PRPackedBool            mSyncCallback;
00348 #endif
00349 
00350 private:
00351   PRPackedBool      mCaseSensitive; // is document CSS case sensitive
00352   PRPackedBool      mEnabled; // is enabled to load new styles
00353   nsCompatibility   mCompatMode;
00354   nsString          mPreferredSheet;  // title of preferred sheet
00355 
00356   nsInterfaceHashtable<nsURIHashKey,nsICSSStyleSheet> mCompleteSheets;
00357   nsDataHashtable<nsURIHashKey,SheetLoadData*> mLoadingDatas; // weak refs
00358   nsDataHashtable<nsURIHashKey,SheetLoadData*> mPendingDatas; // weak refs
00359   
00360   // We're not likely to have many levels of @import...  But likely to have
00361   // some.  Allocate some storage, what the hell.
00362   nsAutoVoidArray   mParsingDatas;
00363 
00364 };
00365 
00366 #endif // nsCSSLoader_h__