Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dist/include/mozilla/dom/XBLChildrenElement.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
#ifndef nsXBLChildrenElement_h___
8
#define nsXBLChildrenElement_h___
9
10
#include "nsINodeList.h"
11
#include "nsBindingManager.h"
12
#include "mozilla/dom/nsXMLElement.h"
13
14
class nsAnonymousContentList;
15
16
namespace mozilla {
17
namespace dom {
18
19
class XBLChildrenElement : public nsXMLElement
20
{
21
public:
22
  explicit XBLChildrenElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
23
    : nsXMLElement(std::move(aNodeInfo))
24
0
  {
25
0
  }
26
27
  // nsISupports
28
  NS_INLINE_DECL_REFCOUNTING_INHERITED(XBLChildrenElement, nsXMLElement)
29
30
  // nsINode interface methods
31
  virtual nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
32
33
  void AppendInsertedChild(nsIContent* aChild, bool aNotify)
34
0
  {
35
0
    // Appending an inserted child causes the inserted
36
0
    // children to be projected instead of default content.
37
0
    MaybeRemoveDefaultContent(aNotify);
38
0
39
0
    mInsertedChildren.AppendElement(aChild);
40
0
    aChild->SetXBLInsertionPoint(this);
41
0
  }
42
43
  void InsertInsertedChildAt(nsIContent* aChild, uint32_t aIndex)
44
0
  {
45
0
    // Inserting an inserted child causes the inserted
46
0
    // children to be projected instead of default content.
47
0
    MaybeRemoveDefaultContent(true);
48
0
49
0
    mInsertedChildren.InsertElementAt(aIndex, aChild);
50
0
    aChild->SetXBLInsertionPoint(this);
51
0
  }
52
53
  void RemoveInsertedChild(nsIContent* aChild)
54
0
  {
55
0
    // Can't use this assertion as we cheat for dynamic insertions and
56
0
    // only insert in the innermost insertion point.
57
0
    //NS_ASSERTION(mInsertedChildren.Contains(aChild),
58
0
    //             "Removing child that's not there");
59
0
    mInsertedChildren.RemoveElement(aChild);
60
0
61
0
    // After removing the inserted child, default content
62
0
    // may be projected into this insertion point.
63
0
    //
64
0
    // FIXME: Layout should be told about this before clearing
65
0
    // mInsertedChildren, this leaves stale styles and frames in the frame tree.
66
0
    MaybeSetupDefaultContent();
67
0
  }
68
69
  void ClearInsertedChildren()
70
0
  {
71
0
    for (auto* child : mInsertedChildren) {
72
0
      if (child->GetXBLInsertionPoint() == this) {
73
0
        child->SetXBLInsertionPoint(nullptr);
74
0
      }
75
0
    }
76
0
    mInsertedChildren.Clear();
77
0
78
0
    // After clearing inserted children, default content
79
0
    // will be projected into this insertion point.
80
0
    //
81
0
    // FIXME: Layout should be told about this before clearing
82
0
    // mInsertedChildren, this leaves stale styles and frames in the frame tree.
83
0
    MaybeSetupDefaultContent();
84
0
  }
85
86
  void MaybeSetupDefaultContent()
87
0
  {
88
0
    if (!HasInsertedChildren()) {
89
0
      for (nsIContent* child = static_cast<nsINode*>(this)->GetFirstChild();
90
0
           child;
91
0
           child = child->GetNextSibling()) {
92
0
        child->SetXBLInsertionPoint(this);
93
0
      }
94
0
    }
95
0
  }
96
97
  void MaybeRemoveDefaultContent(bool aNotify)
98
0
  {
99
0
    if (!HasInsertedChildren() && HasChildren()) {
100
0
      DoRemoveDefaultContent(aNotify);
101
0
    }
102
0
  }
103
104
  uint32_t InsertedChildrenLength()
105
0
  {
106
0
    return mInsertedChildren.Length();
107
0
  }
108
109
  bool HasInsertedChildren()
110
0
  {
111
0
    return !mInsertedChildren.IsEmpty();
112
0
  }
113
114
  int32_t IndexOfInsertedChild(nsIContent* aChild)
115
0
  {
116
0
    return mInsertedChildren.IndexOf(aChild);
117
0
  }
118
119
  bool Includes(nsIContent* aChild)
120
0
  {
121
0
    NS_ASSERTION(!mIncludes.IsEmpty(),
122
0
                 "Shouldn't check for includes on default insertion point");
123
0
    return mIncludes.Contains(aChild->NodeInfo()->NameAtom());
124
0
  }
125
126
  bool IsDefaultInsertion()
127
0
  {
128
0
    return mIncludes.IsEmpty();
129
0
  }
130
131
  nsIContent* InsertedChild(uint32_t aIndex)
132
0
  {
133
0
    return mInsertedChildren[aIndex];
134
0
  }
135
136
protected:
137
  ~XBLChildrenElement();
138
  virtual nsresult BeforeSetAttr(int32_t aNamespaceID, nsAtom* aName,
139
                                 const nsAttrValueOrString* aValue,
140
                                 bool aNotify) override;
141
142
  void DoRemoveDefaultContent(bool aNotify);
143
144
private:
145
  nsTArray<nsIContent*> mInsertedChildren; // WEAK
146
  nsTArray<RefPtr<nsAtom> > mIncludes;
147
};
148
149
} // namespace dom
150
} // namespace mozilla
151
152
class nsAnonymousContentList final : public nsINodeList
153
{
154
public:
155
  explicit nsAnonymousContentList(nsIContent* aParent)
156
    : mParent(aParent)
157
0
  {
158
0
  }
159
160
  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
161
  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsAnonymousContentList)
162
163
  // nsINodeList interface
164
  virtual int32_t IndexOf(nsIContent* aContent) override;
165
0
  virtual nsINode* GetParentObject() override { return mParent; }
166
  virtual nsIContent* Item(uint32_t aIndex) override;
167
  uint32_t Length() override;
168
169
  virtual JSObject* WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto) override;
170
171
0
  bool IsListFor(nsIContent* aContent) {
172
0
    return mParent == aContent;
173
0
  }
174
175
private:
176
  virtual ~nsAnonymousContentList()
177
0
  {
178
0
  }
179
180
  nsCOMPtr<nsIContent> mParent;
181
};
182
183
#endif // nsXBLChildrenElement_h___