observe.html (35800B)
1 <!doctype html> 2 <title>ResizeObserver tests</title> 3 <script src="/resources/testharness.js"></script> 4 <script src="/resources/testharnessreport.js"></script> 5 <script src="./resources/resizeTestHelper.js"></script> 6 <body> 7 <div id="log"></div> 8 9 <script> 10 'use strict'; 11 12 function test0() { 13 let t = createAndAppendElement("div"); 14 t.style.width = "100px"; 15 16 let helper = new ResizeTestHelper( 17 "test0: simple observation", 18 [ 19 { 20 setup: observer => { 21 observer.observe(t); 22 t.style.width = "5px"; 23 }, 24 notify: entries => { 25 assert_equals(entries.length, 1, "1 pending notification"); 26 assert_equals(entries[0].target, t, "target is t"); 27 assert_equals(entries[0].contentRect.width, 5, "target width"); 28 } 29 } 30 ]); 31 return helper.start(() => t.remove()); 32 } 33 34 function test1() { 35 let t = createAndAppendElement("div"); 36 t.style.width = "100px"; 37 38 let helper = new ResizeTestHelper( 39 "test1: multiple observation on same element trigger only one", 40 [ 41 { 42 setup: observer => { 43 observer.observe(t); 44 observer.observe(t); 45 t.style.width = "10px"; 46 }, 47 notify: entries => { 48 assert_equals(entries.length, 1, "1 pending notification"); 49 } 50 } 51 ]); 52 return helper.start(() => t.remove()); 53 } 54 55 function test2() { 56 test(() => { 57 assert_throws_js(TypeError, _=> { 58 let ro = new ResizeObserver(() => {}); 59 ro.observe({}); 60 }); 61 }, 62 "test2: throw exception when observing non-element" 63 ); 64 return Promise.resolve(); 65 } 66 67 function test3() { 68 let t1 = createAndAppendElement("div"); 69 let t2 = createAndAppendElement("div"); 70 t1.style.width = "100px"; 71 t2.style.width = "100px"; 72 73 let helper = new ResizeTestHelper( 74 "test3: disconnect stops all notifications", [ 75 { 76 setup: observer => { 77 observer.observe(t1); 78 observer.observe(t2); 79 observer.disconnect(); 80 t1.style.width = "30px"; 81 }, 82 notify: entries => { 83 assert_unreached("no entries should be observed"); 84 }, 85 timeout: () => { 86 // expected 87 } 88 } 89 ]); 90 return helper.start(() => { 91 t1.remove(); 92 t2.remove(); 93 }); 94 } 95 96 function test4() { 97 let t1 = createAndAppendElement("div"); 98 let t2 = createAndAppendElement("div"); 99 t1.style.width = "100px"; 100 t2.style.width = "100px"; 101 102 let helper = new ResizeTestHelper( 103 "test4: unobserve target stops notifications, unobserve non-observed does nothing", [ 104 { 105 setup: observer => { 106 observer.observe(t1); 107 observer.observe(t2); 108 observer.unobserve(t1); 109 observer.unobserve(document.body); 110 t1.style.width = "40px"; 111 t2.style.width = "40px"; 112 }, 113 notify: entries => { 114 assert_equals(entries.length, 1, "only t2"); 115 assert_equals(entries[0].target, t2, "t2 was observed"); 116 } 117 } 118 ]); 119 return helper.start(() => { 120 t1.remove(); 121 t2.remove(); 122 }); 123 } 124 125 function test5() { 126 const img = new Image(); 127 img.style.width = "15px"; 128 img.style.height = "15px"; 129 img.src = "resources/image.png"; 130 131 return img.decode().then(() => { 132 return new Promise(resolve => { 133 requestAnimationFrame(() => { 134 document.body.appendChild(img); 135 resolve(); 136 }); 137 }); 138 }).then(() => { 139 let helper = new ResizeTestHelper("test5: observe img",[ 140 { 141 setup: observer => { 142 observer.observe(img); 143 }, 144 notify: entries => { 145 return true; 146 } 147 }, 148 { 149 setup: observer => { 150 img.style.width = "15.5px"; 151 }, 152 notify: entries => { 153 assert_equals(entries.length, 1); 154 assert_equals(entries[0].contentRect.width, 15.5); 155 } 156 } 157 ]); 158 return helper.start(() => img.remove()); 159 }, () => { 160 // dummy test for dumping the error message. 161 test(_ => { 162 assert_unreached("decode image failed"); 163 }, "test5: observe img"); 164 }); 165 } 166 167 function test6() { 168 let iframe = createAndAppendElement("iframe"); 169 iframe.width = "300px"; 170 iframe.height = "100px"; 171 iframe.style.display = "block"; 172 173 let resolvePromise; 174 let promise = new Promise((resolve) => { 175 resolvePromise = resolve; 176 }); 177 let test = async_test('test6: iframe notifications'); 178 let testRequested = false; 179 test.add_cleanup(() => iframe.remove()); 180 181 window.addEventListener('message', event => { 182 switch(event.data) { 183 case 'readyToTest': 184 if (!testRequested) { 185 iframe.contentWindow.postMessage('startTest', '*'); 186 testRequested = true; 187 } 188 break; 189 case 'success': 190 case 'fail': 191 window.requestAnimationFrame(() => { 192 resolvePromise(); 193 test.step(() => { 194 assert_equals(event.data, 'success'); 195 test.done(); 196 }); 197 }); 198 break; 199 } 200 }, false); 201 202 iframe.src = "./resources/iframe.html"; 203 return new Promise(function(resolve, reject) { 204 iframe.onload = () => resolve(); 205 iframe.onerror = () => reject(); 206 }).then(() => { 207 return promise; 208 }).catch(error => { 209 test.step(() => { 210 assert_unreached("loading iframe is error"); 211 }); 212 }); 213 } 214 215 function test7() { 216 let harnessTest = async_test("test7: callback.this"); 217 let resolvePromise; 218 let ro = new ResizeObserver( function(entries, obs) { 219 let callbackThis = this; 220 harnessTest.step(() => { 221 assert_equals(callbackThis, ro, "callback.this is ResizeObserver"); 222 assert_equals(obs, ro, "2nd argument is ResizeObserver"); 223 ro.disconnect(); 224 // every reference to RO must be null before test completes 225 // to avoid triggering test leak-detection 226 ro = null; 227 callbackThis = null; 228 obs = null; 229 harnessTest.step_timeout( _ => { 230 harnessTest.done(); 231 resolvePromise(); 232 }, 0); 233 }); 234 } 235 ); 236 237 let t = createAndAppendElement("div"); 238 t.style.width = "100px"; 239 harnessTest.add_cleanup(() => t.remove()); 240 241 ro.observe(t); 242 243 return new Promise( (resolve, reject) => { 244 resolvePromise = resolve; 245 }); 246 } 247 248 function test8() { 249 let t = createAndAppendElement("div"); 250 t.style.width = "100px"; 251 t.style.height = "100px"; 252 253 let helper = new ResizeTestHelper( 254 "test8: simple content-box observation", 255 [ 256 { 257 setup: observer => { 258 259 observer.observe(t, { box: "content-box" }); 260 }, 261 notify: entries => { 262 assert_equals(entries.length, 1, "1 pending notification"); 263 assert_equals(entries[0].target, t, "target is t"); 264 assert_equals(entries[0].contentRect.width, 100, "target width"); 265 assert_equals(entries[0].contentRect.height, 100, "target height"); 266 assert_equals(entries[0].contentRect.top, 0, "target top padding"); 267 assert_equals(entries[0].contentRect.left, 0, "target left padding"); 268 assert_equals(entries[0].contentBoxSize[0].inlineSize, 100, 269 "target content-box inline size"); 270 assert_equals(entries[0].contentBoxSize[0].blockSize, 100, 271 "target content-box block size"); 272 assert_equals(entries[0].borderBoxSize[0].inlineSize, 100, 273 "target border-box inline size"); 274 assert_equals(entries[0].borderBoxSize[0].blockSize, 100, 275 "target border-box block size"); 276 return true; 277 } 278 }, 279 { 280 setup: observer => { 281 t.style.width = "90px"; 282 t.style.height = "90px"; 283 }, 284 notify: entries => { 285 assert_equals(entries.length, 1, "1 pending notification"); 286 assert_equals(entries[0].target, t, "target is t"); 287 assert_equals(entries[0].contentRect.width, 90, "target width"); 288 assert_equals(entries[0].contentRect.height, 90, "target height"); 289 assert_equals(entries[0].contentRect.top, 0, "target top padding"); 290 assert_equals(entries[0].contentRect.left, 0, "target left padding"); 291 assert_equals(entries[0].contentBoxSize[0].inlineSize, 90, 292 "target content-box inline size"); 293 assert_equals(entries[0].contentBoxSize[0].blockSize, 90, 294 "target content-box block size"); 295 assert_equals(entries[0].borderBoxSize[0].inlineSize, 90, 296 "target border-box inline size"); 297 assert_equals(entries[0].borderBoxSize[0].blockSize, 90, 298 "target border-box block size"); 299 return true; 300 } 301 }, 302 { 303 setup: observer => { 304 t.style.padding = "5px"; 305 }, 306 notify: entries => { 307 assert_unreached("the 'content-box' ResizeObserver shouldn't fire " + 308 "for restyles that don't affect the content-box size"); 309 }, 310 timeout: () => { 311 // expected 312 // Note: the border-box size is 100px x 100px right now. 313 } 314 } 315 ]); 316 return helper.start(() => t.remove()); 317 } 318 319 function test9() { 320 let t = createAndAppendElement("div"); 321 t.style.width = "100px"; 322 t.style.height = "100px"; 323 324 let helper = new ResizeTestHelper( 325 "test9: simple content-box observation but keep border-box size unchanged", 326 [ 327 { 328 setup: observer => { 329 observer.observe(t, { box: "content-box" }); 330 }, 331 notify: entries => { 332 assert_equals(entries.length, 1, "1 pending notification"); 333 assert_equals(entries[0].target, t, "target is t"); 334 assert_equals(entries[0].contentRect.width, 100, "target width"); 335 assert_equals(entries[0].contentRect.height, 100, "target height"); 336 assert_equals(entries[0].contentRect.top, 0, "target top padding"); 337 assert_equals(entries[0].contentRect.left, 0, "target left padding"); 338 assert_equals(entries[0].contentBoxSize[0].inlineSize, 100, 339 "target content-box inline size"); 340 assert_equals(entries[0].contentBoxSize[0].blockSize, 100, 341 "target content-box block size"); 342 assert_equals(entries[0].borderBoxSize[0].inlineSize, 100, 343 "target border-box inline size"); 344 assert_equals(entries[0].borderBoxSize[0].blockSize, 100, 345 "target border-box block size"); 346 return true; 347 } 348 }, 349 { 350 setup: observer => { 351 // Keep the border-box size the same, and change the content-box size. 352 t.style.width = "92px"; 353 t.style.height = "92px"; 354 t.style.padding = "4px"; 355 }, 356 notify: entries => { 357 assert_equals(entries.length, 1, "1 pending notification"); 358 assert_equals(entries[0].target, t, "target is t"); 359 assert_equals(entries[0].contentRect.width, 92, "target width"); 360 assert_equals(entries[0].contentRect.height, 92, "target height"); 361 assert_equals(entries[0].contentRect.top, 4, "target top padding"); 362 assert_equals(entries[0].contentRect.left, 4, "target left padding"); 363 assert_equals(entries[0].contentBoxSize[0].inlineSize, 92, 364 "target content-box inline size"); 365 assert_equals(entries[0].contentBoxSize[0].blockSize, 92, 366 "target content-box block size"); 367 assert_equals(entries[0].borderBoxSize[0].inlineSize, 100, 368 "target border-box inline size"); 369 assert_equals(entries[0].borderBoxSize[0].blockSize, 100, 370 "target border-box block size"); 371 } 372 } 373 ]); 374 return helper.start(() => t.remove()); 375 } 376 377 function test10() { 378 let t = createAndAppendElement("div"); 379 t.style.width = "100px"; 380 t.style.height = "100px"; 381 382 let helper = new ResizeTestHelper( 383 "test10: simple border-box observation", 384 [ 385 { 386 setup: observer => { 387 observer.observe(t, { box: "border-box" }); 388 }, 389 notify: entries => { 390 assert_equals(entries.length, 1, "1 pending notification"); 391 assert_equals(entries[0].target, t, "target is t"); 392 assert_equals(entries[0].contentRect.width, 100, "target width"); 393 assert_equals(entries[0].contentRect.height, 100, "target height"); 394 assert_equals(entries[0].contentRect.top, 0, "target top padding"); 395 assert_equals(entries[0].contentRect.left, 0, "target left padding"); 396 assert_equals(entries[0].contentBoxSize[0].inlineSize, 100, 397 "target content-box inline size"); 398 assert_equals(entries[0].contentBoxSize[0].blockSize, 100, 399 "target content-box block size"); 400 assert_equals(entries[0].borderBoxSize[0].inlineSize, 100, 401 "target border-box inline size"); 402 assert_equals(entries[0].borderBoxSize[0].blockSize, 100, 403 "target border-box block size"); 404 return true; 405 } 406 }, 407 { 408 setup: observer => { 409 t.style.padding = "4px"; 410 }, 411 notify: entries => { 412 assert_equals(entries.length, 1, "1 pending notification"); 413 assert_equals(entries[0].target, t, "target is t"); 414 assert_equals(entries[0].contentRect.width, 100, "target width"); 415 assert_equals(entries[0].contentRect.height, 100, "target height"); 416 assert_equals(entries[0].contentRect.top, 4, "target top padding"); 417 assert_equals(entries[0].contentRect.left, 4, "target left padding"); 418 assert_equals(entries[0].contentBoxSize[0].inlineSize, 100, 419 "target content-box inline size"); 420 assert_equals(entries[0].contentBoxSize[0].blockSize, 100, 421 "target content-box block size"); 422 assert_equals(entries[0].borderBoxSize[0].inlineSize, 108, 423 "target border-box inline size"); 424 assert_equals(entries[0].borderBoxSize[0].blockSize, 108, 425 "target border-box block size"); 426 } 427 }, 428 { 429 setup: observer => { 430 t.style.width = "104px"; 431 t.style.height = "104px"; 432 t.style.padding = "2px"; 433 }, 434 notify: entries => { 435 assert_unreached("the 'border-box' ResizeObserver shouldn't fire " + 436 "for restyles that don't affect the border-box size"); 437 }, 438 timeout: () => { 439 // expected: 104 + 2 * 2 = 108. The border-box size is the same. 440 } 441 } 442 ]); 443 return helper.start(() => t.remove()); 444 } 445 446 function test11() { 447 let wrapper = createAndAppendElement("div"); 448 wrapper.style.width = "100px"; 449 wrapper.style.height = "100px"; 450 wrapper.style.writingMode = "vertical-rl"; 451 let t = createAndAppendElement("div", wrapper); 452 t.style.inlineSize = "50px"; 453 t.style.blockSize = "50px"; 454 455 let helper = new ResizeTestHelper( 456 "test11: simple observation with vertical writing mode", 457 [ 458 { 459 setup: observer => { 460 observer.observe(t); 461 }, 462 notify: entries => { 463 assert_equals(entries.length, 1, "1 pending notification"); 464 assert_equals(entries[0].target, t, "target is t"); 465 assert_equals(entries[0].contentRect.width, 50, "target width"); 466 assert_equals(entries[0].contentRect.height, 50, "target height"); 467 assert_equals(entries[0].contentBoxSize[0].inlineSize, 50, 468 "target content-box inline size"); 469 assert_equals(entries[0].contentBoxSize[0].blockSize, 50, 470 "target content-box block size"); 471 assert_equals(entries[0].borderBoxSize[0].inlineSize, 50, 472 "target border-box inline size"); 473 assert_equals(entries[0].borderBoxSize[0].blockSize, 50, 474 "target border-box block size"); 475 return true; 476 } 477 }, 478 { 479 setup: observer => { 480 t.style.blockSize = "75px"; 481 }, 482 notify: entries => { 483 assert_equals(entries.length, 1, "1 pending notification"); 484 assert_equals(entries[0].target, t, "target is t"); 485 assert_equals(entries[0].contentRect.width, 75, "target width"); 486 assert_equals(entries[0].contentRect.height, 50, "target height"); 487 assert_equals(entries[0].contentBoxSize[0].inlineSize, 50, 488 "target content-box inline size"); 489 assert_equals(entries[0].contentBoxSize[0].blockSize, 75, 490 "target content-box block size"); 491 assert_equals(entries[0].borderBoxSize[0].inlineSize, 50, 492 "target border-box inline size"); 493 assert_equals(entries[0].borderBoxSize[0].blockSize, 75, 494 "target border-box block size"); 495 } 496 } 497 ]); 498 499 return helper.start(() => { 500 t.remove(); 501 wrapper.remove(); 502 }); 503 } 504 505 function test12() { 506 let t = createAndAppendElement("div"); 507 t.style.writingMode = "vertical-lr"; 508 t.style.inlineSize = "100px"; 509 t.style.blockSize = "50px"; 510 511 let helper = new ResizeTestHelper( 512 "test12: no observation is fired after the change of writing mode when " + 513 "box's specified size comes from logical size properties.", 514 [ 515 { 516 setup: observer => { 517 observer.observe(t); 518 }, 519 notify: entries => { 520 assert_equals(entries.length, 1, "1 pending notification"); 521 assert_equals(entries[0].target, t, "target is t"); 522 assert_equals(entries[0].contentRect.width, 50, "target width"); 523 assert_equals(entries[0].contentRect.height, 100, "target height"); 524 assert_equals(entries[0].contentBoxSize[0].inlineSize, 100, 525 "target content-box inline size"); 526 assert_equals(entries[0].contentBoxSize[0].blockSize, 50, 527 "target content-box block size"); 528 return true; 529 } 530 }, 531 { 532 setup: observer => { 533 t.style.writingMode = "horizontal-tb"; 534 }, 535 notify: entries => { 536 assert_unreached("the logical size of content-box doesn't change"); 537 }, 538 timeout: () => { 539 // expected: We don't change the logical size of content-box. 540 } 541 } 542 ]); 543 544 return helper.start(() => t.remove()); 545 } 546 547 function test13() { 548 let t = createAndAppendElement("div"); 549 t.style.writingMode = "vertical-lr"; 550 t.style.height = "100px"; 551 t.style.width = "50px"; 552 553 let helper = new ResizeTestHelper( 554 "test13: an observation is fired after the change of writing mode when " + 555 "box's specified size comes from physical size properties.", 556 [ 557 { 558 setup: observer => { 559 observer.observe(t); 560 }, 561 notify: entries => { 562 assert_equals(entries.length, 1, "1 pending notification"); 563 assert_equals(entries[0].target, t, "target is t"); 564 assert_equals(entries[0].contentRect.width, 50, "target width"); 565 assert_equals(entries[0].contentRect.height, 100, "target height"); 566 assert_equals(entries[0].contentBoxSize[0].inlineSize, 100, 567 "target content-box inline size"); 568 assert_equals(entries[0].contentBoxSize[0].blockSize, 50, 569 "target content-box block size"); 570 return true; 571 } 572 }, 573 { 574 setup: observer => { 575 t.style.writingMode = "horizontal-tb"; 576 }, 577 notify: entries => { 578 assert_equals(entries.length, 1, "1 pending notification"); 579 assert_equals(entries[0].target, t, "target is t"); 580 assert_equals(entries[0].contentRect.width, 50, "target width"); 581 assert_equals(entries[0].contentRect.height, 100, "target height"); 582 assert_equals(entries[0].contentBoxSize[0].inlineSize, 50, 583 "target content-box inline size"); 584 assert_equals(entries[0].contentBoxSize[0].blockSize, 100, 585 "target content-box block size"); 586 }, 587 } 588 ]); 589 590 return helper.start(() => t.remove()); 591 } 592 593 function test14() { 594 let t = createAndAppendElement("div"); 595 t.style.width = "100px"; 596 t.style.height = "100px"; 597 598 let helper = new ResizeTestHelper( 599 "test14: observe the same target but using a different box should " + 600 "override the previous one", 601 [ 602 { 603 setup: observer => { 604 observer.observe(t, { box: "content-box" }); 605 observer.observe(t, { box: "border-box" }); 606 }, 607 notify: entries => { 608 assert_equals(entries.length, 1, "1 pending notification"); 609 assert_equals(entries[0].target, t, "target is t"); 610 assert_equals(entries[0].contentRect.width, 100, "target width"); 611 assert_equals(entries[0].contentRect.height, 100, "target height"); 612 assert_equals(entries[0].contentRect.top, 0, "target top padding"); 613 assert_equals(entries[0].contentRect.left, 0, "target left padding"); 614 assert_equals(entries[0].contentBoxSize[0].inlineSize, 100, 615 "target content-box inline size"); 616 assert_equals(entries[0].contentBoxSize[0].blockSize, 100, 617 "target content-box block size"); 618 assert_equals(entries[0].borderBoxSize[0].inlineSize, 100, 619 "target border-box inline size"); 620 assert_equals(entries[0].borderBoxSize[0].blockSize, 100, 621 "target border-box block size"); 622 return true; 623 } 624 }, 625 { 626 setup: observer => { 627 // Change border-box size. 628 t.style.padding = "4px"; 629 }, 630 notify: entries => { 631 assert_equals(entries.length, 1, "1 pending notification"); 632 assert_equals(entries[0].target, t, "target is t"); 633 assert_equals(entries[0].contentRect.width, 100, "target width"); 634 assert_equals(entries[0].contentRect.height, 100, "target height"); 635 assert_equals(entries[0].contentRect.top, 4, "target top padding"); 636 assert_equals(entries[0].contentRect.left, 4, "target left padding"); 637 assert_equals(entries[0].contentBoxSize[0].inlineSize, 100, 638 "target content-box inline size"); 639 assert_equals(entries[0].contentBoxSize[0].blockSize, 100, 640 "target content-box block size"); 641 assert_equals(entries[0].borderBoxSize[0].inlineSize, 108, 642 "target border-box inline size"); 643 assert_equals(entries[0].borderBoxSize[0].blockSize, 108, 644 "target border-box block size"); 645 } 646 }, 647 { 648 setup: observer => { 649 // Change only content-box size. 650 t.style.width = "104px"; 651 t.style.height = "104px"; 652 t.style.padding = "2px"; 653 }, 654 notify: entries => { 655 assert_unreached("the 'border-box' ResizeObserver shouldn't fire " + 656 "for restyles that don't affect the border-box size"); 657 }, 658 timeout: () => { 659 // expected: 104 + 2 * 2 = 108. The border-box size is the same. 660 } 661 } 662 ]); 663 return helper.start(() => t.remove()); 664 } 665 666 function test15() { 667 let t = createAndAppendElement("div"); 668 t.style.height = "100px"; 669 t.style.width = "50px"; 670 671 let helper = new ResizeTestHelper( 672 "test15: an observation is fired with box dimensions 0 when element's " + 673 "display property is set to inline", 674 [ 675 { 676 setup: observer => { 677 observer.observe(t); 678 }, 679 notify: entries => { 680 assert_equals(entries.length, 1, "1 pending notification"); 681 assert_equals(entries[0].target, t, "target is t"); 682 assert_equals(entries[0].contentRect.width, 50, "target width"); 683 assert_equals(entries[0].contentRect.height, 100, "target height"); 684 assert_equals(entries[0].contentBoxSize[0].inlineSize, 50, 685 "target content-box inline size"); 686 assert_equals(entries[0].contentBoxSize[0].blockSize, 100, 687 "target content-box block size"); 688 assert_equals(entries[0].borderBoxSize[0].inlineSize, 50, 689 "target content-box inline size"); 690 assert_equals(entries[0].borderBoxSize[0].blockSize, 100, 691 "target content-box block size"); 692 return true; 693 } 694 }, 695 { 696 setup: observer => { 697 t.style.display = "inline"; 698 }, 699 notify: entries => { 700 assert_equals(entries[0].contentRect.width, 0, "target width"); 701 assert_equals(entries[0].contentRect.height, 0, "target height"); 702 assert_equals(entries[0].contentBoxSize[0].inlineSize, 0, 703 "target content-box inline size"); 704 assert_equals(entries[0].contentBoxSize[0].blockSize, 0, 705 "target content-box block size"); 706 assert_equals(entries[0].borderBoxSize[0].inlineSize, 0, 707 "target border-box inline size"); 708 assert_equals(entries[0].borderBoxSize[0].blockSize, 0, 709 "target border-box block size"); 710 } 711 } 712 ]); 713 714 return helper.start(() => t.remove()); 715 } 716 717 function test16() { 718 let t = createAndAppendElement("span"); 719 720 let helper = new ResizeTestHelper( 721 // See: https://drafts.csswg.org/resize-observer/#intro. 722 "test16: observations fire once with 0x0 size for non-replaced inline elements", 723 [ 724 { 725 setup: observer => { 726 observer.observe(t); 727 }, 728 notify: entries => { 729 assert_equals(entries.length, 1, "1 pending notification"); 730 assert_equals(entries[0].target, t, "target is t"); 731 assert_equals(entries[0].contentRect.width, 0, "target width"); 732 assert_equals(entries[0].contentRect.height, 0, "target height"); 733 assert_equals(entries[0].contentBoxSize[0].inlineSize, 0, 734 "target content-box inline size"); 735 assert_equals(entries[0].contentBoxSize[0].blockSize, 0, 736 "target content-box block size"); 737 assert_equals(entries[0].borderBoxSize[0].inlineSize, 0, 738 "target border-box inline size"); 739 assert_equals(entries[0].borderBoxSize[0].blockSize, 0, 740 "target border-box block size"); 741 } 742 } 743 ]); 744 745 return helper.start(() => t.remove()); 746 747 } 748 749 function test17() { 750 // <div id="outer"> 751 // <div id="nested"> 752 // </div> 753 // </div> 754 755 let outer = document.createElement('div'); 756 outer.style.width = "100px"; 757 outer.style.height = "100px"; 758 outer.style.padding = "10px"; 759 outer.style.border = "1px solid blue" 760 let nested = document.createElement('div'); 761 nested.style.width = "60px"; 762 nested.style.height = "50px"; 763 nested.style.padding = "5%"; 764 nested.style.boxSizing = "border-box"; 765 nested.style.border = "5px solid black"; 766 outer.appendChild(nested); 767 document.body.appendChild(outer); 768 769 let helper = new ResizeTestHelper( 770 "test17: Box sizing snd Resize Observer notifications", 771 [ 772 { 773 setup: observer => { 774 observer.observe(nested, { box: "content-box" }); 775 }, 776 notify: entries => { 777 assert_equals(entries.length, 1, "1 pending notification"); 778 assert_equals(entries[0].target, nested, "target is nested"); 779 assert_equals(entries[0].contentRect.width, 40, "target width"); 780 assert_equals(entries[0].contentRect.height, 30, "target height"); 781 assert_equals(entries[0].contentRect.top, 5, "target top padding"); 782 assert_equals(entries[0].contentRect.left, 5, "target left padding"); 783 assert_equals(entries[0].contentBoxSize[0].inlineSize, 40, 784 "target content-box inline size"); 785 assert_equals(entries[0].contentBoxSize[0].blockSize, 30, 786 "target content-box block size"); 787 assert_equals(entries[0].borderBoxSize[0].inlineSize, 60, 788 "target border-box inline size"); 789 assert_equals(entries[0].borderBoxSize[0].blockSize, 50, 790 "target border-box block size"); 791 return true; 792 } 793 }, 794 { 795 // Changes to a parent's dimensions with a child's padding set as a percentage 796 // should fire observation if content-box is being observed 797 setup: observer => { 798 outer.style.height = "200px"; 799 outer.style.width = "200px"; 800 }, 801 notify: entries => { 802 assert_equals(entries.length, 1, "1 pending notification"); 803 assert_equals(entries[0].target, nested, "target is nested"); 804 assert_equals(entries[0].contentRect.width, 30, "target width"); 805 assert_equals(entries[0].contentRect.height, 20, "target height"); 806 assert_equals(entries[0].contentRect.top, 10, "target top padding"); 807 assert_equals(entries[0].contentRect.left, 10, "target left padding"); 808 assert_equals(entries[0].contentBoxSize[0].inlineSize, 30, 809 "target content-box inline size"); 810 assert_equals(entries[0].contentBoxSize[0].blockSize, 20, 811 "target content-box block size"); 812 assert_equals(entries[0].borderBoxSize[0].inlineSize, 60, 813 "target border-box inline size"); 814 assert_equals(entries[0].borderBoxSize[0].blockSize, 50, 815 "target border-box block size"); 816 return true; 817 } 818 }, 819 { 820 // Changes to a parent's dimensions with a child's padding set as a percentage 821 // should fire observation if content-box is being observed 822 setup: observer => { 823 nested.style.border = "1px solid black"; 824 }, 825 notify: entries => { 826 assert_equals(entries.length, 1, "1 pending notification"); 827 assert_equals(entries[0].target, nested, "target is nested"); 828 assert_equals(entries[0].contentRect.width, 38, "target width"); 829 assert_equals(entries[0].contentRect.height, 28, "target height"); 830 assert_equals(entries[0].contentRect.top, 10, "target top padding"); 831 assert_equals(entries[0].contentRect.left, 10, "target left padding"); 832 assert_equals(entries[0].contentBoxSize[0].inlineSize, 38, 833 "target content-box inline size"); 834 assert_equals(entries[0].contentBoxSize[0].blockSize, 28, 835 "target content-box block size"); 836 assert_equals(entries[0].borderBoxSize[0].inlineSize, 60, 837 "target border-box inline size"); 838 assert_equals(entries[0].borderBoxSize[0].blockSize, 50, 839 "target border-box block size"); 840 return true; 841 } 842 }, 843 { 844 setup: observer => { 845 observer.observe(nested, { box: "border-box" }); 846 }, 847 notify: entries => { 848 assert_equals(entries.length, 1, "1 pending notification"); 849 assert_equals(entries[0].target, nested, "target is nested"); 850 assert_equals(entries[0].contentRect.width, 38, "target width"); 851 assert_equals(entries[0].contentRect.height, 28, "target height"); 852 assert_equals(entries[0].contentRect.top, 10, "target top padding"); 853 assert_equals(entries[0].contentRect.left, 10, "target left padding"); 854 assert_equals(entries[0].contentBoxSize[0].inlineSize, 38, 855 "target content-box inline size"); 856 assert_equals(entries[0].contentBoxSize[0].blockSize, 28, 857 "target content-box block size"); 858 assert_equals(entries[0].borderBoxSize[0].inlineSize, 60, 859 "target border-box inline size"); 860 assert_equals(entries[0].borderBoxSize[0].blockSize, 50, 861 "target border-box block size"); 862 return true; 863 } 864 }, 865 { 866 // Changes to a parent's dimensions with a child's padding set as a percentage 867 // should not fire observation if border-box is being observed 868 setup: observer => { 869 outer.style.height = "100px"; 870 }, 871 notify: entries => { 872 assert_unreached("No observation should be fired when nested border box remains constant"); 873 }, 874 timeout: () => { 875 // expected 876 } 877 }, 878 879 ]); 880 return helper.start(() => nested.remove()); 881 } 882 883 function test18() { 884 let t = createAndAppendElement("div"); 885 t.style.height = "100px"; 886 t.style.width = "50px"; 887 888 let helper = new ResizeTestHelper( 889 "test18: an observation is fired when device-pixel-content-box is being " + 890 "observed", 891 [ 892 { 893 setup: observer => { 894 observer.observe(t, {box: "device-pixel-content-box"}); 895 }, 896 notify: entries => { 897 assert_equals(entries.length, 1, "1 pending notification"); 898 assert_equals(entries[0].target, t, "target is t"); 899 assert_equals(entries[0].contentRect.width, 50, "target width"); 900 assert_equals(entries[0].contentRect.height, 100, "target height"); 901 assert_equals(entries[0].contentBoxSize[0].inlineSize, 50, 902 "target content-box inline size"); 903 assert_equals(entries[0].contentBoxSize[0].blockSize, 100, 904 "target content-box block size"); 905 assert_equals(entries[0].borderBoxSize[0].inlineSize, 50, 906 "target border-box inline size"); 907 assert_equals(entries[0].borderBoxSize[0].blockSize, 100, 908 "target border-box block size"); 909 assert_equals(entries[0].devicePixelContentBoxSize[0].inlineSize, 50, 910 "target device-pixel-content-box inline size"); 911 assert_equals(entries[0].devicePixelContentBoxSize[0].blockSize, 100, 912 "target device-pixel-content-box block size"); 913 } 914 }, 915 ]); 916 917 return helper.start(() => t.remove()); 918 } 919 920 function test19() { 921 // zoom is not a standard css property, so we should check it first. If the 922 // browser doesn't support it, we skip this test. 923 if (!CSS.supports("zoom", "3")) { 924 return Promise.resolve(); 925 } 926 927 let t = createAndAppendElement("div"); 928 t.style.height = "100px"; 929 t.style.width = "50px"; 930 931 let helper = new ResizeTestHelper( 932 "test19: an observation is fired when device-pixel-content-box is being " + 933 "observed and zoom change", 934 [ 935 { 936 setup: observer => { 937 observer.observe(t, {box: "device-pixel-content-box"}); 938 }, 939 notify: entries => { 940 // No need to test again (see test18), so skip this event loop. 941 return true; 942 } 943 }, 944 { 945 setup: observer => { 946 document.body.style.zoom = 3; 947 }, 948 notify: entries => { 949 assert_equals(entries.length, 1, "1 pending notification"); 950 assert_equals(entries[0].target, t, "target is t"); 951 assert_equals(entries[0].contentRect.width, 50, "target width"); 952 assert_equals(entries[0].contentRect.height, 100, "target height"); 953 assert_equals(entries[0].contentBoxSize[0].inlineSize, 50, 954 "target content-box inline size"); 955 assert_equals(entries[0].contentBoxSize[0].blockSize, 100, 956 "target content-box block size"); 957 assert_equals(entries[0].borderBoxSize[0].inlineSize, 50, 958 "target border-box inline size"); 959 assert_equals(entries[0].borderBoxSize[0].blockSize, 100, 960 "target border-box block size"); 961 assert_equals(entries[0].devicePixelContentBoxSize[0].inlineSize, 150, 962 "target device-pixel-content-box inline size"); 963 assert_equals(entries[0].devicePixelContentBoxSize[0].blockSize, 300, 964 "target device-pixel-content-box block size"); 965 return true; 966 } 967 }, 968 { 969 setup: observer => { 970 document.body.style.zoom = ''; 971 }, 972 notify: entries => {} 973 } 974 ]); 975 976 return helper.start(() => t.remove()); 977 } 978 979 let guard; 980 test(_ => { 981 assert_own_property(window, "ResizeObserver"); 982 guard = async_test('guard'); 983 }, "ResizeObserver implemented") 984 985 test0() 986 .then(() => test1()) 987 .then(() => test2()) 988 .then(() => test3()) 989 .then(() => test4()) 990 .then(() => test5()) 991 .then(() => test6()) 992 .then(() => test7()) 993 .then(() => test8()) 994 .then(() => test9()) 995 .then(() => test10()) 996 .then(() => test11()) 997 .then(() => test12()) 998 .then(() => test13()) 999 .then(() => test14()) 1000 .then(() => test15()) 1001 .then(() => test16()) 1002 .then(() => test17()) 1003 .then(() => test18()) 1004 .then(() => test19()) 1005 .then(() => guard.done()); 1006 1007 </script>