1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/content/base/public/FragmentOrElement.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,428 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +/* 1.10 + * Base class for all element classes as well as nsDocumentFragment. This 1.11 + * provides an implementation of nsIDOMNode, implements nsIContent, provides 1.12 + * utility methods for subclasses, and so forth. 1.13 + */ 1.14 + 1.15 +#ifndef FragmentOrElement_h___ 1.16 +#define FragmentOrElement_h___ 1.17 + 1.18 +#include "mozilla/Attributes.h" 1.19 +#include "mozilla/MemoryReporting.h" 1.20 +#include "nsAttrAndChildArray.h" // member 1.21 +#include "nsCycleCollectionParticipant.h" // NS_DECL_CYCLE_* 1.22 +#include "nsIContent.h" // base class 1.23 +#include "nsIDOMXPathNSResolver.h" // base class 1.24 +#include "nsINodeList.h" // base class 1.25 +#include "nsIWeakReference.h" // base class 1.26 +#include "nsNodeUtils.h" // class member nsNodeUtils::CloneNodeImpl 1.27 +#include "nsIHTMLCollection.h" 1.28 + 1.29 +class ContentUnbinder; 1.30 +class nsContentList; 1.31 +class nsDOMAttributeMap; 1.32 +class nsDOMTokenList; 1.33 +class nsIControllers; 1.34 +class nsICSSDeclaration; 1.35 +class nsIDocument; 1.36 +class nsDOMStringMap; 1.37 +class nsINodeInfo; 1.38 +class nsIURI; 1.39 + 1.40 +/** 1.41 + * Class that implements the nsIDOMNodeList interface (a list of children of 1.42 + * the content), by holding a reference to the content and delegating GetLength 1.43 + * and Item to its existing child list. 1.44 + * @see nsIDOMNodeList 1.45 + */ 1.46 +class nsChildContentList MOZ_FINAL : public nsINodeList 1.47 +{ 1.48 +public: 1.49 + nsChildContentList(nsINode* aNode) 1.50 + : mNode(aNode) 1.51 + { 1.52 + SetIsDOMBinding(); 1.53 + } 1.54 + 1.55 + NS_DECL_CYCLE_COLLECTING_ISUPPORTS 1.56 + NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS(nsChildContentList) 1.57 + 1.58 + // nsWrapperCache 1.59 + virtual JSObject* WrapObject(JSContext *cx) MOZ_OVERRIDE; 1.60 + 1.61 + // nsIDOMNodeList interface 1.62 + NS_DECL_NSIDOMNODELIST 1.63 + 1.64 + // nsINodeList interface 1.65 + virtual int32_t IndexOf(nsIContent* aContent) MOZ_OVERRIDE; 1.66 + virtual nsIContent* Item(uint32_t aIndex) MOZ_OVERRIDE; 1.67 + 1.68 + void DropReference() 1.69 + { 1.70 + mNode = nullptr; 1.71 + } 1.72 + 1.73 + virtual nsINode* GetParentObject() MOZ_OVERRIDE 1.74 + { 1.75 + return mNode; 1.76 + } 1.77 + 1.78 +private: 1.79 + // The node whose children make up the list (weak reference) 1.80 + nsINode* mNode; 1.81 +}; 1.82 + 1.83 +/** 1.84 + * A tearoff class for FragmentOrElement to implement additional interfaces 1.85 + */ 1.86 +class nsNode3Tearoff : public nsIDOMXPathNSResolver 1.87 +{ 1.88 +public: 1.89 + NS_DECL_CYCLE_COLLECTING_ISUPPORTS 1.90 + 1.91 + NS_DECL_CYCLE_COLLECTION_CLASS(nsNode3Tearoff) 1.92 + 1.93 + NS_DECL_NSIDOMXPATHNSRESOLVER 1.94 + 1.95 + nsNode3Tearoff(nsINode *aNode) : mNode(aNode) 1.96 + { 1.97 + } 1.98 + 1.99 +protected: 1.100 + virtual ~nsNode3Tearoff() {} 1.101 + 1.102 +private: 1.103 + nsCOMPtr<nsINode> mNode; 1.104 +}; 1.105 + 1.106 +/** 1.107 + * A class that implements nsIWeakReference 1.108 + */ 1.109 + 1.110 +class nsNodeWeakReference MOZ_FINAL : public nsIWeakReference 1.111 +{ 1.112 +public: 1.113 + nsNodeWeakReference(nsINode* aNode) 1.114 + : mNode(aNode) 1.115 + { 1.116 + } 1.117 + 1.118 + ~nsNodeWeakReference(); 1.119 + 1.120 + // nsISupports 1.121 + NS_DECL_ISUPPORTS 1.122 + 1.123 + // nsIWeakReference 1.124 + NS_DECL_NSIWEAKREFERENCE 1.125 + 1.126 + void NoticeNodeDestruction() 1.127 + { 1.128 + mNode = nullptr; 1.129 + } 1.130 + 1.131 +private: 1.132 + nsINode* mNode; 1.133 +}; 1.134 + 1.135 +/** 1.136 + * Tearoff to use for nodes to implement nsISupportsWeakReference 1.137 + */ 1.138 +class nsNodeSupportsWeakRefTearoff MOZ_FINAL : public nsISupportsWeakReference 1.139 +{ 1.140 +public: 1.141 + nsNodeSupportsWeakRefTearoff(nsINode* aNode) 1.142 + : mNode(aNode) 1.143 + { 1.144 + } 1.145 + 1.146 + // nsISupports 1.147 + NS_DECL_CYCLE_COLLECTING_ISUPPORTS 1.148 + 1.149 + // nsISupportsWeakReference 1.150 + NS_DECL_NSISUPPORTSWEAKREFERENCE 1.151 + 1.152 + NS_DECL_CYCLE_COLLECTION_CLASS(nsNodeSupportsWeakRefTearoff) 1.153 + 1.154 +private: 1.155 + nsCOMPtr<nsINode> mNode; 1.156 +}; 1.157 + 1.158 +/** 1.159 + * A generic base class for DOM elements, implementing many nsIContent, 1.160 + * nsIDOMNode and nsIDOMElement methods. 1.161 + */ 1.162 +namespace mozilla { 1.163 +namespace dom { 1.164 + 1.165 +class ShadowRoot; 1.166 +class UndoManager; 1.167 + 1.168 +class FragmentOrElement : public nsIContent 1.169 +{ 1.170 +public: 1.171 + FragmentOrElement(already_AddRefed<nsINodeInfo>& aNodeInfo); 1.172 + FragmentOrElement(already_AddRefed<nsINodeInfo>&& aNodeInfo); 1.173 + virtual ~FragmentOrElement(); 1.174 + 1.175 + NS_DECL_CYCLE_COLLECTING_ISUPPORTS 1.176 + 1.177 + NS_DECL_SIZEOF_EXCLUDING_THIS 1.178 + 1.179 + // nsINode interface methods 1.180 + virtual uint32_t GetChildCount() const MOZ_OVERRIDE; 1.181 + virtual nsIContent *GetChildAt(uint32_t aIndex) const MOZ_OVERRIDE; 1.182 + virtual nsIContent * const * GetChildArray(uint32_t* aChildCount) const MOZ_OVERRIDE; 1.183 + virtual int32_t IndexOf(const nsINode* aPossibleChild) const MOZ_OVERRIDE; 1.184 + virtual nsresult InsertChildAt(nsIContent* aKid, uint32_t aIndex, 1.185 + bool aNotify) MOZ_OVERRIDE; 1.186 + virtual void RemoveChildAt(uint32_t aIndex, bool aNotify) MOZ_OVERRIDE; 1.187 + virtual void GetTextContentInternal(nsAString& aTextContent) MOZ_OVERRIDE; 1.188 + virtual void SetTextContentInternal(const nsAString& aTextContent, 1.189 + mozilla::ErrorResult& aError) MOZ_OVERRIDE; 1.190 + 1.191 + // nsIContent interface methods 1.192 + virtual already_AddRefed<nsINodeList> GetChildren(uint32_t aFilter) MOZ_OVERRIDE; 1.193 + virtual const nsTextFragment *GetText() MOZ_OVERRIDE; 1.194 + virtual uint32_t TextLength() const MOZ_OVERRIDE; 1.195 + virtual nsresult SetText(const char16_t* aBuffer, uint32_t aLength, 1.196 + bool aNotify) MOZ_OVERRIDE; 1.197 + // Need to implement this here too to avoid hiding. 1.198 + nsresult SetText(const nsAString& aStr, bool aNotify) 1.199 + { 1.200 + return SetText(aStr.BeginReading(), aStr.Length(), aNotify); 1.201 + } 1.202 + virtual nsresult AppendText(const char16_t* aBuffer, uint32_t aLength, 1.203 + bool aNotify) MOZ_OVERRIDE; 1.204 + virtual bool TextIsOnlyWhitespace() MOZ_OVERRIDE; 1.205 + virtual bool HasTextForTranslation() MOZ_OVERRIDE; 1.206 + virtual void AppendTextTo(nsAString& aResult) MOZ_OVERRIDE; 1.207 + virtual bool AppendTextTo(nsAString& aResult, 1.208 + const mozilla::fallible_t&) MOZ_OVERRIDE NS_WARN_UNUSED_RESULT; 1.209 + virtual nsIContent *GetBindingParent() const MOZ_OVERRIDE; 1.210 + virtual nsXBLBinding *GetXBLBinding() const MOZ_OVERRIDE; 1.211 + virtual void SetXBLBinding(nsXBLBinding* aBinding, 1.212 + nsBindingManager* aOldBindingManager = nullptr) MOZ_OVERRIDE; 1.213 + virtual ShadowRoot *GetShadowRoot() const MOZ_OVERRIDE; 1.214 + virtual ShadowRoot *GetContainingShadow() const MOZ_OVERRIDE; 1.215 + virtual void SetShadowRoot(ShadowRoot* aBinding) MOZ_OVERRIDE; 1.216 + virtual nsIContent *GetXBLInsertionParent() const MOZ_OVERRIDE; 1.217 + virtual void SetXBLInsertionParent(nsIContent* aContent) MOZ_OVERRIDE; 1.218 + virtual bool IsLink(nsIURI** aURI) const MOZ_OVERRIDE; 1.219 + 1.220 + virtual CustomElementData *GetCustomElementData() const MOZ_OVERRIDE; 1.221 + virtual void SetCustomElementData(CustomElementData* aData) MOZ_OVERRIDE; 1.222 + 1.223 + virtual void DestroyContent() MOZ_OVERRIDE; 1.224 + virtual void SaveSubtreeState() MOZ_OVERRIDE; 1.225 + 1.226 + virtual const nsAttrValue* DoGetClasses() const MOZ_OVERRIDE; 1.227 + NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker) MOZ_OVERRIDE; 1.228 + 1.229 + nsIHTMLCollection* Children(); 1.230 + uint32_t ChildElementCount() 1.231 + { 1.232 + return Children()->Length(); 1.233 + } 1.234 + 1.235 +public: 1.236 + /** 1.237 + * If there are listeners for DOMNodeInserted event, fires the event on all 1.238 + * aNodes 1.239 + */ 1.240 + static void FireNodeInserted(nsIDocument* aDoc, 1.241 + nsINode* aParent, 1.242 + nsTArray<nsCOMPtr<nsIContent> >& aNodes); 1.243 + 1.244 + NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS(FragmentOrElement) 1.245 + 1.246 + /** 1.247 + * Fire a DOMNodeRemoved mutation event for all children of this node 1.248 + */ 1.249 + void FireNodeRemovedForChildren(); 1.250 + 1.251 + virtual bool OwnedOnlyByTheDOMTree() MOZ_OVERRIDE 1.252 + { 1.253 + uint32_t rc = mRefCnt.get(); 1.254 + if (GetParent()) { 1.255 + --rc; 1.256 + } 1.257 + rc -= mAttrsAndChildren.ChildCount(); 1.258 + return rc == 0; 1.259 + } 1.260 + 1.261 + virtual bool IsPurple() MOZ_OVERRIDE 1.262 + { 1.263 + return mRefCnt.IsPurple(); 1.264 + } 1.265 + 1.266 + virtual void RemovePurple() MOZ_OVERRIDE 1.267 + { 1.268 + mRefCnt.RemovePurple(); 1.269 + } 1.270 + 1.271 + static void ClearContentUnbinder(); 1.272 + static bool CanSkip(nsINode* aNode, bool aRemovingAllowed); 1.273 + static bool CanSkipInCC(nsINode* aNode); 1.274 + static bool CanSkipThis(nsINode* aNode); 1.275 + static void RemoveBlackMarkedNode(nsINode* aNode); 1.276 + static void MarkNodeChildren(nsINode* aNode); 1.277 + static void InitCCCallbacks(); 1.278 + static void MarkUserData(void* aObject, nsIAtom* aKey, void* aChild, 1.279 + void *aData); 1.280 + static void MarkUserDataHandler(void* aObject, nsIAtom* aKey, void* aChild, 1.281 + void* aData); 1.282 + 1.283 +protected: 1.284 + /** 1.285 + * Copy attributes and state to another element 1.286 + * @param aDest the object to copy to 1.287 + */ 1.288 + nsresult CopyInnerTo(FragmentOrElement* aDest); 1.289 + 1.290 +public: 1.291 + // Because of a bug in MS C++ compiler nsDOMSlots must be declared public, 1.292 + // otherwise nsXULElement::nsXULSlots doesn't compile. 1.293 + /** 1.294 + * There are a set of DOM- and scripting-specific instance variables 1.295 + * that may only be instantiated when a content object is accessed 1.296 + * through the DOM. Rather than burn actual slots in the content 1.297 + * objects for each of these instance variables, we put them off 1.298 + * in a side structure that's only allocated when the content is 1.299 + * accessed through the DOM. 1.300 + */ 1.301 + class nsDOMSlots : public nsINode::nsSlots 1.302 + { 1.303 + public: 1.304 + nsDOMSlots(); 1.305 + virtual ~nsDOMSlots(); 1.306 + 1.307 + void Traverse(nsCycleCollectionTraversalCallback &cb, bool aIsXUL); 1.308 + void Unlink(bool aIsXUL); 1.309 + 1.310 + size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; 1.311 + 1.312 + /** 1.313 + * The .style attribute (an interface that forwards to the actual 1.314 + * style rules) 1.315 + * @see nsGenericHTMLElement::GetStyle 1.316 + */ 1.317 + nsCOMPtr<nsICSSDeclaration> mStyle; 1.318 + 1.319 + /** 1.320 + * The .dataset attribute. 1.321 + * @see nsGenericHTMLElement::GetDataset 1.322 + */ 1.323 + nsDOMStringMap* mDataset; // [Weak] 1.324 + 1.325 + /** 1.326 + * The .undoManager property. 1.327 + * @see nsGenericHTMLElement::GetUndoManager 1.328 + */ 1.329 + nsRefPtr<UndoManager> mUndoManager; 1.330 + 1.331 + /** 1.332 + * SMIL Overridde style rules (for SMIL animation of CSS properties) 1.333 + * @see nsIContent::GetSMILOverrideStyle 1.334 + */ 1.335 + nsCOMPtr<nsICSSDeclaration> mSMILOverrideStyle; 1.336 + 1.337 + /** 1.338 + * Holds any SMIL override style rules for this element. 1.339 + */ 1.340 + nsRefPtr<mozilla::css::StyleRule> mSMILOverrideStyleRule; 1.341 + 1.342 + /** 1.343 + * An object implementing nsIDOMMozNamedAttrMap for this content (attributes) 1.344 + * @see FragmentOrElement::GetAttributes 1.345 + */ 1.346 + nsRefPtr<nsDOMAttributeMap> mAttributeMap; 1.347 + 1.348 + union { 1.349 + /** 1.350 + * The nearest enclosing content node with a binding that created us. 1.351 + * @see FragmentOrElement::GetBindingParent 1.352 + */ 1.353 + nsIContent* mBindingParent; // [Weak] 1.354 + 1.355 + /** 1.356 + * The controllers of the XUL Element. 1.357 + */ 1.358 + nsIControllers* mControllers; // [OWNER] 1.359 + }; 1.360 + 1.361 + /** 1.362 + * An object implementing the .children property for this element. 1.363 + */ 1.364 + nsRefPtr<nsContentList> mChildrenList; 1.365 + 1.366 + /** 1.367 + * An object implementing the .classList property for this element. 1.368 + */ 1.369 + nsRefPtr<nsDOMTokenList> mClassList; 1.370 + 1.371 + /** 1.372 + * ShadowRoot bound to the element. 1.373 + */ 1.374 + nsRefPtr<ShadowRoot> mShadowRoot; 1.375 + 1.376 + /** 1.377 + * The root ShadowRoot of this element if it is in a shadow tree. 1.378 + */ 1.379 + nsRefPtr<ShadowRoot> mContainingShadow; 1.380 + 1.381 + /** 1.382 + * XBL binding installed on the element. 1.383 + */ 1.384 + nsRefPtr<nsXBLBinding> mXBLBinding; 1.385 + 1.386 + /** 1.387 + * XBL binding installed on the lement. 1.388 + */ 1.389 + nsCOMPtr<nsIContent> mXBLInsertionParent; 1.390 + 1.391 + /** 1.392 + * Web components custom element data. 1.393 + */ 1.394 + nsAutoPtr<CustomElementData> mCustomElementData; 1.395 + }; 1.396 + 1.397 +protected: 1.398 + void GetMarkup(bool aIncludeSelf, nsAString& aMarkup); 1.399 + void SetInnerHTMLInternal(const nsAString& aInnerHTML, ErrorResult& aError); 1.400 + 1.401 + // Override from nsINode 1.402 + virtual nsINode::nsSlots* CreateSlots() MOZ_OVERRIDE; 1.403 + 1.404 + nsDOMSlots *DOMSlots() 1.405 + { 1.406 + return static_cast<nsDOMSlots*>(Slots()); 1.407 + } 1.408 + 1.409 + nsDOMSlots *GetExistingDOMSlots() const 1.410 + { 1.411 + return static_cast<nsDOMSlots*>(GetExistingSlots()); 1.412 + } 1.413 + 1.414 + friend class ::ContentUnbinder; 1.415 + /** 1.416 + * Array containing all attributes and children for this element 1.417 + */ 1.418 + nsAttrAndChildArray mAttrsAndChildren; 1.419 +}; 1.420 + 1.421 +} // namespace dom 1.422 +} // namespace mozilla 1.423 + 1.424 +#define NS_ELEMENT_INTERFACE_TABLE_TO_MAP_SEGUE \ 1.425 + if (NS_SUCCEEDED(rv)) \ 1.426 + return rv; \ 1.427 + \ 1.428 + rv = FragmentOrElement::QueryInterface(aIID, aInstancePtr); \ 1.429 + NS_INTERFACE_TABLE_TO_MAP_SEGUE 1.430 + 1.431 +#endif /* FragmentOrElement_h___ */