mirror of
https://github.com/servo/servo.git
synced 2025-09-05 20:48:22 +01:00
Update web-platform-tests to revision 8a2ceb5f18911302b7a5c1cd2791f4ab50ad4326
This commit is contained in:
parent
462c272380
commit
1f531f66ea
5377 changed files with 174916 additions and 84369 deletions
2
tests/wpt/web-platform-tests/resize-observer/OWNERS
Normal file
2
tests/wpt/web-platform-tests/resize-observer/OWNERS
Normal file
|
@ -0,0 +1,2 @@
|
|||
@atotic
|
||||
@dholbert
|
259
tests/wpt/web-platform-tests/resize-observer/eventloop.html
Normal file
259
tests/wpt/web-platform-tests/resize-observer/eventloop.html
Normal file
|
@ -0,0 +1,259 @@
|
|||
<!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
|
||||
}
|
||||
</style>
|
||||
<p>ResizeObserver notification event loop tests</p>
|
||||
<div id="target1" style="width:100px;height:100px;">t1
|
||||
</div>
|
||||
<div id="container">
|
||||
<div id="a1" style="width:100px;height:100px">
|
||||
<div id="a2" style="width:100px;height:100px">
|
||||
</div>
|
||||
</div>
|
||||
<div id="b1" style="width:100px;height:100px">
|
||||
<div id="b2" style="width:100px;height:100px">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
'use strict';
|
||||
|
||||
let t1 = document.querySelector('#target1');
|
||||
|
||||
// allow uncaught exception because ResizeObserver posts exceptions
|
||||
// to window error handler when limit is exceeded.
|
||||
// This codepath is tested in this file.
|
||||
|
||||
setup({allow_uncaught_exception: true});
|
||||
|
||||
function template() {
|
||||
let helper = new ResizeTestHelper(
|
||||
"test0: title",
|
||||
[
|
||||
{
|
||||
setup: observer => {
|
||||
},
|
||||
notify: (entries, observer) => {
|
||||
return true; // Delay next step
|
||||
}
|
||||
}
|
||||
]);
|
||||
return helper.start();
|
||||
}
|
||||
|
||||
var onErrorCalled = false;
|
||||
|
||||
window.onerror = err => {
|
||||
onErrorCalled = true;
|
||||
}
|
||||
|
||||
function test0() {
|
||||
|
||||
let divs = [t1];
|
||||
let rAF = 0;
|
||||
let helper = new ResizeTestHelper(
|
||||
"test0: multiple notifications inside same event loop",
|
||||
[
|
||||
{
|
||||
setup: observer => {
|
||||
onErrorCalled = false;
|
||||
let t2 = document.createElement('div');
|
||||
let t3 = document.createElement('div');
|
||||
t2.appendChild(t3);
|
||||
t1.appendChild(t2);
|
||||
divs.push(t2);
|
||||
divs.push(t3);
|
||||
observer.observe(t1);
|
||||
observer.observe(t2);
|
||||
observer.observe(t3);
|
||||
},
|
||||
notify: (entries, observer) => {
|
||||
assert_equals(entries.length, 3, "3 notifications");
|
||||
}
|
||||
},
|
||||
{
|
||||
setup: observer => {
|
||||
helper.startCountingRaf();
|
||||
divs.forEach( el => { el.style.width = "101px";});
|
||||
},
|
||||
notify: (entries, observer) => {
|
||||
// t1 is not delivered
|
||||
assert_equals(entries.length, 2, "2 notifications");
|
||||
assert_equals(helper.rafCount, 0, "still in same loop");
|
||||
}
|
||||
},
|
||||
{
|
||||
setup: observer => {
|
||||
divs.forEach( el => { el.style.width = "102px";});
|
||||
},
|
||||
notify: (entries, observer) => {
|
||||
assert_equals(entries.length, 1, "1 notifications");
|
||||
assert_equals(helper.rafCount, 0, "same loop");
|
||||
}
|
||||
},
|
||||
{ // t1 and t2 get notified
|
||||
setup: observer => {
|
||||
},
|
||||
notify: (entries, observer) => {
|
||||
assert_equals(entries.length, 2, "2 notifications");
|
||||
assert_equals(helper.rafCount, 1, "new loop");
|
||||
assert_equals(onErrorCalled, true, "error was fired");
|
||||
observer.disconnect();
|
||||
while (t1.childNodes.length > 0)
|
||||
t1.removeChild(t1.childNodes[0]);
|
||||
}
|
||||
}
|
||||
]);
|
||||
return helper.start();
|
||||
}
|
||||
|
||||
function test1() {
|
||||
|
||||
var resizers = [t1];
|
||||
// Testing depths of shadow roots
|
||||
// DOM: t1 <- t2 <- t3 <-shadow- t4 <- t5
|
||||
let helper = new ResizeTestHelper(
|
||||
"test1: depths of shadow roots",
|
||||
[
|
||||
{
|
||||
setup: observer => {
|
||||
onErrorCalled = false;
|
||||
let t2 = document.createElement('div');
|
||||
t1.appendChild(t2);
|
||||
resizers.push(t2);
|
||||
let t3 = document.createElement('div');
|
||||
resizers.push(t3);
|
||||
t2.appendChild(t3);
|
||||
let shadow = t3.createShadowRoot();
|
||||
let t4 = document.createElement('div');
|
||||
resizers.push(t4);
|
||||
shadow.appendChild(t4);
|
||||
let t5 = document.createElement('div');
|
||||
resizers.push(t5);
|
||||
t4.appendChild(t5);
|
||||
resizers.forEach( el => observer.observe(el) );
|
||||
},
|
||||
notify: (entries, observer) => {
|
||||
assert_equals(entries.length, 5, "all entries resized");
|
||||
}
|
||||
},
|
||||
{
|
||||
setup: observer => {
|
||||
resizers.forEach( el => el.style.width = "111px" );
|
||||
},
|
||||
notify: (entries, observer) => {
|
||||
assert_equals(entries.length, 4, "depth limited");
|
||||
}
|
||||
},
|
||||
{
|
||||
setup: observer => {
|
||||
resizers.forEach( el => el.style.width = "112px" );
|
||||
},
|
||||
notify: (entries, observer) => {
|
||||
assert_equals(entries.length, 3, "depth limited");
|
||||
}
|
||||
},
|
||||
{
|
||||
setup: observer => {
|
||||
resizers.forEach( el => el.style.width = "113px" );
|
||||
},
|
||||
notify: (entries, observer) => {
|
||||
assert_equals(entries.length, 2, "depth limited");
|
||||
}
|
||||
},
|
||||
{
|
||||
setup: observer => {
|
||||
resizers.forEach( el => el.style.width = "114px" );
|
||||
},
|
||||
notify: (entries, observer) => {
|
||||
assert_equals(entries.length, 1, "depth limited");
|
||||
}
|
||||
},
|
||||
{
|
||||
setup: observer => {
|
||||
},
|
||||
notify: (entries, observer) => {
|
||||
assert_equals(entries.length, 4, "limit notifications");
|
||||
assert_equals(onErrorCalled, true, "breached limit");
|
||||
observer.disconnect();
|
||||
t1.removeChild(t1.firstChild);
|
||||
}
|
||||
},
|
||||
]);
|
||||
return helper.start();
|
||||
}
|
||||
|
||||
function test2() {
|
||||
let container = document.querySelector('#container');
|
||||
let a1 = document.querySelector('#a1');
|
||||
let a2 = document.querySelector('#a2');
|
||||
let b1 = document.querySelector('#b1');
|
||||
let b2 = document.querySelector('#b2');
|
||||
let targets = [a1, a2, b1, b2];
|
||||
|
||||
let helper = new ResizeTestHelper(
|
||||
"test2: move target in dom while inside event loop",
|
||||
[
|
||||
{
|
||||
setup: observer => {
|
||||
for (let t of targets)
|
||||
observer.observe(t);
|
||||
},
|
||||
notify: (entries, observer) => {
|
||||
return true; // delay next observation
|
||||
}
|
||||
},
|
||||
{ // resize them all
|
||||
setup: observer => {
|
||||
for (let t of targets)
|
||||
t.style.width = "110px";
|
||||
},
|
||||
notify: (entries, observer) => {
|
||||
assert_equals(entries.length, targets.length, "all targets observed");
|
||||
}
|
||||
},
|
||||
{ // resize all, move dom upwards
|
||||
setup: observer => {
|
||||
for (let t of targets)
|
||||
t.style.width = "130px";
|
||||
container.appendChild(b2);
|
||||
},
|
||||
notify: (entries, observer) => {
|
||||
assert_equals(entries.length, 1, "b2 moved upwards");
|
||||
assert_equals(entries[0].target, a2);
|
||||
}
|
||||
},
|
||||
{ // resize all, move dom downwards
|
||||
setup: observer => {
|
||||
for (let t of targets)
|
||||
t.style.width = "130px";
|
||||
a2.appendChild(b2);
|
||||
},
|
||||
notify: (entries, observer) => {
|
||||
assert_equals(entries.length, 1, "b2 moved downwards");
|
||||
assert_equals(entries[0].target, b2);
|
||||
a1.appendChild(a2);
|
||||
}
|
||||
},
|
||||
]);
|
||||
return helper.start();
|
||||
}
|
||||
|
||||
let guard;
|
||||
test(_ => {
|
||||
assert_own_property(window, "ResizeObserver");
|
||||
guard = async_test('guard');
|
||||
}, "ResizeObserver implemented")
|
||||
|
||||
test0()
|
||||
.then(() => { return test1(); })
|
||||
.then(() => { return test2(); })
|
||||
.then(() => { guard.done(); });
|
||||
|
||||
</script>
|
||||
|
351
tests/wpt/web-platform-tests/resize-observer/notify.html
Normal file
351
tests/wpt/web-platform-tests/resize-observer/notify.html
Normal file
|
@ -0,0 +1,351 @@
|
|||
<!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 does not notify",
|
||||
[
|
||||
{
|
||||
setup: observer => {
|
||||
observer.observe(inline);
|
||||
observer.observe(t1);
|
||||
t1.style.width = "66px";
|
||||
inline.style.width = "66px";
|
||||
},
|
||||
notify: (entries, observer) => {
|
||||
assert_equals(entries.length, 1, "inline elements must not trigger notifications");
|
||||
assert_equals(entries[0].target, t1, "inline elements must not trigger notifications");
|
||||
return true; // Delay next step
|
||||
}
|
||||
},
|
||||
{ // "inline element that becomes block should notify",
|
||||
setup: observer => {
|
||||
inline.style.display = "block";
|
||||
},
|
||||
notify: (entries, observer) => {
|
||||
assert_equals(entries[0].target, inline);
|
||||
}
|
||||
}
|
||||
]);
|
||||
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();
|
||||
}
|
||||
|
||||
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(() => { guard.done(); });
|
||||
|
||||
</script>
|
207
tests/wpt/web-platform-tests/resize-observer/observe.html
Normal file
207
tests/wpt/web-platform-tests/resize-observer/observe.html
Normal file
|
@ -0,0 +1,207 @@
|
|||
<!doctype html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="./resources/resizeTestHelper.js"></script>
|
||||
<p>ResizeObserver tests</p>
|
||||
<div id="target1" style="width:100px;height:100px;">t1</div>
|
||||
<div id="target2" style="width:100px;height:100px;">t2</div>
|
||||
<img id="target3" style="width:100px;height:100px;">
|
||||
<iframe src="./resources/iframe.html" width="300px" height="100px" style="display:block"></iframe>
|
||||
<script>
|
||||
'use strict';
|
||||
|
||||
let t1 = document.querySelector('#target1');
|
||||
let t2 = document.querySelector('#target2');
|
||||
|
||||
// allow uncaught exception because ResizeObserver posts exceptions
|
||||
// to window error handler when limit is exceeded.
|
||||
setup({allow_uncaught_exception: true});
|
||||
|
||||
function test0() {
|
||||
let helper = new ResizeTestHelper(
|
||||
"test0: simple observation",
|
||||
[
|
||||
{
|
||||
setup: observer => {
|
||||
observer.observe(t1);
|
||||
t1.style.width = "5px";
|
||||
},
|
||||
notify: entries => {
|
||||
assert_equals(entries.length, 1, "1 pending notification");
|
||||
assert_equals(entries[0].target, t1, "target is t1");
|
||||
assert_equals(entries[0].contentRect.width, 5, "target width");
|
||||
}
|
||||
}
|
||||
]);
|
||||
return helper.start();
|
||||
}
|
||||
|
||||
function test1() {
|
||||
let helper = new ResizeTestHelper(
|
||||
"test1: multiple observation on same element trigger only one",
|
||||
[
|
||||
{
|
||||
setup: observer => {
|
||||
observer.observe(t1);
|
||||
observer.observe(t1);
|
||||
t1.style.width = "10px";
|
||||
},
|
||||
notify: entries => {
|
||||
assert_equals(entries.length, 1, "1 pending notification");
|
||||
}
|
||||
}
|
||||
]);
|
||||
return helper.start();
|
||||
}
|
||||
|
||||
function test2() {
|
||||
test(() => {
|
||||
assert_throws({name: "TypeError"}, _=> {
|
||||
let ro = new ResizeObserver(() => {});
|
||||
ro.observe({});
|
||||
});
|
||||
},
|
||||
"test2: throw exception when observing non-element"
|
||||
);
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
function test3() {
|
||||
let helper = new ResizeTestHelper(
|
||||
"test3: disconnect stops all notifications", [
|
||||
{
|
||||
setup: observer => {
|
||||
observer.observe(t1);
|
||||
observer.observe(t2);
|
||||
observer.disconnect();
|
||||
t1.style.width = "30px";
|
||||
},
|
||||
notify: entries => {
|
||||
assert_unreached("no entries should be observed");
|
||||
},
|
||||
timeout: () => {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
]);
|
||||
return helper.start();
|
||||
}
|
||||
|
||||
function test4() {
|
||||
let helper = new ResizeTestHelper(
|
||||
"test4: unobserve target stops notifications, unobserve non-observed does nothing", [
|
||||
{
|
||||
setup: observer => {
|
||||
observer.observe(t1);
|
||||
observer.observe(t2);
|
||||
observer.unobserve(t1);
|
||||
observer.unobserve(document.body);
|
||||
t1.style.width = "40px";
|
||||
t2.style.width = "40px";
|
||||
},
|
||||
notify: entries => {
|
||||
assert_equals(entries.length, 1, "only t2");
|
||||
assert_equals(entries[0].target, t2, "t2 was observed");
|
||||
}
|
||||
}
|
||||
]);
|
||||
return helper.start();
|
||||
}
|
||||
|
||||
function test5() {
|
||||
let t3 = document.querySelector('#target3');
|
||||
var helper = new ResizeTestHelper("test5: observe img",[
|
||||
{
|
||||
setup: observer => {
|
||||
observer.observe(t3);
|
||||
},
|
||||
notify: entries => {
|
||||
}
|
||||
},
|
||||
{
|
||||
setup: observer => {
|
||||
t3.style.width = "100.5px";
|
||||
},
|
||||
notify: entries => {
|
||||
assert_equals(entries.length, 1);
|
||||
assert_equals(entries[0].contentRect.width, 100.5);
|
||||
}
|
||||
}
|
||||
]);
|
||||
return helper.start();
|
||||
}
|
||||
|
||||
function test6() {
|
||||
let resolvePromise;
|
||||
let promise = new Promise((resolve) => {
|
||||
resolvePromise = resolve;
|
||||
});
|
||||
let test = async_test('test6: iframe notifications');
|
||||
let testRequested = false;
|
||||
let iframe = document.querySelector('iframe');
|
||||
window.addEventListener('message', event => {
|
||||
switch(event.data) {
|
||||
case 'readyToTest':
|
||||
if (!testRequested) {
|
||||
iframe.contentWindow.postMessage('startTest', '*');
|
||||
testRequested = true;
|
||||
}
|
||||
break;
|
||||
case 'success':
|
||||
case 'fail':
|
||||
window.requestAnimationFrame(() => {
|
||||
test.step( () => {
|
||||
assert_equals(event.data, 'success');
|
||||
test.done();
|
||||
resolvePromise();
|
||||
});
|
||||
});
|
||||
break;
|
||||
}
|
||||
}, false);
|
||||
return promise;
|
||||
}
|
||||
|
||||
function test7() {
|
||||
let harnessTest = async_test("test7: callback.this");
|
||||
let resolvePromise;
|
||||
let ro = new ResizeObserver( function(entries, obs) {
|
||||
let callbackThis = this;
|
||||
resolvePromise();
|
||||
harnessTest.step(() => {
|
||||
assert_equals(callbackThis, ro, "callback.this is ResizeObserver");
|
||||
assert_equals(obs, ro, "2nd argument is ResizeObserver");
|
||||
ro.disconnect();
|
||||
// every reference to RO must be null before test completes
|
||||
// to avoid triggering test leak-detection
|
||||
ro = null;
|
||||
callbackThis = null;
|
||||
obs = null;
|
||||
harnessTest.done();
|
||||
});
|
||||
}
|
||||
);
|
||||
ro.observe(t1);
|
||||
|
||||
return new Promise( (resolve, reject) => {
|
||||
resolvePromise = resolve;
|
||||
});
|
||||
}
|
||||
|
||||
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(() => { guard.done(); });
|
||||
|
||||
</script>
|
|
@ -0,0 +1,38 @@
|
|||
<!doctype html>
|
||||
<head>
|
||||
<script src="./resizeTestHelper.js"></script>
|
||||
</head>
|
||||
<p>iframe test</p>
|
||||
<div id="itarget1" style="width:100px;height:100px;">t1</div>
|
||||
<script>
|
||||
'use strict';
|
||||
let t1 = document.querySelector('#itarget1');
|
||||
function test0() {
|
||||
let timeoutId = window.setTimeout( () => {
|
||||
window.parent.postMessage('fail', '*');
|
||||
}, ResizeTestHelper.TIMEOUT);
|
||||
let ro = new ResizeObserver(function(entries) {
|
||||
window.clearTimeout(timeoutId);
|
||||
window.parent.postMessage('success', '*');
|
||||
});
|
||||
ro.observe(t1);
|
||||
}
|
||||
let testStarted = false;
|
||||
window.addEventListener('message', function(ev) {
|
||||
switch(ev.data) {
|
||||
case 'startTest':
|
||||
testStarted = true;
|
||||
test0();
|
||||
break;
|
||||
}
|
||||
});
|
||||
// How does parent know we've loaded problem is solved by
|
||||
// broadcasting readyToTest message repeatedly until test starts.
|
||||
function broadcastReady() {
|
||||
if (!testStarted) {
|
||||
window.parent.postMessage('readyToTest', '*');
|
||||
window.requestAnimationFrame(broadcastReady);
|
||||
}
|
||||
}
|
||||
broadcastReady();
|
||||
</script>
|
|
@ -0,0 +1,148 @@
|
|||
'use strict';
|
||||
|
||||
/**
|
||||
ResizeTestHelper is a framework to test ResizeObserver
|
||||
notifications. Use it to make assertions about ResizeObserverEntries.
|
||||
This framework is needed because ResizeObservations are
|
||||
delivered asynchronously inside the event loop.
|
||||
|
||||
Features:
|
||||
- can queue multiple notification steps in a test
|
||||
- handles timeouts
|
||||
- returns Promise that is fullfilled when test completes.
|
||||
Use to chain tests (since parallel async ResizeObserver tests
|
||||
would conflict if reusing same DOM elements).
|
||||
|
||||
Usage:
|
||||
|
||||
create ResizeTestHelper for every test.
|
||||
Make assertions inside notify, timeout callbacks.
|
||||
Start tests with helper.start()
|
||||
Chain tests with Promises.
|
||||
Counts animation frames, see startCountingRaf
|
||||
*/
|
||||
|
||||
/*
|
||||
@param name: test name
|
||||
@param steps:
|
||||
{
|
||||
setup: function(ResizeObserver) {
|
||||
// called at the beginning of the test step
|
||||
// your observe/resize code goes here
|
||||
},
|
||||
notify: function(entries, observer) {
|
||||
// ResizeObserver callback.
|
||||
// Make assertions here.
|
||||
// Return true if next step should start on the next event loop.
|
||||
},
|
||||
timeout: function() {
|
||||
// Define this if your test expects to time out.
|
||||
// If undefined, timeout is assert_unreached.
|
||||
}
|
||||
}
|
||||
*/
|
||||
function ResizeTestHelper(name, steps)
|
||||
{
|
||||
this._name = name;
|
||||
this._steps = steps || [];
|
||||
this._stepIdx = -1;
|
||||
this._harnessTest = null;
|
||||
this._observer = new ResizeObserver(this._handleNotification.bind(this));
|
||||
this._timeoutBind = this._handleTimeout.bind(this);
|
||||
this._nextStepBind = this._nextStep.bind(this);
|
||||
}
|
||||
|
||||
ResizeTestHelper.TIMEOUT = 100;
|
||||
|
||||
ResizeTestHelper.prototype = {
|
||||
get _currentStep() {
|
||||
return this._steps[this._stepIdx];
|
||||
},
|
||||
|
||||
_nextStep: function() {
|
||||
if (++this._stepIdx == this._steps.length)
|
||||
return this._done();
|
||||
this._timeoutId = this._harnessTest.step_timeout(
|
||||
this._timeoutBind, ResizeTestHelper.TIMEOUT);
|
||||
try {
|
||||
this._steps[this._stepIdx].setup(this._observer);
|
||||
}
|
||||
catch(err) {
|
||||
this._harnessTest.step(() => {
|
||||
assert_unreached("Caught a throw, possible syntax error");
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
_handleNotification: function(entries) {
|
||||
if (this._timeoutId) {
|
||||
window.clearTimeout(this._timeoutId);
|
||||
delete this._timeoutId;
|
||||
}
|
||||
this._harnessTest.step(() => {
|
||||
let rafDelay = this._currentStep.notify(entries, this._observer);
|
||||
if (rafDelay)
|
||||
window.requestAnimationFrame(this._nextStepBind);
|
||||
else
|
||||
this._nextStep();
|
||||
});
|
||||
},
|
||||
|
||||
_handleTimeout: function() {
|
||||
delete this._timeoutId;
|
||||
this._harnessTest.step(() => {
|
||||
if (this._currentStep.timeout) {
|
||||
this._currentStep.timeout();
|
||||
}
|
||||
else {
|
||||
assert_unreached("Timed out waiting for notification. (" + ResizeTestHelper.TIMEOUT + "ms)");
|
||||
}
|
||||
this._nextStep();
|
||||
});
|
||||
},
|
||||
|
||||
_done: function() {
|
||||
this._observer.disconnect();
|
||||
delete this._observer;
|
||||
this._harnessTest.done();
|
||||
if (this._rafCountRequest) {
|
||||
window.cancelAnimationFrame(this._rafCountRequest);
|
||||
delete this._rafCountRequest;
|
||||
}
|
||||
window.requestAnimationFrame(() => { this._resolvePromise(); });
|
||||
},
|
||||
|
||||
start: function() {
|
||||
this._harnessTest = async_test(this._name);
|
||||
this._harnessTest.step(() => {
|
||||
assert_equals(this._stepIdx, -1, "start can only be called once");
|
||||
this._nextStep();
|
||||
});
|
||||
return new Promise( (resolve, reject) => {
|
||||
this._resolvePromise = resolve;
|
||||
this._rejectPromise = reject;
|
||||
});
|
||||
},
|
||||
|
||||
get rafCount() {
|
||||
if (!this._rafCountRequest)
|
||||
throw "rAF count is not active";
|
||||
return this._rafCount;
|
||||
},
|
||||
|
||||
_incrementRaf: function() {
|
||||
if (this._rafCountRequest) {
|
||||
this._rafCount++;
|
||||
this._rafCountRequest = window.requestAnimationFrame(this._incrementRafBind);
|
||||
}
|
||||
},
|
||||
|
||||
startCountingRaf: function() {
|
||||
if (this._rafCountRequest)
|
||||
window.cancelAnimationFrame(this._rafCountRequest);
|
||||
if (!this._incrementRafBind)
|
||||
this._incrementRafBind = this._incrementRaf.bind(this);
|
||||
this._rafCount = 0;
|
||||
this._rafCountRequest = window.requestAnimationFrame(this._incrementRafBind);
|
||||
}
|
||||
}
|
333
tests/wpt/web-platform-tests/resize-observer/svg.html
Normal file
333
tests/wpt/web-platform-tests/resize-observer/svg.html
Normal file
|
@ -0,0 +1,333 @@
|
|||
<!doctype html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="./resources/resizeTestHelper.js"></script>
|
||||
<p>ResizeObserver svg tests</p>
|
||||
<svg height="430" width="500" >
|
||||
<circle cx="10" cy="10" r="5" style="fill:orange;stroke:black;stroke-width:1" />
|
||||
<ellipse cx="10" cy="30" rx="5" ry="5" style="fill:orange;stroke:black;stroke-width:1"/>
|
||||
<foreignObject cy="50" width="100" height="20">
|
||||
<body>
|
||||
<p>Here is a paragraph that requires word wrap</p>
|
||||
</body>
|
||||
</foreignObject>
|
||||
<image xlink:href="" x="0" y="100" height="30" width="100" />
|
||||
<line x1="0" y1="50" x2="20" y2="70" stroke="black" stroke-width="2"/>
|
||||
<path d="M 0 100 L 100 100 L 50 150 z"
|
||||
style="fill:orange;stroke:black;stroke-width:1" />
|
||||
<polygon points="0,200 100,200 50,250" style="fill:orange;stroke:black;stroke-width:1" />
|
||||
<polyline points="0,300 100,300 50,350" style="fill:orange;stroke:black;stroke-width:1"/>
|
||||
<rect x="0" y="380" width="10" height="10" style="fill:orange; stroke:black; stroke-width:1" />
|
||||
<text x="0" y="400" font-size="20">svg text tag</text>
|
||||
</svg>
|
||||
<script>
|
||||
'use strict';
|
||||
|
||||
setup({allow_uncaught_exception: true});
|
||||
|
||||
function test0() {
|
||||
let target = document.querySelector('circle');
|
||||
let helper = new ResizeTestHelper(
|
||||
"test0: observe svg:circle",
|
||||
[
|
||||
{
|
||||
setup: observer => {
|
||||
observer.observe(target);
|
||||
},
|
||||
notify: (entries, observer) => {
|
||||
return true; // Delay next step
|
||||
}
|
||||
},
|
||||
{
|
||||
setup: observer => {
|
||||
target.setAttribute('r', 10);
|
||||
},
|
||||
notify: (entries, observer) => {
|
||||
assert_equals(entries.length, 1);
|
||||
}
|
||||
}
|
||||
]);
|
||||
return helper.start();
|
||||
}
|
||||
|
||||
function test1() {
|
||||
let target = document.querySelector('ellipse');
|
||||
let helper = new ResizeTestHelper(
|
||||
"test1: observe svg:ellipse",
|
||||
[
|
||||
{
|
||||
setup: observer => {
|
||||
observer.observe(target);
|
||||
},
|
||||
notify: (entries, observer) => {
|
||||
return true; // Delay next step
|
||||
}
|
||||
},
|
||||
{
|
||||
setup: observer => {
|
||||
target.setAttribute('rx', 10);
|
||||
},
|
||||
notify: (entries, observer) => {
|
||||
assert_equals(entries.length, 1);
|
||||
assert_equals(entries[0].contentRect.width, 20);
|
||||
assert_equals(entries[0].contentRect.height, 10);
|
||||
}
|
||||
}
|
||||
]);
|
||||
return helper.start();
|
||||
}
|
||||
|
||||
function test2() {
|
||||
let target = document.querySelector('foreignObject');
|
||||
let helper = new ResizeTestHelper(
|
||||
"test2: observe svg:foreignObject",
|
||||
[
|
||||
{
|
||||
setup: observer => {
|
||||
observer.observe(target);
|
||||
},
|
||||
notify: (entries, observer) => {
|
||||
return true; // Delay next step
|
||||
}
|
||||
},
|
||||
{
|
||||
setup: observer => {
|
||||
target.setAttribute('width', 200);
|
||||
},
|
||||
notify: (entries, observer) => {
|
||||
assert_equals(entries.length, 1);
|
||||
assert_equals(entries[0].contentRect.width, 200);
|
||||
assert_equals(entries[0].contentRect.height, 20);
|
||||
}
|
||||
}
|
||||
]);
|
||||
return helper.start();
|
||||
}
|
||||
|
||||
function test3() {
|
||||
let target = document.querySelector('image');
|
||||
let helper = new ResizeTestHelper(
|
||||
"test3: observe svg:image",
|
||||
[
|
||||
{
|
||||
setup: observer => {
|
||||
observer.observe(target);
|
||||
},
|
||||
notify: (entries, observer) => {
|
||||
return true; // Delay next step
|
||||
}
|
||||
},
|
||||
{
|
||||
setup: observer => {
|
||||
target.setAttribute('height', 40);
|
||||
},
|
||||
notify: (entries, observer) => {
|
||||
assert_equals(entries.length, 1);
|
||||
assert_equals(entries[0].contentRect.width, 100);
|
||||
assert_equals(entries[0].contentRect.height, 40);
|
||||
}
|
||||
}
|
||||
]);
|
||||
return helper.start();
|
||||
}
|
||||
|
||||
function test4() {
|
||||
let target = document.querySelector('line');
|
||||
let helper = new ResizeTestHelper(
|
||||
"test4: observe svg:line",
|
||||
[
|
||||
{
|
||||
setup: observer => {
|
||||
observer.observe(target);
|
||||
},
|
||||
notify: (entries, observer) => {
|
||||
return true; // Delay next step
|
||||
}
|
||||
},
|
||||
{
|
||||
setup: observer => {
|
||||
target.setAttribute('y2', 80);
|
||||
},
|
||||
notify: (entries, observer) => {
|
||||
assert_equals(entries.length, 1);
|
||||
assert_equals(entries[0].contentRect.width, 20);
|
||||
assert_equals(entries[0].contentRect.height, 30);
|
||||
}
|
||||
}
|
||||
]);
|
||||
return helper.start();
|
||||
}
|
||||
|
||||
function test5() {
|
||||
let target = document.querySelector('path');
|
||||
let helper = new ResizeTestHelper(
|
||||
"test5: observe svg:path",
|
||||
[
|
||||
{
|
||||
setup: observer => {
|
||||
observer.observe(target);
|
||||
},
|
||||
notify: (entries, observer) => {
|
||||
return true; // Delay next step
|
||||
}
|
||||
},
|
||||
{
|
||||
setup: observer => {
|
||||
target.setAttribute('d', "M 0 100 L 100 100 L 50 160 z");
|
||||
},
|
||||
notify: (entries, observer) => {
|
||||
assert_equals(entries.length, 1);
|
||||
assert_equals(entries[0].contentRect.width, 100);
|
||||
assert_equals(entries[0].contentRect.height, 60);
|
||||
}
|
||||
}
|
||||
]);
|
||||
return helper.start();
|
||||
}
|
||||
|
||||
function test6() {
|
||||
let target = document.querySelector('polygon');
|
||||
let helper = new ResizeTestHelper(
|
||||
"test6: observe svg:path",
|
||||
[
|
||||
{
|
||||
setup: observer => {
|
||||
observer.observe(target);
|
||||
},
|
||||
notify: (entries, observer) => {
|
||||
return true; // Delay next step
|
||||
}
|
||||
},
|
||||
{
|
||||
setup: observer => {
|
||||
target.setAttribute('points', "0,200 100,200 50,260");
|
||||
},
|
||||
notify: (entries, observer) => {
|
||||
assert_equals(entries.length, 1);
|
||||
assert_equals(entries[0].contentRect.width, 100);
|
||||
assert_equals(entries[0].contentRect.height, 60);
|
||||
}
|
||||
}
|
||||
]);
|
||||
return helper.start();
|
||||
}
|
||||
|
||||
function test7() {
|
||||
let target = document.querySelector('polyline');
|
||||
let helper = new ResizeTestHelper(
|
||||
"test7: observe svg:polyline",
|
||||
[
|
||||
{
|
||||
setup: observer => {
|
||||
observer.observe(target);
|
||||
},
|
||||
notify: (entries, observer) => {
|
||||
return true; // Delay next step
|
||||
}
|
||||
},
|
||||
{
|
||||
setup: observer => {
|
||||
target.setAttribute('points', "0,300 100,300 50,360");
|
||||
},
|
||||
notify: (entries, observer) => {
|
||||
assert_equals(entries.length, 1);
|
||||
assert_equals(entries[0].contentRect.width, 100);
|
||||
assert_equals(entries[0].contentRect.height, 60);
|
||||
}
|
||||
}
|
||||
]);
|
||||
return helper.start();
|
||||
}
|
||||
|
||||
function test8() {
|
||||
let target = document.querySelector('rect');
|
||||
let helper = new ResizeTestHelper(
|
||||
"test8: observe svg:rect",
|
||||
[
|
||||
{
|
||||
setup: observer => {
|
||||
observer.observe(target);
|
||||
},
|
||||
notify: (entries, observer) => {
|
||||
return true; // Delay next step
|
||||
}
|
||||
},
|
||||
{
|
||||
setup: observer => {
|
||||
target.setAttribute('width', "20");
|
||||
},
|
||||
notify: (entries, observer) => {
|
||||
assert_equals(entries.length, 1);
|
||||
assert_equals(entries[0].contentRect.width, 20);
|
||||
assert_equals(entries[0].contentRect.height, 10);
|
||||
}
|
||||
}
|
||||
]);
|
||||
return helper.start();
|
||||
}
|
||||
|
||||
function test9() {
|
||||
let target = document.querySelector('text');
|
||||
let helper = new ResizeTestHelper(
|
||||
"test9: observe svg:text",
|
||||
[
|
||||
{
|
||||
setup: observer => {
|
||||
observer.observe(target);
|
||||
},
|
||||
notify: (entries, observer) => {
|
||||
return true; // Delay next step
|
||||
}
|
||||
},
|
||||
{
|
||||
setup: observer => {
|
||||
target.setAttribute('font-size', "25");
|
||||
},
|
||||
notify: (entries, observer) => {
|
||||
assert_equals(entries.length, 1);
|
||||
}
|
||||
}
|
||||
]);
|
||||
return helper.start();
|
||||
}
|
||||
|
||||
|
||||
function test10() {
|
||||
let target = document.querySelector('svg');
|
||||
let helper = new ResizeTestHelper(
|
||||
"test10: observe svg:svg, top/left is 0 even with padding",
|
||||
[
|
||||
{
|
||||
setup: observer => {
|
||||
observer.observe(target);
|
||||
},
|
||||
notify: (entries, observer) => {
|
||||
assert_equals(entries.length, 1);
|
||||
assert_equals(entries[0].contentRect.top, 0);
|
||||
assert_equals(entries[0].contentRect.left, 0);
|
||||
}
|
||||
}
|
||||
]);
|
||||
return helper.start();
|
||||
}
|
||||
|
||||
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(() => { guard.done(); });
|
||||
|
||||
</script>
|
Loading…
Add table
Add a link
Reference in a new issue