| 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 var util = {}; | 5 var util = {}; |
| 6 | 6 |
| 7 // Creates a <webview> tag in document.body and returns the reference to it. | 7 // Creates a <webview> tag in document.body and returns the reference to it. |
| 8 // It also sets a dummy src. The dummy src is significant because this makes | 8 // It also sets a dummy src. The dummy src is significant because this makes |
| 9 // sure that the <object> shim is created (asynchronously at this point) for the | 9 // sure that the <object> shim is created (asynchronously at this point) for the |
| 10 // <webview> tag. This makes the <webview> tag ready for add/removeEventListener | 10 // <webview> tag. This makes the <webview> tag ready for add/removeEventListener |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 84 | 84 |
| 85 // Check contentWindow. | 85 // Check contentWindow. |
| 86 chrome.test.assertEq('object', typeof webview.contentWindow); | 86 chrome.test.assertEq('object', typeof webview.contentWindow); |
| 87 chrome.test.assertEq('function', | 87 chrome.test.assertEq('function', |
| 88 typeof webview.contentWindow.postMessage); | 88 typeof webview.contentWindow.postMessage); |
| 89 | 89 |
| 90 chrome.test.succeed(); | 90 chrome.test.succeed(); |
| 91 }, 0); | 91 }, 0); |
| 92 }, | 92 }, |
| 93 | 93 |
| 94 function webViewEventListeners() { | |
| 95 var webview = document.createElement('webview'); | |
| 96 webview.setAttribute('src', 'data:text/html,webview check api'); | |
| 97 document.body.appendChild(webview); | |
| 98 | |
| 99 var validEvents = [ | |
| 100 'exit', | |
| 101 'loadabort', | |
| 102 'loadredirect', | |
| 103 'loadstart', | |
| 104 'loadstop' | |
| 105 ]; | |
| 106 var invalidEvents = [ | |
| 107 'makemesandwich', | |
| 108 'sudomakemesandwich' | |
| 109 ]; | |
| 110 | |
| 111 // Timeout is necessary to give the mutation observers of the webview tag | |
| 112 // shim a chance to fire. | |
| 113 setTimeout(function() { | |
| 114 for (var i = 0; i < validEvents.length; ++i) { | |
| 115 chrome.test.assertTrue( | |
| 116 webview.addEventListener(validEvents[i], function() {})); | |
| 117 } | |
| 118 | |
| 119 for (var i = 0; i < invalidEvents.length; ++i) { | |
| 120 chrome.test.assertFalse( | |
| 121 webview.addEventListener(invalidEvents[i], function() {})); | |
| 122 } | |
| 123 | |
| 124 chrome.test.succeed(); | |
| 125 }, 0); | |
| 126 }, | |
| 127 | |
| 128 function webViewEventName() { | 94 function webViewEventName() { |
| 129 var webview = document.createElement('webview'); | 95 var webview = document.createElement('webview'); |
| 130 webview.setAttribute('src', 'data:text/html,webview check api'); | 96 webview.setAttribute('src', 'data:text/html,webview check api'); |
| 131 document.body.appendChild(webview); | 97 document.body.appendChild(webview); |
| 132 | 98 |
| 133 setTimeout(function() { | 99 setTimeout(function() { |
| 134 webview.addEventListener('loadstart', function(evt) { | 100 webview.addEventListener('loadstart', function(evt) { |
| 135 chrome.test.assertEq('loadstart', evt.name); | 101 chrome.test.assertEq('loadstart', evt.type); |
| 136 }); | 102 }); |
| 137 | 103 |
| 138 webview.addEventListener('loadstop', function(evt) { | 104 webview.addEventListener('loadstop', function(evt) { |
| 139 chrome.test.assertEq('loadstop', evt.name); | 105 chrome.test.assertEq('loadstop', evt.type); |
| 140 webview.terminate(); | 106 webview.terminate(); |
| 141 }); | 107 }); |
| 142 | 108 |
| 143 webview.addEventListener('exit', function(evt) { | 109 webview.addEventListener('exit', function(evt) { |
| 144 chrome.test.assertEq('exit', evt.name); | 110 chrome.test.assertEq('exit', evt.type); |
| 145 chrome.test.succeed(); | 111 chrome.test.succeed(); |
| 146 }); | 112 }); |
| 147 | 113 |
| 148 webview.setAttribute('src', 'data:text/html,trigger navigation'); | 114 webview.setAttribute('src', 'data:text/html,trigger navigation'); |
| 149 }, 0); | 115 }, 0); |
| 150 }, | 116 }, |
| 151 | 117 |
| 152 // This test registers two listeners on an event (loadcommit) and removes | 118 // This test registers two listeners on an event (loadcommit) and removes |
| 153 // the <webview> tag when the first listener fires. | 119 // the <webview> tag when the first listener fires. |
| 154 // Current expected behavior is that the second event listener will still | 120 // Current expected behavior is that the second event listener will still |
| (...skipping 12 matching lines...) Expand all Loading... |
| 167 webview = null; | 133 webview = null; |
| 168 // Make sure the js executes after nulling |webview|. | 134 // Make sure the js executes after nulling |webview|. |
| 169 continuedAfterDelete = true; | 135 continuedAfterDelete = true; |
| 170 } else if (loadCommitCount == 2) { | 136 } else if (loadCommitCount == 2) { |
| 171 chrome.test.assertTrue(continuedAfterDelete); | 137 chrome.test.assertTrue(continuedAfterDelete); |
| 172 chrome.test.succeed(); | 138 chrome.test.succeed(); |
| 173 } | 139 } |
| 174 }; | 140 }; |
| 175 | 141 |
| 176 var onLoadCommitA = function(e) { | 142 var onLoadCommitA = function(e) { |
| 177 chrome.test.assertEq('loadcommit', e.name); | 143 chrome.test.assertEq('loadcommit', e.type); |
| 178 if (e.url == url) { | 144 if (e.detail.url == url) { |
| 179 updateLoadCommitCount(); | 145 updateLoadCommitCount(); |
| 180 } | 146 } |
| 181 }; | 147 }; |
| 182 var onLoadCommitB = function(e) { | 148 var onLoadCommitB = function(e) { |
| 183 chrome.test.assertEq('loadcommit', e.name); | 149 chrome.test.assertEq('loadcommit', e.type); |
| 184 if (e.url == url) { | 150 if (e.detail.url == url) { |
| 185 updateLoadCommitCount(); | 151 updateLoadCommitCount(); |
| 186 } | 152 } |
| 187 }; | 153 }; |
| 188 | 154 |
| 189 setTimeout(function() { | 155 setTimeout(function() { |
| 190 // The test starts from here, by setting the src to |url|. Event | 156 // The test starts from here, by setting the src to |url|. Event |
| 191 // listener registration works because we already have a (dummy) src set | 157 // listener registration works because we already have a (dummy) src set |
| 192 // on the <webview> tag. | 158 // on the <webview> tag. |
| 193 webview.addEventListener('loadcommit', onLoadCommitA); | 159 webview.addEventListener('loadcommit', onLoadCommitA); |
| 194 webview.addEventListener('loadcommit', onLoadCommitB); | 160 webview.addEventListener('loadcommit', onLoadCommitB); |
| 195 webview.setAttribute('src', url); | 161 webview.setAttribute('src', url); |
| 196 }, 0); | 162 }, 0); |
| 197 }, | 163 }, |
| 198 | 164 |
| 199 // This test checks the current behavior of dynamic event listener | |
| 200 // registration 'during' an event listener fire. | |
| 201 // Once an event starts firing its listeners, any mutation to the list of | |
| 202 // event listeners for this event are deferred until all of the listeners | |
| 203 // have fired. | |
| 204 // | |
| 205 // Step1: Loads a guest with |urlStep1| with two listeners to 'loadcommit': | |
| 206 // onLoadCommitA and onLoadCommitB. When first of them fires, we try to | |
| 207 // remove the other and add a third listener (onLoadCommitC). | |
| 208 // Current expected behavior is these add/remove will be ignored and the | |
| 209 // original two listeners will fire. | |
| 210 // Step2: We change the guest to |urlStep2|. This will cause 'loadcommit' to | |
| 211 // fire with mutated event listeners list (that is one of | |
| 212 // onLoadCommitA/onLoadCommitB and onLoadCommitC). | |
| 213 function dynamicEventListenerRegistrationOnListenerFire() { | |
| 214 var urlStep1 = 'data:text/html,<body>Two</body>'; | |
| 215 var urlStep2 = 'data:text/html,<body>Three</body>'; | |
| 216 var webview = util.createWebViewTagInDOM(); | |
| 217 | |
| 218 var listenerFireCount1 = 0; // Step 1 listeners. | |
| 219 var listenerFireCount2 = 0; // Step 2 listeners. | |
| 220 | |
| 221 var loadCommitACalledStep1 = false; | |
| 222 var loadCommitBCalledStep1 = false; | |
| 223 | |
| 224 var loadCommitACalledStep2 = false; | |
| 225 var loadCommitBCalledStep2 = false; | |
| 226 var loadCommitCCalledStep2 = false; | |
| 227 | |
| 228 var expectAToFireInStep2; | |
| 229 var expectBToFireInStep2; | |
| 230 | |
| 231 var updateTestStateOnListenerStep1 = function() { | |
| 232 ++listenerFireCount1; | |
| 233 if (listenerFireCount1 == 1) { // First listener fire on Step 1. | |
| 234 chrome.test.assertTrue(loadCommitACalledStep1 || | |
| 235 loadCommitBCalledStep1); | |
| 236 // Add an event listener and remove one existing one when the first | |
| 237 // listener fires. Current implmementation does not expect any of | |
| 238 // these to be reflected before all event listeners are fired for the | |
| 239 // current event. | |
| 240 | |
| 241 // Remove. | |
| 242 if (loadCommitACalledStep1) { | |
| 243 webview.removeEventListener('loadcommit', onLoadCommitB); | |
| 244 expectAToFireInStep2 = true; | |
| 245 expectBToFireInStep2 = false; | |
| 246 } else { | |
| 247 webview.removeEventListener('loadcommit', onLoadCommitA); | |
| 248 expectAToFireInStep2 = false; | |
| 249 expectBToFireInStep2 = true; | |
| 250 } | |
| 251 // Add the other one. | |
| 252 webview.addEventListener('loadcommit', onLoadCommitC); | |
| 253 } else if (listenerFireCount1 == 2) { // Last listener fire on Step 1. | |
| 254 chrome.test.assertTrue(loadCommitACalledStep1 && | |
| 255 loadCommitBCalledStep1); | |
| 256 // Move to Step 2. | |
| 257 webview.setAttribute('src', urlStep2); | |
| 258 } else { | |
| 259 // More than expected listeners fired. | |
| 260 chrome.test.fail(); | |
| 261 } | |
| 262 }; | |
| 263 | |
| 264 var updateTestStateOnListenerStep2 = function() { | |
| 265 ++listenerFireCount2; | |
| 266 if (listenerFireCount2 == 2) { | |
| 267 // Exactly one of onLoadCommitA and onLoadCommitB must be called. | |
| 268 chrome.test.assertTrue(loadCommitACalledStep2 || | |
| 269 loadCommitBCalledStep2); | |
| 270 // onLoadCommitC must be called. | |
| 271 chrome.test.assertTrue(loadCommitCCalledStep2); | |
| 272 | |
| 273 chrome.test.succeed(); | |
| 274 } else if (listenerFireCount2 > 2) { | |
| 275 // More than expected listeners fired. | |
| 276 chrome.test.fail(); | |
| 277 } | |
| 278 }; | |
| 279 | |
| 280 var onLoadCommitA = function(e) { | |
| 281 chrome.test.assertEq('loadcommit', e.name); | |
| 282 switch (e.url) { | |
| 283 case urlStep1: // Step 1. | |
| 284 chrome.test.log('Step 1. onLoadCommitA'); | |
| 285 chrome.test.assertFalse(loadCommitACalledStep1); | |
| 286 loadCommitACalledStep1 = true; | |
| 287 | |
| 288 updateTestStateOnListenerStep1(); | |
| 289 break; | |
| 290 case urlStep2: // Step 2. | |
| 291 chrome.test.log('Step 2. onLoadCommitA'); | |
| 292 chrome.test.assertTrue(expectAToFireInStep2); | |
| 293 // Can be called at most once. | |
| 294 chrome.test.assertFalse(loadCommitACalledStep2); | |
| 295 loadCommitACalledStep2 = true; | |
| 296 | |
| 297 updateTestStateOnListenerStep2(); | |
| 298 break; | |
| 299 } | |
| 300 }; | |
| 301 | |
| 302 var onLoadCommitB = function(e) { | |
| 303 chrome.test.assertEq('loadcommit', e.name); | |
| 304 switch (e.url) { | |
| 305 case urlStep1: // Step 1. | |
| 306 chrome.test.log('Step 1. onLoadCommitB'); | |
| 307 chrome.test.assertFalse(loadCommitBCalledStep1); | |
| 308 loadCommitBCalledStep1 = true; | |
| 309 | |
| 310 updateTestStateOnListenerStep1(); | |
| 311 break; | |
| 312 case urlStep2: // Step 2. | |
| 313 chrome.test.log('Step 2. onLoadCommitB'); | |
| 314 chrome.test.assertTrue(expecBToFireInStep2); | |
| 315 // Can be called at most once. | |
| 316 chrome.test.assertFalse(loadCommitBCalledStep2); | |
| 317 loadCommitBCalledStep2 = true; | |
| 318 | |
| 319 updateTestStateOnListenerStep2(); | |
| 320 break; | |
| 321 } | |
| 322 }; | |
| 323 | |
| 324 var onLoadCommitC = function(e) { | |
| 325 chrome.test.assertEq('loadcommit', e.name); | |
| 326 switch (e.url) { | |
| 327 case urlStep1: // Step 1. | |
| 328 chrome.test.fail(); | |
| 329 break; | |
| 330 case urlStep2: // Step 2. | |
| 331 chrome.test.log('Step 2. onLoadCommitC'); | |
| 332 chrome.test.assertFalse(loadCommitCCalledStep2); | |
| 333 loadCommitCCalledStep2 = true; | |
| 334 | |
| 335 updateTestStateOnListenerStep2(); | |
| 336 break; | |
| 337 } | |
| 338 }; | |
| 339 | |
| 340 setTimeout(function() { | |
| 341 // The test starts from here, by setting the src to |urlStep1|. Event | |
| 342 // listener registration works because we already have a (dummy) src set | |
| 343 // on the <webview> tag. | |
| 344 webview.addEventListener('loadcommit', onLoadCommitA); | |
| 345 webview.addEventListener('loadcommit', onLoadCommitB); | |
| 346 webview.setAttribute('src', urlStep1); | |
| 347 }, 0); | |
| 348 }, | |
| 349 | |
| 350 // This test registers two event listeners on a same event (loadcommit). | 165 // This test registers two event listeners on a same event (loadcommit). |
| 351 // Each of the listener tries to change some properties on the event param, | 166 // Each of the listener tries to change some properties on the event param, |
| 352 // which should not be possible. | 167 // which should not be possible. |
| 353 function cannotMutateEventName() { | 168 function cannotMutateEventName() { |
| 354 var webview = util.createWebViewTagInDOM(); | 169 var webview = util.createWebViewTagInDOM(); |
| 355 var url = 'data:text/html,<body>Two</body>'; | 170 var url = 'data:text/html,<body>Two</body>'; |
| 356 | 171 |
| 357 var loadCommitACalled = false; | 172 var loadCommitACalled = false; |
| 358 var loadCommitBCalled = false; | 173 var loadCommitBCalled = false; |
| 359 | 174 |
| 360 var maybeFinishTest = function(e) { | 175 var maybeFinishTest = function(e) { |
| 361 if (loadCommitACalled && loadCommitBCalled) { | 176 if (loadCommitACalled && loadCommitBCalled) { |
| 362 chrome.test.assertEq('loadcommit', e.name); | 177 chrome.test.assertEq('loadcommit', e.type); |
| 363 chrome.test.assertTrue(e.isTopLevel); | |
| 364 chrome.test.succeed(); | 178 chrome.test.succeed(); |
| 365 } | 179 } |
| 366 }; | 180 }; |
| 367 | 181 |
| 368 var onLoadCommitA = function(e) { | 182 var onLoadCommitA = function(e) { |
| 369 if (e.url == url) { | 183 if (e.detail.url == url) { |
| 370 chrome.test.assertEq('loadcommit', e.name); | 184 chrome.test.assertEq('loadcommit', e.type); |
| 371 chrome.test.assertTrue(e.isTopLevel); | 185 chrome.test.assertTrue(e.detail.isTopLevel); |
| 372 chrome.test.assertFalse(loadCommitACalled); | 186 chrome.test.assertFalse(loadCommitACalled); |
| 373 loadCommitACalled = true; | 187 loadCommitACalled = true; |
| 374 // Try mucking with properities inside |e|. | 188 // Try mucking with properities inside |e|. |
| 375 e.name = 'modified'; | 189 e.type = 'modified'; |
| 376 e.isTopLevel = 'string-value'; | |
| 377 maybeFinishTest(e); | 190 maybeFinishTest(e); |
| 378 } | 191 } |
| 379 }; | 192 }; |
| 380 var onLoadCommitB = function(e) { | 193 var onLoadCommitB = function(e) { |
| 381 if (e.url == url) { | 194 if (e.detail.url == url) { |
| 382 chrome.test.assertEq('loadcommit', e.name); | 195 chrome.test.assertEq('loadcommit', e.type); |
| 383 chrome.test.assertTrue(e.isTopLevel); | 196 chrome.test.assertTrue(e.detail.isTopLevel); |
| 384 chrome.test.assertFalse(loadCommitBCalled); | 197 chrome.test.assertFalse(loadCommitBCalled); |
| 385 loadCommitBCalled = true; | 198 loadCommitBCalled = true; |
| 386 // Try mucking with properities inside |e|. | 199 // Try mucking with properities inside |e|. |
| 387 e.name = 'modified'; | 200 e.type = 'modified'; |
| 388 e.isTopLevel = 'string-value'; | |
| 389 maybeFinishTest(e); | 201 maybeFinishTest(e); |
| 390 } | 202 } |
| 391 }; | 203 }; |
| 392 | 204 |
| 393 setTimeout(function() { | 205 setTimeout(function() { |
| 394 // The test starts from here, by setting the src to |url|. Event | 206 // The test starts from here, by setting the src to |url|. Event |
| 395 // listener registration works because we already have a (dummy) src set | 207 // listener registration works because we already have a (dummy) src set |
| 396 // on the <webview> tag. | 208 // on the <webview> tag. |
| 397 webview.addEventListener('loadcommit', onLoadCommitA); | 209 webview.addEventListener('loadcommit', onLoadCommitA); |
| 398 webview.addEventListener('loadcommit', onLoadCommitB); | 210 webview.addEventListener('loadcommit', onLoadCommitB); |
| 399 webview.setAttribute('src', url); | 211 webview.setAttribute('src', url); |
| 400 }, 0); | 212 }, 0); |
| 401 } | 213 } |
| 402 ]); | 214 ]); |
| 403 }; | 215 }; |
| OLD | NEW |