2001-09-25 05:32:19 +04:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* ***** BEGIN LICENSE BLOCK *****
|
|
|
|
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
1998-04-14 00:24:54 +04:00
|
|
|
*
|
2001-09-25 05:32:19 +04:00
|
|
|
* The contents of this file are subject to the Netscape 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/NPL/
|
1998-04-14 00:24:54 +04:00
|
|
|
*
|
2001-09-25 05:32:19 +04:00
|
|
|
* 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.
|
1998-04-14 00:24:54 +04:00
|
|
|
*
|
1999-11-06 06:40:37 +03:00
|
|
|
* The Original Code is mozilla.org code.
|
|
|
|
*
|
2001-09-25 05:32:19 +04:00
|
|
|
* The Initial Developer of the Original Code is
|
|
|
|
* Netscape Communications Corporation.
|
|
|
|
* Portions created by the Initial Developer are Copyright (C) 1998
|
|
|
|
* the Initial Developer. All Rights Reserved.
|
1999-11-06 06:40:37 +03:00
|
|
|
*
|
2001-08-02 18:34:55 +04:00
|
|
|
* Contributor(s):
|
|
|
|
* Daniel Glazman <glazman@netscape.com>
|
2001-09-25 05:32:19 +04:00
|
|
|
*
|
|
|
|
*
|
|
|
|
* Alternatively, the contents of this file may be used under the terms of
|
|
|
|
* either 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 NPL, 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 NPL, the GPL or the LGPL.
|
|
|
|
*
|
|
|
|
* ***** END LICENSE BLOCK ***** */
|
1999-02-12 20:45:58 +03:00
|
|
|
#include "nsCOMPtr.h"
|
1998-04-14 00:24:54 +04:00
|
|
|
#include "nsIStyleSet.h"
|
|
|
|
#include "nsIStyleSheet.h"
|
1999-10-08 07:09:31 +04:00
|
|
|
#include "nsIStyleRuleProcessor.h"
|
1998-04-14 00:24:54 +04:00
|
|
|
#include "nsIStyleRule.h"
|
2001-06-01 02:19:43 +04:00
|
|
|
#include "nsICSSStyleRule.h"
|
1998-04-14 00:24:54 +04:00
|
|
|
#include "nsISupportsArray.h"
|
|
|
|
#include "nsIFrame.h"
|
1998-09-10 23:32:14 +04:00
|
|
|
#include "nsIPresContext.h"
|
|
|
|
#include "nsIPresShell.h"
|
|
|
|
#include "nsIContent.h"
|
1999-01-23 10:01:57 +03:00
|
|
|
#include "nsIDocument.h"
|
1998-09-10 23:32:14 +04:00
|
|
|
#include "nsIStyleFrameConstruction.h"
|
1998-12-02 03:30:42 +03:00
|
|
|
#include "nsLayoutAtoms.h"
|
1999-11-10 06:41:09 +03:00
|
|
|
#include "nsTimer.h"
|
2000-06-03 01:45:06 +04:00
|
|
|
#include "nsICSSStyleSheet.h"
|
|
|
|
#include "nsNetUtil.h"
|
2000-08-12 10:28:02 +04:00
|
|
|
#include "nsIStyleRuleSupplier.h"
|
2001-06-01 02:19:43 +04:00
|
|
|
#include "nsRuleNode.h"
|
2001-10-24 04:01:09 +04:00
|
|
|
#include "nsRuleWalker.h"
|
2001-08-02 18:34:55 +04:00
|
|
|
#include "nsIBodySuper.h"
|
|
|
|
#include "nsIHTMLDocument.h"
|
|
|
|
#include "nsIDOMHTMLBodyElement.h"
|
2000-08-12 10:28:02 +04:00
|
|
|
|
1999-10-20 02:27:20 +04:00
|
|
|
#ifdef MOZ_PERF_METRICS
|
2000-02-11 04:21:36 +03:00
|
|
|
#include "nsITimeRecorder.h"
|
|
|
|
#define STYLESET_START_TIMER(a) \
|
|
|
|
StartTimer(a)
|
|
|
|
#define STYLESET_STOP_TIMER(a) \
|
|
|
|
StopTimer(a)
|
|
|
|
#else
|
|
|
|
#define STYLESET_START_TIMER(a) ((void)0)
|
|
|
|
#define STYLESET_STOP_TIMER(a) ((void)0)
|
1999-09-20 10:53:40 +04:00
|
|
|
#endif
|
1998-04-14 00:24:54 +04:00
|
|
|
|
2001-06-01 02:19:43 +04:00
|
|
|
#include "nsISizeOfHandler.h"
|
2001-01-03 02:13:49 +03:00
|
|
|
|
2001-06-01 02:19:43 +04:00
|
|
|
static NS_DEFINE_IID(kIStyleFrameConstructionIID, NS_ISTYLE_FRAME_CONSTRUCTION_IID);
|
2001-01-03 02:13:49 +03:00
|
|
|
|
1999-09-20 10:53:40 +04:00
|
|
|
class StyleSetImpl : public nsIStyleSet
|
1999-10-20 02:27:20 +04:00
|
|
|
#ifdef MOZ_PERF_METRICS
|
1999-09-20 10:53:40 +04:00
|
|
|
, public nsITimeRecorder
|
|
|
|
#endif
|
|
|
|
{
|
1998-04-14 00:24:54 +04:00
|
|
|
public:
|
|
|
|
StyleSetImpl();
|
|
|
|
|
|
|
|
NS_DECL_ISUPPORTS
|
|
|
|
|
|
|
|
virtual void AppendOverrideStyleSheet(nsIStyleSheet* aSheet);
|
|
|
|
virtual void InsertOverrideStyleSheetAfter(nsIStyleSheet* aSheet,
|
|
|
|
nsIStyleSheet* aAfterSheet);
|
|
|
|
virtual void InsertOverrideStyleSheetBefore(nsIStyleSheet* aSheet,
|
|
|
|
nsIStyleSheet* aBeforeSheet);
|
|
|
|
virtual void RemoveOverrideStyleSheet(nsIStyleSheet* aSheet);
|
|
|
|
virtual PRInt32 GetNumberOfOverrideStyleSheets();
|
|
|
|
virtual nsIStyleSheet* GetOverrideStyleSheetAt(PRInt32 aIndex);
|
|
|
|
|
1999-01-23 10:01:57 +03:00
|
|
|
virtual void AddDocStyleSheet(nsIStyleSheet* aSheet, nsIDocument* aDocument);
|
1998-04-14 00:24:54 +04:00
|
|
|
virtual void RemoveDocStyleSheet(nsIStyleSheet* aSheet);
|
|
|
|
virtual PRInt32 GetNumberOfDocStyleSheets();
|
|
|
|
virtual nsIStyleSheet* GetDocStyleSheetAt(PRInt32 aIndex);
|
|
|
|
|
|
|
|
virtual void AppendBackstopStyleSheet(nsIStyleSheet* aSheet);
|
|
|
|
virtual void InsertBackstopStyleSheetAfter(nsIStyleSheet* aSheet,
|
|
|
|
nsIStyleSheet* aAfterSheet);
|
|
|
|
virtual void InsertBackstopStyleSheetBefore(nsIStyleSheet* aSheet,
|
|
|
|
nsIStyleSheet* aBeforeSheet);
|
|
|
|
virtual void RemoveBackstopStyleSheet(nsIStyleSheet* aSheet);
|
|
|
|
virtual PRInt32 GetNumberOfBackstopStyleSheets();
|
|
|
|
virtual nsIStyleSheet* GetBackstopStyleSheetAt(PRInt32 aIndex);
|
2000-05-28 00:03:14 +04:00
|
|
|
virtual void ReplaceBackstopStyleSheets(nsISupportsArray* aNewSheets);
|
2000-06-22 00:44:59 +04:00
|
|
|
|
2000-06-03 01:45:06 +04:00
|
|
|
NS_IMETHOD EnableQuirkStyleSheet(PRBool aEnable);
|
|
|
|
|
2000-06-22 00:44:59 +04:00
|
|
|
NS_IMETHOD NotifyStyleSheetStateChanged(PRBool aDisabled);
|
|
|
|
|
1998-04-14 00:24:54 +04:00
|
|
|
virtual nsIStyleContext* ResolveStyleFor(nsIPresContext* aPresContext,
|
|
|
|
nsIContent* aContent,
|
1998-11-03 23:19:28 +03:00
|
|
|
nsIStyleContext* aParentContext,
|
1998-06-05 10:00:55 +04:00
|
|
|
PRBool aForceUnique = PR_FALSE);
|
1998-04-14 00:24:54 +04:00
|
|
|
|
1998-05-19 01:05:52 +04:00
|
|
|
virtual nsIStyleContext* ResolvePseudoStyleFor(nsIPresContext* aPresContext,
|
1998-11-03 23:19:28 +03:00
|
|
|
nsIContent* aParentContent,
|
1998-05-19 01:05:52 +04:00
|
|
|
nsIAtom* aPseudoTag,
|
1998-11-03 23:19:28 +03:00
|
|
|
nsIStyleContext* aParentContext,
|
2001-02-16 00:24:47 +03:00
|
|
|
PRBool aForceUnique = PR_FALSE,
|
|
|
|
nsICSSPseudoComparator* aComparator = nsnull);
|
1998-05-19 01:05:52 +04:00
|
|
|
|
|
|
|
virtual nsIStyleContext* ProbePseudoStyleFor(nsIPresContext* aPresContext,
|
1998-11-03 23:19:28 +03:00
|
|
|
nsIContent* aParentContent,
|
1998-05-19 01:05:52 +04:00
|
|
|
nsIAtom* aPseudoTag,
|
1998-11-03 23:19:28 +03:00
|
|
|
nsIStyleContext* aParentContext,
|
1998-06-05 10:00:55 +04:00
|
|
|
PRBool aForceUnique = PR_FALSE);
|
1998-05-19 01:05:52 +04:00
|
|
|
|
2001-06-01 02:19:43 +04:00
|
|
|
NS_IMETHOD Shutdown();
|
|
|
|
|
2001-10-24 04:01:09 +04:00
|
|
|
virtual nsresult GetRuleTree(nsRuleNode** aResult);
|
|
|
|
virtual nsresult ClearCachedDataInRuleTree(nsIStyleRule* aRule);
|
|
|
|
|
2001-07-25 10:33:06 +04:00
|
|
|
virtual nsresult ClearStyleData(nsIPresContext* aPresContext, nsIStyleRule* aRule, nsIStyleContext* aContext);
|
2001-06-01 02:19:43 +04:00
|
|
|
|
2001-08-02 18:34:55 +04:00
|
|
|
virtual nsresult RemoveBodyFixupRule(nsIDocument *aDocument);
|
|
|
|
|
1999-09-04 03:35:41 +04:00
|
|
|
NS_IMETHOD ReParentStyleContext(nsIPresContext* aPresContext,
|
|
|
|
nsIStyleContext* aStyleContext,
|
|
|
|
nsIStyleContext* aNewParentContext,
|
|
|
|
nsIStyleContext** aNewStyleContext);
|
|
|
|
|
1999-04-20 04:02:22 +04:00
|
|
|
NS_IMETHOD HasStateDependentStyle(nsIPresContext* aPresContext,
|
|
|
|
nsIContent* aContent);
|
|
|
|
|
1998-12-29 06:38:16 +03:00
|
|
|
NS_IMETHOD ConstructRootFrame(nsIPresContext* aPresContext,
|
|
|
|
nsIContent* aContent,
|
|
|
|
nsIFrame*& aFrameSubTree);
|
1999-03-01 19:57:35 +03:00
|
|
|
NS_IMETHOD ReconstructDocElementHierarchy(nsIPresContext* aPresContext);
|
1998-09-10 23:32:14 +04:00
|
|
|
NS_IMETHOD ContentAppended(nsIPresContext* aPresContext,
|
|
|
|
nsIContent* aContainer,
|
|
|
|
PRInt32 aNewIndexInContainer);
|
|
|
|
NS_IMETHOD ContentInserted(nsIPresContext* aPresContext,
|
|
|
|
nsIContent* aContainer,
|
|
|
|
nsIContent* aChild,
|
|
|
|
PRInt32 aIndexInContainer);
|
|
|
|
NS_IMETHOD ContentReplaced(nsIPresContext* aPresContext,
|
|
|
|
nsIContent* aContainer,
|
|
|
|
nsIContent* aOldChild,
|
|
|
|
nsIContent* aNewChild,
|
|
|
|
PRInt32 aIndexInContainer);
|
|
|
|
NS_IMETHOD ContentRemoved(nsIPresContext* aPresContext,
|
|
|
|
nsIContent* aContainer,
|
|
|
|
nsIContent* aChild,
|
|
|
|
PRInt32 aIndexInContainer);
|
|
|
|
|
1998-09-30 03:47:03 +04:00
|
|
|
NS_IMETHOD ContentChanged(nsIPresContext* aPresContext,
|
|
|
|
nsIContent* aContent,
|
|
|
|
nsISupports* aSubContent);
|
1999-04-20 04:02:22 +04:00
|
|
|
NS_IMETHOD ContentStatesChanged(nsIPresContext* aPresContext,
|
|
|
|
nsIContent* aContent1,
|
|
|
|
nsIContent* aContent2);
|
1998-09-30 03:47:03 +04:00
|
|
|
NS_IMETHOD AttributeChanged(nsIPresContext* aPresContext,
|
|
|
|
nsIContent* aChild,
|
1999-10-16 03:16:45 +04:00
|
|
|
PRInt32 aNameSpaceID,
|
1998-09-30 03:47:03 +04:00
|
|
|
nsIAtom* aAttribute,
|
2001-08-25 06:01:08 +04:00
|
|
|
PRInt32 aModType,
|
1998-09-30 03:47:03 +04:00
|
|
|
PRInt32 aHint); // See nsStyleConsts fot hint values
|
|
|
|
|
1998-04-14 00:24:54 +04:00
|
|
|
// xxx style rules enumeration
|
|
|
|
|
1998-11-26 04:34:53 +03:00
|
|
|
// Style change notifications
|
|
|
|
NS_IMETHOD StyleRuleChanged(nsIPresContext* aPresContext,
|
|
|
|
nsIStyleSheet* aStyleSheet,
|
|
|
|
nsIStyleRule* aStyleRule,
|
|
|
|
PRInt32 aHint); // See nsStyleConsts fot hint values
|
|
|
|
NS_IMETHOD StyleRuleAdded(nsIPresContext* aPresContext,
|
|
|
|
nsIStyleSheet* aStyleSheet,
|
|
|
|
nsIStyleRule* aStyleRule);
|
|
|
|
NS_IMETHOD StyleRuleRemoved(nsIPresContext* aPresContext,
|
|
|
|
nsIStyleSheet* aStyleSheet,
|
|
|
|
nsIStyleRule* aStyleRule);
|
|
|
|
|
1999-02-04 20:03:46 +03:00
|
|
|
// Notification that we were unable to render a replaced element.
|
|
|
|
NS_IMETHOD CantRenderReplacedElement(nsIPresContext* aPresContext,
|
|
|
|
nsIFrame* aFrame);
|
|
|
|
|
1999-02-24 07:03:50 +03:00
|
|
|
// Request to create a continuing frame
|
|
|
|
NS_IMETHOD CreateContinuingFrame(nsIPresContext* aPresContext,
|
|
|
|
nsIFrame* aFrame,
|
|
|
|
nsIFrame* aParentFrame,
|
|
|
|
nsIFrame** aContinuingFrame);
|
|
|
|
|
1999-07-02 08:46:19 +04:00
|
|
|
// Request to find the primary frame associated with a given content object.
|
|
|
|
// This is typically called by the pres shell when there is no mapping in
|
|
|
|
// the pres shell hash table
|
1999-08-05 07:09:22 +04:00
|
|
|
NS_IMETHOD FindPrimaryFrameFor(nsIPresContext* aPresContext,
|
|
|
|
nsIFrameManager* aFrameManager,
|
|
|
|
nsIContent* aContent,
|
2001-01-17 01:10:04 +03:00
|
|
|
nsIFrame** aFrame,
|
|
|
|
nsFindFrameHint* aHint);
|
1999-07-02 08:46:19 +04:00
|
|
|
|
2001-09-13 00:19:41 +04:00
|
|
|
// Get the XBL insertion point for a child
|
|
|
|
NS_IMETHOD GetInsertionPoint(nsIPresShell* aPresShell,
|
|
|
|
nsIFrame* aParentFrame,
|
|
|
|
nsIContent* aChildContent,
|
|
|
|
nsIFrame** aInsertionPoint);
|
|
|
|
|
2000-08-12 10:28:02 +04:00
|
|
|
// APIs for registering objects that can supply additional
|
|
|
|
// rules during processing.
|
|
|
|
NS_IMETHOD SetStyleRuleSupplier(nsIStyleRuleSupplier* aSupplier);
|
|
|
|
NS_IMETHOD GetStyleRuleSupplier(nsIStyleRuleSupplier** aSupplier);
|
|
|
|
|
2001-10-16 09:31:36 +04:00
|
|
|
#ifdef DEBUG
|
1998-04-14 00:24:54 +04:00
|
|
|
virtual void List(FILE* out = stdout, PRInt32 aIndent = 0);
|
|
|
|
|
2000-03-31 11:08:36 +04:00
|
|
|
virtual void SizeOf(nsISizeOfHandler *aSizeofHandler, PRUint32 &aSize);
|
2001-10-16 09:31:36 +04:00
|
|
|
#endif
|
2000-03-31 11:08:36 +04:00
|
|
|
virtual void ResetUniqueStyleItems(void);
|
|
|
|
|
2001-10-24 04:01:09 +04:00
|
|
|
void AddImportantRules(nsRuleNode* aRuleNode);
|
2000-03-31 11:08:36 +04:00
|
|
|
|
1999-10-20 02:27:20 +04:00
|
|
|
#ifdef MOZ_PERF_METRICS
|
1999-09-20 10:53:40 +04:00
|
|
|
NS_DECL_NSITIMERECORDER
|
|
|
|
#endif
|
|
|
|
|
2000-05-16 06:43:33 +04:00
|
|
|
NS_IMETHOD AttributeAffectsStyle(nsIAtom *aAttribute, nsIContent *aContent,
|
|
|
|
PRBool &aAffects);
|
|
|
|
|
2000-08-12 10:28:02 +04:00
|
|
|
void WalkRuleProcessors(nsISupportsArrayEnumFunc aFunc, void* aData,
|
|
|
|
nsIContent* aContent);
|
|
|
|
|
1998-04-14 00:24:54 +04:00
|
|
|
private:
|
2000-11-08 06:13:53 +03:00
|
|
|
static nsrefcnt gInstances;
|
|
|
|
static nsIURI *gQuirkURI;
|
|
|
|
|
1998-04-14 00:24:54 +04:00
|
|
|
// These are not supported and are not implemented!
|
|
|
|
StyleSetImpl(const StyleSetImpl& aCopy);
|
|
|
|
StyleSetImpl& operator=(const StyleSetImpl& aCopy);
|
|
|
|
|
|
|
|
protected:
|
|
|
|
virtual ~StyleSetImpl();
|
|
|
|
PRBool EnsureArray(nsISupportsArray** aArray);
|
1999-10-08 07:09:31 +04:00
|
|
|
void RecycleArray(nsISupportsArray** aArray);
|
2000-08-12 10:28:02 +04:00
|
|
|
|
2001-06-01 02:19:43 +04:00
|
|
|
void EnsureRuleWalker(nsIPresContext* aPresContext);
|
|
|
|
|
2000-08-12 10:28:02 +04:00
|
|
|
void ClearRuleProcessors(void);
|
|
|
|
void ClearOverrideRuleProcessors(void);
|
|
|
|
void ClearBackstopRuleProcessors(void);
|
|
|
|
void ClearDocRuleProcessors(void);
|
|
|
|
|
1999-10-08 07:09:31 +04:00
|
|
|
nsresult GatherRuleProcessors(void);
|
|
|
|
|
2001-06-01 02:19:43 +04:00
|
|
|
nsIStyleContext* GetContext(nsIPresContext* aPresContext,
|
|
|
|
nsIStyleContext* aParentContext,
|
|
|
|
nsIAtom* aPseudoTag,
|
|
|
|
PRBool aForceUnique);
|
2001-10-16 09:31:36 +04:00
|
|
|
#ifdef DEBUG
|
1998-04-14 00:24:54 +04:00
|
|
|
void List(FILE* out, PRInt32 aIndent, nsISupportsArray* aSheets);
|
1998-06-26 09:49:01 +04:00
|
|
|
void ListContexts(nsIStyleContext* aRootContext, FILE* out, PRInt32 aIndent);
|
2001-10-16 09:31:36 +04:00
|
|
|
#endif
|
1998-04-14 00:24:54 +04:00
|
|
|
|
1999-10-08 07:09:31 +04:00
|
|
|
nsISupportsArray* mOverrideSheets; // most significant first
|
|
|
|
nsISupportsArray* mDocSheets; // " "
|
|
|
|
nsISupportsArray* mBackstopSheets; // " "
|
|
|
|
|
2000-08-12 10:28:02 +04:00
|
|
|
nsISupportsArray* mBackstopRuleProcessors; // least significant first
|
|
|
|
nsISupportsArray* mDocRuleProcessors; // " "
|
|
|
|
nsISupportsArray* mOverrideRuleProcessors; // " "
|
1999-10-08 07:09:31 +04:00
|
|
|
|
1998-10-13 23:09:39 +04:00
|
|
|
nsISupportsArray* mRecycler;
|
1998-11-03 23:19:28 +03:00
|
|
|
|
1998-09-10 23:32:14 +04:00
|
|
|
nsIStyleFrameConstruction* mFrameConstructor;
|
2000-06-03 01:45:06 +04:00
|
|
|
nsIStyleSheet* mQuirkStyleSheet; // cached instance for enabling/disabling
|
|
|
|
|
2000-08-12 10:28:02 +04:00
|
|
|
nsCOMPtr<nsIStyleRuleSupplier> mStyleRuleSupplier;
|
|
|
|
|
2001-10-24 04:01:09 +04:00
|
|
|
nsRuleNode* mRuleTree; // This is the root of our rule tree. It is a lexicographic tree of
|
|
|
|
// matched rules that style contexts use to look up properties.
|
|
|
|
nsRuleWalker* mRuleWalker; // This is an instance of a rule walker that can be used
|
|
|
|
// to navigate through our tree.
|
2000-03-31 11:08:36 +04:00
|
|
|
|
1999-11-12 00:35:34 +03:00
|
|
|
MOZ_TIMER_DECLARE(mStyleResolutionWatch)
|
2000-02-11 04:21:36 +03:00
|
|
|
|
|
|
|
#ifdef MOZ_PERF_METRICS
|
|
|
|
PRBool mTimerEnabled; // true if timing is enabled, false if disabled
|
|
|
|
#endif
|
|
|
|
|
1998-04-14 00:24:54 +04:00
|
|
|
};
|
|
|
|
|
2000-11-08 06:13:53 +03:00
|
|
|
nsrefcnt StyleSetImpl::gInstances = 0;
|
|
|
|
nsIURI *StyleSetImpl::gQuirkURI = 0;
|
|
|
|
|
1998-04-14 00:24:54 +04:00
|
|
|
StyleSetImpl::StyleSetImpl()
|
|
|
|
: mOverrideSheets(nsnull),
|
|
|
|
mDocSheets(nsnull),
|
1998-09-10 23:32:14 +04:00
|
|
|
mBackstopSheets(nsnull),
|
2000-08-12 10:28:02 +04:00
|
|
|
mBackstopRuleProcessors(nsnull),
|
|
|
|
mDocRuleProcessors(nsnull),
|
|
|
|
mOverrideRuleProcessors(nsnull),
|
1999-02-12 20:45:58 +03:00
|
|
|
mRecycler(nsnull),
|
2000-06-22 00:44:59 +04:00
|
|
|
mFrameConstructor(nsnull),
|
2000-08-12 10:28:02 +04:00
|
|
|
mQuirkStyleSheet(nsnull),
|
2001-10-24 04:01:09 +04:00
|
|
|
mStyleRuleSupplier(nsnull),
|
|
|
|
mRuleTree(nsnull),
|
|
|
|
mRuleWalker(nsnull)
|
2000-02-11 04:21:36 +03:00
|
|
|
#ifdef MOZ_PERF_METRICS
|
|
|
|
,mTimerEnabled(PR_FALSE)
|
|
|
|
#endif
|
1998-04-14 00:24:54 +04:00
|
|
|
{
|
|
|
|
NS_INIT_REFCNT();
|
2000-11-08 06:13:53 +03:00
|
|
|
if (gInstances++ == 0)
|
|
|
|
{
|
|
|
|
const char kQuirk_href[] = "resource:/res/quirk.css";
|
|
|
|
NS_NewURI (&gQuirkURI, kQuirk_href);
|
|
|
|
NS_ASSERTION (gQuirkURI != 0, "Cannot allocate nsStyleSetImpl::gQuirkURI");
|
2001-06-01 02:19:43 +04:00
|
|
|
}
|
1998-04-14 00:24:54 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
StyleSetImpl::~StyleSetImpl()
|
|
|
|
{
|
|
|
|
NS_IF_RELEASE(mOverrideSheets);
|
|
|
|
NS_IF_RELEASE(mDocSheets);
|
|
|
|
NS_IF_RELEASE(mBackstopSheets);
|
2000-08-12 10:28:02 +04:00
|
|
|
NS_IF_RELEASE(mBackstopRuleProcessors);
|
|
|
|
NS_IF_RELEASE(mDocRuleProcessors);
|
|
|
|
NS_IF_RELEASE(mOverrideRuleProcessors);
|
1998-09-10 23:32:14 +04:00
|
|
|
NS_IF_RELEASE(mFrameConstructor);
|
1998-10-13 23:09:39 +04:00
|
|
|
NS_IF_RELEASE(mRecycler);
|
2000-06-03 01:45:06 +04:00
|
|
|
NS_IF_RELEASE(mQuirkStyleSheet);
|
2000-11-08 06:13:53 +03:00
|
|
|
if (--gInstances == 0)
|
|
|
|
{
|
|
|
|
NS_IF_RELEASE (gQuirkURI);
|
|
|
|
}
|
1998-04-14 00:24:54 +04:00
|
|
|
}
|
|
|
|
|
1999-10-20 02:27:20 +04:00
|
|
|
#ifndef MOZ_PERF_METRICS
|
2001-08-21 05:48:11 +04:00
|
|
|
NS_IMPL_ISUPPORTS1(StyleSetImpl, nsIStyleSet)
|
1999-09-20 10:53:40 +04:00
|
|
|
#else
|
|
|
|
NS_IMPL_ISUPPORTS2(StyleSetImpl, nsIStyleSet, nsITimeRecorder)
|
|
|
|
#endif
|
1998-04-14 00:24:54 +04:00
|
|
|
|
|
|
|
PRBool StyleSetImpl::EnsureArray(nsISupportsArray** aArray)
|
|
|
|
{
|
|
|
|
if (nsnull == *aArray) {
|
1999-10-08 07:09:31 +04:00
|
|
|
(*aArray) = mRecycler;
|
|
|
|
mRecycler = nsnull;
|
|
|
|
if (nsnull == *aArray) {
|
|
|
|
if (NS_OK != NS_NewISupportsArray(aArray)) {
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
StyleSetImpl::RecycleArray(nsISupportsArray** aArray)
|
|
|
|
{
|
|
|
|
if (! mRecycler) {
|
|
|
|
mRecycler = *aArray; // take ref
|
|
|
|
mRecycler->Clear();
|
|
|
|
*aArray = nsnull;
|
|
|
|
}
|
|
|
|
else { // already have a recycled array
|
|
|
|
NS_RELEASE(*aArray);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
StyleSetImpl::ClearRuleProcessors(void)
|
|
|
|
{
|
2000-08-12 10:28:02 +04:00
|
|
|
ClearBackstopRuleProcessors();
|
|
|
|
ClearDocRuleProcessors();
|
|
|
|
ClearOverrideRuleProcessors();
|
1999-10-08 07:09:31 +04:00
|
|
|
}
|
2000-08-12 10:28:02 +04:00
|
|
|
|
|
|
|
void
|
|
|
|
StyleSetImpl::ClearBackstopRuleProcessors(void)
|
|
|
|
{
|
|
|
|
if (mBackstopRuleProcessors)
|
|
|
|
RecycleArray(&mBackstopRuleProcessors);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
StyleSetImpl::ClearDocRuleProcessors(void)
|
|
|
|
{
|
|
|
|
if (mDocRuleProcessors)
|
|
|
|
RecycleArray(&mDocRuleProcessors);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
StyleSetImpl::ClearOverrideRuleProcessors(void)
|
|
|
|
{
|
|
|
|
if (mOverrideRuleProcessors)
|
|
|
|
RecycleArray(&mOverrideRuleProcessors);
|
|
|
|
}
|
|
|
|
|
1999-10-08 07:09:31 +04:00
|
|
|
struct RuleProcessorData {
|
|
|
|
RuleProcessorData(nsISupportsArray* aRuleProcessors)
|
|
|
|
: mRuleProcessors(aRuleProcessors),
|
|
|
|
mPrevProcessor(nsnull)
|
|
|
|
{}
|
|
|
|
|
|
|
|
nsISupportsArray* mRuleProcessors;
|
|
|
|
nsIStyleRuleProcessor* mPrevProcessor;
|
|
|
|
};
|
|
|
|
|
|
|
|
static PRBool
|
|
|
|
EnumRuleProcessor(nsISupports* aSheet, void* aData)
|
|
|
|
{
|
|
|
|
nsIStyleSheet* sheet = (nsIStyleSheet*)aSheet;
|
|
|
|
RuleProcessorData* data = (RuleProcessorData*)aData;
|
|
|
|
|
|
|
|
nsIStyleRuleProcessor* processor = nsnull;
|
|
|
|
nsresult result = sheet->GetStyleRuleProcessor(processor, data->mPrevProcessor);
|
|
|
|
if (NS_SUCCEEDED(result) && processor) {
|
|
|
|
if (processor != data->mPrevProcessor) {
|
|
|
|
data->mRuleProcessors->AppendElement(processor);
|
|
|
|
data->mPrevProcessor = processor; // ref is held by array
|
1998-04-14 00:24:54 +04:00
|
|
|
}
|
1999-10-08 07:09:31 +04:00
|
|
|
NS_RELEASE(processor);
|
1998-04-14 00:24:54 +04:00
|
|
|
}
|
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
|
1999-10-08 07:09:31 +04:00
|
|
|
nsresult
|
|
|
|
StyleSetImpl::GatherRuleProcessors(void)
|
|
|
|
{
|
|
|
|
nsresult result = NS_ERROR_OUT_OF_MEMORY;
|
2000-08-12 10:28:02 +04:00
|
|
|
if (mBackstopSheets && !mBackstopRuleProcessors) {
|
|
|
|
if (EnsureArray(&mBackstopRuleProcessors)) {
|
|
|
|
RuleProcessorData data(mBackstopRuleProcessors);
|
1999-10-08 07:09:31 +04:00
|
|
|
mBackstopSheets->EnumerateBackwards(EnumRuleProcessor, &data);
|
2000-08-12 10:28:02 +04:00
|
|
|
PRUint32 count;
|
|
|
|
mBackstopRuleProcessors->Count(&count);
|
|
|
|
if (0 == count) {
|
|
|
|
RecycleArray(&mBackstopRuleProcessors);
|
|
|
|
}
|
|
|
|
} else return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mDocSheets && !mDocRuleProcessors) {
|
|
|
|
if (EnsureArray(&mDocRuleProcessors)) {
|
|
|
|
RuleProcessorData data(mDocRuleProcessors);
|
1999-10-08 07:09:31 +04:00
|
|
|
mDocSheets->EnumerateBackwards(EnumRuleProcessor, &data);
|
2000-08-12 10:28:02 +04:00
|
|
|
PRUint32 count;
|
|
|
|
mDocRuleProcessors->Count(&count);
|
|
|
|
if (0 == count) {
|
|
|
|
RecycleArray(&mDocRuleProcessors);
|
|
|
|
}
|
|
|
|
} else return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mOverrideSheets && !mOverrideRuleProcessors) {
|
|
|
|
if (EnsureArray(&mOverrideRuleProcessors)) {
|
|
|
|
RuleProcessorData data(mOverrideRuleProcessors);
|
1999-10-08 07:09:31 +04:00
|
|
|
mOverrideSheets->EnumerateBackwards(EnumRuleProcessor, &data);
|
2000-08-12 10:28:02 +04:00
|
|
|
PRUint32 count;
|
|
|
|
mOverrideRuleProcessors->Count(&count);
|
|
|
|
if (0 == count) {
|
|
|
|
RecycleArray(&mOverrideRuleProcessors);
|
|
|
|
}
|
|
|
|
} else return result;
|
1999-10-08 07:09:31 +04:00
|
|
|
}
|
2000-08-12 10:28:02 +04:00
|
|
|
|
|
|
|
return NS_OK;
|
1999-10-08 07:09:31 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
1998-04-14 00:24:54 +04:00
|
|
|
// ----- Override sheets
|
|
|
|
|
|
|
|
void StyleSetImpl::AppendOverrideStyleSheet(nsIStyleSheet* aSheet)
|
|
|
|
{
|
|
|
|
NS_PRECONDITION(nsnull != aSheet, "null arg");
|
|
|
|
if (EnsureArray(&mOverrideSheets)) {
|
1999-01-23 10:01:57 +03:00
|
|
|
mOverrideSheets->RemoveElement(aSheet);
|
1998-04-14 00:24:54 +04:00
|
|
|
mOverrideSheets->AppendElement(aSheet);
|
2000-08-12 10:28:02 +04:00
|
|
|
ClearOverrideRuleProcessors();
|
1998-04-14 00:24:54 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void StyleSetImpl::InsertOverrideStyleSheetAfter(nsIStyleSheet* aSheet,
|
|
|
|
nsIStyleSheet* aAfterSheet)
|
|
|
|
{
|
|
|
|
NS_PRECONDITION(nsnull != aSheet, "null arg");
|
|
|
|
if (EnsureArray(&mOverrideSheets)) {
|
1999-01-23 10:01:57 +03:00
|
|
|
mOverrideSheets->RemoveElement(aSheet);
|
1998-04-14 00:24:54 +04:00
|
|
|
PRInt32 index = mOverrideSheets->IndexOf(aAfterSheet);
|
|
|
|
mOverrideSheets->InsertElementAt(aSheet, ++index);
|
2000-08-12 10:28:02 +04:00
|
|
|
ClearOverrideRuleProcessors();
|
1998-04-14 00:24:54 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void StyleSetImpl::InsertOverrideStyleSheetBefore(nsIStyleSheet* aSheet,
|
|
|
|
nsIStyleSheet* aBeforeSheet)
|
|
|
|
{
|
|
|
|
NS_PRECONDITION(nsnull != aSheet, "null arg");
|
|
|
|
if (EnsureArray(&mOverrideSheets)) {
|
1999-01-23 10:01:57 +03:00
|
|
|
mOverrideSheets->RemoveElement(aSheet);
|
1998-04-14 00:24:54 +04:00
|
|
|
PRInt32 index = mOverrideSheets->IndexOf(aBeforeSheet);
|
|
|
|
mOverrideSheets->InsertElementAt(aSheet, ((-1 < index) ? index : 0));
|
2000-08-12 10:28:02 +04:00
|
|
|
ClearOverrideRuleProcessors();
|
1998-04-14 00:24:54 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void StyleSetImpl::RemoveOverrideStyleSheet(nsIStyleSheet* aSheet)
|
|
|
|
{
|
|
|
|
NS_PRECONDITION(nsnull != aSheet, "null arg");
|
|
|
|
|
|
|
|
if (nsnull != mOverrideSheets) {
|
|
|
|
mOverrideSheets->RemoveElement(aSheet);
|
2000-08-12 10:28:02 +04:00
|
|
|
ClearOverrideRuleProcessors();
|
1998-04-14 00:24:54 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
PRInt32 StyleSetImpl::GetNumberOfOverrideStyleSheets()
|
|
|
|
{
|
|
|
|
if (nsnull != mOverrideSheets) {
|
1999-05-13 08:56:04 +04:00
|
|
|
PRUint32 cnt;
|
|
|
|
nsresult rv = mOverrideSheets->Count(&cnt);
|
|
|
|
if (NS_FAILED(rv)) return 0; // XXX error?
|
|
|
|
return cnt;
|
1998-04-14 00:24:54 +04:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsIStyleSheet* StyleSetImpl::GetOverrideStyleSheetAt(PRInt32 aIndex)
|
|
|
|
{
|
|
|
|
nsIStyleSheet* sheet = nsnull;
|
1999-04-03 22:56:45 +04:00
|
|
|
if (nsnull != mOverrideSheets) {
|
1998-04-14 00:24:54 +04:00
|
|
|
sheet = (nsIStyleSheet*)mOverrideSheets->ElementAt(aIndex);
|
|
|
|
}
|
|
|
|
return sheet;
|
|
|
|
}
|
|
|
|
|
|
|
|
// -------- Doc Sheets
|
|
|
|
|
1999-01-23 10:01:57 +03:00
|
|
|
void StyleSetImpl::AddDocStyleSheet(nsIStyleSheet* aSheet, nsIDocument* aDocument)
|
1998-04-14 00:24:54 +04:00
|
|
|
{
|
1999-01-23 10:01:57 +03:00
|
|
|
NS_PRECONDITION((nsnull != aSheet) && (nsnull != aDocument), "null arg");
|
1998-04-14 00:24:54 +04:00
|
|
|
if (EnsureArray(&mDocSheets)) {
|
1999-01-23 10:01:57 +03:00
|
|
|
mDocSheets->RemoveElement(aSheet);
|
|
|
|
// lowest index last
|
2001-06-20 07:27:48 +04:00
|
|
|
PRInt32 newDocIndex = 0;
|
|
|
|
aDocument->GetIndexOfStyleSheet(aSheet, &newDocIndex);
|
1999-05-13 08:56:04 +04:00
|
|
|
PRUint32 count;
|
|
|
|
nsresult rv = mDocSheets->Count(&count);
|
|
|
|
if (NS_FAILED(rv)) return; // XXX error?
|
1999-02-23 11:10:24 +03:00
|
|
|
PRUint32 index;
|
1999-01-23 10:01:57 +03:00
|
|
|
for (index = 0; index < count; index++) {
|
|
|
|
nsIStyleSheet* sheet = (nsIStyleSheet*)mDocSheets->ElementAt(index);
|
2001-06-20 07:27:48 +04:00
|
|
|
PRInt32 sheetDocIndex = 0;
|
|
|
|
aDocument->GetIndexOfStyleSheet(sheet, &sheetDocIndex);
|
1999-01-23 10:01:57 +03:00
|
|
|
if (sheetDocIndex < newDocIndex) {
|
|
|
|
mDocSheets->InsertElementAt(aSheet, index);
|
|
|
|
index = count; // break loop
|
|
|
|
}
|
|
|
|
NS_RELEASE(sheet);
|
1998-09-10 23:32:14 +04:00
|
|
|
}
|
1999-05-13 08:56:04 +04:00
|
|
|
PRUint32 cnt;
|
|
|
|
rv = mDocSheets->Count(&cnt);
|
|
|
|
if (NS_FAILED(rv)) return; // XXX error?
|
|
|
|
if (cnt == count) { // didn't insert it
|
1999-01-23 10:01:57 +03:00
|
|
|
mDocSheets->AppendElement(aSheet);
|
1998-09-10 23:32:14 +04:00
|
|
|
}
|
1998-04-14 00:24:54 +04:00
|
|
|
|
1998-09-10 23:32:14 +04:00
|
|
|
if (nsnull == mFrameConstructor) {
|
|
|
|
aSheet->QueryInterface(kIStyleFrameConstructionIID, (void **)&mFrameConstructor);
|
|
|
|
}
|
2000-08-12 10:28:02 +04:00
|
|
|
ClearDocRuleProcessors();
|
1998-04-14 00:24:54 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void StyleSetImpl::RemoveDocStyleSheet(nsIStyleSheet* aSheet)
|
|
|
|
{
|
|
|
|
NS_PRECONDITION(nsnull != aSheet, "null arg");
|
|
|
|
|
|
|
|
if (nsnull != mDocSheets) {
|
|
|
|
mDocSheets->RemoveElement(aSheet);
|
2000-08-12 10:28:02 +04:00
|
|
|
ClearDocRuleProcessors();
|
1998-04-14 00:24:54 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
PRInt32 StyleSetImpl::GetNumberOfDocStyleSheets()
|
|
|
|
{
|
|
|
|
if (nsnull != mDocSheets) {
|
1999-05-13 08:56:04 +04:00
|
|
|
PRUint32 cnt;
|
|
|
|
nsresult rv = mDocSheets->Count(&cnt);
|
|
|
|
if (NS_FAILED(rv)) return 0; // XXX error?
|
|
|
|
return cnt;
|
1998-04-14 00:24:54 +04:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsIStyleSheet* StyleSetImpl::GetDocStyleSheetAt(PRInt32 aIndex)
|
|
|
|
{
|
|
|
|
nsIStyleSheet* sheet = nsnull;
|
1999-01-23 10:01:57 +03:00
|
|
|
if (nsnull != mDocSheets) {
|
1998-04-14 00:24:54 +04:00
|
|
|
sheet = (nsIStyleSheet*)mDocSheets->ElementAt(aIndex);
|
|
|
|
}
|
|
|
|
return sheet;
|
|
|
|
}
|
|
|
|
|
|
|
|
// ------ backstop sheets
|
|
|
|
|
|
|
|
void StyleSetImpl::AppendBackstopStyleSheet(nsIStyleSheet* aSheet)
|
|
|
|
{
|
|
|
|
NS_PRECONDITION(nsnull != aSheet, "null arg");
|
|
|
|
if (EnsureArray(&mBackstopSheets)) {
|
1999-01-23 10:01:57 +03:00
|
|
|
mBackstopSheets->RemoveElement(aSheet);
|
1998-04-14 00:24:54 +04:00
|
|
|
mBackstopSheets->AppendElement(aSheet);
|
2000-08-12 10:28:02 +04:00
|
|
|
ClearBackstopRuleProcessors();
|
1998-04-14 00:24:54 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void StyleSetImpl::InsertBackstopStyleSheetAfter(nsIStyleSheet* aSheet,
|
|
|
|
nsIStyleSheet* aAfterSheet)
|
|
|
|
{
|
|
|
|
NS_PRECONDITION(nsnull != aSheet, "null arg");
|
|
|
|
if (EnsureArray(&mBackstopSheets)) {
|
1999-01-23 10:01:57 +03:00
|
|
|
mBackstopSheets->RemoveElement(aSheet);
|
1998-04-14 00:24:54 +04:00
|
|
|
PRInt32 index = mBackstopSheets->IndexOf(aAfterSheet);
|
|
|
|
mBackstopSheets->InsertElementAt(aSheet, ++index);
|
2000-08-12 10:28:02 +04:00
|
|
|
ClearBackstopRuleProcessors();
|
1998-04-14 00:24:54 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void StyleSetImpl::InsertBackstopStyleSheetBefore(nsIStyleSheet* aSheet,
|
|
|
|
nsIStyleSheet* aBeforeSheet)
|
|
|
|
{
|
|
|
|
NS_PRECONDITION(nsnull != aSheet, "null arg");
|
|
|
|
if (EnsureArray(&mBackstopSheets)) {
|
1999-01-23 10:01:57 +03:00
|
|
|
mBackstopSheets->RemoveElement(aSheet);
|
1998-04-14 00:24:54 +04:00
|
|
|
PRInt32 index = mBackstopSheets->IndexOf(aBeforeSheet);
|
|
|
|
mBackstopSheets->InsertElementAt(aSheet, ((-1 < index) ? index : 0));
|
2000-08-12 10:28:02 +04:00
|
|
|
ClearBackstopRuleProcessors();
|
1998-04-14 00:24:54 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void StyleSetImpl::RemoveBackstopStyleSheet(nsIStyleSheet* aSheet)
|
|
|
|
{
|
|
|
|
NS_PRECONDITION(nsnull != aSheet, "null arg");
|
|
|
|
|
|
|
|
if (nsnull != mBackstopSheets) {
|
|
|
|
mBackstopSheets->RemoveElement(aSheet);
|
2000-08-12 10:28:02 +04:00
|
|
|
ClearBackstopRuleProcessors();
|
1998-04-14 00:24:54 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
PRInt32 StyleSetImpl::GetNumberOfBackstopStyleSheets()
|
|
|
|
{
|
|
|
|
if (nsnull != mBackstopSheets) {
|
1999-05-13 08:56:04 +04:00
|
|
|
PRUint32 cnt;
|
|
|
|
nsresult rv = mBackstopSheets->Count(&cnt);
|
|
|
|
if (NS_FAILED(rv)) return 0; // XXX error?
|
|
|
|
return cnt;
|
1998-04-14 00:24:54 +04:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2000-06-03 01:45:06 +04:00
|
|
|
NS_IMETHODIMP StyleSetImpl::EnableQuirkStyleSheet(PRBool aEnable)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
if (nsnull == mQuirkStyleSheet) {
|
|
|
|
// first find the quirk sheet:
|
|
|
|
// - run through all of the backstop sheets and check for a CSSStyleSheet that
|
|
|
|
// has the URL we want
|
|
|
|
PRUint32 i, nSheets = GetNumberOfBackstopStyleSheets();
|
|
|
|
for (i=0; i< nSheets; i++) {
|
|
|
|
nsCOMPtr<nsIStyleSheet> sheet;
|
|
|
|
sheet = getter_AddRefs(GetBackstopStyleSheetAt(i));
|
|
|
|
if (sheet) {
|
|
|
|
nsCOMPtr<nsICSSStyleSheet> cssSheet;
|
2001-01-04 23:44:42 +03:00
|
|
|
sheet->QueryInterface(NS_GET_IID(nsICSSStyleSheet), getter_AddRefs(cssSheet));
|
2000-06-03 01:45:06 +04:00
|
|
|
if (cssSheet) {
|
|
|
|
nsCOMPtr<nsIStyleSheet> quirkSheet;
|
|
|
|
PRBool bHasSheet = PR_FALSE;
|
2000-11-08 06:13:53 +03:00
|
|
|
NS_ASSERTION(gQuirkURI != nsnull, "StyleSetImpl::gQuirkStyleSet is not initialized!");
|
|
|
|
if (gQuirkURI != nsnull
|
|
|
|
&& NS_SUCCEEDED(cssSheet->ContainsStyleSheet(gQuirkURI, bHasSheet,
|
|
|
|
getter_AddRefs(quirkSheet)))
|
|
|
|
&& bHasSheet) {
|
2000-06-03 01:45:06 +04:00
|
|
|
NS_ASSERTION(quirkSheet, "QuirkSheet must be set: ContainsStyleSheet is hosed");
|
|
|
|
// cache the sheet for faster lookup next time
|
|
|
|
mQuirkStyleSheet = quirkSheet.get();
|
|
|
|
// addref for our cached reference
|
|
|
|
NS_ADDREF(mQuirkStyleSheet);
|
2001-06-07 03:34:17 +04:00
|
|
|
// only one quirk style sheet can exist, so stop looking
|
|
|
|
break;
|
2000-06-03 01:45:06 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (mQuirkStyleSheet) {
|
2001-09-25 02:36:43 +04:00
|
|
|
#if defined(DEBUG_warren) || defined(DEBUG_attinasi)
|
2000-10-29 02:17:53 +04:00
|
|
|
printf( "%s Quirk StyleSheet\n", aEnable ? "Enabling" : "Disabling" );
|
|
|
|
#endif
|
2000-06-03 01:45:06 +04:00
|
|
|
mQuirkStyleSheet->SetEnabled(aEnable);
|
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2000-06-22 00:44:59 +04:00
|
|
|
NS_IMETHODIMP
|
|
|
|
StyleSetImpl::NotifyStyleSheetStateChanged(PRBool aDisabled)
|
|
|
|
{
|
|
|
|
ClearRuleProcessors();
|
|
|
|
GatherRuleProcessors();
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1998-04-14 00:24:54 +04:00
|
|
|
nsIStyleSheet* StyleSetImpl::GetBackstopStyleSheetAt(PRInt32 aIndex)
|
|
|
|
{
|
|
|
|
nsIStyleSheet* sheet = nsnull;
|
1999-04-03 22:56:45 +04:00
|
|
|
if (nsnull != mBackstopSheets) {
|
1998-04-14 00:24:54 +04:00
|
|
|
sheet = (nsIStyleSheet*)mBackstopSheets->ElementAt(aIndex);
|
|
|
|
}
|
|
|
|
return sheet;
|
|
|
|
}
|
|
|
|
|
2000-05-28 00:03:14 +04:00
|
|
|
void
|
|
|
|
StyleSetImpl::ReplaceBackstopStyleSheets(nsISupportsArray* aNewBackstopSheets)
|
|
|
|
{
|
2000-08-12 10:28:02 +04:00
|
|
|
ClearBackstopRuleProcessors();
|
2000-05-28 00:03:14 +04:00
|
|
|
NS_IF_RELEASE(mBackstopSheets);
|
|
|
|
mBackstopSheets = aNewBackstopSheets;
|
|
|
|
NS_IF_ADDREF(mBackstopSheets);
|
|
|
|
}
|
2000-06-22 00:44:59 +04:00
|
|
|
|
1999-06-15 10:15:51 +04:00
|
|
|
struct RulesMatchingData {
|
|
|
|
RulesMatchingData(nsIPresContext* aPresContext,
|
|
|
|
nsIAtom* aMedium,
|
|
|
|
nsIContent* aContent,
|
|
|
|
nsIStyleContext* aParentContext,
|
2001-10-24 04:01:09 +04:00
|
|
|
nsRuleWalker* aRuleWalker)
|
1999-06-15 10:15:51 +04:00
|
|
|
: mPresContext(aPresContext),
|
|
|
|
mMedium(aMedium),
|
|
|
|
mContent(aContent),
|
|
|
|
mParentContext(aParentContext),
|
2001-06-01 02:19:43 +04:00
|
|
|
mRuleWalker(aRuleWalker)
|
1999-06-15 10:15:51 +04:00
|
|
|
{
|
|
|
|
}
|
|
|
|
nsIPresContext* mPresContext;
|
|
|
|
nsIAtom* mMedium;
|
|
|
|
nsIContent* mContent;
|
|
|
|
nsIStyleContext* mParentContext;
|
2001-10-24 04:01:09 +04:00
|
|
|
nsRuleWalker* mRuleWalker;
|
1999-06-15 10:15:51 +04:00
|
|
|
};
|
|
|
|
|
|
|
|
static PRBool
|
1999-10-08 07:09:31 +04:00
|
|
|
EnumRulesMatching(nsISupports* aProcessor, void* aData)
|
1998-04-14 00:24:54 +04:00
|
|
|
{
|
1999-10-08 07:09:31 +04:00
|
|
|
nsIStyleRuleProcessor* processor = (nsIStyleRuleProcessor*)aProcessor;
|
1999-06-15 10:15:51 +04:00
|
|
|
RulesMatchingData* data = (RulesMatchingData*)aData;
|
1998-04-14 00:24:54 +04:00
|
|
|
|
1999-10-08 07:09:31 +04:00
|
|
|
processor->RulesMatching(data->mPresContext, data->mMedium, data->mContent,
|
2001-06-01 02:19:43 +04:00
|
|
|
data->mParentContext, data->mRuleWalker);
|
1999-06-15 10:15:51 +04:00
|
|
|
return PR_TRUE;
|
1998-04-14 00:24:54 +04:00
|
|
|
}
|
|
|
|
|
1998-11-03 23:19:28 +03:00
|
|
|
nsIStyleContext* StyleSetImpl::GetContext(nsIPresContext* aPresContext,
|
2001-06-01 02:19:43 +04:00
|
|
|
nsIStyleContext* aParentContext,
|
|
|
|
nsIAtom* aPseudoTag,
|
|
|
|
PRBool aForceUnique)
|
1998-05-19 01:05:52 +04:00
|
|
|
{
|
1998-11-03 23:19:28 +03:00
|
|
|
nsIStyleContext* result = nsnull;
|
2001-06-01 02:19:43 +04:00
|
|
|
|
2001-10-24 04:01:09 +04:00
|
|
|
nsRuleNode* ruleNode = mRuleWalker->GetCurrentNode();
|
2001-06-01 02:19:43 +04:00
|
|
|
|
1999-09-21 11:50:16 +04:00
|
|
|
if ((PR_FALSE == aForceUnique) && (nsnull != aParentContext)) {
|
2001-06-01 02:19:43 +04:00
|
|
|
aParentContext->FindChildWithRules(aPseudoTag, ruleNode, result);
|
1998-05-19 01:05:52 +04:00
|
|
|
}
|
2000-03-31 11:08:36 +04:00
|
|
|
|
1998-11-03 23:19:28 +03:00
|
|
|
if (nsnull == result) {
|
2001-06-01 02:19:43 +04:00
|
|
|
if (NS_SUCCEEDED(NS_NewStyleContext(&result, aParentContext, aPseudoTag, ruleNode, aPresContext))) {
|
|
|
|
if (PR_TRUE == aForceUnique)
|
1999-09-21 11:50:16 +04:00
|
|
|
result->ForceUnique();
|
1998-05-27 03:14:56 +04:00
|
|
|
}
|
2000-06-22 00:44:59 +04:00
|
|
|
#ifdef NOISY_DEBUG
|
2000-10-29 02:17:53 +04:00
|
|
|
fprintf(stdout, "+++ NewSC %d +++\n", ++gNewCount);
|
2000-03-31 11:08:36 +04:00
|
|
|
#endif
|
1999-09-21 11:50:16 +04:00
|
|
|
}
|
2000-06-22 00:44:59 +04:00
|
|
|
#ifdef NOISY_DEBUG
|
1999-09-21 11:50:16 +04:00
|
|
|
else {
|
2000-10-29 02:17:53 +04:00
|
|
|
fprintf(stdout, "--- SharedSC %d ---\n", ++gSharedCount);
|
1998-05-19 01:05:52 +04:00
|
|
|
}
|
2000-03-31 11:08:36 +04:00
|
|
|
#endif
|
|
|
|
|
1998-05-19 01:05:52 +04:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2001-06-01 02:19:43 +04:00
|
|
|
void
|
2001-10-24 04:01:09 +04:00
|
|
|
StyleSetImpl::AddImportantRules(nsRuleNode* aCurrNode)
|
2001-06-01 02:19:43 +04:00
|
|
|
{
|
|
|
|
// XXX Note: this is still incorrect from a cascade standpoint, but
|
|
|
|
// it preserves the existing incorrect cascade behavior.
|
2001-10-24 04:01:09 +04:00
|
|
|
nsRuleNode* parent = aCurrNode->GetParent();
|
2001-06-01 02:19:43 +04:00
|
|
|
if (parent)
|
|
|
|
AddImportantRules(parent);
|
|
|
|
|
|
|
|
nsCOMPtr<nsIStyleRule> rule;;
|
|
|
|
aCurrNode->GetRule(getter_AddRefs(rule));
|
|
|
|
nsCOMPtr<nsICSSStyleRule> cssRule(do_QueryInterface(rule));
|
|
|
|
if (cssRule) {
|
|
|
|
nsCOMPtr<nsIStyleRule> impRule = getter_AddRefs(cssRule->GetImportantRule());
|
|
|
|
if (impRule)
|
|
|
|
mRuleWalker->Forward(impRule);
|
1998-09-11 06:05:30 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1998-11-03 23:19:28 +03:00
|
|
|
#ifdef NS_DEBUG
|
|
|
|
#define NS_ASSERT_REFCOUNT(ptr,cnt,msg) { \
|
|
|
|
nsrefcnt count = ptr->AddRef(); \
|
|
|
|
ptr->Release(); \
|
|
|
|
NS_ASSERTION(--count == cnt, msg); \
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
#define NS_ASSERT_REFCOUNT(ptr,cnt,msg) {}
|
|
|
|
#endif
|
|
|
|
|
2001-06-01 02:19:43 +04:00
|
|
|
void StyleSetImpl::EnsureRuleWalker(nsIPresContext* aPresContext)
|
|
|
|
{
|
|
|
|
if (mRuleWalker)
|
|
|
|
return;
|
|
|
|
|
2001-10-24 04:01:09 +04:00
|
|
|
nsRuleNode::CreateRootNode(aPresContext, &mRuleTree);
|
|
|
|
mRuleWalker = new nsRuleWalker(mRuleTree);
|
2001-06-01 02:19:43 +04:00
|
|
|
}
|
|
|
|
|
1998-04-14 00:24:54 +04:00
|
|
|
nsIStyleContext* StyleSetImpl::ResolveStyleFor(nsIPresContext* aPresContext,
|
|
|
|
nsIContent* aContent,
|
1998-11-03 23:19:28 +03:00
|
|
|
nsIStyleContext* aParentContext,
|
1998-06-05 10:00:55 +04:00
|
|
|
PRBool aForceUnique)
|
1998-04-14 00:24:54 +04:00
|
|
|
{
|
1999-11-10 06:41:09 +03:00
|
|
|
MOZ_TIMER_DEBUGLOG(("Start: StyleSetImpl::ResolveStyleFor(), this=%p\n", this));
|
2000-02-11 04:21:36 +03:00
|
|
|
STYLESET_START_TIMER(NS_TIMER_STYLE_RESOLUTION);
|
|
|
|
|
1998-04-14 00:24:54 +04:00
|
|
|
nsIStyleContext* result = nsnull;
|
|
|
|
|
1999-06-22 23:16:40 +04:00
|
|
|
NS_ASSERTION(aContent, "must have content");
|
|
|
|
NS_ASSERTION(aPresContext, "must have pres context");
|
1998-04-14 00:24:54 +04:00
|
|
|
|
1999-06-22 23:16:40 +04:00
|
|
|
if (aContent && aPresContext) {
|
2000-08-12 10:28:02 +04:00
|
|
|
GatherRuleProcessors();
|
|
|
|
if (mBackstopRuleProcessors || mDocRuleProcessors || mOverrideRuleProcessors) {
|
2001-06-01 02:19:43 +04:00
|
|
|
EnsureRuleWalker(aPresContext);
|
|
|
|
nsCOMPtr<nsIAtom> medium;
|
|
|
|
aPresContext->GetMedium(getter_AddRefs(medium));
|
|
|
|
RulesMatchingData data(aPresContext, medium, aContent, aParentContext, mRuleWalker);
|
|
|
|
WalkRuleProcessors(EnumRulesMatching, &data, aContent);
|
|
|
|
|
|
|
|
// Walk all of the rules and add in the !important counterparts.
|
2001-10-24 04:01:09 +04:00
|
|
|
nsRuleNode* ruleNode = mRuleWalker->GetCurrentNode();
|
2001-06-01 02:19:43 +04:00
|
|
|
AddImportantRules(ruleNode);
|
|
|
|
result = GetContext(aPresContext, aParentContext, nsnull, aForceUnique);
|
|
|
|
|
|
|
|
// Now reset the walker back to the root of the tree.
|
|
|
|
mRuleWalker->Reset();
|
1998-07-17 09:43:31 +04:00
|
|
|
}
|
1998-05-19 01:05:52 +04:00
|
|
|
}
|
|
|
|
|
1999-11-10 06:41:09 +03:00
|
|
|
MOZ_TIMER_DEBUGLOG(("Stop: StyleSetImpl::ResolveStyleFor(), this=%p\n", this));
|
2000-02-11 04:21:36 +03:00
|
|
|
STYLESET_STOP_TIMER(NS_TIMER_STYLE_RESOLUTION);
|
1998-05-19 01:05:52 +04:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
1999-06-15 10:15:51 +04:00
|
|
|
struct PseudoRulesMatchingData {
|
|
|
|
PseudoRulesMatchingData(nsIPresContext* aPresContext,
|
|
|
|
nsIAtom* aMedium,
|
|
|
|
nsIContent* aParentContent,
|
|
|
|
nsIAtom* aPseudoTag,
|
|
|
|
nsIStyleContext* aParentContext,
|
2001-02-16 00:24:47 +03:00
|
|
|
nsICSSPseudoComparator* aComparator,
|
2001-10-24 04:01:09 +04:00
|
|
|
nsRuleWalker* aWalker)
|
1999-06-15 10:15:51 +04:00
|
|
|
: mPresContext(aPresContext),
|
|
|
|
mMedium(aMedium),
|
|
|
|
mParentContent(aParentContent),
|
|
|
|
mPseudoTag(aPseudoTag),
|
|
|
|
mParentContext(aParentContext),
|
2001-02-16 00:24:47 +03:00
|
|
|
mComparator(aComparator),
|
2001-06-01 02:19:43 +04:00
|
|
|
mRuleWalker(aWalker)
|
1999-06-15 10:15:51 +04:00
|
|
|
{
|
|
|
|
}
|
2001-02-16 00:24:47 +03:00
|
|
|
nsIPresContext* mPresContext;
|
|
|
|
nsIAtom* mMedium;
|
|
|
|
nsIContent* mParentContent;
|
|
|
|
nsIAtom* mPseudoTag;
|
|
|
|
nsIStyleContext* mParentContext;
|
|
|
|
nsICSSPseudoComparator* mComparator;
|
2001-10-24 04:01:09 +04:00
|
|
|
nsRuleWalker* mRuleWalker;
|
1999-06-15 10:15:51 +04:00
|
|
|
};
|
1998-05-19 01:05:52 +04:00
|
|
|
|
1999-06-15 10:15:51 +04:00
|
|
|
static PRBool
|
1999-10-08 07:09:31 +04:00
|
|
|
EnumPseudoRulesMatching(nsISupports* aProcessor, void* aData)
|
1998-05-19 01:05:52 +04:00
|
|
|
{
|
1999-10-08 07:09:31 +04:00
|
|
|
nsIStyleRuleProcessor* processor = (nsIStyleRuleProcessor*)aProcessor;
|
1999-06-15 10:15:51 +04:00
|
|
|
PseudoRulesMatchingData* data = (PseudoRulesMatchingData*)aData;
|
1998-05-19 01:05:52 +04:00
|
|
|
|
1999-10-08 07:09:31 +04:00
|
|
|
processor->RulesMatching(data->mPresContext, data->mMedium,
|
|
|
|
data->mParentContent, data->mPseudoTag,
|
2001-06-01 02:19:43 +04:00
|
|
|
data->mParentContext, data->mComparator, data->mRuleWalker);
|
1999-06-15 10:15:51 +04:00
|
|
|
return PR_TRUE;
|
1998-05-19 01:05:52 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
nsIStyleContext* StyleSetImpl::ResolvePseudoStyleFor(nsIPresContext* aPresContext,
|
1998-11-03 23:19:28 +03:00
|
|
|
nsIContent* aParentContent,
|
1998-05-19 01:05:52 +04:00
|
|
|
nsIAtom* aPseudoTag,
|
1998-11-03 23:19:28 +03:00
|
|
|
nsIStyleContext* aParentContext,
|
2001-02-16 00:24:47 +03:00
|
|
|
PRBool aForceUnique,
|
|
|
|
nsICSSPseudoComparator* aComparator)
|
1998-05-19 01:05:52 +04:00
|
|
|
{
|
1999-11-10 06:41:09 +03:00
|
|
|
MOZ_TIMER_DEBUGLOG(("Start: StyleSetImpl::ResolvePseudoStyleFor(), this=%p\n", this));
|
2000-02-11 04:21:36 +03:00
|
|
|
STYLESET_START_TIMER(NS_TIMER_STYLE_RESOLUTION);
|
|
|
|
|
1998-05-19 01:05:52 +04:00
|
|
|
nsIStyleContext* result = nsnull;
|
|
|
|
|
1999-06-22 23:16:40 +04:00
|
|
|
NS_ASSERTION(aPseudoTag, "must have pseudo tag");
|
|
|
|
NS_ASSERTION(aPresContext, "must have pres context");
|
1998-05-19 01:05:52 +04:00
|
|
|
|
1999-06-22 23:16:40 +04:00
|
|
|
if (aPseudoTag && aPresContext) {
|
2000-08-12 10:28:02 +04:00
|
|
|
GatherRuleProcessors();
|
|
|
|
if (mBackstopRuleProcessors || mDocRuleProcessors || mOverrideRuleProcessors) {
|
2001-06-01 02:19:43 +04:00
|
|
|
nsCOMPtr<nsIAtom> medium;
|
|
|
|
aPresContext->GetMedium(getter_AddRefs(medium));
|
|
|
|
EnsureRuleWalker(aPresContext);
|
|
|
|
PseudoRulesMatchingData data(aPresContext, medium, aParentContent,
|
|
|
|
aPseudoTag, aParentContext, aComparator, mRuleWalker);
|
|
|
|
WalkRuleProcessors(EnumPseudoRulesMatching, &data, aParentContent);
|
|
|
|
|
|
|
|
// Walk all of the rules and add in the !important counterparts.
|
2001-10-24 04:01:09 +04:00
|
|
|
nsRuleNode* ruleNode = mRuleWalker->GetCurrentNode();
|
2001-06-01 02:19:43 +04:00
|
|
|
AddImportantRules(ruleNode);
|
|
|
|
result = GetContext(aPresContext, aParentContext, aPseudoTag, aForceUnique);
|
|
|
|
|
|
|
|
// Now reset the walker back to the root of the tree.
|
|
|
|
mRuleWalker->Reset();
|
1998-10-13 23:09:39 +04:00
|
|
|
}
|
1998-05-19 01:05:52 +04:00
|
|
|
}
|
|
|
|
|
1999-11-10 06:41:09 +03:00
|
|
|
MOZ_TIMER_DEBUGLOG(("Stop: StyleSetImpl::ResolvePseudoStyleFor(), this=%p\n", this));
|
2000-02-11 04:21:36 +03:00
|
|
|
STYLESET_STOP_TIMER(NS_TIMER_STYLE_RESOLUTION);
|
1998-05-19 01:05:52 +04:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsIStyleContext* StyleSetImpl::ProbePseudoStyleFor(nsIPresContext* aPresContext,
|
1998-11-03 23:19:28 +03:00
|
|
|
nsIContent* aParentContent,
|
1998-05-19 01:05:52 +04:00
|
|
|
nsIAtom* aPseudoTag,
|
1998-11-03 23:19:28 +03:00
|
|
|
nsIStyleContext* aParentContext,
|
1998-06-05 10:00:55 +04:00
|
|
|
PRBool aForceUnique)
|
1998-05-19 01:05:52 +04:00
|
|
|
{
|
1999-11-10 06:41:09 +03:00
|
|
|
MOZ_TIMER_DEBUGLOG(("Start: StyleSetImpl::ProbePseudoStyleFor(), this=%p\n", this));
|
2000-02-11 04:21:36 +03:00
|
|
|
STYLESET_START_TIMER(NS_TIMER_STYLE_RESOLUTION);
|
|
|
|
|
1998-05-19 01:05:52 +04:00
|
|
|
nsIStyleContext* result = nsnull;
|
|
|
|
|
1999-06-22 23:16:40 +04:00
|
|
|
NS_ASSERTION(aPseudoTag, "must have pseudo tag");
|
|
|
|
NS_ASSERTION(aPresContext, "must have pres context");
|
1998-05-19 01:05:52 +04:00
|
|
|
|
1999-06-22 23:16:40 +04:00
|
|
|
if (aPseudoTag && aPresContext) {
|
2000-08-12 10:28:02 +04:00
|
|
|
GatherRuleProcessors();
|
|
|
|
if (mBackstopRuleProcessors || mDocRuleProcessors || mOverrideRuleProcessors) {
|
2001-06-01 02:19:43 +04:00
|
|
|
nsCOMPtr<nsIAtom> medium;
|
|
|
|
aPresContext->GetMedium(getter_AddRefs(medium));
|
|
|
|
EnsureRuleWalker(aPresContext);
|
|
|
|
PseudoRulesMatchingData data(aPresContext, medium, aParentContent,
|
|
|
|
aPseudoTag, aParentContext, nsnull, mRuleWalker);
|
|
|
|
WalkRuleProcessors(EnumPseudoRulesMatching, &data, aParentContent);
|
|
|
|
|
|
|
|
// Walk all of the rules and add in the !important counterparts.
|
2001-10-24 04:01:09 +04:00
|
|
|
nsRuleNode* ruleNode = mRuleWalker->GetCurrentNode();
|
2001-06-01 02:19:43 +04:00
|
|
|
AddImportantRules(ruleNode);
|
2001-10-24 04:01:09 +04:00
|
|
|
if (!mRuleWalker->AtRoot())
|
2001-06-01 02:19:43 +04:00
|
|
|
result = GetContext(aPresContext, aParentContext, aPseudoTag, aForceUnique);
|
|
|
|
|
|
|
|
// Now reset the walker back to the root of the tree.
|
|
|
|
mRuleWalker->Reset();
|
1998-10-13 23:09:39 +04:00
|
|
|
}
|
1998-04-14 00:24:54 +04:00
|
|
|
}
|
1999-10-12 03:42:56 +04:00
|
|
|
|
1999-11-10 06:41:09 +03:00
|
|
|
MOZ_TIMER_DEBUGLOG(("Stop: StyleSetImpl::ProbePseudoStyleFor(), this=%p\n", this));
|
2000-02-11 04:21:36 +03:00
|
|
|
STYLESET_STOP_TIMER(NS_TIMER_STYLE_RESOLUTION);
|
1998-04-14 00:24:54 +04:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2001-06-01 02:19:43 +04:00
|
|
|
NS_IMETHODIMP
|
|
|
|
StyleSetImpl::Shutdown()
|
|
|
|
{
|
2001-10-24 04:01:09 +04:00
|
|
|
delete mRuleWalker;
|
2001-10-25 04:19:21 +04:00
|
|
|
if (mRuleTree)
|
|
|
|
{
|
|
|
|
mRuleTree->Destroy();
|
|
|
|
mRuleTree = nsnull;
|
|
|
|
}
|
2001-06-01 02:19:43 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
2001-10-24 04:01:09 +04:00
|
|
|
StyleSetImpl::GetRuleTree(nsRuleNode** aResult)
|
2001-06-01 02:19:43 +04:00
|
|
|
{
|
|
|
|
*aResult = mRuleTree;
|
2001-10-24 04:01:09 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
StyleSetImpl::ClearCachedDataInRuleTree(nsIStyleRule* aInlineStyleRule)
|
|
|
|
{
|
|
|
|
if (mRuleTree)
|
|
|
|
mRuleTree->ClearCachedDataInSubtree(aInlineStyleRule);
|
2001-06-01 02:19:43 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
1999-09-04 03:35:41 +04:00
|
|
|
|
2001-07-25 10:33:06 +04:00
|
|
|
nsresult
|
|
|
|
StyleSetImpl::ClearStyleData(nsIPresContext* aPresContext, nsIStyleRule* aRule, nsIStyleContext* aContext)
|
|
|
|
{
|
|
|
|
// XXXdwh. If we're willing to *really* optimize this
|
|
|
|
// invalidation, we could only invalidate the struct data
|
|
|
|
// that actually changed. For example, if someone changes
|
|
|
|
// style.left, we really only need to blow away cached
|
|
|
|
// data in the position struct.
|
|
|
|
if (aContext) {
|
2001-10-24 04:01:09 +04:00
|
|
|
nsRuleNode* ruleNode;
|
|
|
|
aContext->GetRuleNode(&ruleNode);
|
2001-07-25 10:33:06 +04:00
|
|
|
ruleNode->ClearCachedData(aRule);
|
|
|
|
|
|
|
|
// We don't need to mess with the style tree in this case, since the act of
|
|
|
|
// changing inline style attributes automatically causes re-resolution to a new style context
|
|
|
|
// (with new descendant style contexts as well).
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// XXXdwh This is not terribly fast, but fortunately this case is rare (and often a full tree
|
|
|
|
// invalidation anyway). Improving performance here would involve a footprint
|
|
|
|
// increase. Mappings from rule nodes to their associated style contexts as well as
|
|
|
|
// mappings from rules to their associated rule nodes would enable us to avoid the two
|
|
|
|
// tree walks that occur here.
|
|
|
|
|
|
|
|
// Crawl the entire rule tree and blow away all data for rule nodes (and their descendants)
|
|
|
|
// that have the given rule.
|
|
|
|
if (mRuleTree)
|
|
|
|
mRuleTree->ClearCachedDataInSubtree(aRule);
|
|
|
|
|
|
|
|
// We need to crawl the entire style context tree, and for each style context we need
|
|
|
|
// to see if the specified rule is matched. If so, that context and all its descendant
|
|
|
|
// contexts must have their data wiped.
|
|
|
|
nsCOMPtr<nsIPresShell> shell;
|
|
|
|
aPresContext->GetShell(getter_AddRefs(shell));
|
|
|
|
nsIFrame* rootFrame;
|
|
|
|
shell->GetRootFrame(&rootFrame);
|
|
|
|
if (rootFrame) {
|
|
|
|
nsCOMPtr<nsIStyleContext> rootContext;
|
|
|
|
rootFrame->GetStyleContext(getter_AddRefs(rootContext));
|
|
|
|
if (rootContext)
|
|
|
|
rootContext->ClearStyleData(aPresContext, aRule);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2001-08-02 18:34:55 +04:00
|
|
|
nsresult
|
|
|
|
StyleSetImpl::RemoveBodyFixupRule(nsIDocument *aDocument)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
nsCOMPtr<nsIHTMLDocument> htmlDoc = do_QueryInterface(aDocument);
|
|
|
|
if (htmlDoc) {
|
|
|
|
nsCOMPtr<nsIDOMHTMLBodyElement> node;
|
|
|
|
htmlDoc->GetBodyElement(getter_AddRefs(node));
|
|
|
|
if (node) {
|
|
|
|
nsCOMPtr<nsIBodySuper> bodyElement = do_QueryInterface(node);
|
|
|
|
bodyElement->RemoveBodyFixupRule();
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-09-04 03:35:41 +04:00
|
|
|
NS_IMETHODIMP
|
|
|
|
StyleSetImpl::ReParentStyleContext(nsIPresContext* aPresContext,
|
|
|
|
nsIStyleContext* aStyleContext,
|
|
|
|
nsIStyleContext* aNewParentContext,
|
|
|
|
nsIStyleContext** aNewStyleContext)
|
|
|
|
{
|
|
|
|
NS_ASSERTION(aPresContext, "must have pres context");
|
2000-03-31 11:08:36 +04:00
|
|
|
NS_ASSERTION(aStyleContext, "must have style context");
|
|
|
|
NS_ASSERTION(aNewStyleContext, "must have new style context");
|
1999-09-04 03:35:41 +04:00
|
|
|
|
|
|
|
nsresult result = NS_ERROR_NULL_POINTER;
|
|
|
|
|
|
|
|
if (aPresContext && aStyleContext && aNewStyleContext) {
|
|
|
|
nsIStyleContext* oldParent = aStyleContext->GetParent();
|
|
|
|
|
|
|
|
if (oldParent == aNewParentContext) {
|
|
|
|
result = NS_OK;
|
|
|
|
NS_ADDREF(aStyleContext); // for return
|
|
|
|
*aNewStyleContext = aStyleContext;
|
|
|
|
}
|
|
|
|
else { // really a new parent
|
|
|
|
nsIStyleContext* newChild = nsnull;
|
|
|
|
nsIAtom* pseudoTag = nsnull;
|
|
|
|
aStyleContext->GetPseudoType(pseudoTag);
|
2001-06-01 02:19:43 +04:00
|
|
|
|
2001-10-24 04:01:09 +04:00
|
|
|
nsRuleNode* ruleNode;
|
|
|
|
aStyleContext->GetRuleNode(&ruleNode);
|
1999-09-04 03:35:41 +04:00
|
|
|
if (aNewParentContext) {
|
2001-06-01 02:19:43 +04:00
|
|
|
result = aNewParentContext->FindChildWithRules(pseudoTag, ruleNode, newChild);
|
1999-09-04 03:35:41 +04:00
|
|
|
}
|
|
|
|
if (newChild) { // new parent already has one
|
|
|
|
*aNewStyleContext = newChild;
|
|
|
|
}
|
|
|
|
else { // need to make one in the new parent
|
|
|
|
result = NS_NewStyleContext(aNewStyleContext, aNewParentContext, pseudoTag,
|
2001-06-01 02:19:43 +04:00
|
|
|
ruleNode, aPresContext);
|
1999-09-04 03:35:41 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IF_RELEASE(pseudoTag);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IF_RELEASE(oldParent);
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
1999-04-20 04:02:22 +04:00
|
|
|
struct StatefulData {
|
1999-10-08 07:09:31 +04:00
|
|
|
StatefulData(nsIPresContext* aPresContext, nsIAtom* aMedium, nsIContent* aContent)
|
1999-04-20 04:02:22 +04:00
|
|
|
: mPresContext(aPresContext),
|
1999-10-08 07:09:31 +04:00
|
|
|
mMedium(aMedium),
|
1999-04-20 04:02:22 +04:00
|
|
|
mContent(aContent),
|
|
|
|
mStateful(PR_FALSE)
|
|
|
|
{}
|
|
|
|
nsIPresContext* mPresContext;
|
1999-10-08 07:09:31 +04:00
|
|
|
nsIAtom* mMedium;
|
1999-04-20 04:02:22 +04:00
|
|
|
nsIContent* mContent;
|
|
|
|
PRBool mStateful;
|
|
|
|
};
|
|
|
|
|
1999-10-08 07:09:31 +04:00
|
|
|
static PRBool SheetHasStatefulStyle(nsISupports* aProcessor, void *aData)
|
1999-04-20 04:02:22 +04:00
|
|
|
{
|
1999-10-08 07:09:31 +04:00
|
|
|
nsIStyleRuleProcessor* processor = (nsIStyleRuleProcessor*)aProcessor;
|
1999-04-20 04:02:22 +04:00
|
|
|
StatefulData* data = (StatefulData*)aData;
|
1999-10-08 07:09:31 +04:00
|
|
|
if (NS_OK == processor->HasStateDependentStyle(data->mPresContext, data->mMedium,
|
|
|
|
data->mContent)) {
|
1999-04-20 04:02:22 +04:00
|
|
|
data->mStateful = PR_TRUE;
|
|
|
|
return PR_FALSE; // stop iteration
|
|
|
|
}
|
|
|
|
return PR_TRUE; // continue
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test if style is dependent on content state
|
|
|
|
NS_IMETHODIMP
|
|
|
|
StyleSetImpl::HasStateDependentStyle(nsIPresContext* aPresContext,
|
|
|
|
nsIContent* aContent)
|
|
|
|
{
|
2000-08-12 10:28:02 +04:00
|
|
|
GatherRuleProcessors();
|
|
|
|
if (mBackstopRuleProcessors || mDocRuleProcessors || mOverrideRuleProcessors) {
|
1999-10-08 07:09:31 +04:00
|
|
|
nsIAtom* medium = nsnull;
|
|
|
|
aPresContext->GetMedium(&medium);
|
|
|
|
StatefulData data(aPresContext, medium, aContent);
|
2000-08-12 10:28:02 +04:00
|
|
|
WalkRuleProcessors(SheetHasStatefulStyle, &data, aContent);
|
1999-10-08 07:09:31 +04:00
|
|
|
NS_IF_RELEASE(medium);
|
|
|
|
return ((data.mStateful) ? NS_OK : NS_COMFALSE);
|
|
|
|
}
|
|
|
|
return NS_COMFALSE;
|
1999-04-20 04:02:22 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
1998-12-29 06:38:16 +03:00
|
|
|
NS_IMETHODIMP StyleSetImpl::ConstructRootFrame(nsIPresContext* aPresContext,
|
|
|
|
nsIContent* aDocElement,
|
|
|
|
nsIFrame*& aFrameSubTree)
|
1998-09-10 23:32:14 +04:00
|
|
|
{
|
1999-12-05 02:49:50 +03:00
|
|
|
nsCOMPtr<nsIPresShell> shell;
|
|
|
|
aPresContext->GetShell(getter_AddRefs(shell));
|
|
|
|
return mFrameConstructor->ConstructRootFrame(shell, aPresContext, aDocElement,
|
1998-12-29 06:38:16 +03:00
|
|
|
aFrameSubTree);
|
1998-09-10 23:32:14 +04:00
|
|
|
}
|
|
|
|
|
1998-11-17 05:14:38 +03:00
|
|
|
NS_IMETHODIMP
|
1999-03-01 19:57:35 +03:00
|
|
|
StyleSetImpl::ReconstructDocElementHierarchy(nsIPresContext* aPresContext)
|
1998-11-17 05:14:38 +03:00
|
|
|
{
|
1999-03-01 19:57:35 +03:00
|
|
|
return mFrameConstructor->ReconstructDocElementHierarchy(aPresContext);
|
1998-11-17 05:14:38 +03:00
|
|
|
}
|
|
|
|
|
1998-09-10 23:32:14 +04:00
|
|
|
NS_IMETHODIMP StyleSetImpl::ContentAppended(nsIPresContext* aPresContext,
|
|
|
|
nsIContent* aContainer,
|
|
|
|
PRInt32 aNewIndexInContainer)
|
|
|
|
{
|
1998-09-30 03:47:03 +04:00
|
|
|
return mFrameConstructor->ContentAppended(aPresContext,
|
1998-09-10 23:32:14 +04:00
|
|
|
aContainer, aNewIndexInContainer);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP StyleSetImpl::ContentInserted(nsIPresContext* aPresContext,
|
|
|
|
nsIContent* aContainer,
|
|
|
|
nsIContent* aChild,
|
|
|
|
PRInt32 aIndexInContainer)
|
|
|
|
{
|
1998-09-30 03:47:03 +04:00
|
|
|
return mFrameConstructor->ContentInserted(aPresContext, aContainer,
|
1999-12-06 10:44:18 +03:00
|
|
|
aChild, aIndexInContainer, nsnull);
|
1998-09-10 23:32:14 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP StyleSetImpl::ContentReplaced(nsIPresContext* aPresContext,
|
|
|
|
nsIContent* aContainer,
|
|
|
|
nsIContent* aOldChild,
|
|
|
|
nsIContent* aNewChild,
|
|
|
|
PRInt32 aIndexInContainer)
|
|
|
|
{
|
1998-09-30 03:47:03 +04:00
|
|
|
return mFrameConstructor->ContentReplaced(aPresContext, aContainer,
|
1998-09-10 23:32:14 +04:00
|
|
|
aOldChild, aNewChild, aIndexInContainer);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP StyleSetImpl::ContentRemoved(nsIPresContext* aPresContext,
|
|
|
|
nsIContent* aContainer,
|
|
|
|
nsIContent* aChild,
|
|
|
|
PRInt32 aIndexInContainer)
|
|
|
|
{
|
1998-09-30 03:47:03 +04:00
|
|
|
return mFrameConstructor->ContentRemoved(aPresContext, aContainer,
|
1998-09-10 23:32:14 +04:00
|
|
|
aChild, aIndexInContainer);
|
|
|
|
}
|
|
|
|
|
1998-09-30 03:47:03 +04:00
|
|
|
NS_IMETHODIMP
|
|
|
|
StyleSetImpl::ContentChanged(nsIPresContext* aPresContext,
|
|
|
|
nsIContent* aContent,
|
|
|
|
nsISupports* aSubContent)
|
|
|
|
{
|
|
|
|
return mFrameConstructor->ContentChanged(aPresContext,
|
|
|
|
aContent, aSubContent);
|
|
|
|
}
|
|
|
|
|
1999-02-27 10:11:04 +03:00
|
|
|
NS_IMETHODIMP
|
1999-04-20 04:02:22 +04:00
|
|
|
StyleSetImpl::ContentStatesChanged(nsIPresContext* aPresContext,
|
|
|
|
nsIContent* aContent1,
|
|
|
|
nsIContent* aContent2)
|
1999-02-27 10:11:04 +03:00
|
|
|
{
|
1999-04-20 04:02:22 +04:00
|
|
|
return mFrameConstructor->ContentStatesChanged(aPresContext, aContent1, aContent2);
|
1999-02-27 10:11:04 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
1998-09-30 03:47:03 +04:00
|
|
|
NS_IMETHODIMP
|
|
|
|
StyleSetImpl::AttributeChanged(nsIPresContext* aPresContext,
|
|
|
|
nsIContent* aContent,
|
1999-10-16 03:16:45 +04:00
|
|
|
PRInt32 aNameSpaceID,
|
1998-09-30 03:47:03 +04:00
|
|
|
nsIAtom* aAttribute,
|
2001-08-25 06:01:08 +04:00
|
|
|
PRInt32 aModType,
|
1998-09-30 03:47:03 +04:00
|
|
|
PRInt32 aHint)
|
|
|
|
{
|
|
|
|
return mFrameConstructor->AttributeChanged(aPresContext, aContent,
|
2001-08-25 06:01:08 +04:00
|
|
|
aNameSpaceID, aAttribute, aModType, aHint);
|
1998-09-30 03:47:03 +04:00
|
|
|
}
|
|
|
|
|
1998-11-17 05:14:38 +03:00
|
|
|
|
1998-11-26 04:34:53 +03:00
|
|
|
// Style change notifications
|
|
|
|
NS_IMETHODIMP
|
|
|
|
StyleSetImpl::StyleRuleChanged(nsIPresContext* aPresContext,
|
|
|
|
nsIStyleSheet* aStyleSheet,
|
|
|
|
nsIStyleRule* aStyleRule,
|
|
|
|
PRInt32 aHint)
|
|
|
|
{
|
|
|
|
return mFrameConstructor->StyleRuleChanged(aPresContext, aStyleSheet, aStyleRule, aHint);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
StyleSetImpl::StyleRuleAdded(nsIPresContext* aPresContext,
|
|
|
|
nsIStyleSheet* aStyleSheet,
|
|
|
|
nsIStyleRule* aStyleRule)
|
|
|
|
{
|
|
|
|
return mFrameConstructor->StyleRuleAdded(aPresContext, aStyleSheet, aStyleRule);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
StyleSetImpl::StyleRuleRemoved(nsIPresContext* aPresContext,
|
|
|
|
nsIStyleSheet* aStyleSheet,
|
|
|
|
nsIStyleRule* aStyleRule)
|
|
|
|
{
|
|
|
|
return mFrameConstructor->StyleRuleRemoved(aPresContext, aStyleSheet, aStyleRule);
|
|
|
|
}
|
1998-04-14 00:24:54 +04:00
|
|
|
|
1999-02-04 20:03:46 +03:00
|
|
|
NS_IMETHODIMP
|
|
|
|
StyleSetImpl::CantRenderReplacedElement(nsIPresContext* aPresContext,
|
|
|
|
nsIFrame* aFrame)
|
|
|
|
{
|
1999-12-05 02:49:50 +03:00
|
|
|
nsCOMPtr<nsIPresShell> shell;
|
|
|
|
aPresContext->GetShell(getter_AddRefs(shell));
|
|
|
|
return mFrameConstructor->CantRenderReplacedElement(shell, aPresContext, aFrame);
|
1999-02-04 20:03:46 +03:00
|
|
|
}
|
|
|
|
|
1999-02-24 07:03:50 +03:00
|
|
|
NS_IMETHODIMP
|
|
|
|
StyleSetImpl::CreateContinuingFrame(nsIPresContext* aPresContext,
|
|
|
|
nsIFrame* aFrame,
|
|
|
|
nsIFrame* aParentFrame,
|
|
|
|
nsIFrame** aContinuingFrame)
|
|
|
|
{
|
1999-12-05 02:49:50 +03:00
|
|
|
nsCOMPtr<nsIPresShell> shell;
|
|
|
|
aPresContext->GetShell(getter_AddRefs(shell));
|
|
|
|
return mFrameConstructor->CreateContinuingFrame(shell, aPresContext, aFrame, aParentFrame,
|
1999-02-24 07:03:50 +03:00
|
|
|
aContinuingFrame);
|
|
|
|
}
|
|
|
|
|
1999-07-02 08:46:19 +04:00
|
|
|
// Request to find the primary frame associated with a given content object.
|
|
|
|
// This is typically called by the pres shell when there is no mapping in
|
|
|
|
// the pres shell hash table
|
|
|
|
NS_IMETHODIMP
|
1999-08-05 07:09:22 +04:00
|
|
|
StyleSetImpl::FindPrimaryFrameFor(nsIPresContext* aPresContext,
|
|
|
|
nsIFrameManager* aFrameManager,
|
|
|
|
nsIContent* aContent,
|
2001-01-17 01:10:04 +03:00
|
|
|
nsIFrame** aFrame,
|
|
|
|
nsFindFrameHint* aHint)
|
1999-07-02 08:46:19 +04:00
|
|
|
{
|
1999-08-05 07:09:22 +04:00
|
|
|
return mFrameConstructor->FindPrimaryFrameFor(aPresContext, aFrameManager,
|
2001-01-17 01:10:04 +03:00
|
|
|
aContent, aFrame, aHint);
|
1999-07-02 08:46:19 +04:00
|
|
|
}
|
|
|
|
|
2001-09-13 00:19:41 +04:00
|
|
|
NS_IMETHODIMP
|
|
|
|
StyleSetImpl::GetInsertionPoint(nsIPresShell* aPresShell,
|
|
|
|
nsIFrame* aParentFrame,
|
|
|
|
nsIContent* aChildContent,
|
|
|
|
nsIFrame** aInsertionPoint)
|
|
|
|
{
|
|
|
|
return mFrameConstructor->GetInsertionPoint(aPresShell, aParentFrame,
|
|
|
|
aChildContent, aInsertionPoint);
|
|
|
|
}
|
|
|
|
|
2001-10-16 09:31:36 +04:00
|
|
|
#ifdef DEBUG
|
1998-04-14 00:24:54 +04:00
|
|
|
void StyleSetImpl::List(FILE* out, PRInt32 aIndent, nsISupportsArray* aSheets)
|
|
|
|
{
|
1999-05-13 08:56:04 +04:00
|
|
|
PRUint32 cnt = 0;
|
|
|
|
if (aSheets) {
|
|
|
|
nsresult rv = aSheets->Count(&cnt);
|
|
|
|
if (NS_FAILED(rv)) return; // XXX error?
|
|
|
|
}
|
1998-04-14 00:24:54 +04:00
|
|
|
|
1999-05-13 08:56:04 +04:00
|
|
|
for (PRInt32 index = 0; index < (PRInt32)cnt; index++) {
|
1998-04-14 00:24:54 +04:00
|
|
|
nsIStyleSheet* sheet = (nsIStyleSheet*)aSheets->ElementAt(index);
|
|
|
|
sheet->List(out, aIndent);
|
|
|
|
fputs("\n", out);
|
|
|
|
NS_RELEASE(sheet);
|
|
|
|
}
|
|
|
|
}
|
2001-10-16 09:31:36 +04:00
|
|
|
#endif
|
1998-04-14 00:24:54 +04:00
|
|
|
|
2000-08-12 10:28:02 +04:00
|
|
|
// APIs for registering objects that can supply additional
|
|
|
|
// rules during processing.
|
|
|
|
NS_IMETHODIMP
|
|
|
|
StyleSetImpl::SetStyleRuleSupplier(nsIStyleRuleSupplier* aSupplier)
|
|
|
|
{
|
|
|
|
mStyleRuleSupplier = aSupplier;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
StyleSetImpl::GetStyleRuleSupplier(nsIStyleRuleSupplier** aSupplier)
|
|
|
|
{
|
|
|
|
*aSupplier = mStyleRuleSupplier;
|
|
|
|
NS_IF_ADDREF(*aSupplier);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-10-16 09:31:36 +04:00
|
|
|
#ifdef DEBUG
|
1998-04-14 00:24:54 +04:00
|
|
|
void StyleSetImpl::List(FILE* out, PRInt32 aIndent)
|
|
|
|
{
|
1999-02-27 10:11:04 +03:00
|
|
|
// List(out, aIndent, mOverrideSheets);
|
1998-04-14 00:24:54 +04:00
|
|
|
List(out, aIndent, mDocSheets);
|
1999-02-27 10:11:04 +03:00
|
|
|
// List(out, aIndent, mBackstopSheets);
|
1998-04-14 00:24:54 +04:00
|
|
|
}
|
|
|
|
|
1999-09-20 10:53:40 +04:00
|
|
|
|
1998-06-26 09:49:01 +04:00
|
|
|
void StyleSetImpl::ListContexts(nsIStyleContext* aRootContext, FILE* out, PRInt32 aIndent)
|
1998-05-19 01:05:52 +04:00
|
|
|
{
|
1998-06-26 09:49:01 +04:00
|
|
|
aRootContext->List(out, aIndent);
|
1998-05-19 01:05:52 +04:00
|
|
|
}
|
2001-10-16 09:31:36 +04:00
|
|
|
#endif
|
1998-05-19 01:05:52 +04:00
|
|
|
|
1998-04-14 00:24:54 +04:00
|
|
|
|
2001-10-20 00:59:33 +04:00
|
|
|
NS_EXPORT nsresult
|
1998-04-14 00:24:54 +04:00
|
|
|
NS_NewStyleSet(nsIStyleSet** aInstancePtrResult)
|
|
|
|
{
|
|
|
|
if (aInstancePtrResult == nsnull) {
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
}
|
|
|
|
|
|
|
|
StyleSetImpl *it = new StyleSetImpl();
|
|
|
|
|
|
|
|
if (nsnull == it) {
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
}
|
|
|
|
|
2001-01-04 23:44:42 +03:00
|
|
|
return it->QueryInterface(NS_GET_IID(nsIStyleSet), (void **) aInstancePtrResult);
|
1998-04-14 00:24:54 +04:00
|
|
|
}
|
1999-09-20 10:53:40 +04:00
|
|
|
|
|
|
|
// nsITimeRecorder implementation
|
|
|
|
|
1999-10-20 02:27:20 +04:00
|
|
|
#ifdef MOZ_PERF_METRICS
|
2000-02-11 04:21:36 +03:00
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
StyleSetImpl::EnableTimer(PRUint32 aTimerID)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
|
|
|
|
if (NS_TIMER_STYLE_RESOLUTION == aTimerID) {
|
|
|
|
mTimerEnabled = PR_TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
rv = NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
StyleSetImpl::DisableTimer(PRUint32 aTimerID)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
|
|
|
|
if (NS_TIMER_STYLE_RESOLUTION == aTimerID) {
|
|
|
|
mTimerEnabled = PR_FALSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
rv = NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
StyleSetImpl::IsTimerEnabled(PRBool *aIsEnabled, PRUint32 aTimerID)
|
|
|
|
{
|
|
|
|
NS_ASSERTION(aIsEnabled != nsnull, "aIsEnabled paramter cannot be null" );
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
|
|
|
|
if (NS_TIMER_STYLE_RESOLUTION == aTimerID) {
|
|
|
|
if (*aIsEnabled != nsnull) {
|
|
|
|
*aIsEnabled = mTimerEnabled;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
rv = NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
1999-09-20 10:53:40 +04:00
|
|
|
NS_IMETHODIMP
|
|
|
|
StyleSetImpl::ResetTimer(PRUint32 aTimerID)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
|
|
|
|
if (NS_TIMER_STYLE_RESOLUTION == aTimerID) {
|
1999-11-10 06:41:09 +03:00
|
|
|
MOZ_TIMER_RESET(mStyleResolutionWatch);
|
1999-09-20 10:53:40 +04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
rv = NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
StyleSetImpl::StartTimer(PRUint32 aTimerID)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
|
|
|
|
if (NS_TIMER_STYLE_RESOLUTION == aTimerID) {
|
2000-02-11 04:21:36 +03:00
|
|
|
// only do it if enabled
|
|
|
|
if (mTimerEnabled) {
|
|
|
|
MOZ_TIMER_START(mStyleResolutionWatch);
|
|
|
|
} else {
|
2000-10-29 02:17:53 +04:00
|
|
|
#ifdef NOISY_DEBUG
|
|
|
|
printf( "Attempt to start timer while disabled - ignoring\n" );
|
|
|
|
#endif
|
2000-02-11 04:21:36 +03:00
|
|
|
}
|
1999-09-20 10:53:40 +04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
rv = NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
StyleSetImpl::StopTimer(PRUint32 aTimerID)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
|
|
|
|
if (NS_TIMER_STYLE_RESOLUTION == aTimerID) {
|
2000-02-11 04:21:36 +03:00
|
|
|
// only do it if enabled
|
|
|
|
if (mTimerEnabled) {
|
|
|
|
MOZ_TIMER_STOP(mStyleResolutionWatch);
|
|
|
|
} else {
|
2000-10-29 02:17:53 +04:00
|
|
|
#ifdef NOISY_DEBUG
|
|
|
|
printf( "Attempt to stop timer while disabled - ignoring\n" );
|
|
|
|
#endif
|
2000-02-11 04:21:36 +03:00
|
|
|
}
|
1999-09-20 10:53:40 +04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
rv = NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
StyleSetImpl::PrintTimer(PRUint32 aTimerID)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
|
|
|
|
if (NS_TIMER_STYLE_RESOLUTION == aTimerID) {
|
1999-11-10 06:41:09 +03:00
|
|
|
MOZ_TIMER_PRINT(mStyleResolutionWatch);
|
1999-09-20 10:53:40 +04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
rv = NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
1999-09-21 01:36:53 +04:00
|
|
|
#endif
|
|
|
|
|
2000-03-31 11:08:36 +04:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
// static
|
|
|
|
nsUniqueStyleItems *nsUniqueStyleItems ::mInstance = nsnull;
|
|
|
|
|
|
|
|
void StyleSetImpl::ResetUniqueStyleItems(void)
|
|
|
|
{
|
|
|
|
UNIQUE_STYLE_ITEMS(uniqueItems);
|
|
|
|
uniqueItems->Clear();
|
|
|
|
}
|
|
|
|
|
2000-05-16 06:43:33 +04:00
|
|
|
struct AttributeContentPair {
|
|
|
|
nsIAtom *attribute;
|
|
|
|
nsIContent *content;
|
|
|
|
};
|
|
|
|
|
|
|
|
static PRBool
|
|
|
|
EnumAffectsStyle(nsISupports *aElement, void *aData)
|
|
|
|
{
|
|
|
|
nsIStyleSheet *sheet = NS_STATIC_CAST(nsIStyleSheet *, aElement);
|
|
|
|
AttributeContentPair *pair = (AttributeContentPair *)aData;
|
|
|
|
PRBool affects;
|
|
|
|
if (NS_FAILED(sheet->AttributeAffectsStyle(pair->attribute, pair->content,
|
|
|
|
affects)) || affects)
|
|
|
|
return PR_FALSE; // stop checking
|
|
|
|
|
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
StyleSetImpl::AttributeAffectsStyle(nsIAtom *aAttribute, nsIContent *aContent,
|
|
|
|
PRBool &aAffects)
|
|
|
|
{
|
|
|
|
AttributeContentPair pair;
|
|
|
|
pair.attribute = aAttribute;
|
|
|
|
pair.content = aContent;
|
|
|
|
|
2001-03-29 05:30:03 +04:00
|
|
|
/* scoped sheets should be checked first, since - if present - they will contain
|
|
|
|
the bulk of the applicable rules for the content node. */
|
|
|
|
if (mStyleRuleSupplier)
|
|
|
|
mStyleRuleSupplier->AttributeAffectsStyle(EnumAffectsStyle, &pair, aContent, &aAffects);
|
|
|
|
|
|
|
|
if (!aAffects) {
|
|
|
|
/* check until we find a sheet that will be affected */
|
|
|
|
if ((mDocSheets && !mDocSheets->EnumerateForwards(EnumAffectsStyle, &pair)) ||
|
|
|
|
(mOverrideSheets && !mOverrideSheets->EnumerateForwards(EnumAffectsStyle,
|
|
|
|
&pair)) ||
|
|
|
|
(mBackstopSheets && !mBackstopSheets->EnumerateForwards(EnumAffectsStyle,
|
|
|
|
&pair))) {
|
|
|
|
aAffects = PR_TRUE;
|
|
|
|
} else {
|
|
|
|
aAffects = PR_FALSE;
|
|
|
|
}
|
2000-05-16 06:43:33 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2001-10-16 09:31:36 +04:00
|
|
|
#ifdef DEBUG
|
2000-03-31 11:08:36 +04:00
|
|
|
/******************************************************************************
|
|
|
|
* SizeOf method:
|
|
|
|
*
|
|
|
|
* Self (reported as StyleSetImpl's size):
|
|
|
|
* 1) sizeof(*this) + sizeof (overhead only) each collection that exists
|
|
|
|
* and the FrameConstructor overhead
|
|
|
|
*
|
|
|
|
* Contained / Aggregated data (not reported as StyleSetImpl's size):
|
|
|
|
* 1) Override Sheets, DocSheets, BackstopSheets, RuleProcessors, Recycler
|
|
|
|
* are all delegated to.
|
|
|
|
*
|
|
|
|
* Children / siblings / parents:
|
|
|
|
* none
|
|
|
|
*
|
|
|
|
******************************************************************************/
|
|
|
|
void StyleSetImpl::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize)
|
|
|
|
{
|
|
|
|
NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null");
|
|
|
|
|
|
|
|
// first get the unique items collection
|
|
|
|
UNIQUE_STYLE_ITEMS(uniqueItems);
|
|
|
|
|
|
|
|
if(! uniqueItems->AddItem((void*)this) ){
|
|
|
|
NS_ASSERTION(0, "StyleSet has already been conted in SizeOf operation");
|
|
|
|
// styleset has already been accounted for
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
// get or create a tag for this instance
|
|
|
|
nsCOMPtr<nsIAtom> tag;
|
|
|
|
tag = getter_AddRefs(NS_NewAtom("StyleSet"));
|
|
|
|
// get the size of an empty instance and add to the sizeof handler
|
|
|
|
aSize = sizeof(StyleSetImpl);
|
|
|
|
|
|
|
|
// Next get the size of the OVERHEAD of objects we will delegate to:
|
|
|
|
if (mOverrideSheets && uniqueItems->AddItem(mOverrideSheets)){
|
|
|
|
aSize += sizeof(*mOverrideSheets);
|
|
|
|
}
|
|
|
|
if (mDocSheets && uniqueItems->AddItem(mDocSheets)){
|
|
|
|
aSize += sizeof(*mDocSheets);
|
|
|
|
}
|
|
|
|
if (mBackstopSheets && uniqueItems->AddItem(mBackstopSheets)){
|
|
|
|
aSize += sizeof(*mBackstopSheets);
|
|
|
|
}
|
2000-08-12 10:28:02 +04:00
|
|
|
if (mBackstopRuleProcessors && uniqueItems->AddItem(mBackstopRuleProcessors)){
|
|
|
|
aSize += sizeof(*mBackstopRuleProcessors);
|
|
|
|
}
|
|
|
|
if (mDocRuleProcessors && uniqueItems->AddItem(mDocRuleProcessors)){
|
|
|
|
aSize += sizeof(*mDocRuleProcessors);
|
|
|
|
}
|
|
|
|
if (mOverrideRuleProcessors && uniqueItems->AddItem(mOverrideRuleProcessors)){
|
|
|
|
aSize += sizeof(*mOverrideRuleProcessors);
|
2000-03-31 11:08:36 +04:00
|
|
|
}
|
|
|
|
if (mRecycler && uniqueItems->AddItem(mRecycler)){
|
|
|
|
aSize += sizeof(*mRecycler);
|
|
|
|
}
|
2000-06-03 01:45:06 +04:00
|
|
|
if (mQuirkStyleSheet) {
|
|
|
|
aSize += sizeof(mQuirkStyleSheet); // just the pointer: the sheet is counted elsewhere
|
|
|
|
}
|
|
|
|
///////////////////////////////////////////////
|
2000-03-31 11:08:36 +04:00
|
|
|
// now the FrameConstructor
|
|
|
|
if(mFrameConstructor && uniqueItems->AddItem((void*)mFrameConstructor)){
|
|
|
|
aSize += sizeof(mFrameConstructor);
|
|
|
|
}
|
|
|
|
aSizeOfHandler->AddSize(tag,aSize);
|
|
|
|
|
|
|
|
///////////////////////////////////////////////
|
|
|
|
// Now travers the collections and delegate
|
|
|
|
PRInt32 numSheets, curSheet;
|
|
|
|
PRUint32 localSize=0;
|
|
|
|
numSheets = GetNumberOfOverrideStyleSheets();
|
|
|
|
for(curSheet=0; curSheet < numSheets; curSheet++){
|
|
|
|
nsIStyleSheet* pSheet = GetOverrideStyleSheetAt(curSheet); //addref
|
|
|
|
if(pSheet){
|
|
|
|
localSize=0;
|
|
|
|
pSheet->SizeOf(aSizeOfHandler, localSize);
|
|
|
|
}
|
|
|
|
NS_IF_RELEASE(pSheet);
|
|
|
|
}
|
|
|
|
|
|
|
|
numSheets = GetNumberOfDocStyleSheets();
|
|
|
|
for(curSheet=0; curSheet < numSheets; curSheet++){
|
|
|
|
nsIStyleSheet* pSheet = GetDocStyleSheetAt(curSheet);
|
|
|
|
if(pSheet){
|
|
|
|
localSize=0;
|
|
|
|
pSheet->SizeOf(aSizeOfHandler, localSize);
|
|
|
|
}
|
|
|
|
NS_IF_RELEASE(pSheet);
|
|
|
|
}
|
|
|
|
|
|
|
|
numSheets = GetNumberOfBackstopStyleSheets();
|
|
|
|
for(curSheet=0; curSheet < numSheets; curSheet++){
|
|
|
|
nsIStyleSheet* pSheet = GetBackstopStyleSheetAt(curSheet);
|
|
|
|
if(pSheet){
|
|
|
|
localSize=0;
|
|
|
|
pSheet->SizeOf(aSizeOfHandler, localSize);
|
|
|
|
}
|
|
|
|
NS_IF_RELEASE(pSheet);
|
|
|
|
}
|
|
|
|
///////////////////////////////////////////////
|
|
|
|
// rule processors
|
|
|
|
PRUint32 numRuleProcessors,curRuleProcessor;
|
2000-08-12 10:28:02 +04:00
|
|
|
if(mBackstopRuleProcessors){
|
|
|
|
mBackstopRuleProcessors->Count(&numRuleProcessors);
|
|
|
|
for(curRuleProcessor=0; curRuleProcessor < numRuleProcessors; curRuleProcessor++){
|
|
|
|
nsIStyleRuleProcessor* processor =
|
|
|
|
(nsIStyleRuleProcessor* )mBackstopRuleProcessors->ElementAt(curRuleProcessor);
|
|
|
|
if(processor){
|
|
|
|
localSize=0;
|
|
|
|
processor->SizeOf(aSizeOfHandler, localSize);
|
|
|
|
}
|
|
|
|
NS_IF_RELEASE(processor);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(mDocRuleProcessors){
|
|
|
|
mDocRuleProcessors->Count(&numRuleProcessors);
|
|
|
|
for(curRuleProcessor=0; curRuleProcessor < numRuleProcessors; curRuleProcessor++){
|
|
|
|
nsIStyleRuleProcessor* processor =
|
|
|
|
(nsIStyleRuleProcessor* )mDocRuleProcessors->ElementAt(curRuleProcessor);
|
|
|
|
if(processor){
|
|
|
|
localSize=0;
|
|
|
|
processor->SizeOf(aSizeOfHandler, localSize);
|
|
|
|
}
|
|
|
|
NS_IF_RELEASE(processor);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(mOverrideRuleProcessors){
|
|
|
|
mOverrideRuleProcessors->Count(&numRuleProcessors);
|
2000-03-31 11:08:36 +04:00
|
|
|
for(curRuleProcessor=0; curRuleProcessor < numRuleProcessors; curRuleProcessor++){
|
|
|
|
nsIStyleRuleProcessor* processor =
|
2000-08-12 10:28:02 +04:00
|
|
|
(nsIStyleRuleProcessor* )mOverrideRuleProcessors->ElementAt(curRuleProcessor);
|
2000-03-31 11:08:36 +04:00
|
|
|
if(processor){
|
|
|
|
localSize=0;
|
|
|
|
processor->SizeOf(aSizeOfHandler, localSize);
|
|
|
|
}
|
|
|
|
NS_IF_RELEASE(processor);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////
|
|
|
|
// and the recycled ones too
|
|
|
|
if(mRecycler){
|
|
|
|
mRecycler->Count(&numRuleProcessors);
|
|
|
|
for(curRuleProcessor=0; curRuleProcessor < numRuleProcessors; curRuleProcessor++){
|
|
|
|
nsIStyleRuleProcessor* processor =
|
|
|
|
(nsIStyleRuleProcessor* )mRecycler->ElementAt(curRuleProcessor);
|
|
|
|
if(processor && uniqueItems->AddItem((void*)processor)){
|
|
|
|
localSize=0;
|
|
|
|
processor->SizeOf(aSizeOfHandler, localSize);
|
|
|
|
}
|
|
|
|
NS_IF_RELEASE(processor);
|
|
|
|
}
|
|
|
|
}
|
2000-06-22 00:44:59 +04:00
|
|
|
|
|
|
|
// XXX - do the stylecontext cache too
|
|
|
|
|
2000-03-31 11:08:36 +04:00
|
|
|
// now delegate the sizeof to the larger or more complex aggregated objects
|
|
|
|
// - none
|
|
|
|
}
|
2001-10-16 09:31:36 +04:00
|
|
|
#endif
|
2000-08-12 10:28:02 +04:00
|
|
|
|
|
|
|
void
|
|
|
|
StyleSetImpl::WalkRuleProcessors(nsISupportsArrayEnumFunc aFunc, void* aData,
|
|
|
|
nsIContent* aContent)
|
|
|
|
{
|
|
|
|
// Walk the backstop rules first.
|
|
|
|
if (mBackstopRuleProcessors)
|
|
|
|
mBackstopRuleProcessors->EnumerateForwards(aFunc, aData);
|
|
|
|
|
|
|
|
PRBool useRuleProcessors = PR_TRUE;
|
|
|
|
if (mStyleRuleSupplier) {
|
|
|
|
// We can supply additional document-level sheets that should be walked.
|
|
|
|
mStyleRuleSupplier->WalkRules(this, aFunc, aData, aContent);
|
|
|
|
mStyleRuleSupplier->UseDocumentRules(aContent, &useRuleProcessors);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Walk the doc rules next.
|
|
|
|
if (mDocRuleProcessors && useRuleProcessors)
|
|
|
|
mDocRuleProcessors->EnumerateForwards(aFunc, aData);
|
|
|
|
|
|
|
|
// Walk the override rules last.
|
|
|
|
if (mOverrideRuleProcessors)
|
|
|
|
mOverrideRuleProcessors->EnumerateForwards(aFunc, aData);
|
|
|
|
}
|