nsGenConList.h (4416B)
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 <functional> 13 14 #include "mozilla/FunctionRef.h" 15 #include "mozilla/LinkedList.h" 16 #include "nsCSSPseudoElements.h" 17 #include "nsStyleStruct.h" 18 #include "nsTextNode.h" 19 20 class nsGenConList; 21 class nsIFrame; 22 23 struct nsGenConNode : public mozilla::LinkedListElement<nsGenConNode> { 24 using StyleContentType = mozilla::StyleContentItem::Tag; 25 26 // The wrapper frame for all of the pseudo-element's content. This 27 // frame generally has useful style data and has the 28 // NS_FRAME_GENERATED_CONTENT bit set (so we use it to track removal), 29 // but does not necessarily for |nsCounterChangeNode|s. 30 nsIFrame* mPseudoFrame; 31 32 // Index within the list of things specified by the 'content' property, 33 // which is needed to do 'content: open-quote open-quote' correctly, 34 // and needed for similar cases for counters. 35 const int32_t mContentIndex; 36 37 // null for: 38 // * content: no-open-quote / content: no-close-quote 39 // * counter nodes for increments and resets 40 RefPtr<nsTextNode> mText; 41 42 explicit nsGenConNode(int32_t aContentIndex) 43 : mPseudoFrame(nullptr), mContentIndex(aContentIndex) {} 44 45 /** 46 * Finish initializing the generated content node once we know the 47 * relevant text frame. This must be called just after 48 * the textframe has been initialized. This need not be called at all 49 * for nodes that don't generate text. This will generally set the 50 * mPseudoFrame, insert the node into aList, and set aTextFrame up 51 * with the correct text. 52 * @param aList the list the node belongs to 53 * @param aPseudoFrame the :before or :after frame 54 * @param aTextFrame the textframe where the node contents will render 55 * @return true iff this marked the list dirty 56 */ 57 virtual bool InitTextFrame(nsGenConList* aList, nsIFrame* aPseudoFrame, 58 nsIFrame* aTextFrame) { 59 mPseudoFrame = aPseudoFrame; 60 CheckFrameAssertions(); 61 return false; 62 } 63 64 virtual ~nsGenConNode() = default; // XXX Avoid, perhaps? 65 66 protected: 67 void CheckFrameAssertions(); 68 }; 69 70 class nsGenConList { 71 protected: 72 mozilla::LinkedList<nsGenConNode> mList; 73 uint32_t mSize; 74 75 public: 76 nsGenConList() : mSize(0), mLastInserted(nullptr) {} 77 ~nsGenConList() { Clear(); } 78 void Clear(); 79 static nsGenConNode* Next(nsGenConNode* aNode) { 80 MOZ_ASSERT(aNode, "aNode cannot be nullptr!"); 81 return aNode->getNext(); 82 } 83 static nsGenConNode* Prev(nsGenConNode* aNode) { 84 MOZ_ASSERT(aNode, "aNode cannot be nullptr!"); 85 return aNode->getPrevious(); 86 } 87 void Insert(nsGenConNode* aNode); 88 89 // Destroy all nodes with aFrame as parent. Returns true if some nodes 90 // have been destroyed; otherwise false. 91 bool DestroyNodesFor(nsIFrame* aFrame); 92 93 // Return the first node for aFrame on this list, or nullptr. 94 nsGenConNode* GetFirstNodeFor(nsIFrame* aFrame) const { 95 return mNodes.Get(aFrame); 96 } 97 98 // Return true if |aNode1| is after |aNode2|. 99 static bool NodeAfter(const nsGenConNode* aNode1, const nsGenConNode* aNode2); 100 101 // Find the first element in the list for which the given comparator returns 102 // true. This does a binary search on the list contents. 103 nsGenConNode* BinarySearch( 104 const mozilla::FunctionRef<bool(nsGenConNode*)>& aIsAfter); 105 106 nsGenConNode* GetLast() { return mList.getLast(); } 107 108 bool IsFirst(nsGenConNode* aNode) { 109 MOZ_ASSERT(aNode, "aNode cannot be nullptr!"); 110 return aNode == mList.getFirst(); 111 } 112 113 bool IsLast(nsGenConNode* aNode) { 114 MOZ_ASSERT(aNode, "aNode cannot be nullptr!"); 115 return aNode == mList.getLast(); 116 } 117 118 private: 119 void Destroy(nsGenConNode* aNode) { 120 MOZ_ASSERT(aNode, "aNode cannot be nullptr!"); 121 delete aNode; 122 mSize--; 123 } 124 125 // Map from frame to the first nsGenConNode of it in the list. 126 nsTHashMap<nsPtrHashKey<nsIFrame>, nsGenConNode*> mNodes; 127 128 // A weak pointer to the node most recently inserted, used to avoid repeated 129 // list traversals in Insert(). 130 nsGenConNode* mLastInserted; 131 }; 132 133 #endif /* nsGenConList_h___ */