OLD | NEW |
1 /* Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 /* Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 * Use of this source code is governed by a BSD-style license that can be | 2 * Use of this source code is governed by a BSD-style license that can be |
3 * found in the LICENSE file. | 3 * found in the LICENSE file. |
4 * | 4 * |
5 * Helper javascript injected whenever a DomMutationEventObserver is created. | 5 * Helper javascript injected whenever a DomMutationEventObserver is created. |
6 * | 6 * |
7 * This script uses MutationObservers to watch for changes to the DOM, then | 7 * This script uses MutationObservers to watch for changes to the DOM, then |
8 * reports the event to the observer using the DomAutomationController. An | 8 * reports the event to the observer using the DomAutomationController. An |
9 * anonymous namespace is used to prevent conflict with other Javascript. | 9 * anonymous namespace is used to prevent conflict with other Javascript. |
10 * | 10 * |
11 * Args: | 11 * Args: |
12 * automation_id: Automation id used to route DomAutomationController messages. | 12 * automation_id: Automation id used to route DomAutomationController messages. |
13 * observer_id: Id of the observer who will be receiving the messages. | 13 * observer_id: Id of the observer who will be receiving the messages. |
14 * observer_type: One of 'add', 'remove', or 'change'. | 14 * observer_type: One of 'add', 'remove', 'change', or 'exists'. |
15 * pattern: Pattern used to select the DOM node of interest. | 15 * pattern: Pattern used to select the DOM node of interest. |
16 * ptype: Type of |pattern|, either 'xpath' or 'css'. | 16 * ptype: Type of |pattern|, either 'xpath' or 'css'. |
17 * expected_value: If not null, regular expression matching text contents | 17 * expected_value: If not null, regular expression matching text contents |
18 * expected after the mutation. | 18 * expected after the mutation. |
19 */ | 19 */ |
20 | 20 |
21 function(automation_id, observer_id, observer_type, pattern, ptype, | 21 function(automation_id, observer_id, observer_type, pattern, ptype, |
22 expected_value) { | 22 expected_value) { |
23 | 23 |
24 /* Raise an event for the DomMutationEventObserver. | 24 /* Raise an event for the DomMutationEventObserver. |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
95 for (var j=0; j<mutations.length; j++) { | 95 for (var j=0; j<mutations.length; j++) { |
96 if (nodeValueTextEquals(mutations[j].target, expected_value)) { | 96 if (nodeValueTextEquals(mutations[j].target, expected_value)) { |
97 raiseEvent(); | 97 raiseEvent(); |
98 observer.disconnect(); | 98 observer.disconnect(); |
99 delete observer; | 99 delete observer; |
100 return; | 100 return; |
101 } | 101 } |
102 } | 102 } |
103 } | 103 } |
104 | 104 |
| 105 /* Calls raiseEvent if the expected node exists in the DOM. |
| 106 * |
| 107 * Args: |
| 108 * mutations: A list of mutation objects. |
| 109 * observer: The mutation observer object associated with this callback. |
| 110 */ |
| 111 function existsNodeCallback(mutations, observer) { |
| 112 var node = firstMatchingNode(pattern, ptype); |
| 113 if (node && nodeValueTextEquals(node, expected_value)) { |
| 114 raiseEvent(); |
| 115 observer.disconnect(); |
| 116 delete observer; |
| 117 return; |
| 118 } |
| 119 } |
| 120 |
105 /* Return true if the xpath matches the given node. | 121 /* Return true if the xpath matches the given node. |
106 * | 122 * |
107 * Args: | 123 * Args: |
108 * node: A node object from the DOM. | 124 * node: A node object from the DOM. |
109 * xpath: A string in the format of an xpath. | 125 * xpath: A string in the format of an xpath. |
110 */ | 126 */ |
111 function XPathMatchesNode(node, xpath) { | 127 function XPathMatchesNode(node, xpath) { |
112 var con = document.evaluate(xpath, document, null, | 128 var con = document.evaluate(xpath, document, null, |
113 XPathResult.UNORDERED_NODE_ITERATOR_TYPE, null); | 129 XPathResult.UNORDERED_NODE_ITERATOR_TYPE, null); |
114 var thisNode = con.iterateNext(); | 130 var thisNode = con.iterateNext(); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
177 } | 193 } |
178 | 194 |
179 /* Watch for a node matching pattern to be added to the DOM. | 195 /* Watch for a node matching pattern to be added to the DOM. |
180 * | 196 * |
181 * Args: | 197 * Args: |
182 * pattern: A string in the format of either an XPath or CSS Selector. | 198 * pattern: A string in the format of either an XPath or CSS Selector. |
183 * ptype: Either 'xpath' or 'css'. | 199 * ptype: Either 'xpath' or 'css'. |
184 */ | 200 */ |
185 function observeAdd(pattern, ptype) { | 201 function observeAdd(pattern, ptype) { |
186 window.domAutomationController.send("success"); | 202 window.domAutomationController.send("success"); |
187 if (firstMatchingNode(pattern, ptype)) { | 203 var node = firstMatchingNode(pattern, ptype); |
| 204 if (node && nodeValueTextEquals(node, expected_value)) { |
188 raiseEvent(); | 205 raiseEvent(); |
189 console.log("Matching node in DOM, assuming it was previously added."); | 206 console.log("Matching node in DOM, assuming it was previously added."); |
190 return; | 207 return; |
191 } | 208 } |
192 | 209 |
193 var obs = new WebKitMutationObserver(addNodeCallback); | 210 var obs = new WebKitMutationObserver(addNodeCallback); |
194 obs.observe(document, | 211 obs.observe(document, |
195 { childList: true, | 212 { childList: true, |
196 attributes: true, | 213 attributes: true, |
197 subtree: true}); | 214 subtree: true}); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
236 window.domAutomationController.send("success"); | 253 window.domAutomationController.send("success"); |
237 | 254 |
238 var obs = new WebKitMutationObserver(changeNodeCallback); | 255 var obs = new WebKitMutationObserver(changeNodeCallback); |
239 obs.observe(node, | 256 obs.observe(node, |
240 { childList: true, | 257 { childList: true, |
241 attributes: true, | 258 attributes: true, |
242 characterData: true, | 259 characterData: true, |
243 subtree: true}); | 260 subtree: true}); |
244 } | 261 } |
245 | 262 |
| 263 /* Watch for a node matching pattern to exist in the DOM. |
| 264 * |
| 265 * Args: |
| 266 * pattern: A string in the format of either an XPath or CSS Selector. |
| 267 * ptype: Either 'xpath' or 'css'. |
| 268 */ |
| 269 function observeExists(pattern, ptype) { |
| 270 window.domAutomationController.send("success"); |
| 271 var node = firstMatchingNode(pattern, ptype); |
| 272 if (node && nodeValueTextEquals(node, expected_value)) { |
| 273 raiseEvent(); |
| 274 console.log("Node already exists in DOM."); |
| 275 return; |
| 276 } |
| 277 |
| 278 var obs = new WebKitMutationObserver(existsNodeCallback); |
| 279 obs.observe(document, |
| 280 { childList: true, |
| 281 attributes: true, |
| 282 subtree: true}); |
| 283 } |
246 | 284 |
247 /* Interpret arguments and launch the requested observer function. */ | 285 /* Interpret arguments and launch the requested observer function. */ |
248 var observer; | 286 var observer; |
249 switch (observer_type) { | 287 switch (observer_type) { |
250 case "add": | 288 case "add": |
251 observeAdd(pattern, ptype); | 289 observeAdd(pattern, ptype); |
252 break; | 290 break; |
253 case "remove": | 291 case "remove": |
254 observeRemove(pattern, ptype); | 292 observeRemove(pattern, ptype); |
255 break; | 293 break; |
256 case "change": | 294 case "change": |
257 observeChange(pattern, ptype); | 295 observeChange(pattern, ptype); |
258 break; | 296 break; |
| 297 case "exists": |
| 298 observeExists(pattern, ptype); |
| 299 break; |
259 } | 300 } |
260 | 301 |
261 console.log("MutationObserver javscript injection completed.") | 302 console.log("MutationObserver javscript injection completed.") |
262 | 303 |
263 } | 304 } |
OLD | NEW |