1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 /* base class for nsCounterList and nsQuoteList */ 8 9 #ifndef nsGenConList_h___ 10 #define nsGenConList_h___ 11 12 #include "mozilla/LinkedList.h" 13 #include "nsStyleStruct.h" 14 #include "nsCSSPseudoElements.h" 15 #include "nsTextNode.h" 16 17 class nsGenConList; 18 class nsIFrame; 19 20 struct nsGenConNode : public mozilla::LinkedListElement<nsGenConNode> { 21 using StyleContentType = mozilla::StyleContentItem::Tag; 22 23 // The wrapper frame for all of the pseudo-element's content. This 24 // frame generally has useful style data and has the 25 // NS_FRAME_GENERATED_CONTENT bit set (so we use it to track removal), 26 // but does not necessarily for |nsCounterChangeNode|s. 27 nsIFrame* mPseudoFrame; 28 29 // Index within the list of things specified by the 'content' property, 30 // which is needed to do 'content: open-quote open-quote' correctly, 31 // and needed for similar cases for counters. 32 const int32_t mContentIndex; 33 34 // null for: 35 // * content: no-open-quote / content: no-close-quote 36 // * counter nodes for increments and resets 37 RefPtr<nsTextNode> mText; 38 nsGenConNodensGenConNode39 explicit nsGenConNode(int32_t aContentIndex) 40 : mPseudoFrame(nullptr), mContentIndex(aContentIndex) {} 41 42 /** 43 * Finish initializing the generated content node once we know the 44 * relevant text frame. This must be called just after 45 * the textframe has been initialized. This need not be called at all 46 * for nodes that don't generate text. This will generally set the 47 * mPseudoFrame, insert the node into aList, and set aTextFrame up 48 * with the correct text. 49 * @param aList the list the node belongs to 50 * @param aPseudoFrame the :before or :after frame 51 * @param aTextFrame the textframe where the node contents will render 52 * @return true iff this marked the list dirty 53 */ InitTextFramensGenConNode54 virtual bool InitTextFrame(nsGenConList* aList, nsIFrame* aPseudoFrame, 55 nsIFrame* aTextFrame) { 56 mPseudoFrame = aPseudoFrame; 57 CheckFrameAssertions(); 58 return false; 59 } 60 61 virtual ~nsGenConNode() = default; // XXX Avoid, perhaps? 62 63 protected: 64 void CheckFrameAssertions(); 65 }; 66 67 class nsGenConList { 68 protected: 69 mozilla::LinkedList<nsGenConNode> mList; 70 uint32_t mSize; 71 72 public: nsGenConList()73 nsGenConList() : mSize(0), mLastInserted(nullptr) {} ~nsGenConList()74 ~nsGenConList() { Clear(); } 75 void Clear(); Next(nsGenConNode * aNode)76 static nsGenConNode* Next(nsGenConNode* aNode) { 77 MOZ_ASSERT(aNode, "aNode cannot be nullptr!"); 78 return aNode->getNext(); 79 } Prev(nsGenConNode * aNode)80 static nsGenConNode* Prev(nsGenConNode* aNode) { 81 MOZ_ASSERT(aNode, "aNode cannot be nullptr!"); 82 return aNode->getPrevious(); 83 } 84 void Insert(nsGenConNode* aNode); 85 86 // Destroy all nodes with aFrame as parent. Returns true if some nodes 87 // have been destroyed; otherwise false. 88 bool DestroyNodesFor(nsIFrame* aFrame); 89 90 // Return the first node for aFrame on this list, or nullptr. GetFirstNodeFor(nsIFrame * aFrame)91 nsGenConNode* GetFirstNodeFor(nsIFrame* aFrame) const { 92 return mNodes.Get(aFrame); 93 } 94 95 // Return true if |aNode1| is after |aNode2|. 96 static bool NodeAfter(const nsGenConNode* aNode1, const nsGenConNode* aNode2); 97 IsFirst(nsGenConNode * aNode)98 bool IsFirst(nsGenConNode* aNode) { 99 MOZ_ASSERT(aNode, "aNode cannot be nullptr!"); 100 return aNode == mList.getFirst(); 101 } 102 IsLast(nsGenConNode * aNode)103 bool IsLast(nsGenConNode* aNode) { 104 MOZ_ASSERT(aNode, "aNode cannot be nullptr!"); 105 return aNode == mList.getLast(); 106 } 107 108 private: Destroy(nsGenConNode * aNode)109 void Destroy(nsGenConNode* aNode) { 110 MOZ_ASSERT(aNode, "aNode cannot be nullptr!"); 111 delete aNode; 112 mSize--; 113 } 114 115 // Map from frame to the first nsGenConNode of it in the list. 116 nsTHashMap<nsPtrHashKey<nsIFrame>, nsGenConNode*> mNodes; 117 118 // A weak pointer to the node most recently inserted, used to avoid repeated 119 // list traversals in Insert(). 120 nsGenConNode* mLastInserted; 121 }; 122 123 #endif /* nsGenConList_h___ */ 124