tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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>