| <!doctype html> | |
| <script src="/resources/testharness.js"></script> | |
| <script src="/resources/testharnessreport.js"></script> | |
| <script src="./resources/resizeTestHelper.js"></script> | |
| <style> | |
| div { | |
| border: 1px dotted gray | |
| } | |
| .transform { | |
| transform: scale(2,2) rotate(90deg) | |
| } | |
| </style> | |
| <p>ResizeObserver tests</p> | |
| <div id="target1" style="width:100px;height:100px;">t1 | |
| <div id="target2" style="width:100px;height:100px;">t2 | |
| <div id="target3" style="width:100px;height:100px;">t3 | |
| <span id="inline">inline</span> | |
| </div> | |
| </div> | |
| </div> | |
| <div id="absolute" style="width:100.5px;height:100.5px;position:absolute;top:10.3px;left:10.3px"></div> | |
| <script> | |
| 'use strict'; | |
| let t1 = document.querySelector('#target1'); | |
| let t2 = document.querySelector('#target2'); | |
| let t3 = document.querySelector('#target3'); | |
| let abs = document.querySelector('#absolute'); | |
| let inline = document.querySelector('#inline'); | |
| function test0() { | |
| let helper = new ResizeTestHelper( | |
| "test0: notification ordering", | |
| [ | |
| { | |
| setup: observer => { | |
| observer.observe(t3); | |
| observer.observe(t2); | |
| observer.observe(t1); | |
| t1.style.width = "5px"; | |
| t3.style.width = "5px"; | |
| t2.style.width = "5px"; | |
| }, | |
| notify: (entries, observer) => { | |
| assert_equals(entries.length, 3, "3 resizes"); | |
| assert_equals(entries[0].target, t3, "ordering"); | |
| assert_equals(entries[1].target, t2, "ordering"); | |
| assert_equals(entries[2].target, t1, "ordering"); | |
| observer.disconnect(); | |
| t1.style.width = "100px"; | |
| t2.style.width = "100px"; | |
| t3.style.width = "100px"; | |
| } | |
| } | |
| ]); | |
| return helper.start(); | |
| } | |
| function test1() { | |
| let helper = new ResizeTestHelper( | |
| "test1: display:none triggers notification", | |
| [ | |
| { | |
| setup: observer => { | |
| observer.observe(t1); | |
| }, | |
| notify: (entries, observer) => { | |
| return true; // Delay next step | |
| } | |
| }, | |
| { | |
| setup: observer => { | |
| t1.style.display = "none"; | |
| }, | |
| notify: (entries, observer) => { | |
| t1.style.display = ""; | |
| } | |
| } | |
| ]); | |
| return helper.start(); | |
| } | |
| function test2() { | |
| let helper = new ResizeTestHelper( | |
| "test2: remove/appendChild trigger notification", | |
| [ | |
| { | |
| setup: observer => { | |
| observer.observe(t1); | |
| }, | |
| notify: (entries, observer) => { | |
| return true; // Delay next step | |
| } | |
| }, | |
| { // "removeChild triggers notification" | |
| setup: observer => { | |
| t1.parentNode.removeChild(t1); | |
| }, | |
| notify: (entries, observer) => { | |
| assert_equals(entries[0].target, t1); | |
| return true; // Delay next step | |
| } | |
| }, | |
| { // "appendChild triggers notification", | |
| setup: observer => { | |
| document.body.appendChild(t1); | |
| }, | |
| notify: (entries, observer) => { | |
| assert_equals(entries[0].target, t1) | |
| } | |
| } | |
| ]); | |
| return helper.start(); | |
| } | |
| function test3() { | |
| let helper = new ResizeTestHelper( | |
| "test3: dimensions match", | |
| [ | |
| { | |
| setup: observer => { | |
| observer.observe(t1); | |
| t1.style.width = "200.5px"; | |
| t1.style.height = "100px"; | |
| t1.style.paddingLeft = "20px"; | |
| t1.style.paddingTop = "10px"; | |
| }, | |
| notify: (entries, observer) => { | |
| assert_equals(entries[0].contentRect.left,20); | |
| assert_equals(entries[0].contentRect.top,10); | |
| assert_between_inclusive(entries[0].contentRect.width, 200.4, 200.6, "width is not rounded"); | |
| assert_equals(entries[0].contentRect.height, 100); | |
| } | |
| } | |
| ]); | |
| return helper.start(); | |
| } | |
| function test4() { | |
| let helper = new ResizeTestHelper( | |
| "test4: transform do not cause notifications", | |
| [ | |
| { | |
| setup: observer => { | |
| observer.observe(t2); | |
| }, | |
| notify: (entries, observer) => { | |
| return true; // Delay next step | |
| } | |
| }, | |
| { | |
| setup: observer => { | |
| t2.classList.add("transform"); | |
| }, | |
| notify: (entries, observer) => { | |
| assert_unreached("transform must not trigger notifications"); | |
| }, | |
| timeout: () => { | |
| t2.classList.remove("transform"); | |
| } | |
| } | |
| ]); | |
| return helper.start(); | |
| } | |
| function test5() { | |
| let helper = new ResizeTestHelper( | |
| "test5: moving an element does not trigger notifications", | |
| [ | |
| { | |
| setup: observer => { | |
| observer.observe(abs); | |
| }, | |
| notify: (entries, observer) => { | |
| return true; // Delay next step | |
| } | |
| }, | |
| { | |
| setup: observer => { | |
| abs.style.top = "20.33px"; | |
| abs.style.left = "20.33px"; | |
| }, | |
| notify: (entries, observer) => { | |
| assert_unreached("movement should not cause resize notifications"); | |
| }, | |
| timeout: () => { | |
| } | |
| } | |
| ]); | |
| return helper.start(); | |
| } | |
| function test6() { | |
| let helper = new ResizeTestHelper( | |
| "test6: inline element notifies once with 0x0.", | |
| [ | |
| { | |
| setup: observer => { | |
| observer.observe(inline); | |
| }, | |
| notify: (entries, observer) => { | |
| assert_equals(entries.length, 1, "observing inline element triggers notification"); | |
| assert_equals(entries[0].target, inline, "observing inline element triggers notification"); | |
| assert_equals(entries[0].contentRect.width, 0); | |
| assert_equals(entries[0].contentRect.height, 0); | |
| return true; // Delay next step | |
| } | |
| }, | |
| { | |
| setup: observer => { | |
| inline.style.width = "66px"; | |
| }, | |
| notify: (entries, observer) => { | |
| assert_unreached("resizing inline element should not cause resize notifications"); | |
| }, | |
| timeout: () => { | |
| // expected | |
| } | |
| }, | |
| { // "inline element that becomes block should notify", | |
| setup: observer => { | |
| inline.style.display = "block"; | |
| }, | |
| notify: (entries, observer) => { | |
| assert_equals(entries.length, 1, "inline element becoming a non-zero sized block triggers a notification"); | |
| assert_equals(entries[0].target, inline, "inline element becoming a non-zero sized block triggers a notification"); | |
| } | |
| } | |
| ]); | |
| return helper.start(); | |
| } | |
| function test7() { | |
| let helper = new ResizeTestHelper( | |
| "test7: unobserve inside notify callback", | |
| [ | |
| { | |
| setup: observer => { | |
| observer.observe(t1); | |
| observer.observe(t2); | |
| }, | |
| notify: (entries, observer) => { | |
| t1.style.width = "777px"; | |
| t2.style.width = "777px"; | |
| observer.unobserve(t1); | |
| return true; // Delay next step | |
| } | |
| }, | |
| { | |
| setup: observer => { | |
| }, | |
| notify: (entries, observer) => { | |
| assert_equals(entries.length, 1, "only t2 is observed"); | |
| assert_equals(entries[0].target, t2, "only t2 is observed"); | |
| } | |
| } | |
| ]); | |
| return helper.start(); | |
| } | |
| function test8() { | |
| let helper = new ResizeTestHelper( | |
| "test8: observe inside notify callback", | |
| [ | |
| { | |
| setup: observer => { | |
| observer.observe(t1); | |
| }, | |
| notify: (entries, observer) => { | |
| observer.observe(t2); | |
| t2.style.width = "888px"; | |
| return true; // Delay next step | |
| } | |
| }, | |
| { | |
| setup: observer => { | |
| }, | |
| notify: (entries, observer) => { | |
| assert_equals(entries.length, 1, "only t2 is observed"); | |
| assert_equals(entries[0].target, t2, "only t2 is observed"); | |
| } | |
| } | |
| ]); | |
| return helper.start(); | |
| } | |
| function test9() { | |
| let helper = new ResizeTestHelper( | |
| "test9: disconnect inside notify callback", | |
| [ | |
| { | |
| setup: observer => { | |
| observer.observe(t1); | |
| }, | |
| notify: (entries, observer) => { | |
| t1.style.width = "999px"; | |
| observer.disconnect(); | |
| return true; // Delay next step | |
| } | |
| }, | |
| { | |
| setup: observer => { | |
| }, | |
| notify: (entries, observer) => { | |
| assert_unreached("there should be no notifications after disconnect"); | |
| }, | |
| timeout: () => { | |
| } | |
| } | |
| ]); | |
| return helper.start(); | |
| } | |
| function test10() { | |
| var parent = t1.parentNode; | |
| let helper = new ResizeTestHelper( | |
| "test10: element notifies when parent removed", | |
| [ | |
| { | |
| setup: observer => { | |
| observer.observe(t3); | |
| }, | |
| notify: (entries, observer) => { | |
| return true; // Delay next step | |
| } | |
| }, | |
| { | |
| setup: observer => { | |
| t1.parentNode.removeChild(t1); | |
| }, | |
| notify: (entries, observer) => { | |
| assert_equals(entries.length, 1); | |
| assert_equals(entries[0].target, t3); | |
| parent.appendChild(t1); | |
| } | |
| } | |
| ]); | |
| return helper.start(); | |
| } | |
| function test11() { | |
| let t = createAndAppendElement("div"); | |
| t.style.display = "none"; | |
| let helper = new ResizeTestHelper( | |
| "test11: display:none element should be notified", | |
| [ | |
| { | |
| setup: observer => { | |
| observer.observe(t); | |
| }, | |
| notify: entries => { | |
| assert_equals(entries.length, 1, "1 pending notification"); | |
| assert_equals(entries[0].target, t, "target is t"); | |
| assert_equals(entries[0].contentRect.width, 0, "target width"); | |
| assert_equals(entries[0].contentRect.height, 0, "target height"); | |
| } | |
| } | |
| ]); | |
| return helper.start(() => t.remove()); | |
| } | |
| function test12() { | |
| let t = createAndAppendElement("div"); | |
| t.style.width = "0px"; | |
| let helper = new ResizeTestHelper( | |
| "test12: element sized 0x0 should be notified", | |
| [ | |
| { | |
| setup: observer => { | |
| observer.observe(t); | |
| }, | |
| notify: entries => { | |
| assert_equals(entries.length, 1, "1 pending notification"); | |
| assert_equals(entries[0].target, t, "target is t"); | |
| assert_equals(entries[0].contentRect.width, 0, "target width"); | |
| assert_equals(entries[0].contentRect.height, 0, "target height"); | |
| } | |
| } | |
| ]); | |
| return helper.start(() => t.remove()); | |
| } | |
| let guard; | |
| test(_ => { | |
| assert_own_property(window, "ResizeObserver"); | |
| guard = async_test('guard'); | |
| }, "ResizeObserver implemented") | |
| test0() | |
| .then(() => { return test1(); }) | |
| .then(() => { return test2(); }) | |
| .then(() => { return test3(); }) | |
| .then(() => { return test4(); }) | |
| .then(() => { return test5(); }) | |
| .then(() => { return test6(); }) | |
| .then(() => { return test7(); }) | |
| .then(() => { return test8(); }) | |
| .then(() => { return test9(); }) | |
| .then(() => { return test10(); }) | |
| .then(() => { return test11(); }) | |
| .then(() => { return test12(); }) | |
| .then(() => { guard.done(); }); | |
| </script> |