Back to index

lightning-sunbird  0.9+nobinonly
nsStyleSet.h
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) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Daniel Glazman <glazman@netscape.com>
00024  *   Brian Ryner    <bryner@brianryner.com>
00025  *
00026  * Alternatively, the contents of this file may be used under the terms of
00027  * either of the GNU General Public License Version 2 or later (the "GPL"),
00028  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00029  * in which case the provisions of the GPL or the LGPL are applicable instead
00030  * of those above. If you wish to allow use of your version of this file only
00031  * under the terms of either the GPL or the LGPL, and not to allow others to
00032  * use your version of this file under the terms of the MPL, indicate your
00033  * decision by deleting the provisions above and replace them with the notice
00034  * and other provisions required by the GPL or the LGPL. If you do not delete
00035  * the provisions above, a recipient may use your version of this file under
00036  * the terms of any one of the MPL, the GPL or the LGPL.
00037  *
00038  * ***** END LICENSE BLOCK ***** */
00039 
00040 #ifndef nsStyleSet_h_
00041 #define nsStyleSet_h_
00042 
00043 #include "nsIStyleRuleProcessor.h"
00044 #include "nsICSSStyleSheet.h"
00045 #include "nsVoidArray.h"
00046 #include "nsIStyleRuleSupplier.h"
00047 #include "nsRuleNode.h"
00048 
00049 class nsIURI;
00050 
00051 // The style set object is created by the document viewer and ownership is
00052 // then handed off to the PresShell.  Only the PresShell should delete a
00053 // style set.
00054 
00055 class nsStyleSet
00056 {
00057  public:
00058   nsStyleSet();
00059 
00060   // Initialize the object.  You must check the return code and not use
00061   // the nsStyleSet if Init() fails.
00062 
00063   nsresult Init(nsPresContext *aPresContext);
00064 
00065   // For getting the cached default data in case we hit out-of-memory.
00066   // To be used only by nsRuleNode.
00067   nsCachedStyleData* DefaultStyleData() { return &mDefaultStyleData; }
00068 
00069   // clear out all of the computed style data
00070   void ClearStyleData(nsPresContext *aPresContext);
00071 
00072   // enable / disable the Quirk style sheet
00073   void EnableQuirkStyleSheet(PRBool aEnable);
00074 
00075   // get a style context for a non-pseudo frame.
00076   already_AddRefed<nsStyleContext>
00077   ResolveStyleFor(nsIContent* aContent, nsStyleContext* aParentContext);
00078 
00079   // Get a style context for a non-element (which no rules will match).
00080   // Eventually, this should go away and we shouldn't even create style
00081   // contexts for such content nodes.  However, not doing any rule
00082   // matching for them is a first step.
00083   //
00084   // XXX This is temporary.  It should go away when we stop creating
00085   // style contexts for text nodes and placeholder frames.  (We also use
00086   // it once to create a style context for the nsFirstLetterFrame that
00087   // represents everything except the first letter.)
00088   //
00089   already_AddRefed<nsStyleContext>
00090   ResolveStyleForNonElement(nsStyleContext* aParentContext);
00091 
00092   // get a style context for a pseudo-element (i.e.,
00093   // |aPseudoTag == nsCOMPtr<nsIAtom>(do_GetAtom(":first-line"))|;
00094   already_AddRefed<nsStyleContext>
00095   ResolvePseudoStyleFor(nsIContent* aParentContent,
00096                         nsIAtom* aPseudoTag,
00097                         nsStyleContext* aParentContext,
00098                         nsICSSPseudoComparator* aComparator = nsnull);
00099 
00100   // This funtions just like ResolvePseudoStyleFor except that it will
00101   // return nsnull if there are no explicit style rules for that
00102   // pseudo element.
00103   already_AddRefed<nsStyleContext>
00104   ProbePseudoStyleFor(nsIContent* aParentContent,
00105                       nsIAtom* aPseudoTag,
00106                       nsStyleContext* aParentContext);
00107 
00108   // Begin ignoring style context destruction, to avoid lots of unnecessary
00109   // work on document teardown.
00110   void BeginShutdown(nsPresContext* aPresContext);
00111 
00112   // Free all of the data associated with this style set.
00113   void Shutdown(nsPresContext* aPresContext);
00114 
00115   // Notification that a style context is being destroyed.
00116   void NotifyStyleContextDestroyed(nsPresContext* aPresContext,
00117                                    nsStyleContext* aStyleContext);
00118 
00119   // Get a new style context that lives in a different parent
00120   // The new context will be the same as the old if the new parent is the
00121   // same as the old parent.
00122   already_AddRefed<nsStyleContext>
00123     ReParentStyleContext(nsPresContext* aPresContext,
00124                          nsStyleContext* aStyleContext,
00125                          nsStyleContext* aNewParentContext);
00126 
00127   // Test if style is dependent on content state
00128   nsReStyleHint HasStateDependentStyle(nsPresContext* aPresContext,
00129                                        nsIContent*     aContent,
00130                                        PRInt32         aStateMask);
00131 
00132   // Test if style is dependent on the presence of an attribute.
00133   nsReStyleHint HasAttributeDependentStyle(nsPresContext* aPresContext,
00134                                            nsIContent*     aContent,
00135                                            nsIAtom*        aAttribute,
00136                                            PRInt32         aModType);
00137 
00138   // APIs for registering objects that can supply additional
00139   // rules during processing.
00140   void SetStyleRuleSupplier(nsIStyleRuleSupplier* aSupplier)
00141   {
00142     mStyleRuleSupplier = aSupplier;
00143   }
00144 
00145   nsIStyleRuleSupplier* GetStyleRuleSupplier() const
00146   {
00147     return mStyleRuleSupplier;
00148   }
00149 
00150   // Free global data at module shutdown
00151   static void FreeGlobals() { NS_IF_RELEASE(gQuirkURI); }
00152 
00153   // The "origins" of the CSS cascade, from lowest precedence to
00154   // highest (for non-!important rules).
00155   enum sheetType {
00156     eAgentSheet, // CSS
00157     ePresHintSheet,
00158     eUserSheet, // CSS
00159     eHTMLPresHintSheet,
00160     eDocSheet, // CSS
00161     eStyleAttrSheet,
00162     eOverrideSheet, // CSS
00163     eSheetTypeCount
00164     // be sure to keep the number of bits in |mDirty| below updated when
00165     // changing the number of sheet types
00166   };
00167 
00168   // APIs to manipulate the style sheet lists.  The sheets in each
00169   // list are stored with the most significant sheet last.
00170   nsresult AppendStyleSheet(sheetType aType, nsIStyleSheet *aSheet);
00171   nsresult PrependStyleSheet(sheetType aType, nsIStyleSheet *aSheet);
00172   nsresult RemoveStyleSheet(sheetType aType, nsIStyleSheet *aSheet);
00173   nsresult ReplaceSheets(sheetType aType,
00174                          const nsCOMArray<nsIStyleSheet> &aNewSheets);
00175 
00176   //Enable/Disable entire author style level (Doc & PresHint levels)
00177   PRBool GetAuthorStyleDisabled();
00178   nsresult SetAuthorStyleDisabled(PRBool aStyleDisabled);
00179 
00180   PRInt32 SheetCount(sheetType aType) const {
00181     return mSheets[aType].Count();
00182   }
00183 
00184   nsIStyleSheet* StyleSheetAt(sheetType aType, PRInt32 aIndex) const {
00185     return mSheets[aType].ObjectAt(aIndex);
00186   }
00187 
00188   nsresult AddDocStyleSheet(nsIStyleSheet* aSheet, nsIDocument* aDocument);
00189 
00190   void     BeginUpdate();
00191   nsresult EndUpdate();
00192 
00193  private:
00194   // Not to be implemented
00195   nsStyleSet(const nsStyleSet& aCopy);
00196   nsStyleSet& operator=(const nsStyleSet& aCopy);
00197 
00198   // Returns false on out-of-memory.
00199   PRBool BuildDefaultStyleData(nsPresContext* aPresContext);
00200 
00201   // Update the rule processor list after a change to the style sheet list.
00202   nsresult GatherRuleProcessors(sheetType aType);
00203 
00204   void AddImportantRules(nsRuleNode* aCurrLevelNode,
00205                          nsRuleNode* aLastPrevLevelNode);
00206 
00207 #ifdef DEBUG
00208   // Just like AddImportantRules except it doesn't actually add anything; it
00209   // just asserts that there are no important rules between aCurrLevelNode and
00210   // aLastPrevLevelNode.
00211   void AssertNoImportantRules(nsRuleNode* aCurrLevelNode,
00212                               nsRuleNode* aLastPrevLevelNode);
00213   
00214   // Just like AddImportantRules except it doesn't actually add anything; it
00215   // just asserts that there are no CSS rules between aCurrLevelNode and
00216   // aLastPrevLevelNode.  Mostly useful for the preshint levels.
00217   void AssertNoCSSRules(nsRuleNode* aCurrLevelNode,
00218                         nsRuleNode* aLastPrevLevelNode);
00219 #endif
00220   
00221   // Enumerate the rules in a way that cares about the order of the
00222   // rules.
00223   void FileRules(nsIStyleRuleProcessor::EnumFunc aCollectorFunc,
00224                  RuleProcessorData* aData);
00225 
00226   // Enumerate all the rules in a way that doesn't care about the order
00227   // of the rules and break out if the enumeration is halted.
00228   void WalkRuleProcessors(nsIStyleRuleProcessor::EnumFunc aFunc,
00229                           RuleProcessorData* aData);
00230 
00231   already_AddRefed<nsStyleContext> GetContext(nsPresContext* aPresContext,
00232                                               nsStyleContext* aParentContext,
00233                                               nsIAtom* aPseudoTag);
00234 
00235   nsPresContext* PresContext() { return mRuleTree->GetPresContext(); }
00236 
00237   static nsIURI  *gQuirkURI;
00238 
00239   nsCOMArray<nsIStyleSheet> mSheets[eSheetTypeCount];
00240 
00241   nsCOMPtr<nsIStyleRuleProcessor> mRuleProcessors[eSheetTypeCount];
00242 
00243   // cached instance for enabling/disabling
00244   nsCOMPtr<nsIStyleSheet> mQuirkStyleSheet;
00245 
00246   nsCOMPtr<nsIStyleRuleSupplier> mStyleRuleSupplier;
00247 
00248   // To be used only in case of emergency, such as being out of memory
00249   // or operating on a deleted rule node.  The latter should never
00250   // happen, of course.
00251   nsCachedStyleData mDefaultStyleData;
00252 
00253   nsRuleNode* mRuleTree; // This is the root of our rule tree.  It is a
00254                          // lexicographic tree of matched rules that style
00255                          // contexts use to look up properties.
00256   nsRuleWalker* mRuleWalker; // This is an instance of a rule walker that can
00257                              // be used to navigate through our tree.
00258 
00259   PRInt32 mDestroyedCount; // used to batch style context GC
00260   nsVoidArray mRoots; // style contexts with no parent
00261 
00262   PRUint16 mBatching;
00263 
00264   unsigned mInShutdown : 1;
00265   unsigned mAuthorStyleDisabled: 1;
00266   unsigned mDirty : 7;  // one dirty bit is used per sheet type
00267 };
00268 
00269 #endif