Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
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/. */
6 #ifndef nsNodeUtils_h___
7 #define nsNodeUtils_h___
9 #include "nsIContent.h" // for use in inline function (ParentChainChanged)
10 #include "nsIMutationObserver.h" // for use in inline function (ParentChainChanged)
11 #include "js/TypeDecls.h"
12 #include "nsCOMArray.h"
14 struct CharacterDataChangeInfo;
15 class nsIVariant;
16 class nsIDOMNode;
17 class nsIDOMUserDataHandler;
18 template<class E> class nsCOMArray;
19 class nsCycleCollectionTraversalCallback;
21 class nsNodeUtils
22 {
23 public:
24 /**
25 * Send CharacterDataWillChange notifications to nsIMutationObservers.
26 * @param aContent Node whose data changed
27 * @param aInfo Struct with information details about the change
28 * @see nsIMutationObserver::CharacterDataWillChange
29 */
30 static void CharacterDataWillChange(nsIContent* aContent,
31 CharacterDataChangeInfo* aInfo);
33 /**
34 * Send CharacterDataChanged notifications to nsIMutationObservers.
35 * @param aContent Node whose data changed
36 * @param aInfo Struct with information details about the change
37 * @see nsIMutationObserver::CharacterDataChanged
38 */
39 static void CharacterDataChanged(nsIContent* aContent,
40 CharacterDataChangeInfo* aInfo);
42 /**
43 * Send AttributeWillChange notifications to nsIMutationObservers.
44 * @param aElement Element whose data will change
45 * @param aNameSpaceID Namespace of changing attribute
46 * @param aAttribute Local-name of changing attribute
47 * @param aModType Type of change (add/change/removal)
48 * @see nsIMutationObserver::AttributeWillChange
49 */
50 static void AttributeWillChange(mozilla::dom::Element* aElement,
51 int32_t aNameSpaceID,
52 nsIAtom* aAttribute,
53 int32_t aModType);
55 /**
56 * Send AttributeChanged notifications to nsIMutationObservers.
57 * @param aElement Element whose data changed
58 * @param aNameSpaceID Namespace of changed attribute
59 * @param aAttribute Local-name of changed attribute
60 * @param aModType Type of change (add/change/removal)
61 * @see nsIMutationObserver::AttributeChanged
62 */
63 static void AttributeChanged(mozilla::dom::Element* aElement,
64 int32_t aNameSpaceID,
65 nsIAtom* aAttribute,
66 int32_t aModType);
67 /**
68 * Send AttributeSetToCurrentValue notifications to nsIMutationObservers.
69 * @param aElement Element whose data changed
70 * @param aNameSpaceID Namespace of the attribute
71 * @param aAttribute Local-name of the attribute
72 * @see nsIMutationObserver::AttributeSetToCurrentValue
73 */
74 static void AttributeSetToCurrentValue(mozilla::dom::Element* aElement,
75 int32_t aNameSpaceID,
76 nsIAtom* aAttribute);
78 /**
79 * Send ContentAppended notifications to nsIMutationObservers
80 * @param aContainer Node into which new child/children were added
81 * @param aFirstNewContent First new child
82 * @param aNewIndexInContainer Index of first new child
83 * @see nsIMutationObserver::ContentAppended
84 */
85 static void ContentAppended(nsIContent* aContainer,
86 nsIContent* aFirstNewContent,
87 int32_t aNewIndexInContainer);
89 /**
90 * Send ContentInserted notifications to nsIMutationObservers
91 * @param aContainer Node into which new child was inserted
92 * @param aChild Newly inserted child
93 * @param aIndexInContainer Index of new child
94 * @see nsIMutationObserver::ContentInserted
95 */
96 static void ContentInserted(nsINode* aContainer,
97 nsIContent* aChild,
98 int32_t aIndexInContainer);
99 /**
100 * Send ContentRemoved notifications to nsIMutationObservers
101 * @param aContainer Node from which child was removed
102 * @param aChild Removed child
103 * @param aIndexInContainer Index of removed child
104 * @see nsIMutationObserver::ContentRemoved
105 */
106 static void ContentRemoved(nsINode* aContainer,
107 nsIContent* aChild,
108 int32_t aIndexInContainer,
109 nsIContent* aPreviousSibling);
110 /**
111 * Send ParentChainChanged notifications to nsIMutationObservers
112 * @param aContent The piece of content that had its parent changed.
113 * @see nsIMutationObserver::ParentChainChanged
114 */
115 static inline void ParentChainChanged(nsIContent *aContent)
116 {
117 nsINode::nsSlots* slots = aContent->GetExistingSlots();
118 if (slots && !slots->mMutationObservers.IsEmpty()) {
119 NS_OBSERVER_ARRAY_NOTIFY_OBSERVERS(slots->mMutationObservers,
120 nsIMutationObserver,
121 ParentChainChanged,
122 (aContent));
123 }
124 }
126 /**
127 * To be called when reference count of aNode drops to zero.
128 * @param aNode The node which is going to be deleted.
129 */
130 static void LastRelease(nsINode* aNode);
132 /**
133 * Clones aNode, its attributes and, if aDeep is true, its descendant nodes
134 * If aNewNodeInfoManager is not null, it is used to create new nodeinfos for
135 * the clones. aNodesWithProperties will be filled with all the nodes that
136 * have properties, and every node in it will be followed by its clone.
137 *
138 * @param aNode Node to clone.
139 * @param aDeep If true the function will be called recursively on
140 * descendants of the node
141 * @param aNewNodeInfoManager The nodeinfo manager to use to create new
142 * nodeinfos for aNode and its attributes and
143 * descendants. May be null if the nodeinfos
144 * shouldn't be changed.
145 * @param aNodesWithProperties All nodes (from amongst aNode and its
146 * descendants) with properties. Every node will
147 * be followed by its clone.
148 * @param aResult *aResult will contain the cloned node.
149 */
150 static nsresult Clone(nsINode *aNode, bool aDeep,
151 nsNodeInfoManager *aNewNodeInfoManager,
152 nsCOMArray<nsINode> &aNodesWithProperties,
153 nsINode **aResult)
154 {
155 return CloneAndAdopt(aNode, true, aDeep, aNewNodeInfoManager,
156 JS::NullPtr(), aNodesWithProperties, nullptr, aResult);
157 }
159 /**
160 * Clones aNode, its attributes and, if aDeep is true, its descendant nodes
161 */
162 static nsresult Clone(nsINode *aNode, bool aDeep, nsINode **aResult)
163 {
164 nsCOMArray<nsINode> dummyNodeWithProperties;
165 return CloneAndAdopt(aNode, true, aDeep, nullptr, JS::NullPtr(),
166 dummyNodeWithProperties, aNode->GetParent(), aResult);
167 }
169 /**
170 * Walks aNode, its attributes and descendant nodes. If aNewNodeInfoManager is
171 * not null, it is used to create new nodeinfos for the nodes. Also reparents
172 * the XPConnect wrappers for the nodes into aReparentScope if non-null.
173 * aNodesWithProperties will be filled with all the nodes that have
174 * properties.
175 *
176 * @param aNode Node to adopt.
177 * @param aNewNodeInfoManager The nodeinfo manager to use to create new
178 * nodeinfos for aNode and its attributes and
179 * descendants. May be null if the nodeinfos
180 * shouldn't be changed.
181 * @param aReparentScope New scope for the wrappers, or null if no reparenting
182 * should be done.
183 * @param aNodesWithProperties All nodes (from amongst aNode and its
184 * descendants) with properties.
185 */
186 static nsresult Adopt(nsINode *aNode, nsNodeInfoManager *aNewNodeInfoManager,
187 JS::Handle<JSObject*> aReparentScope,
188 nsCOMArray<nsINode> &aNodesWithProperties)
189 {
190 nsCOMPtr<nsINode> node;
191 nsresult rv = CloneAndAdopt(aNode, false, true, aNewNodeInfoManager,
192 aReparentScope, aNodesWithProperties,
193 nullptr, getter_AddRefs(node));
195 nsMutationGuard::DidMutate();
197 return rv;
198 }
200 /**
201 * Call registered userdata handlers for operation aOperation for the nodes in
202 * aNodesWithProperties. If aCloned is true aNodesWithProperties should
203 * contain both the original and the cloned nodes (and only the userdata
204 * handlers registered for the original nodes will be called).
205 *
206 * @param aNodesWithProperties Contains the nodes that might have properties
207 * registered on them. If aCloned is true every
208 * one of those nodes should be immediately
209 * followed in the array by the cloned node.
210 * @param aOwnerDocument The ownerDocument of the original nodes.
211 * @param aOperation The operation to call a userdata handler for.
212 * @param aCloned If true aNodesWithProperties will contain both original
213 * and cloned nodes.
214 */
215 static nsresult CallUserDataHandlers(nsCOMArray<nsINode> &aNodesWithProperties,
216 nsIDocument *aOwnerDocument,
217 uint16_t aOperation, bool aCloned);
219 /**
220 * Helper for the cycle collector to traverse the DOM UserData and
221 * UserDataHandlers for aNode.
222 *
223 * @param aNode the node to traverse UserData and UserDataHandlers for
224 * @param aCb the cycle collection callback
225 */
226 static void TraverseUserData(nsINode* aNode,
227 nsCycleCollectionTraversalCallback &aCb);
229 /**
230 * A basic implementation of the DOM cloneNode method. Calls nsINode::Clone to
231 * do the actual cloning of the node.
232 *
233 * @param aNode the node to clone
234 * @param aDeep if true all descendants will be cloned too
235 * @param aCallUserDataHandlers if true, user data handlers will be called
236 * @param aResult the clone
237 */
238 static nsresult CloneNodeImpl(nsINode *aNode, bool aDeep,
239 bool aCallUserDataHandlers,
240 nsINode **aResult);
242 /**
243 * Release the UserData and UserDataHandlers for aNode.
244 *
245 * @param aNode the node to release the UserData and UserDataHandlers for
246 */
247 static void UnlinkUserData(nsINode *aNode);
249 /**
250 * Returns a true if the node is a HTMLTemplate element.
251 *
252 * @param aNode a node to test for HTMLTemplate elementness.
253 */
254 static bool IsTemplateElement(const nsINode *aNode);
256 /**
257 * Returns the first child of a node or the first child of
258 * a template element's content if the provided node is a
259 * template element.
260 *
261 * @param aNode A node from which to retrieve the first child.
262 */
263 static nsIContent* GetFirstChildOfTemplateOrNode(nsINode* aNode);
265 private:
266 /**
267 * Walks aNode, its attributes and, if aDeep is true, its descendant nodes.
268 * If aClone is true the nodes will be cloned. If aNewNodeInfoManager is
269 * not null, it is used to create new nodeinfos for the nodes. Also reparents
270 * the XPConnect wrappers for the nodes into aReparentScope if non-null.
271 * aNodesWithProperties will be filled with all the nodes that have
272 * properties.
273 *
274 * @param aNode Node to adopt/clone.
275 * @param aClone If true the node will be cloned and the cloned node will
276 * be in aResult.
277 * @param aDeep If true the function will be called recursively on
278 * descendants of the node
279 * @param aNewNodeInfoManager The nodeinfo manager to use to create new
280 * nodeinfos for aNode and its attributes and
281 * descendants. May be null if the nodeinfos
282 * shouldn't be changed.
283 * @param aReparentScope Scope into which wrappers should be reparented, or
284 * null if no reparenting should be done.
285 * @param aNodesWithProperties All nodes (from amongst aNode and its
286 * descendants) with properties. If aClone is
287 * true every node will be followed by its
288 * clone.
289 * @param aParent If aClone is true the cloned node will be appended to
290 * aParent's children. May be null. If not null then aNode
291 * must be an nsIContent.
292 * @param aResult If aClone is true then *aResult will contain the cloned
293 * node.
294 */
295 static nsresult CloneAndAdopt(nsINode *aNode, bool aClone, bool aDeep,
296 nsNodeInfoManager *aNewNodeInfoManager,
297 JS::Handle<JSObject*> aReparentScope,
298 nsCOMArray<nsINode> &aNodesWithProperties,
299 nsINode *aParent, nsINode **aResult);
300 };
302 #endif // nsNodeUtils_h___