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: /* base class for nsCounterList and nsQuoteList */ michael@0: michael@0: #ifndef nsGenConList_h___ michael@0: #define nsGenConList_h___ michael@0: michael@0: #include "nsIFrame.h" michael@0: #include "nsStyleStruct.h" michael@0: #include "prclist.h" michael@0: #include "nsIDOMCharacterData.h" michael@0: #include "nsCSSPseudoElements.h" michael@0: michael@0: class nsGenConList; michael@0: michael@0: struct nsGenConNode : public PRCList { michael@0: // The wrapper frame for all of the pseudo-element's content. This michael@0: // frame generally has useful style data and has the michael@0: // NS_FRAME_GENERATED_CONTENT bit set (so we use it to track removal), michael@0: // but does not necessarily for |nsCounterChangeNode|s. michael@0: nsIFrame* mPseudoFrame; michael@0: michael@0: // Index within the list of things specified by the 'content' property, michael@0: // which is needed to do 'content: open-quote open-quote' correctly, michael@0: // and needed for similar cases for counters. michael@0: const int32_t mContentIndex; michael@0: michael@0: // null for 'content:no-open-quote', 'content:no-close-quote' and for michael@0: // counter nodes for increments and resets (rather than uses) michael@0: nsCOMPtr mText; michael@0: michael@0: nsGenConNode(int32_t aContentIndex) michael@0: : mPseudoFrame(nullptr) michael@0: , mContentIndex(aContentIndex) michael@0: { michael@0: } michael@0: michael@0: /** michael@0: * Finish initializing the generated content node once we know the michael@0: * relevant text frame. This must be called just after michael@0: * the textframe has been initialized. This need not be called at all michael@0: * for nodes that don't generate text. This will generally set the michael@0: * mPseudoFrame, insert the node into aList, and set aTextFrame up michael@0: * with the correct text. michael@0: * @param aList the list the node belongs to michael@0: * @param aPseudoFrame the :before or :after frame michael@0: * @param aTextFrame the textframe where the node contents will render michael@0: * @return true iff this marked the list dirty michael@0: */ michael@0: virtual bool InitTextFrame(nsGenConList* aList, nsIFrame* aPseudoFrame, michael@0: nsIFrame* aTextFrame) michael@0: { michael@0: mPseudoFrame = aPseudoFrame; michael@0: CheckFrameAssertions(); michael@0: return false; michael@0: } michael@0: michael@0: virtual ~nsGenConNode() {} // XXX Avoid, perhaps? michael@0: michael@0: protected: michael@0: void CheckFrameAssertions() { michael@0: NS_ASSERTION(mContentIndex < michael@0: int32_t(mPseudoFrame->StyleContent()->ContentCount()), michael@0: "index out of range"); michael@0: // We allow negative values of mContentIndex for 'counter-reset' and michael@0: // 'counter-increment'. michael@0: michael@0: NS_ASSERTION(mContentIndex < 0 || michael@0: mPseudoFrame->StyleContext()->GetPseudo() == michael@0: nsCSSPseudoElements::before || michael@0: mPseudoFrame->StyleContext()->GetPseudo() == michael@0: nsCSSPseudoElements::after, michael@0: "not :before/:after generated content and not counter change"); michael@0: NS_ASSERTION(mContentIndex < 0 || michael@0: mPseudoFrame->GetStateBits() & NS_FRAME_GENERATED_CONTENT, michael@0: "not generated content and not counter change"); michael@0: } michael@0: }; michael@0: michael@0: class nsGenConList { michael@0: protected: michael@0: nsGenConNode* mFirstNode; michael@0: uint32_t mSize; michael@0: public: michael@0: nsGenConList() : mFirstNode(nullptr), mSize(0) {} michael@0: ~nsGenConList() { Clear(); } michael@0: void Clear(); michael@0: static nsGenConNode* Next(nsGenConNode* aNode) { michael@0: return static_cast(PR_NEXT_LINK(aNode)); michael@0: } michael@0: static nsGenConNode* Prev(nsGenConNode* aNode) { michael@0: return static_cast(PR_PREV_LINK(aNode)); michael@0: } michael@0: void Insert(nsGenConNode* aNode); michael@0: // returns whether any nodes have been destroyed michael@0: bool DestroyNodesFor(nsIFrame* aFrame); //destroy all nodes with aFrame as parent michael@0: michael@0: // Return true if |aNode1| is after |aNode2|. michael@0: static bool NodeAfter(const nsGenConNode* aNode1, michael@0: const nsGenConNode* aNode2); michael@0: michael@0: void Remove(nsGenConNode* aNode) { PR_REMOVE_LINK(aNode); mSize--; } michael@0: bool IsLast(nsGenConNode* aNode) { return (Next(aNode) == mFirstNode); } michael@0: }; michael@0: michael@0: #endif /* nsGenConList_h___ */