Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dist/include/mozilla/dom/FragmentOrElement.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
/*
8
 * Base class for all element classes as well as nsDocumentFragment.  This
9
 * provides an implementation of nsINode, implements nsIContent, provides
10
 * utility methods for subclasses, and so forth.
11
 */
12
13
#ifndef FragmentOrElement_h___
14
#define FragmentOrElement_h___
15
16
#include "mozilla/Attributes.h"
17
#include "mozilla/MemoryReporting.h"
18
#include "mozilla/UniquePtr.h"
19
#include "AttrArray.h"                    // member
20
#include "nsCycleCollectionParticipant.h" // NS_DECL_CYCLE_*
21
#include "nsIContent.h"                   // base class
22
#include "nsNodeUtils.h"                  // class member nsNodeUtils::CloneNodeImpl
23
#include "nsIHTMLCollection.h"
24
#include "nsDataHashtable.h"
25
#include "nsXBLBinding.h"
26
27
class ContentUnbinder;
28
class nsContentList;
29
class nsLabelsNodeList;
30
class nsDOMAttributeMap;
31
class nsDOMTokenList;
32
class nsIControllers;
33
class nsICSSDeclaration;
34
class nsDOMCSSAttributeDeclaration;
35
class nsIDocument;
36
class nsDOMStringMap;
37
class nsIURI;
38
39
namespace mozilla {
40
class DeclarationBlock;
41
namespace dom {
42
struct CustomElementData;
43
class Element;
44
} // namespace dom
45
} // namespace mozilla
46
47
/**
48
 * Tearoff to use for nodes to implement nsISupportsWeakReference
49
 */
50
class nsNodeSupportsWeakRefTearoff final : public nsISupportsWeakReference
51
{
52
public:
53
  explicit nsNodeSupportsWeakRefTearoff(nsINode* aNode)
54
    : mNode(aNode)
55
0
  {
56
0
  }
57
58
  // nsISupports
59
  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
60
61
  // nsISupportsWeakReference
62
  NS_DECL_NSISUPPORTSWEAKREFERENCE
63
64
  NS_DECL_CYCLE_COLLECTION_CLASS(nsNodeSupportsWeakRefTearoff)
65
66
private:
67
0
  ~nsNodeSupportsWeakRefTearoff() {}
68
69
  nsCOMPtr<nsINode> mNode;
70
};
71
72
/**
73
 * A generic base class for DOM elements and document fragments,
74
 * implementing many nsIContent, nsINode and Element methods.
75
 */
76
namespace mozilla {
77
namespace dom {
78
79
class ShadowRoot;
80
81
class FragmentOrElement : public nsIContent
82
{
83
public:
84
  explicit FragmentOrElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
85
  explicit FragmentOrElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
86
87
  // We want to avoid the overhead of extra function calls for
88
  // refcounting when we're not doing refcount logging, so we can't
89
  // NS_DECL_ISUPPORTS_INHERITED.
90
  NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) override;
91
  NS_INLINE_DECL_REFCOUNTING_INHERITED(FragmentOrElement, nsIContent);
92
93
  NS_DECL_ADDSIZEOFEXCLUDINGTHIS
94
95
  // nsINode interface methods
96
  virtual void GetTextContentInternal(nsAString& aTextContent,
97
                                      mozilla::OOMReporter& aError) override;
98
  virtual void SetTextContentInternal(const nsAString& aTextContent,
99
                                      nsIPrincipal* aSubjectPrincipal,
100
                                      mozilla::ErrorResult& aError) override;
101
102
  // nsIContent interface methods
103
  virtual already_AddRefed<nsINodeList> GetChildren(uint32_t aFilter) override;
104
  virtual const nsTextFragment *GetText() override;
105
  virtual uint32_t TextLength() const override;
106
  virtual bool TextIsOnlyWhitespace() override;
107
  virtual bool ThreadSafeTextIsOnlyWhitespace() const override;
108
  virtual nsXBLBinding* DoGetXBLBinding() const override;
109
  virtual bool IsLink(nsIURI** aURI) const override;
110
111
  virtual void DestroyContent() override;
112
  virtual void SaveSubtreeState() override;
113
114
  nsIHTMLCollection* Children();
115
  uint32_t ChildElementCount()
116
0
  {
117
0
    return Children()->Length();
118
0
  }
119
120
public:
121
  /**
122
   * If there are listeners for DOMNodeInserted event, fires the event on all
123
   * aNodes
124
   */
125
  static void FireNodeInserted(nsIDocument* aDoc,
126
                               nsINode* aParent,
127
                               nsTArray<nsCOMPtr<nsIContent> >& aNodes);
128
129
  NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_INHERITED(FragmentOrElement,
130
                                                                   nsIContent)
131
132
  /**
133
   * Fire a DOMNodeRemoved mutation event for all children of this node
134
   */
135
  void FireNodeRemovedForChildren();
136
137
  static void ClearContentUnbinder();
138
  static bool CanSkip(nsINode* aNode, bool aRemovingAllowed);
139
  static bool CanSkipInCC(nsINode* aNode);
140
  static bool CanSkipThis(nsINode* aNode);
141
  static void RemoveBlackMarkedNode(nsINode* aNode);
142
  static void MarkNodeChildren(nsINode* aNode);
143
  static void InitCCCallbacks();
144
145
  /**
146
   * Is the HTML local name a void element?
147
   */
148
  static bool IsHTMLVoid(nsAtom* aLocalName);
149
protected:
150
  virtual ~FragmentOrElement();
151
152
  /**
153
   * Copy attributes and state to another element
154
   * @param aDest the object to copy to
155
   */
156
  nsresult CopyInnerTo(FragmentOrElement* aDest);
157
158
public:
159
  /**
160
   * There are a set of DOM- and scripting-specific instance variables
161
   * that may only be instantiated when a content object is accessed
162
   * through the DOM. Rather than burn actual slots in the content
163
   * objects for each of these instance variables, we put them off
164
   * in a side structure that's only allocated when the content is
165
   * accessed through the DOM.
166
   */
167
168
  class nsExtendedDOMSlots : public nsIContent::nsExtendedContentSlots
169
  {
170
  public:
171
    nsExtendedDOMSlots();
172
    ~nsExtendedDOMSlots();
173
174
    void TraverseExtendedSlots(nsCycleCollectionTraversalCallback&) final;
175
    void UnlinkExtendedSlots() final;
176
177
    size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const final;
178
179
    /**
180
     * SMIL Overridde style rules (for SMIL animation of CSS properties)
181
     * @see Element::GetSMILOverrideStyle
182
     */
183
    RefPtr<nsDOMCSSAttributeDeclaration> mSMILOverrideStyle;
184
185
    /**
186
     * Holds any SMIL override style declaration for this element.
187
     */
188
    RefPtr<DeclarationBlock> mSMILOverrideStyleDeclaration;
189
190
    /**
191
    * The controllers of the XUL Element.
192
    */
193
    nsCOMPtr<nsIControllers> mControllers;
194
195
    /**
196
     * An object implementing the .labels property for this element.
197
     */
198
    RefPtr<nsLabelsNodeList> mLabelsList;
199
200
    /**
201
     * ShadowRoot bound to the element.
202
     */
203
    RefPtr<ShadowRoot> mShadowRoot;
204
205
    /**
206
     * XBL binding installed on the element.
207
     */
208
    RefPtr<nsXBLBinding> mXBLBinding;
209
210
    /**
211
     * Web components custom element data.
212
     */
213
    RefPtr<CustomElementData> mCustomElementData;
214
  };
215
216
  class nsDOMSlots : public nsIContent::nsContentSlots
217
  {
218
  public:
219
    nsDOMSlots();
220
    ~nsDOMSlots();
221
222
    void Traverse(nsCycleCollectionTraversalCallback&) final;
223
    void Unlink() final;
224
225
    size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
226
227
    /**
228
     * The .style attribute (an interface that forwards to the actual
229
     * style rules)
230
     * @see nsGenericHTMLElement::GetStyle
231
     */
232
    nsCOMPtr<nsICSSDeclaration> mStyle;
233
234
    /**
235
     * The .dataset attribute.
236
     * @see nsGenericHTMLElement::GetDataset
237
     */
238
    nsDOMStringMap* mDataset; // [Weak]
239
240
    /**
241
     * @see Element::Attributes
242
     */
243
    RefPtr<nsDOMAttributeMap> mAttributeMap;
244
245
    /**
246
     * An object implementing the .children property for this element.
247
     */
248
    RefPtr<nsContentList> mChildrenList;
249
250
    /**
251
     * An object implementing the .classList property for this element.
252
     */
253
    RefPtr<nsDOMTokenList> mClassList;
254
  };
255
256
  /**
257
   * In case ExtendedDOMSlots is needed before normal DOMSlots, an instance of
258
   * FatSlots class, which combines those two slot types, is created.
259
   * This way we can avoid extra allocation for ExtendedDOMSlots.
260
   * FatSlots is useful for example when creating Custom Elements.
261
   */
262
  class FatSlots final : public nsDOMSlots, public nsExtendedDOMSlots
263
  {
264
  public:
265
    FatSlots()
266
      : nsDOMSlots()
267
      , nsExtendedDOMSlots()
268
0
    {
269
0
      MOZ_COUNT_CTOR(FatSlots);
270
0
      SetExtendedContentSlots(this, false);
271
0
    }
272
273
    ~FatSlots() final
274
0
    {
275
0
      MOZ_COUNT_DTOR(FatSlots);
276
0
    }
277
  };
278
279
protected:
280
  void GetMarkup(bool aIncludeSelf, nsAString& aMarkup);
281
  void SetInnerHTMLInternal(const nsAString& aInnerHTML, ErrorResult& aError);
282
283
  // Override from nsINode
284
  nsIContent::nsContentSlots* CreateSlots() override
285
0
  {
286
0
    return new nsDOMSlots();
287
0
  }
288
289
  nsIContent::nsExtendedContentSlots* CreateExtendedSlots() final
290
0
  {
291
0
    return new nsExtendedDOMSlots();
292
0
  }
293
294
  nsDOMSlots* DOMSlots()
295
0
  {
296
0
    return static_cast<nsDOMSlots*>(Slots());
297
0
  }
298
299
  nsDOMSlots *GetExistingDOMSlots() const
300
0
  {
301
0
    return static_cast<nsDOMSlots*>(GetExistingSlots());
302
0
  }
303
304
  nsExtendedDOMSlots* ExtendedDOMSlots()
305
0
  {
306
0
    nsContentSlots* slots = GetExistingContentSlots();
307
0
    if (!slots) {
308
0
      FatSlots* fatSlots = new FatSlots();
309
0
      mSlots = fatSlots;
310
0
      return fatSlots;
311
0
    }
312
0
313
0
    if (!slots->GetExtendedContentSlots()) {
314
0
      slots->SetExtendedContentSlots(CreateExtendedSlots(), true);
315
0
    }
316
0
317
0
    return static_cast<nsExtendedDOMSlots*>(slots->GetExtendedContentSlots());
318
0
  }
319
320
  const nsExtendedDOMSlots* GetExistingExtendedDOMSlots() const
321
0
  {
322
0
    return static_cast<const nsExtendedDOMSlots*>(
323
0
      GetExistingExtendedContentSlots());
324
0
  }
325
326
  nsExtendedDOMSlots* GetExistingExtendedDOMSlots()
327
0
  {
328
0
    return static_cast<nsExtendedDOMSlots*>(GetExistingExtendedContentSlots());
329
0
  }
330
331
  friend class ::ContentUnbinder;
332
  /**
333
   * Array containing all attributes for this element
334
   */
335
  AttrArray mAttrs;
336
};
337
338
} // namespace dom
339
} // namespace mozilla
340
341
#define NS_ELEMENT_INTERFACE_TABLE_TO_MAP_SEGUE                               \
342
0
    if (NS_SUCCEEDED(rv))                                                     \
343
0
      return rv;                                                              \
344
0
                                                                              \
345
0
    rv = FragmentOrElement::QueryInterface(aIID, aInstancePtr);               \
346
0
    NS_INTERFACE_TABLE_TO_MAP_SEGUE
347
348
#endif /* FragmentOrElement_h___ */