OLD | NEW |
(Empty) | |
| 1 <!doctype html> |
| 2 <head> |
| 3 <script src="../resources/testharness.js"></script> |
| 4 <script src="../resources/testharnessreport.js"></script> |
| 5 <script src="./resources/resizeTestHelper.js"></script> |
| 6 <style> |
| 7 div { |
| 8 border: 1px dotted gray |
| 9 } |
| 10 .transform { |
| 11 transform: scale(2,2) rotate(90deg) |
| 12 } |
| 13 </style> |
| 14 </head> |
| 15 <p>ResizeObserver tests</p> |
| 16 <div id="target1" style="width:100px;height:100px;">t1 |
| 17 <div id="target2" style="width:100px;height:100px;">t2 |
| 18 <div id="target3" style="width:100px;height:100px;">t3 |
| 19 <span id="inline">inline</span> |
| 20 </div> |
| 21 </div> |
| 22 </div> |
| 23 <div id="absolute" style="width:100.5px;height:100.5px;position:absolute;top:10.
3px;left:10.3px"> |
| 24 <script> |
| 25 'use strict'; |
| 26 |
| 27 var helper = new ResizeTestHelper(); |
| 28 |
| 29 let t1 = document.querySelector('#target1'); |
| 30 let t2 = document.querySelector('#target2'); |
| 31 let t3 = document.querySelector('#target3'); |
| 32 let abs = document.querySelector('#absolute'); |
| 33 let inline = document.querySelector('#inline'); |
| 34 |
| 35 setup({allow_uncaught_exception: true}); |
| 36 |
| 37 function test0() { |
| 38 helper.createTest( |
| 39 "test0: notification ordering", |
| 40 setup => { |
| 41 helper.observer.disconnect(); |
| 42 helper.observer.observe(t3); |
| 43 helper.observer.observe(t2); |
| 44 helper.observer.observe(t1); |
| 45 t1.style.width = "5px"; |
| 46 t3.style.width = "5px"; |
| 47 t2.style.width = "5px"; |
| 48 |
| 49 }, |
| 50 entries => { |
| 51 assert_equals(entries.length, 3, "3 resizes"); |
| 52 assert_equals(entries[0].target, t3, "ordering"); |
| 53 assert_equals(entries[1].target, t2, "ordering"); |
| 54 assert_equals(entries[2].target, t1, "ordering"); |
| 55 t1.style.width = "100px"; |
| 56 t2.style.width = "100px"; |
| 57 t3.style.width = "100px"; |
| 58 test1(); |
| 59 } |
| 60 ); |
| 61 } |
| 62 |
| 63 function test1() { |
| 64 helper.createTest( |
| 65 "test1: display:none triggers notification", |
| 66 setup => { |
| 67 helper.observer.disconnect(); |
| 68 helper.observer.observe(t1); |
| 69 }, |
| 70 entries => { |
| 71 // initial observation happens here |
| 72 } |
| 73 ); |
| 74 helper.createTest( |
| 75 "display:none triggers notification, part 2", |
| 76 setup => { |
| 77 t1.style.display = "none"; |
| 78 }, |
| 79 entries => { |
| 80 // initial observation happens here |
| 81 t1.style.display = ""; |
| 82 test2(); |
| 83 } |
| 84 ); |
| 85 } |
| 86 |
| 87 |
| 88 function test2() { |
| 89 helper.createTest( |
| 90 "test2: remove/reinsert", |
| 91 setup => { |
| 92 helper.observer.disconnect(); |
| 93 helper.observer.observe(t1); |
| 94 }, |
| 95 entries => { |
| 96 // initial observation |
| 97 } |
| 98 ); |
| 99 helper.createTest( |
| 100 "removeChild triggers notification", |
| 101 setup => { |
| 102 t1.parentNode.removeChild(t1); |
| 103 }, |
| 104 entries => { |
| 105 assert_equals(entries[0].target, t1); |
| 106 } |
| 107 ); |
| 108 helper.createTest( |
| 109 "appendChild triggers notification", |
| 110 setup => { |
| 111 document.body.appendChild(t1); |
| 112 }, |
| 113 entries => { |
| 114 assert_equals(entries[0].target, t1); |
| 115 test3(); |
| 116 } |
| 117 ); |
| 118 } |
| 119 |
| 120 |
| 121 function test3() { |
| 122 helper.createTest( |
| 123 "test3: dimensions match", |
| 124 setup => { |
| 125 helper.observer.disconnect(); |
| 126 helper.observer.observe(t1); |
| 127 t1.style.width = "200.5px"; |
| 128 t1.style.height = "100px"; |
| 129 t1.style.paddingLeft = "20px"; |
| 130 t1.style.paddingTop = "10px"; |
| 131 }, |
| 132 entries => { |
| 133 assert_equals(entries[0].contentRect.left,20); |
| 134 assert_equals(entries[0].contentRect.top,10); |
| 135 assert_between_inclusive(entries[0].contentRect.width, 200.4, 200.6, "widt
h is not rounded"); |
| 136 assert_equals(entries[0].contentRect.height, 100); |
| 137 test4(); |
| 138 } |
| 139 ); |
| 140 } |
| 141 |
| 142 function test4() { |
| 143 helper.createTest( |
| 144 "test4: transform do not cause notifications", |
| 145 setup => { |
| 146 helper.observer.disconnect(); |
| 147 helper.observer.observe(t2); |
| 148 }, |
| 149 entries => { |
| 150 // initial notification |
| 151 } |
| 152 ); |
| 153 helper.createTest( |
| 154 "transform do not cause notification, part 2", |
| 155 setup => { |
| 156 t2.classList.add("transform"); |
| 157 }, |
| 158 entries => { |
| 159 assert_unreached("transform must not trigger notifications"); |
| 160 }, |
| 161 timeout => { |
| 162 t2.classList.remove("transform"); |
| 163 test5(); |
| 164 } |
| 165 ); |
| 166 } |
| 167 |
| 168 |
| 169 function test5() { |
| 170 helper.createTest( |
| 171 "test5: moving an element does not trigger notifications", |
| 172 setup => { |
| 173 helper.observer.disconnect(); |
| 174 helper.observer.observe(abs); |
| 175 }, |
| 176 entries => { |
| 177 // initial observation |
| 178 } |
| 179 ); |
| 180 helper.createTest( |
| 181 "moving an element does not trigger notifications, part 2", |
| 182 setup => { |
| 183 abs.style.top = "20.33px"; |
| 184 abs.style.left = "20.33px"; |
| 185 }, |
| 186 entries => { |
| 187 assert_unreached("movement should not cause resize notifications"); |
| 188 }, |
| 189 timeout => { |
| 190 test6(); |
| 191 } |
| 192 ); |
| 193 } |
| 194 |
| 195 function test6() { |
| 196 helper.createTest( |
| 197 "test6: inline element does not notify", |
| 198 setup => { |
| 199 helper.observer.disconnect(); |
| 200 helper.observer.observe(inline); |
| 201 helper.observer.observe(t1); |
| 202 t1.style.width = "66px"; |
| 203 inline.style.width = "66px"; |
| 204 }, |
| 205 entries => { |
| 206 assert_equals(entries.length, 1, "inline elements must not trigger notific
ations"); |
| 207 assert_equals(entries[0].target, t1, "inline elements must not trigger no
tifications"); |
| 208 } |
| 209 ); |
| 210 helper.createTest( |
| 211 "inline element that becomes block should notify", |
| 212 setup => { |
| 213 inline.style.display = "block"; |
| 214 }, |
| 215 entries => { |
| 216 assert_equals(entries[0].target, inline); |
| 217 test7(); |
| 218 } |
| 219 ); |
| 220 } |
| 221 |
| 222 function test7() { |
| 223 let test = async_test("test7: unobserve inside notify callback"); |
| 224 |
| 225 let notifyStep = 0; |
| 226 let notify = entries => { |
| 227 switch(notifyStep) { |
| 228 case 0: |
| 229 // initial setup |
| 230 t1.style.width = "777px"; |
| 231 t2.style.width = "777px"; |
| 232 ro.unobserve(t1); |
| 233 break; |
| 234 case 1: |
| 235 test.step(_ => { |
| 236 assert_equals(entries.length, 1, "only t2 is observed"); |
| 237 assert_equals(entries[0].target, t2, "only t2 is observed"); |
| 238 test8(); |
| 239 helper.startTests(); |
| 240 test.done(); |
| 241 ro.disconnect(); |
| 242 }); |
| 243 break; |
| 244 } |
| 245 notifyStep++; |
| 246 } |
| 247 |
| 248 let ro = new ResizeObserver(notify); |
| 249 ro.observe(t1); |
| 250 ro.observe(t2); |
| 251 } |
| 252 |
| 253 function test8() { |
| 254 let test = async_test("test8: observe inside notify callback"); |
| 255 |
| 256 let notifyStep = 0; |
| 257 let notify = entries => { |
| 258 switch(notifyStep) { |
| 259 case 0: |
| 260 // intial setup |
| 261 ro.observe(t2); |
| 262 t2.style.width = "888px"; |
| 263 break; |
| 264 case 1: |
| 265 test.step( _ => { |
| 266 assert_equals(entries.length, 1, "only t2 is observed"); |
| 267 assert_equals(entries[0].target, t2, "only t2 is observed"); |
| 268 test9(); |
| 269 test.done(); |
| 270 ro.disconnect(); |
| 271 }); |
| 272 break; |
| 273 } |
| 274 notifyStep++; |
| 275 } |
| 276 |
| 277 let ro = new ResizeObserver(notify); |
| 278 ro.observe(t1); |
| 279 } |
| 280 |
| 281 function test9() { |
| 282 let test = async_test("test9: disconnect inside notify callback"); |
| 283 |
| 284 let notifyStep = 0; |
| 285 let timeoutId = 0; |
| 286 let notify = entries => { |
| 287 switch(notifyStep) { |
| 288 case 0: |
| 289 // intial setup |
| 290 t1.style.width = "888px"; |
| 291 ro.disconnect(); |
| 292 timeoutId = test.step_timeout(_ => { |
| 293 test10(); |
| 294 test.done(); |
| 295 }, ResizeTestHelper.TIMEOUT); |
| 296 break; |
| 297 case 1: |
| 298 window.clearTimeout(timeoutId); |
| 299 test.step( _ => { |
| 300 assert_unreached("there should be no notifications after disconnect"); |
| 301 }); |
| 302 break; |
| 303 } |
| 304 notifyStep++; |
| 305 } |
| 306 |
| 307 let ro = new ResizeObserver(notify); |
| 308 ro.observe(t1); |
| 309 } |
| 310 |
| 311 var onErrorCalled = false; |
| 312 |
| 313 window.onerror = err => { |
| 314 onErrorCalled = true; |
| 315 } |
| 316 |
| 317 function test10() { |
| 318 helper.createTest( |
| 319 "test10: multiple notifications inside same event loop, with limit exceeded"
, |
| 320 setup => { |
| 321 onErrorCalled = false; |
| 322 helper.observer.disconnect(); |
| 323 helper.observer.observe(t1); |
| 324 }, |
| 325 entries => { |
| 326 // initial notification |
| 327 } |
| 328 ); |
| 329 let rAF = 0; |
| 330 |
| 331 // Following tests should all complete within |
| 332 // a same event loop. Use rAF to detect loop end. |
| 333 for (let i=0; i<20; i++) { |
| 334 helper.createTest( |
| 335 "notify with error" + i, |
| 336 setup => { |
| 337 if (i == 0) |
| 338 window.requestAnimationFrame(_ => { rAF++; }); |
| 339 t1.style.width = i * 10 + "px"; |
| 340 }, |
| 341 entries => { |
| 342 if (i < 15) { |
| 343 assert_equals(rAF, 0, "must stay in same notify loop for 16 loops"); |
| 344 } |
| 345 else if (i >= 15) { |
| 346 assert_true(onErrorCalled, "window.onerror should be called if limit e
xceeded"); |
| 347 assert_equals(rAF, 1, "raf was called after limit was exceeded"); |
| 348 } |
| 349 } |
| 350 ); |
| 351 } |
| 352 helper.startTests(); |
| 353 }; |
| 354 |
| 355 test0(); |
| 356 helper.startTests(); |
| 357 |
| 358 </script> |
| 359 <!-- file:///usr/local/google/home/atotic/chromium/src/third_party/WebKit/Layout
Tests/resize-observer/notify.html --> |
OLD | NEW |