/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___ */ |