content/base/public/FragmentOrElement.h

branch
TOR_BUG_9701
changeset 9
a63d609f5ebe
equal deleted inserted replaced
-1:000000000000 0:e27f77a1768f
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6 /*
7 * Base class for all element classes as well as nsDocumentFragment. This
8 * provides an implementation of nsIDOMNode, implements nsIContent, provides
9 * utility methods for subclasses, and so forth.
10 */
11
12 #ifndef FragmentOrElement_h___
13 #define FragmentOrElement_h___
14
15 #include "mozilla/Attributes.h"
16 #include "mozilla/MemoryReporting.h"
17 #include "nsAttrAndChildArray.h" // member
18 #include "nsCycleCollectionParticipant.h" // NS_DECL_CYCLE_*
19 #include "nsIContent.h" // base class
20 #include "nsIDOMXPathNSResolver.h" // base class
21 #include "nsINodeList.h" // base class
22 #include "nsIWeakReference.h" // base class
23 #include "nsNodeUtils.h" // class member nsNodeUtils::CloneNodeImpl
24 #include "nsIHTMLCollection.h"
25
26 class ContentUnbinder;
27 class nsContentList;
28 class nsDOMAttributeMap;
29 class nsDOMTokenList;
30 class nsIControllers;
31 class nsICSSDeclaration;
32 class nsIDocument;
33 class nsDOMStringMap;
34 class nsINodeInfo;
35 class nsIURI;
36
37 /**
38 * Class that implements the nsIDOMNodeList interface (a list of children of
39 * the content), by holding a reference to the content and delegating GetLength
40 * and Item to its existing child list.
41 * @see nsIDOMNodeList
42 */
43 class nsChildContentList MOZ_FINAL : public nsINodeList
44 {
45 public:
46 nsChildContentList(nsINode* aNode)
47 : mNode(aNode)
48 {
49 SetIsDOMBinding();
50 }
51
52 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
53 NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS(nsChildContentList)
54
55 // nsWrapperCache
56 virtual JSObject* WrapObject(JSContext *cx) MOZ_OVERRIDE;
57
58 // nsIDOMNodeList interface
59 NS_DECL_NSIDOMNODELIST
60
61 // nsINodeList interface
62 virtual int32_t IndexOf(nsIContent* aContent) MOZ_OVERRIDE;
63 virtual nsIContent* Item(uint32_t aIndex) MOZ_OVERRIDE;
64
65 void DropReference()
66 {
67 mNode = nullptr;
68 }
69
70 virtual nsINode* GetParentObject() MOZ_OVERRIDE
71 {
72 return mNode;
73 }
74
75 private:
76 // The node whose children make up the list (weak reference)
77 nsINode* mNode;
78 };
79
80 /**
81 * A tearoff class for FragmentOrElement to implement additional interfaces
82 */
83 class nsNode3Tearoff : public nsIDOMXPathNSResolver
84 {
85 public:
86 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
87
88 NS_DECL_CYCLE_COLLECTION_CLASS(nsNode3Tearoff)
89
90 NS_DECL_NSIDOMXPATHNSRESOLVER
91
92 nsNode3Tearoff(nsINode *aNode) : mNode(aNode)
93 {
94 }
95
96 protected:
97 virtual ~nsNode3Tearoff() {}
98
99 private:
100 nsCOMPtr<nsINode> mNode;
101 };
102
103 /**
104 * A class that implements nsIWeakReference
105 */
106
107 class nsNodeWeakReference MOZ_FINAL : public nsIWeakReference
108 {
109 public:
110 nsNodeWeakReference(nsINode* aNode)
111 : mNode(aNode)
112 {
113 }
114
115 ~nsNodeWeakReference();
116
117 // nsISupports
118 NS_DECL_ISUPPORTS
119
120 // nsIWeakReference
121 NS_DECL_NSIWEAKREFERENCE
122
123 void NoticeNodeDestruction()
124 {
125 mNode = nullptr;
126 }
127
128 private:
129 nsINode* mNode;
130 };
131
132 /**
133 * Tearoff to use for nodes to implement nsISupportsWeakReference
134 */
135 class nsNodeSupportsWeakRefTearoff MOZ_FINAL : public nsISupportsWeakReference
136 {
137 public:
138 nsNodeSupportsWeakRefTearoff(nsINode* aNode)
139 : mNode(aNode)
140 {
141 }
142
143 // nsISupports
144 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
145
146 // nsISupportsWeakReference
147 NS_DECL_NSISUPPORTSWEAKREFERENCE
148
149 NS_DECL_CYCLE_COLLECTION_CLASS(nsNodeSupportsWeakRefTearoff)
150
151 private:
152 nsCOMPtr<nsINode> mNode;
153 };
154
155 /**
156 * A generic base class for DOM elements, implementing many nsIContent,
157 * nsIDOMNode and nsIDOMElement methods.
158 */
159 namespace mozilla {
160 namespace dom {
161
162 class ShadowRoot;
163 class UndoManager;
164
165 class FragmentOrElement : public nsIContent
166 {
167 public:
168 FragmentOrElement(already_AddRefed<nsINodeInfo>& aNodeInfo);
169 FragmentOrElement(already_AddRefed<nsINodeInfo>&& aNodeInfo);
170 virtual ~FragmentOrElement();
171
172 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
173
174 NS_DECL_SIZEOF_EXCLUDING_THIS
175
176 // nsINode interface methods
177 virtual uint32_t GetChildCount() const MOZ_OVERRIDE;
178 virtual nsIContent *GetChildAt(uint32_t aIndex) const MOZ_OVERRIDE;
179 virtual nsIContent * const * GetChildArray(uint32_t* aChildCount) const MOZ_OVERRIDE;
180 virtual int32_t IndexOf(const nsINode* aPossibleChild) const MOZ_OVERRIDE;
181 virtual nsresult InsertChildAt(nsIContent* aKid, uint32_t aIndex,
182 bool aNotify) MOZ_OVERRIDE;
183 virtual void RemoveChildAt(uint32_t aIndex, bool aNotify) MOZ_OVERRIDE;
184 virtual void GetTextContentInternal(nsAString& aTextContent) MOZ_OVERRIDE;
185 virtual void SetTextContentInternal(const nsAString& aTextContent,
186 mozilla::ErrorResult& aError) MOZ_OVERRIDE;
187
188 // nsIContent interface methods
189 virtual already_AddRefed<nsINodeList> GetChildren(uint32_t aFilter) MOZ_OVERRIDE;
190 virtual const nsTextFragment *GetText() MOZ_OVERRIDE;
191 virtual uint32_t TextLength() const MOZ_OVERRIDE;
192 virtual nsresult SetText(const char16_t* aBuffer, uint32_t aLength,
193 bool aNotify) MOZ_OVERRIDE;
194 // Need to implement this here too to avoid hiding.
195 nsresult SetText(const nsAString& aStr, bool aNotify)
196 {
197 return SetText(aStr.BeginReading(), aStr.Length(), aNotify);
198 }
199 virtual nsresult AppendText(const char16_t* aBuffer, uint32_t aLength,
200 bool aNotify) MOZ_OVERRIDE;
201 virtual bool TextIsOnlyWhitespace() MOZ_OVERRIDE;
202 virtual bool HasTextForTranslation() MOZ_OVERRIDE;
203 virtual void AppendTextTo(nsAString& aResult) MOZ_OVERRIDE;
204 virtual bool AppendTextTo(nsAString& aResult,
205 const mozilla::fallible_t&) MOZ_OVERRIDE NS_WARN_UNUSED_RESULT;
206 virtual nsIContent *GetBindingParent() const MOZ_OVERRIDE;
207 virtual nsXBLBinding *GetXBLBinding() const MOZ_OVERRIDE;
208 virtual void SetXBLBinding(nsXBLBinding* aBinding,
209 nsBindingManager* aOldBindingManager = nullptr) MOZ_OVERRIDE;
210 virtual ShadowRoot *GetShadowRoot() const MOZ_OVERRIDE;
211 virtual ShadowRoot *GetContainingShadow() const MOZ_OVERRIDE;
212 virtual void SetShadowRoot(ShadowRoot* aBinding) MOZ_OVERRIDE;
213 virtual nsIContent *GetXBLInsertionParent() const MOZ_OVERRIDE;
214 virtual void SetXBLInsertionParent(nsIContent* aContent) MOZ_OVERRIDE;
215 virtual bool IsLink(nsIURI** aURI) const MOZ_OVERRIDE;
216
217 virtual CustomElementData *GetCustomElementData() const MOZ_OVERRIDE;
218 virtual void SetCustomElementData(CustomElementData* aData) MOZ_OVERRIDE;
219
220 virtual void DestroyContent() MOZ_OVERRIDE;
221 virtual void SaveSubtreeState() MOZ_OVERRIDE;
222
223 virtual const nsAttrValue* DoGetClasses() const MOZ_OVERRIDE;
224 NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker) MOZ_OVERRIDE;
225
226 nsIHTMLCollection* Children();
227 uint32_t ChildElementCount()
228 {
229 return Children()->Length();
230 }
231
232 public:
233 /**
234 * If there are listeners for DOMNodeInserted event, fires the event on all
235 * aNodes
236 */
237 static void FireNodeInserted(nsIDocument* aDoc,
238 nsINode* aParent,
239 nsTArray<nsCOMPtr<nsIContent> >& aNodes);
240
241 NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS(FragmentOrElement)
242
243 /**
244 * Fire a DOMNodeRemoved mutation event for all children of this node
245 */
246 void FireNodeRemovedForChildren();
247
248 virtual bool OwnedOnlyByTheDOMTree() MOZ_OVERRIDE
249 {
250 uint32_t rc = mRefCnt.get();
251 if (GetParent()) {
252 --rc;
253 }
254 rc -= mAttrsAndChildren.ChildCount();
255 return rc == 0;
256 }
257
258 virtual bool IsPurple() MOZ_OVERRIDE
259 {
260 return mRefCnt.IsPurple();
261 }
262
263 virtual void RemovePurple() MOZ_OVERRIDE
264 {
265 mRefCnt.RemovePurple();
266 }
267
268 static void ClearContentUnbinder();
269 static bool CanSkip(nsINode* aNode, bool aRemovingAllowed);
270 static bool CanSkipInCC(nsINode* aNode);
271 static bool CanSkipThis(nsINode* aNode);
272 static void RemoveBlackMarkedNode(nsINode* aNode);
273 static void MarkNodeChildren(nsINode* aNode);
274 static void InitCCCallbacks();
275 static void MarkUserData(void* aObject, nsIAtom* aKey, void* aChild,
276 void *aData);
277 static void MarkUserDataHandler(void* aObject, nsIAtom* aKey, void* aChild,
278 void* aData);
279
280 protected:
281 /**
282 * Copy attributes and state to another element
283 * @param aDest the object to copy to
284 */
285 nsresult CopyInnerTo(FragmentOrElement* aDest);
286
287 public:
288 // Because of a bug in MS C++ compiler nsDOMSlots must be declared public,
289 // otherwise nsXULElement::nsXULSlots doesn't compile.
290 /**
291 * There are a set of DOM- and scripting-specific instance variables
292 * that may only be instantiated when a content object is accessed
293 * through the DOM. Rather than burn actual slots in the content
294 * objects for each of these instance variables, we put them off
295 * in a side structure that's only allocated when the content is
296 * accessed through the DOM.
297 */
298 class nsDOMSlots : public nsINode::nsSlots
299 {
300 public:
301 nsDOMSlots();
302 virtual ~nsDOMSlots();
303
304 void Traverse(nsCycleCollectionTraversalCallback &cb, bool aIsXUL);
305 void Unlink(bool aIsXUL);
306
307 size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
308
309 /**
310 * The .style attribute (an interface that forwards to the actual
311 * style rules)
312 * @see nsGenericHTMLElement::GetStyle
313 */
314 nsCOMPtr<nsICSSDeclaration> mStyle;
315
316 /**
317 * The .dataset attribute.
318 * @see nsGenericHTMLElement::GetDataset
319 */
320 nsDOMStringMap* mDataset; // [Weak]
321
322 /**
323 * The .undoManager property.
324 * @see nsGenericHTMLElement::GetUndoManager
325 */
326 nsRefPtr<UndoManager> mUndoManager;
327
328 /**
329 * SMIL Overridde style rules (for SMIL animation of CSS properties)
330 * @see nsIContent::GetSMILOverrideStyle
331 */
332 nsCOMPtr<nsICSSDeclaration> mSMILOverrideStyle;
333
334 /**
335 * Holds any SMIL override style rules for this element.
336 */
337 nsRefPtr<mozilla::css::StyleRule> mSMILOverrideStyleRule;
338
339 /**
340 * An object implementing nsIDOMMozNamedAttrMap for this content (attributes)
341 * @see FragmentOrElement::GetAttributes
342 */
343 nsRefPtr<nsDOMAttributeMap> mAttributeMap;
344
345 union {
346 /**
347 * The nearest enclosing content node with a binding that created us.
348 * @see FragmentOrElement::GetBindingParent
349 */
350 nsIContent* mBindingParent; // [Weak]
351
352 /**
353 * The controllers of the XUL Element.
354 */
355 nsIControllers* mControllers; // [OWNER]
356 };
357
358 /**
359 * An object implementing the .children property for this element.
360 */
361 nsRefPtr<nsContentList> mChildrenList;
362
363 /**
364 * An object implementing the .classList property for this element.
365 */
366 nsRefPtr<nsDOMTokenList> mClassList;
367
368 /**
369 * ShadowRoot bound to the element.
370 */
371 nsRefPtr<ShadowRoot> mShadowRoot;
372
373 /**
374 * The root ShadowRoot of this element if it is in a shadow tree.
375 */
376 nsRefPtr<ShadowRoot> mContainingShadow;
377
378 /**
379 * XBL binding installed on the element.
380 */
381 nsRefPtr<nsXBLBinding> mXBLBinding;
382
383 /**
384 * XBL binding installed on the lement.
385 */
386 nsCOMPtr<nsIContent> mXBLInsertionParent;
387
388 /**
389 * Web components custom element data.
390 */
391 nsAutoPtr<CustomElementData> mCustomElementData;
392 };
393
394 protected:
395 void GetMarkup(bool aIncludeSelf, nsAString& aMarkup);
396 void SetInnerHTMLInternal(const nsAString& aInnerHTML, ErrorResult& aError);
397
398 // Override from nsINode
399 virtual nsINode::nsSlots* CreateSlots() MOZ_OVERRIDE;
400
401 nsDOMSlots *DOMSlots()
402 {
403 return static_cast<nsDOMSlots*>(Slots());
404 }
405
406 nsDOMSlots *GetExistingDOMSlots() const
407 {
408 return static_cast<nsDOMSlots*>(GetExistingSlots());
409 }
410
411 friend class ::ContentUnbinder;
412 /**
413 * Array containing all attributes and children for this element
414 */
415 nsAttrAndChildArray mAttrsAndChildren;
416 };
417
418 } // namespace dom
419 } // namespace mozilla
420
421 #define NS_ELEMENT_INTERFACE_TABLE_TO_MAP_SEGUE \
422 if (NS_SUCCEEDED(rv)) \
423 return rv; \
424 \
425 rv = FragmentOrElement::QueryInterface(aIID, aInstancePtr); \
426 NS_INTERFACE_TABLE_TO_MAP_SEGUE
427
428 #endif /* FragmentOrElement_h___ */

mercurial