michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: /* michael@0: * a class that walks the lexicographic tree of rule nodes as style michael@0: * rules are matched michael@0: */ michael@0: michael@0: #ifndef nsRuleWalker_h_ michael@0: #define nsRuleWalker_h_ michael@0: michael@0: #include "nsRuleNode.h" michael@0: #include "nsIStyleRule.h" michael@0: #include "StyleRule.h" michael@0: michael@0: class nsRuleWalker { michael@0: public: michael@0: nsRuleNode* CurrentNode() { return mCurrent; } michael@0: void SetCurrentNode(nsRuleNode* aNode) { michael@0: NS_ASSERTION(aNode, "Must have node here!"); michael@0: mCurrent = aNode; michael@0: } michael@0: michael@0: protected: michael@0: void DoForward(nsIStyleRule* aRule) { michael@0: mCurrent = mCurrent->Transition(aRule, mLevel, mImportance); michael@0: NS_POSTCONDITION(mCurrent, "Transition messed up"); michael@0: } michael@0: michael@0: public: michael@0: void Forward(nsIStyleRule* aRule) { michael@0: NS_PRECONDITION(!nsRefPtr(do_QueryObject(aRule)), michael@0: "Calling the wrong Forward() overload"); michael@0: DoForward(aRule); michael@0: } michael@0: void Forward(mozilla::css::StyleRule* aRule) { michael@0: DoForward(aRule); michael@0: mCheckForImportantRules = michael@0: mCheckForImportantRules && !aRule->GetImportantRule(); michael@0: } michael@0: // ForwardOnPossiblyCSSRule should only be used by callers that have michael@0: // an explicit list of rules they need to walk, with the list michael@0: // already containing any important rules they care about. michael@0: void ForwardOnPossiblyCSSRule(nsIStyleRule* aRule) { michael@0: DoForward(aRule); michael@0: } michael@0: michael@0: void Reset() { mCurrent = mRoot; } michael@0: michael@0: bool AtRoot() { return mCurrent == mRoot; } michael@0: michael@0: void SetLevel(uint8_t aLevel, bool aImportance, michael@0: bool aCheckForImportantRules) { michael@0: NS_ASSERTION(!aCheckForImportantRules || !aImportance, michael@0: "Shouldn't be checking for important rules while walking " michael@0: "important rules"); michael@0: mLevel = aLevel; michael@0: mImportance = aImportance; michael@0: mCheckForImportantRules = aCheckForImportantRules; michael@0: } michael@0: uint8_t GetLevel() const { return mLevel; } michael@0: bool GetImportance() const { return mImportance; } michael@0: bool GetCheckForImportantRules() const { return mCheckForImportantRules; } michael@0: michael@0: bool AuthorStyleDisabled() const { return mAuthorStyleDisabled; } michael@0: michael@0: // We define the visited-relevant link to be the link that is the michael@0: // nearest self-or-ancestor to the node being matched. michael@0: enum VisitedHandlingType { michael@0: // Do rule matching as though all links are unvisited. michael@0: eRelevantLinkUnvisited, michael@0: // Do rule matching as though the relevant link is visited and all michael@0: // other links are unvisited. michael@0: eRelevantLinkVisited, michael@0: // Do rule matching as though a rule should match if it would match michael@0: // given any set of visitedness states. (used by users other than michael@0: // nsRuleWalker) michael@0: eLinksVisitedOrUnvisited michael@0: }; michael@0: michael@0: private: michael@0: nsRuleNode* mCurrent; // Our current position. Never null. michael@0: nsRuleNode* mRoot; // The root of the tree we're walking. michael@0: uint8_t mLevel; // an nsStyleSet::sheetType michael@0: bool mImportance; michael@0: bool mCheckForImportantRules; // If true, check for important rules as michael@0: // we walk and set to false if we find michael@0: // one. michael@0: bool mAuthorStyleDisabled; michael@0: michael@0: public: michael@0: nsRuleWalker(nsRuleNode* aRoot, bool aAuthorStyleDisabled) michael@0: : mCurrent(aRoot) michael@0: , mRoot(aRoot) michael@0: , mAuthorStyleDisabled(aAuthorStyleDisabled) michael@0: { michael@0: NS_ASSERTION(mCurrent, "Caller screwed up and gave us null node"); michael@0: MOZ_COUNT_CTOR(nsRuleWalker); michael@0: } michael@0: ~nsRuleWalker() { MOZ_COUNT_DTOR(nsRuleWalker); } michael@0: }; michael@0: michael@0: #endif /* !defined(nsRuleWalker_h_) */