1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/content/base/src/nsNodeUtils.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,302 @@ 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 +#ifndef nsNodeUtils_h___ 1.10 +#define nsNodeUtils_h___ 1.11 + 1.12 +#include "nsIContent.h" // for use in inline function (ParentChainChanged) 1.13 +#include "nsIMutationObserver.h" // for use in inline function (ParentChainChanged) 1.14 +#include "js/TypeDecls.h" 1.15 +#include "nsCOMArray.h" 1.16 + 1.17 +struct CharacterDataChangeInfo; 1.18 +class nsIVariant; 1.19 +class nsIDOMNode; 1.20 +class nsIDOMUserDataHandler; 1.21 +template<class E> class nsCOMArray; 1.22 +class nsCycleCollectionTraversalCallback; 1.23 + 1.24 +class nsNodeUtils 1.25 +{ 1.26 +public: 1.27 + /** 1.28 + * Send CharacterDataWillChange notifications to nsIMutationObservers. 1.29 + * @param aContent Node whose data changed 1.30 + * @param aInfo Struct with information details about the change 1.31 + * @see nsIMutationObserver::CharacterDataWillChange 1.32 + */ 1.33 + static void CharacterDataWillChange(nsIContent* aContent, 1.34 + CharacterDataChangeInfo* aInfo); 1.35 + 1.36 + /** 1.37 + * Send CharacterDataChanged notifications to nsIMutationObservers. 1.38 + * @param aContent Node whose data changed 1.39 + * @param aInfo Struct with information details about the change 1.40 + * @see nsIMutationObserver::CharacterDataChanged 1.41 + */ 1.42 + static void CharacterDataChanged(nsIContent* aContent, 1.43 + CharacterDataChangeInfo* aInfo); 1.44 + 1.45 + /** 1.46 + * Send AttributeWillChange notifications to nsIMutationObservers. 1.47 + * @param aElement Element whose data will change 1.48 + * @param aNameSpaceID Namespace of changing attribute 1.49 + * @param aAttribute Local-name of changing attribute 1.50 + * @param aModType Type of change (add/change/removal) 1.51 + * @see nsIMutationObserver::AttributeWillChange 1.52 + */ 1.53 + static void AttributeWillChange(mozilla::dom::Element* aElement, 1.54 + int32_t aNameSpaceID, 1.55 + nsIAtom* aAttribute, 1.56 + int32_t aModType); 1.57 + 1.58 + /** 1.59 + * Send AttributeChanged notifications to nsIMutationObservers. 1.60 + * @param aElement Element whose data changed 1.61 + * @param aNameSpaceID Namespace of changed attribute 1.62 + * @param aAttribute Local-name of changed attribute 1.63 + * @param aModType Type of change (add/change/removal) 1.64 + * @see nsIMutationObserver::AttributeChanged 1.65 + */ 1.66 + static void AttributeChanged(mozilla::dom::Element* aElement, 1.67 + int32_t aNameSpaceID, 1.68 + nsIAtom* aAttribute, 1.69 + int32_t aModType); 1.70 + /** 1.71 + * Send AttributeSetToCurrentValue notifications to nsIMutationObservers. 1.72 + * @param aElement Element whose data changed 1.73 + * @param aNameSpaceID Namespace of the attribute 1.74 + * @param aAttribute Local-name of the attribute 1.75 + * @see nsIMutationObserver::AttributeSetToCurrentValue 1.76 + */ 1.77 + static void AttributeSetToCurrentValue(mozilla::dom::Element* aElement, 1.78 + int32_t aNameSpaceID, 1.79 + nsIAtom* aAttribute); 1.80 + 1.81 + /** 1.82 + * Send ContentAppended notifications to nsIMutationObservers 1.83 + * @param aContainer Node into which new child/children were added 1.84 + * @param aFirstNewContent First new child 1.85 + * @param aNewIndexInContainer Index of first new child 1.86 + * @see nsIMutationObserver::ContentAppended 1.87 + */ 1.88 + static void ContentAppended(nsIContent* aContainer, 1.89 + nsIContent* aFirstNewContent, 1.90 + int32_t aNewIndexInContainer); 1.91 + 1.92 + /** 1.93 + * Send ContentInserted notifications to nsIMutationObservers 1.94 + * @param aContainer Node into which new child was inserted 1.95 + * @param aChild Newly inserted child 1.96 + * @param aIndexInContainer Index of new child 1.97 + * @see nsIMutationObserver::ContentInserted 1.98 + */ 1.99 + static void ContentInserted(nsINode* aContainer, 1.100 + nsIContent* aChild, 1.101 + int32_t aIndexInContainer); 1.102 + /** 1.103 + * Send ContentRemoved notifications to nsIMutationObservers 1.104 + * @param aContainer Node from which child was removed 1.105 + * @param aChild Removed child 1.106 + * @param aIndexInContainer Index of removed child 1.107 + * @see nsIMutationObserver::ContentRemoved 1.108 + */ 1.109 + static void ContentRemoved(nsINode* aContainer, 1.110 + nsIContent* aChild, 1.111 + int32_t aIndexInContainer, 1.112 + nsIContent* aPreviousSibling); 1.113 + /** 1.114 + * Send ParentChainChanged notifications to nsIMutationObservers 1.115 + * @param aContent The piece of content that had its parent changed. 1.116 + * @see nsIMutationObserver::ParentChainChanged 1.117 + */ 1.118 + static inline void ParentChainChanged(nsIContent *aContent) 1.119 + { 1.120 + nsINode::nsSlots* slots = aContent->GetExistingSlots(); 1.121 + if (slots && !slots->mMutationObservers.IsEmpty()) { 1.122 + NS_OBSERVER_ARRAY_NOTIFY_OBSERVERS(slots->mMutationObservers, 1.123 + nsIMutationObserver, 1.124 + ParentChainChanged, 1.125 + (aContent)); 1.126 + } 1.127 + } 1.128 + 1.129 + /** 1.130 + * To be called when reference count of aNode drops to zero. 1.131 + * @param aNode The node which is going to be deleted. 1.132 + */ 1.133 + static void LastRelease(nsINode* aNode); 1.134 + 1.135 + /** 1.136 + * Clones aNode, its attributes and, if aDeep is true, its descendant nodes 1.137 + * If aNewNodeInfoManager is not null, it is used to create new nodeinfos for 1.138 + * the clones. aNodesWithProperties will be filled with all the nodes that 1.139 + * have properties, and every node in it will be followed by its clone. 1.140 + * 1.141 + * @param aNode Node to clone. 1.142 + * @param aDeep If true the function will be called recursively on 1.143 + * descendants of the node 1.144 + * @param aNewNodeInfoManager The nodeinfo manager to use to create new 1.145 + * nodeinfos for aNode and its attributes and 1.146 + * descendants. May be null if the nodeinfos 1.147 + * shouldn't be changed. 1.148 + * @param aNodesWithProperties All nodes (from amongst aNode and its 1.149 + * descendants) with properties. Every node will 1.150 + * be followed by its clone. 1.151 + * @param aResult *aResult will contain the cloned node. 1.152 + */ 1.153 + static nsresult Clone(nsINode *aNode, bool aDeep, 1.154 + nsNodeInfoManager *aNewNodeInfoManager, 1.155 + nsCOMArray<nsINode> &aNodesWithProperties, 1.156 + nsINode **aResult) 1.157 + { 1.158 + return CloneAndAdopt(aNode, true, aDeep, aNewNodeInfoManager, 1.159 + JS::NullPtr(), aNodesWithProperties, nullptr, aResult); 1.160 + } 1.161 + 1.162 + /** 1.163 + * Clones aNode, its attributes and, if aDeep is true, its descendant nodes 1.164 + */ 1.165 + static nsresult Clone(nsINode *aNode, bool aDeep, nsINode **aResult) 1.166 + { 1.167 + nsCOMArray<nsINode> dummyNodeWithProperties; 1.168 + return CloneAndAdopt(aNode, true, aDeep, nullptr, JS::NullPtr(), 1.169 + dummyNodeWithProperties, aNode->GetParent(), aResult); 1.170 + } 1.171 + 1.172 + /** 1.173 + * Walks aNode, its attributes and descendant nodes. If aNewNodeInfoManager is 1.174 + * not null, it is used to create new nodeinfos for the nodes. Also reparents 1.175 + * the XPConnect wrappers for the nodes into aReparentScope if non-null. 1.176 + * aNodesWithProperties will be filled with all the nodes that have 1.177 + * properties. 1.178 + * 1.179 + * @param aNode Node to adopt. 1.180 + * @param aNewNodeInfoManager The nodeinfo manager to use to create new 1.181 + * nodeinfos for aNode and its attributes and 1.182 + * descendants. May be null if the nodeinfos 1.183 + * shouldn't be changed. 1.184 + * @param aReparentScope New scope for the wrappers, or null if no reparenting 1.185 + * should be done. 1.186 + * @param aNodesWithProperties All nodes (from amongst aNode and its 1.187 + * descendants) with properties. 1.188 + */ 1.189 + static nsresult Adopt(nsINode *aNode, nsNodeInfoManager *aNewNodeInfoManager, 1.190 + JS::Handle<JSObject*> aReparentScope, 1.191 + nsCOMArray<nsINode> &aNodesWithProperties) 1.192 + { 1.193 + nsCOMPtr<nsINode> node; 1.194 + nsresult rv = CloneAndAdopt(aNode, false, true, aNewNodeInfoManager, 1.195 + aReparentScope, aNodesWithProperties, 1.196 + nullptr, getter_AddRefs(node)); 1.197 + 1.198 + nsMutationGuard::DidMutate(); 1.199 + 1.200 + return rv; 1.201 + } 1.202 + 1.203 + /** 1.204 + * Call registered userdata handlers for operation aOperation for the nodes in 1.205 + * aNodesWithProperties. If aCloned is true aNodesWithProperties should 1.206 + * contain both the original and the cloned nodes (and only the userdata 1.207 + * handlers registered for the original nodes will be called). 1.208 + * 1.209 + * @param aNodesWithProperties Contains the nodes that might have properties 1.210 + * registered on them. If aCloned is true every 1.211 + * one of those nodes should be immediately 1.212 + * followed in the array by the cloned node. 1.213 + * @param aOwnerDocument The ownerDocument of the original nodes. 1.214 + * @param aOperation The operation to call a userdata handler for. 1.215 + * @param aCloned If true aNodesWithProperties will contain both original 1.216 + * and cloned nodes. 1.217 + */ 1.218 + static nsresult CallUserDataHandlers(nsCOMArray<nsINode> &aNodesWithProperties, 1.219 + nsIDocument *aOwnerDocument, 1.220 + uint16_t aOperation, bool aCloned); 1.221 + 1.222 + /** 1.223 + * Helper for the cycle collector to traverse the DOM UserData and 1.224 + * UserDataHandlers for aNode. 1.225 + * 1.226 + * @param aNode the node to traverse UserData and UserDataHandlers for 1.227 + * @param aCb the cycle collection callback 1.228 + */ 1.229 + static void TraverseUserData(nsINode* aNode, 1.230 + nsCycleCollectionTraversalCallback &aCb); 1.231 + 1.232 + /** 1.233 + * A basic implementation of the DOM cloneNode method. Calls nsINode::Clone to 1.234 + * do the actual cloning of the node. 1.235 + * 1.236 + * @param aNode the node to clone 1.237 + * @param aDeep if true all descendants will be cloned too 1.238 + * @param aCallUserDataHandlers if true, user data handlers will be called 1.239 + * @param aResult the clone 1.240 + */ 1.241 + static nsresult CloneNodeImpl(nsINode *aNode, bool aDeep, 1.242 + bool aCallUserDataHandlers, 1.243 + nsINode **aResult); 1.244 + 1.245 + /** 1.246 + * Release the UserData and UserDataHandlers for aNode. 1.247 + * 1.248 + * @param aNode the node to release the UserData and UserDataHandlers for 1.249 + */ 1.250 + static void UnlinkUserData(nsINode *aNode); 1.251 + 1.252 + /** 1.253 + * Returns a true if the node is a HTMLTemplate element. 1.254 + * 1.255 + * @param aNode a node to test for HTMLTemplate elementness. 1.256 + */ 1.257 + static bool IsTemplateElement(const nsINode *aNode); 1.258 + 1.259 + /** 1.260 + * Returns the first child of a node or the first child of 1.261 + * a template element's content if the provided node is a 1.262 + * template element. 1.263 + * 1.264 + * @param aNode A node from which to retrieve the first child. 1.265 + */ 1.266 + static nsIContent* GetFirstChildOfTemplateOrNode(nsINode* aNode); 1.267 + 1.268 +private: 1.269 + /** 1.270 + * Walks aNode, its attributes and, if aDeep is true, its descendant nodes. 1.271 + * If aClone is true the nodes will be cloned. If aNewNodeInfoManager is 1.272 + * not null, it is used to create new nodeinfos for the nodes. Also reparents 1.273 + * the XPConnect wrappers for the nodes into aReparentScope if non-null. 1.274 + * aNodesWithProperties will be filled with all the nodes that have 1.275 + * properties. 1.276 + * 1.277 + * @param aNode Node to adopt/clone. 1.278 + * @param aClone If true the node will be cloned and the cloned node will 1.279 + * be in aResult. 1.280 + * @param aDeep If true the function will be called recursively on 1.281 + * descendants of the node 1.282 + * @param aNewNodeInfoManager The nodeinfo manager to use to create new 1.283 + * nodeinfos for aNode and its attributes and 1.284 + * descendants. May be null if the nodeinfos 1.285 + * shouldn't be changed. 1.286 + * @param aReparentScope Scope into which wrappers should be reparented, or 1.287 + * null if no reparenting should be done. 1.288 + * @param aNodesWithProperties All nodes (from amongst aNode and its 1.289 + * descendants) with properties. If aClone is 1.290 + * true every node will be followed by its 1.291 + * clone. 1.292 + * @param aParent If aClone is true the cloned node will be appended to 1.293 + * aParent's children. May be null. If not null then aNode 1.294 + * must be an nsIContent. 1.295 + * @param aResult If aClone is true then *aResult will contain the cloned 1.296 + * node. 1.297 + */ 1.298 + static nsresult CloneAndAdopt(nsINode *aNode, bool aClone, bool aDeep, 1.299 + nsNodeInfoManager *aNewNodeInfoManager, 1.300 + JS::Handle<JSObject*> aReparentScope, 1.301 + nsCOMArray<nsINode> &aNodesWithProperties, 1.302 + nsINode *aParent, nsINode **aResult); 1.303 +}; 1.304 + 1.305 +#endif // nsNodeUtils_h___