forked from mirrors/gecko-dev
		
	
		
			
				
	
	
		
			511 lines
		
	
	
	
		
			19 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			511 lines
		
	
	
	
		
			19 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 | |
|   * vim: ft=cpp tw=78 sw=2 et ts=2
 | |
|  *
 | |
|  * ***** BEGIN LICENSE BLOCK *****
 | |
|  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 | |
|  *
 | |
|  * The contents of this file are subject to the Mozilla Public License Version
 | |
|  * 1.1 (the "License"); you may not use this file except in compliance with
 | |
|  * the License. You may obtain a copy of the License at
 | |
|  * http://www.mozilla.org/MPL/
 | |
|  *
 | |
|  * Software distributed under the License is distributed on an "AS IS" basis,
 | |
|  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 | |
|  * for the specific language governing rights and limitations under the
 | |
|  * License.
 | |
|  *
 | |
|  * The Original Code is mozilla.org code.
 | |
|  *
 | |
|  * The Initial Developer of the Original Code is
 | |
|  * Netscape Communications Corporation.
 | |
|  * Portions created by the Initial Developer are Copyright (C) 1999
 | |
|  * the Initial Developer. All Rights Reserved.
 | |
|  *
 | |
|  * Contributor(s):
 | |
|  *   Boris Zbarsky <bzbarsky@mit.edu>
 | |
|  *
 | |
|  * Alternatively, the contents of this file may be used under the terms of
 | |
|  * either of the GNU General Public License Version 2 or later (the "GPL"),
 | |
|  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 | |
|  * in which case the provisions of the GPL or the LGPL are applicable instead
 | |
|  * of those above. If you wish to allow use of your version of this file only
 | |
|  * under the terms of either the GPL or the LGPL, and not to allow others to
 | |
|  * use your version of this file under the terms of the MPL, indicate your
 | |
|  * decision by deleting the provisions above and replace them with the notice
 | |
|  * and other provisions required by the GPL or the LGPL. If you do not delete
 | |
|  * the provisions above, a recipient may use your version of this file under
 | |
|  * the terms of any one of the MPL, the GPL or the LGPL.
 | |
|  *
 | |
|  * ***** END LICENSE BLOCK *****
 | |
|  *
 | |
|  * This Original Code has been modified by IBM Corporation. Modifications made by IBM 
 | |
|  * described herein are Copyright (c) International Business Machines Corporation, 2000.
 | |
|  * Modifications to Mozilla code or documentation identified per MPL Section 3.3
 | |
|  *
 | |
|  * Date             Modified by     Description of modification
 | |
|  * 04/20/2000       IBM Corp.      OS/2 VisualAge build.
 | |
|  */
 | |
| 
 | |
| /* loading of CSS style sheets using the network APIs */
 | |
| 
 | |
| #ifndef nsCSSLoader_h__
 | |
| #define nsCSSLoader_h__
 | |
| 
 | |
| class CSSLoaderImpl;
 | |
| class nsIURI;
 | |
| class nsICSSStyleSheet;
 | |
| class nsIStyleSheetLinkingElement;
 | |
| class nsICSSLoaderObserver;
 | |
| class nsICSSParser;
 | |
| class nsICSSImportRule;
 | |
| class nsMediaList;
 | |
| 
 | |
| #include "nsICSSLoader.h"
 | |
| #include "nsIRunnable.h"
 | |
| #include "nsIUnicharStreamLoader.h"
 | |
| #include "nsCOMPtr.h"
 | |
| #include "nsCOMArray.h"
 | |
| #include "nsString.h"
 | |
| #include "nsURIHashKey.h"
 | |
| #include "nsInterfaceHashtable.h"
 | |
| #include "nsDataHashtable.h"
 | |
| #include "nsAutoPtr.h"
 | |
| #include "nsTArray.h"
 | |
| #include "nsIPrincipal.h"
 | |
| #include "nsTObserverArray.h"
 | |
| 
 | |
| /**
 | |
|  * OVERALL ARCHITECTURE
 | |
|  *
 | |
|  * The CSS Loader gets requests to load various sorts of style sheets:
 | |
|  * inline style from <style> elements, linked style, @import-ed child
 | |
|  * sheets, non-document sheets.  The loader handles the following tasks:
 | |
|  *
 | |
|  * 1) Checking whether the load is allowed: CheckLoadAllowed()
 | |
|  * 2) Creation of the actual style sheet objects: CreateSheet()
 | |
|  * 3) setting of the right media, title, enabled state, etc on the
 | |
|  *    sheet: PrepareSheet()
 | |
|  * 4) Insertion of the sheet in the proper cascade order:
 | |
|  *    InsertSheetInDoc() and InsertChildSheet()
 | |
|  * 5) Load of the sheet: LoadSheet()
 | |
|  * 6) Parsing of the sheet: ParseSheet()
 | |
|  * 7) Cleanup: SheetComplete()
 | |
|  *
 | |
|  * The detailed documentation for these functions is found with the
 | |
|  * function implementations.
 | |
|  *
 | |
|  * The following helper object is used:
 | |
|  *    SheetLoadData -- a small class that is used to store all the
 | |
|  *                     information needed for the loading of a sheet;
 | |
|  *                     this class handles listening for the stream
 | |
|  *                     loader completion and also handles charset
 | |
|  *                     determination.
 | |
|  */
 | |
| 
 | |
| /*********************************************
 | |
|  * Data needed to properly load a stylesheet *
 | |
|  *********************************************/
 | |
| 
 | |
| class SheetLoadData : public nsIRunnable,
 | |
|                       public nsIUnicharStreamLoaderObserver
 | |
| {
 | |
| public:
 | |
|   virtual ~SheetLoadData(void);
 | |
|   // Data for loading a sheet linked from a document
 | |
|   SheetLoadData(CSSLoaderImpl* aLoader,
 | |
|                 const nsSubstring& aTitle,
 | |
|                 nsIURI* aURI,
 | |
|                 nsICSSStyleSheet* aSheet,
 | |
|                 nsIStyleSheetLinkingElement* aOwningElement,
 | |
|                 PRBool aIsAlternate,
 | |
|                 nsICSSLoaderObserver* aObserver,
 | |
|                 nsIPrincipal* aLoaderPrincipal);
 | |
| 
 | |
|   // Data for loading a sheet linked from an @import rule
 | |
|   SheetLoadData(CSSLoaderImpl* aLoader,
 | |
|                 nsIURI* aURI,
 | |
|                 nsICSSStyleSheet* aSheet,
 | |
|                 SheetLoadData* aParentData,
 | |
|                 nsICSSLoaderObserver* aObserver,
 | |
|                 nsIPrincipal* aLoaderPrincipal);
 | |
| 
 | |
|   // Data for loading a non-document sheet
 | |
|   SheetLoadData(CSSLoaderImpl* aLoader,
 | |
|                 nsIURI* aURI,
 | |
|                 nsICSSStyleSheet* aSheet,
 | |
|                 PRBool aSyncLoad,
 | |
|                 PRBool aAllowUnsafeRules,
 | |
|                 nsICSSLoaderObserver* aObserver,
 | |
|                 nsIPrincipal* aLoaderPrincipal);
 | |
| 
 | |
|   already_AddRefed<nsIURI> GetReferrerURI();
 | |
|   
 | |
|   NS_DECL_ISUPPORTS
 | |
|   NS_DECL_NSIRUNNABLE
 | |
|   NS_DECL_NSIUNICHARSTREAMLOADEROBSERVER
 | |
| 
 | |
|   // Hold a ref to the CSSLoader so we can call back to it to let it
 | |
|   // know the load finished
 | |
|   CSSLoaderImpl*             mLoader; // strong ref
 | |
| 
 | |
|   // Title needed to pull datas out of the pending datas table when
 | |
|   // the preferred title is changed
 | |
|   nsString                   mTitle;
 | |
| 
 | |
|   // Charset we decided to use for the sheet
 | |
|   nsCString                  mCharset;
 | |
| 
 | |
|   // URI we're loading.  Null for inline sheets
 | |
|   nsCOMPtr<nsIURI>           mURI;
 | |
| 
 | |
|   // Should be 1 for non-inline sheets.
 | |
|   PRUint32                   mLineNumber;
 | |
| 
 | |
|   // The sheet we're loading data for
 | |
|   nsCOMPtr<nsICSSStyleSheet> mSheet;
 | |
| 
 | |
|   // Linked list of datas for the same URI as us
 | |
|   SheetLoadData*             mNext;  // strong ref
 | |
| 
 | |
|   // Load data for the sheet that @import-ed us if we were @import-ed
 | |
|   // during the parse
 | |
|   SheetLoadData*             mParentData;  // strong ref
 | |
| 
 | |
|   // Number of sheets we @import-ed that are still loading
 | |
|   PRUint32                   mPendingChildren;
 | |
| 
 | |
|   // mSyncLoad is true when the load needs to be synchronous -- right
 | |
|   // now only for LoadSheetSync and children of sync loads.
 | |
|   PRPackedBool               mSyncLoad : 1;
 | |
| 
 | |
|   // mIsNonDocumentSheet is true if the load was triggered by LoadSheetSync or
 | |
|   // LoadSheet or an @import from such a sheet.  Non-document sheet loads can
 | |
|   // proceed even if we have no document.
 | |
|   PRPackedBool               mIsNonDocumentSheet : 1;
 | |
| 
 | |
|   // mIsLoading is true from the moment we are placed in the loader's
 | |
|   // "loading datas" table (right after the async channel is opened)
 | |
|   // to the moment we are removed from said table (due to the load
 | |
|   // completing or being cancelled).
 | |
|   PRPackedBool               mIsLoading : 1;
 | |
| 
 | |
|   // mIsCancelled is set to true when a sheet load is stopped by
 | |
|   // Stop() or StopLoadingSheet().  SheetLoadData::OnStreamComplete()
 | |
|   // checks this to avoid parsing sheets that have been cancelled and
 | |
|   // such.
 | |
|   PRPackedBool               mIsCancelled : 1;
 | |
| 
 | |
|   // mMustNotify is true if the load data is being loaded async and
 | |
|   // the original function call that started the load has returned.
 | |
|   // XXXbz sort our relationship with load/error events!
 | |
|   PRPackedBool               mMustNotify : 1;
 | |
|   
 | |
|   // mWasAlternate is true if the sheet was an alternate when the load data was
 | |
|   // created.
 | |
|   PRPackedBool               mWasAlternate : 1;
 | |
|   
 | |
|   // mAllowUnsafeRules is true if we should allow unsafe rules to be parsed
 | |
|   // in the loaded sheet.
 | |
|   PRPackedBool               mAllowUnsafeRules : 1;
 | |
|   
 | |
|   // This is the element that imported the sheet.  Needed to get the
 | |
|   // charset set on it.
 | |
|   nsCOMPtr<nsIStyleSheetLinkingElement> mOwningElement;
 | |
| 
 | |
|   // The observer that wishes to be notified of load completion
 | |
|   nsCOMPtr<nsICSSLoaderObserver>        mObserver;
 | |
| 
 | |
|   // The principal that identifies who started loading us.
 | |
|   nsCOMPtr<nsIPrincipal> mLoaderPrincipal;
 | |
| };
 | |
| 
 | |
| class nsURIAndPrincipalHashKey : public nsURIHashKey
 | |
| {
 | |
| public:
 | |
|   typedef nsURIAndPrincipalHashKey* KeyType;
 | |
|   typedef const nsURIAndPrincipalHashKey* KeyTypePointer;
 | |
| 
 | |
|   nsURIAndPrincipalHashKey(const nsURIAndPrincipalHashKey* aKey)
 | |
|     : nsURIHashKey(aKey->mKey), mPrincipal(aKey->mPrincipal)
 | |
|   {
 | |
|     MOZ_COUNT_CTOR(nsURIAndPrincipalHashKey);
 | |
|   }
 | |
|   nsURIAndPrincipalHashKey(nsIURI* aURI, nsIPrincipal* aPrincipal)
 | |
|     : nsURIHashKey(aURI), mPrincipal(aPrincipal)
 | |
|   {
 | |
|     MOZ_COUNT_CTOR(nsURIAndPrincipalHashKey);
 | |
|   }
 | |
|   nsURIAndPrincipalHashKey(const nsURIAndPrincipalHashKey& toCopy)
 | |
|     : nsURIHashKey(toCopy), mPrincipal(toCopy.mPrincipal)
 | |
|   {
 | |
|     MOZ_COUNT_CTOR(nsURIAndPrincipalHashKey);
 | |
|   }
 | |
|   ~nsURIAndPrincipalHashKey()
 | |
|   {
 | |
|     MOZ_COUNT_DTOR(nsURIAndPrincipalHashKey);
 | |
|   }
 | |
|  
 | |
|   nsURIAndPrincipalHashKey* GetKey() const {
 | |
|     return const_cast<nsURIAndPrincipalHashKey*>(this);
 | |
|   }
 | |
|   const nsURIAndPrincipalHashKey* GetKeyPointer() const { return this; }
 | |
|  
 | |
|   PRBool KeyEquals(const nsURIAndPrincipalHashKey* aKey) const {
 | |
|     if (!nsURIHashKey::KeyEquals(aKey->mKey)) {
 | |
|       return PR_FALSE;
 | |
|     }
 | |
| 
 | |
|     if (!mPrincipal != !aKey->mPrincipal) {
 | |
|       // One or the other has a principal, but not both... not equal
 | |
|       return PR_FALSE;
 | |
|     }
 | |
|        
 | |
|     PRBool eq;
 | |
|     return !mPrincipal ||
 | |
|       NS_SUCCEEDED(mPrincipal->Equals(aKey->mPrincipal, &eq)) && eq;
 | |
|   }
 | |
|  
 | |
|   static const nsURIAndPrincipalHashKey*
 | |
|   KeyToPointer(nsURIAndPrincipalHashKey* aKey) { return aKey; }
 | |
|   static PLDHashNumber HashKey(const nsURIAndPrincipalHashKey* aKey) {
 | |
|     return nsURIHashKey::HashKey(aKey->mKey);
 | |
|   }
 | |
|      
 | |
|   enum { ALLOW_MEMMOVE = PR_TRUE };
 | |
|  
 | |
| protected:
 | |
|   nsCOMPtr<nsIPrincipal> mPrincipal;
 | |
| };
 | |
| 
 | |
| /***********************************************************************
 | |
|  * Enum that describes the state of the sheet returned by CreateSheet. *
 | |
|  ***********************************************************************/
 | |
| enum StyleSheetState {
 | |
|   eSheetStateUnknown = 0,
 | |
|   eSheetNeedsParser,
 | |
|   eSheetPending,
 | |
|   eSheetLoading,
 | |
|   eSheetComplete
 | |
| };
 | |
| 
 | |
| 
 | |
| /**********************
 | |
|  * Loader Declaration *
 | |
|  **********************/
 | |
| 
 | |
| class CSSLoaderImpl : public nsICSSLoader
 | |
| {
 | |
| public:
 | |
|   CSSLoaderImpl(void);
 | |
|   virtual ~CSSLoaderImpl(void);
 | |
| 
 | |
|   NS_DECL_ISUPPORTS
 | |
| 
 | |
|   static void Shutdown(); // called at app shutdown
 | |
|   
 | |
|   // nsICSSLoader methods
 | |
|   NS_IMETHOD Init(nsIDocument* aDocument);
 | |
|   NS_IMETHOD DropDocumentReference(void);
 | |
| 
 | |
|   NS_IMETHOD SetCaseSensitive(PRBool aCaseSensitive);
 | |
|   NS_IMETHOD SetCompatibilityMode(nsCompatibility aCompatMode);
 | |
|   NS_IMETHOD SetPreferredSheet(const nsAString& aTitle);
 | |
|   NS_IMETHOD GetPreferredSheet(nsAString& aTitle);
 | |
| 
 | |
|   NS_IMETHOD GetParserFor(nsICSSStyleSheet* aSheet,
 | |
|                           nsICSSParser** aParser);
 | |
|   NS_IMETHOD RecycleParser(nsICSSParser* aParser);
 | |
| 
 | |
|   NS_IMETHOD LoadInlineStyle(nsIContent* aElement,
 | |
|                              nsIUnicharInputStream* aStream, 
 | |
|                              PRUint32 aLineNumber,
 | |
|                              const nsSubstring& aTitle,
 | |
|                              const nsSubstring& aMedia,
 | |
|                              nsICSSLoaderObserver* aObserver,
 | |
|                              PRBool* aCompleted,
 | |
|                              PRBool* aIsAlternate);
 | |
| 
 | |
|   NS_IMETHOD LoadStyleLink(nsIContent* aElement,
 | |
|                            nsIURI* aURL, 
 | |
|                            const nsSubstring& aTitle,
 | |
|                            const nsSubstring& aMedia,
 | |
|                            PRBool aHasAlternateRel,
 | |
|                            nsICSSLoaderObserver* aObserver,
 | |
|                            PRBool* aIsAlternate);
 | |
| 
 | |
|   NS_IMETHOD LoadChildSheet(nsICSSStyleSheet* aParentSheet,
 | |
|                             nsIURI* aURL, 
 | |
|                             nsMediaList* aMedia,
 | |
|                             nsICSSImportRule* aRule);
 | |
| 
 | |
|   NS_IMETHOD LoadSheetSync(nsIURI* aURL, PRBool aAllowUnsafeRules,
 | |
|                            nsICSSStyleSheet** aSheet);
 | |
| 
 | |
|   NS_IMETHOD LoadSheet(nsIURI* aURL,
 | |
|                        nsIPrincipal* aOriginPrincipal,
 | |
|                        nsICSSLoaderObserver* aObserver,
 | |
|                        nsICSSStyleSheet** aSheet);
 | |
| 
 | |
|   NS_IMETHOD LoadSheet(nsIURI* aURL,
 | |
|                        nsIPrincipal* aOriginPrincipal,
 | |
|                        nsICSSLoaderObserver* aObserver);
 | |
| 
 | |
|   // stop loading all sheets
 | |
|   NS_IMETHOD Stop(void);
 | |
| 
 | |
|   // stop loading one sheet
 | |
|   NS_IMETHOD StopLoadingSheet(nsIURI* aURL);
 | |
| 
 | |
|   /**
 | |
|    * Is the loader enabled or not.
 | |
|    * When disabled, processing of new styles is disabled and an attempt
 | |
|    * to do so will fail with a return code of
 | |
|    * NS_ERROR_NOT_AVAILABLE. Note that this DOES NOT disable
 | |
|    * currently loading styles or already processed styles.
 | |
|    */
 | |
|   NS_IMETHOD GetEnabled(PRBool *aEnabled);
 | |
|   NS_IMETHOD SetEnabled(PRBool aEnabled);
 | |
| 
 | |
|   NS_IMETHOD_(PRBool) HasPendingLoads();
 | |
|   NS_IMETHOD AddObserver(nsICSSLoaderObserver* aObserver);
 | |
|   NS_IMETHOD_(void) RemoveObserver(nsICSSLoaderObserver* aObserver);  
 | |
| 
 | |
|   // local helper methods (some are public for access from statics)
 | |
| 
 | |
|   // IsAlternate can change our currently selected style set if none
 | |
|   // is selected and aHasAlternateRel is false.
 | |
|   PRBool IsAlternate(const nsAString& aTitle, PRBool aHasAlternateRel);
 | |
| 
 | |
| private:
 | |
|   // Note: null aSourcePrincipal indicates that the content policy and
 | |
|   // CheckLoadURI checks should be skipped.
 | |
|   nsresult CheckLoadAllowed(nsIPrincipal* aSourcePrincipal,
 | |
|                             nsIURI* aTargetURI,
 | |
|                             nsISupports* aContext);
 | |
| 
 | |
| 
 | |
|   // For inline style, the aURI param is null, but the aLinkingContent
 | |
|   // must be non-null then.  The loader principal must never be null
 | |
|   // if aURI is not null.
 | |
|   nsresult CreateSheet(nsIURI* aURI,
 | |
|                        nsIContent* aLinkingContent,
 | |
|                        nsIPrincipal* aLoaderPrincipal,
 | |
|                        PRBool aSyncLoad,
 | |
|                        StyleSheetState& aSheetState,
 | |
|                        nsICSSStyleSheet** aSheet);
 | |
| 
 | |
|   // Pass in either a media string or the nsMediaList from the
 | |
|   // CSSParser.  Don't pass both.
 | |
|   // If aIsAlternate is non-null, this method will set *aIsAlternate to
 | |
|   // correspond to the sheet's enabled state (which it will set no matter what)
 | |
|   nsresult PrepareSheet(nsICSSStyleSheet* aSheet,
 | |
|                         const nsSubstring& aTitle,
 | |
|                         const nsSubstring& aMediaString,
 | |
|                         nsMediaList* aMediaList,
 | |
|                         PRBool aHasAlternateRel = PR_FALSE,
 | |
|                         PRBool *aIsAlternate = nsnull);
 | |
| 
 | |
|   nsresult InsertSheetInDoc(nsICSSStyleSheet* aSheet,
 | |
|                             nsIContent* aLinkingContent,
 | |
|                             nsIDocument* aDocument);
 | |
| 
 | |
|   nsresult InsertChildSheet(nsICSSStyleSheet* aSheet,
 | |
|                             nsICSSStyleSheet* aParentSheet,
 | |
|                             nsICSSImportRule* aParentRule);
 | |
| 
 | |
|   nsresult InternalLoadNonDocumentSheet(nsIURI* aURL,
 | |
|                                         PRBool aAllowUnsafeRules,
 | |
|                                         nsIPrincipal* aOriginPrincipal,
 | |
|                                         nsICSSStyleSheet** aSheet,
 | |
|                                         nsICSSLoaderObserver* aObserver);
 | |
| 
 | |
|   // Post a load event for aObserver to be notified about aSheet.  The
 | |
|   // notification will be sent with status NS_OK unless the load event is
 | |
|   // canceled at some point (in which case it will be sent with
 | |
|   // NS_BINDING_ABORTED).  aWasAlternate indicates the state when the load was
 | |
|   // initiated, not the state at some later time.  aURI should be the URI the
 | |
|   // sheet was loaded from (may be null for inline sheets).
 | |
|   nsresult PostLoadEvent(nsIURI* aURI,
 | |
|                          nsICSSStyleSheet* aSheet,
 | |
|                          nsICSSLoaderObserver* aObserver,
 | |
|                          PRBool aWasAlternate);
 | |
| 
 | |
|   // Start the loads of all the sheets in mPendingDatas
 | |
|   void StartAlternateLoads();
 | |
|   
 | |
| public:
 | |
|   // Handle an event posted by PostLoadEvent
 | |
|   void HandleLoadEvent(SheetLoadData* aEvent);
 | |
| 
 | |
| protected:
 | |
|   // Note: LoadSheet is responsible for releasing aLoadData and setting the
 | |
|   // sheet to complete on failure.
 | |
|   nsresult LoadSheet(SheetLoadData* aLoadData, StyleSheetState aSheetState);
 | |
| 
 | |
|   friend class SheetLoadData;
 | |
| 
 | |
|   // Protected functions and members are ones that SheetLoadData needs
 | |
|   // access to.
 | |
| 
 | |
|   // Parse the stylesheet in aLoadData.  The sheet data comes from aStream.
 | |
|   // Set aCompleted to true if the parse finished, false otherwise (e.g. if the
 | |
|   // sheet had an @import).  If aCompleted is true when this returns, then
 | |
|   // ParseSheet also called SheetComplete on aLoadData
 | |
|   nsresult ParseSheet(nsIUnicharInputStream* aStream,
 | |
|                       SheetLoadData* aLoadData,
 | |
|                       PRBool& aCompleted);
 | |
| 
 | |
|   // The load of the sheet in aLoadData is done, one way or another.  Do final
 | |
|   // cleanup, including releasing aLoadData.
 | |
|   void SheetComplete(SheetLoadData* aLoadData, nsresult aStatus);
 | |
| 
 | |
| public:
 | |
|   typedef nsTArray<nsRefPtr<SheetLoadData> > LoadDataArray;
 | |
|   
 | |
| private:
 | |
|   // The guts of SheetComplete.  This may be called recursively on parent datas
 | |
|   // or datas that had glommed on to a single load.  The array is there so load
 | |
|   // datas whose observers need to be notified can be added to it.
 | |
|   void DoSheetComplete(SheetLoadData* aLoadData, nsresult aStatus,
 | |
|                        LoadDataArray& aDatasToNotify);
 | |
| 
 | |
|   static nsCOMArray<nsICSSParser>* gParsers;  // array of idle CSS parsers
 | |
| 
 | |
|   // the load data needs access to the document...
 | |
|   nsIDocument*      mDocument;  // the document we live for
 | |
| 
 | |
| #ifdef DEBUG
 | |
|   PRPackedBool            mSyncCallback;
 | |
| #endif
 | |
| 
 | |
|   PRPackedBool      mCaseSensitive; // is document CSS case sensitive
 | |
|   PRPackedBool      mEnabled; // is enabled to load new styles
 | |
|   nsCompatibility   mCompatMode;
 | |
|   nsString          mPreferredSheet;  // title of preferred sheet
 | |
| 
 | |
|   nsInterfaceHashtable<nsURIAndPrincipalHashKey,
 | |
|                        nsICSSStyleSheet> mCompleteSheets;
 | |
|   nsDataHashtable<nsURIAndPrincipalHashKey,
 | |
|                   SheetLoadData*> mLoadingDatas; // weak refs
 | |
|   nsDataHashtable<nsURIAndPrincipalHashKey,
 | |
|                   SheetLoadData*> mPendingDatas; // weak refs
 | |
|   
 | |
|   // We're not likely to have many levels of @import...  But likely to have
 | |
|   // some.  Allocate some storage, what the hell.
 | |
|   nsAutoVoidArray   mParsingDatas;
 | |
| 
 | |
|   // The array of posted stylesheet loaded events (SheetLoadDatas) we have.
 | |
|   // Note that these are rare.
 | |
|   LoadDataArray mPostedEvents;
 | |
| 
 | |
|   // Number of datas still waiting to be notified on if we're notifying on a
 | |
|   // whole bunch at once (e.g. in one of the stop methods).  This is used to
 | |
|   // make sure that HasPendingLoads() won't return false until we're notifying
 | |
|   // on the last data we're working with.
 | |
|   PRUint32 mDatasToNotifyOn;
 | |
| 
 | |
|   // Our array of "global" observers
 | |
|   nsTObserverArray<nsCOMPtr<nsICSSLoaderObserver> > mObservers;
 | |
| };
 | |
| 
 | |
| #endif // nsCSSLoader_h__
 | 
