Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/layout/base/nsGenConList.h
Line
Count
Source (jump to first uncovered line)
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 "nsIFrame.h"
14
#include "nsStyleStruct.h"
15
#include "nsCSSPseudoElements.h"
16
#include "nsTextNode.h"
17
18
class nsGenConList;
19
20
struct nsGenConNode : public mozilla::LinkedListElement<nsGenConNode> {
21
  using StyleContentType = mozilla::StyleContentType;
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 'content:no-open-quote', 'content:no-close-quote' and for
35
  // counter nodes for increments and resets (rather than uses)
36
  RefPtr<nsTextNode> mText;
37
38
  explicit nsGenConNode(int32_t aContentIndex)
39
    : mPseudoFrame(nullptr)
40
    , mContentIndex(aContentIndex)
41
0
  {
42
0
  }
43
44
  /**
45
   * Finish initializing the generated content node once we know the
46
   * relevant text frame. This must be called just after
47
   * the textframe has been initialized. This need not be called at all
48
   * for nodes that don't generate text. This will generally set the
49
   * mPseudoFrame, insert the node into aList, and set aTextFrame up
50
   * with the correct text.
51
   * @param aList the list the node belongs to
52
   * @param aPseudoFrame the :before or :after frame
53
   * @param aTextFrame the textframe where the node contents will render
54
   * @return true iff this marked the list dirty
55
   */
56
  virtual bool InitTextFrame(nsGenConList* aList, nsIFrame* aPseudoFrame,
57
                             nsIFrame* aTextFrame)
58
0
  {
59
0
    mPseudoFrame = aPseudoFrame;
60
0
    CheckFrameAssertions();
61
0
    return false;
62
0
  }
63
64
0
  virtual ~nsGenConNode() {} // XXX Avoid, perhaps?
65
66
protected:
67
0
  void CheckFrameAssertions() {
68
0
    NS_ASSERTION(mContentIndex <
69
0
                   int32_t(mPseudoFrame->StyleContent()->ContentCount()),
70
0
                 "index out of range");
71
0
      // We allow negative values of mContentIndex for 'counter-reset' and
72
0
      // 'counter-increment'.
73
0
74
0
    NS_ASSERTION(mContentIndex < 0 ||
75
0
                 mPseudoFrame->Style()->GetPseudo() ==
76
0
                   nsCSSPseudoElements::before() ||
77
0
                 mPseudoFrame->Style()->GetPseudo() ==
78
0
                   nsCSSPseudoElements::after(),
79
0
                 "not :before/:after generated content and not counter change");
80
0
    NS_ASSERTION(mContentIndex < 0 ||
81
0
                 mPseudoFrame->GetStateBits() & NS_FRAME_GENERATED_CONTENT,
82
0
                 "not generated content and not counter change");
83
0
  }
84
};
85
86
class nsGenConList {
87
protected:
88
  mozilla::LinkedList<nsGenConNode> mList;
89
  uint32_t mSize;
90
91
public:
92
0
  nsGenConList() : mSize(0), mLastInserted(nullptr) {}
93
0
  ~nsGenConList() { Clear(); }
94
  void Clear();
95
0
  static nsGenConNode* Next(nsGenConNode* aNode) {
96
0
    MOZ_ASSERT(aNode, "aNode cannot be nullptr!");
97
0
    return aNode->getNext();
98
0
  }
99
0
  static nsGenConNode* Prev(nsGenConNode* aNode) {
100
0
    MOZ_ASSERT(aNode, "aNode cannot be nullptr!");
101
0
    return aNode->getPrevious();
102
0
  }
103
  void Insert(nsGenConNode* aNode);
104
105
  // Destroy all nodes with aFrame as parent. Returns true if some nodes
106
  // have been destroyed; otherwise false.
107
  bool DestroyNodesFor(nsIFrame* aFrame);
108
109
  // Return true if |aNode1| is after |aNode2|.
110
  static bool NodeAfter(const nsGenConNode* aNode1,
111
                        const nsGenConNode* aNode2);
112
113
0
  bool IsFirst(nsGenConNode* aNode) {
114
0
    MOZ_ASSERT(aNode, "aNode cannot be nullptr!");
115
0
    return aNode == mList.getFirst();
116
0
  }
117
118
0
  bool IsLast(nsGenConNode* aNode) {
119
0
    MOZ_ASSERT(aNode, "aNode cannot be nullptr!");
120
0
    return aNode == mList.getLast();
121
0
  }
122
123
private:
124
  void Destroy(nsGenConNode* aNode)
125
0
  {
126
0
    MOZ_ASSERT(aNode, "aNode cannot be nullptr!");
127
0
    delete aNode;
128
0
    mSize--;
129
0
  }
130
131
  // Map from frame to the first nsGenConNode of it in the list.
132
  nsDataHashtable<nsPtrHashKey<nsIFrame>, nsGenConNode*> mNodes;
133
134
  // A weak pointer to the node most recently inserted, used to avoid repeated
135
  // list traversals in Insert().
136
  nsGenConNode* mLastInserted;
137
};
138
139
#endif /* nsGenConList_h___ */