Auto merge of #20457 - servo-wpt-sync:wpt_update_27-03-2018, r=jdm

Sync WPT with upstream (27-03-2018)

Automated downstream sync of changes from upstream as of 27-03-2018.
[no-wpt-sync]

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/20457)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2018-03-28 13:27:24 -04:00 committed by GitHub
commit e04d517bff
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
33 changed files with 1160 additions and 968 deletions

View file

@ -117941,6 +117941,78 @@
{}
]
],
"css/css-layout-api/position-fragment-htb-ltr.https.html": [
[
"/css/css-layout-api/position-fragment-htb-ltr.https.html",
[
[
"/css/css-layout-api/position-fragment-ref.html",
"=="
]
],
{}
]
],
"css/css-layout-api/position-fragment-htb-rtl.https.html": [
[
"/css/css-layout-api/position-fragment-htb-rtl.https.html",
[
[
"/css/css-layout-api/position-fragment-ref.html",
"=="
]
],
{}
]
],
"css/css-layout-api/position-fragment-vlr-ltr.https.html": [
[
"/css/css-layout-api/position-fragment-vlr-ltr.https.html",
[
[
"/css/css-layout-api/position-fragment-ref.html",
"=="
]
],
{}
]
],
"css/css-layout-api/position-fragment-vlr-rtl.https.html": [
[
"/css/css-layout-api/position-fragment-vlr-rtl.https.html",
[
[
"/css/css-layout-api/position-fragment-ref.html",
"=="
]
],
{}
]
],
"css/css-layout-api/position-fragment-vrl-ltr.https.html": [
[
"/css/css-layout-api/position-fragment-vrl-ltr.https.html",
[
[
"/css/css-layout-api/position-fragment-ref.html",
"=="
]
],
{}
]
],
"css/css-layout-api/position-fragment-vrl-rtl.https.html": [
[
"/css/css-layout-api/position-fragment-vrl-rtl.https.html",
[
[
"/css/css-layout-api/position-fragment-ref.html",
"=="
]
],
{}
]
],
"css/css-layout-api/style-map-multi.https.html": [
[
"/css/css-layout-api/style-map-multi.https.html",
@ -122777,18 +122849,6 @@
{}
]
],
"css/css-position/position-sticky-nested-bottom.html": [
[
"/css/css-position/position-sticky-nested-bottom.html",
[
[
"/css/css-position/position-sticky-nested-bottom-ref.html",
"=="
]
],
{}
]
],
"css/css-position/position-sticky-nested-inline.html": [
[
"/css/css-position/position-sticky-nested-inline.html",
@ -122801,30 +122861,6 @@
{}
]
],
"css/css-position/position-sticky-nested-left.html": [
[
"/css/css-position/position-sticky-nested-left.html",
[
[
"/css/css-position/position-sticky-nested-left-ref.html",
"=="
]
],
{}
]
],
"css/css-position/position-sticky-nested-right.html": [
[
"/css/css-position/position-sticky-nested-right.html",
[
[
"/css/css-position/position-sticky-nested-right-ref.html",
"=="
]
],
{}
]
],
"css/css-position/position-sticky-nested-table.html": [
[
"/css/css-position/position-sticky-nested-table.html",
@ -122837,18 +122873,6 @@
{}
]
],
"css/css-position/position-sticky-nested-top.html": [
[
"/css/css-position/position-sticky-nested-top.html",
[
[
"/css/css-position/position-sticky-nested-top-ref.html",
"=="
]
],
{}
]
],
"css/css-position/position-sticky-rendering.html": [
[
"/css/css-position/position-sticky-rendering.html",
@ -248314,6 +248338,11 @@
{}
]
],
"css/css-layout-api/position-fragment-ref.html": [
[
{}
]
],
"css/css-layout-api/style-map-multi-ref.html": [
[
{}
@ -248334,6 +248363,11 @@
{}
]
],
"css/css-layout-api/support/layout-position-child-worklet.js": [
[
{}
]
],
"css/css-lists/OWNERS": [
[
{}
@ -249784,36 +249818,16 @@
{}
]
],
"css/css-position/position-sticky-nested-bottom-ref.html": [
[
{}
]
],
"css/css-position/position-sticky-nested-inline-ref.html": [
[
{}
]
],
"css/css-position/position-sticky-nested-left-ref.html": [
[
{}
]
],
"css/css-position/position-sticky-nested-right-ref.html": [
[
{}
]
],
"css/css-position/position-sticky-nested-table-ref.html": [
[
{}
]
],
"css/css-position/position-sticky-nested-top-ref.html": [
[
{}
]
],
"css/css-position/position-sticky-rendering-ref.html": [
[
{}
@ -292669,6 +292683,11 @@
{}
]
],
"service-workers/service-worker/resources/navigation-timing-worker.js": [
[
{}
]
],
"service-workers/service-worker/resources/notification_icon.py": [
[
{}
@ -297969,11 +297988,21 @@
{}
]
],
"workers/modules/resources/dynamic-import-given-url-worker.js": [
[
{}
]
],
"workers/modules/resources/dynamic-import-worker.js": [
[
{}
]
],
"workers/modules/resources/import-meta-url-worker.js": [
[
{}
]
],
"workers/modules/resources/nested-dynamic-import-worker.js": [
[
{}
@ -314246,6 +314275,30 @@
{}
]
],
"css/css-position/position-sticky-nested-bottom.html": [
[
"/css/css-position/position-sticky-nested-bottom.html",
{}
]
],
"css/css-position/position-sticky-nested-left.html": [
[
"/css/css-position/position-sticky-nested-left.html",
{}
]
],
"css/css-position/position-sticky-nested-right.html": [
[
"/css/css-position/position-sticky-nested-right.html",
{}
]
],
"css/css-position/position-sticky-nested-top.html": [
[
"/css/css-position/position-sticky-nested-top.html",
{}
]
],
"css/css-position/position-sticky-offset-overflow.html": [
[
"/css/css-position/position-sticky-offset-overflow.html",
@ -317528,6 +317581,12 @@
{}
]
],
"css/css-typed-om/the-stylepropertymap/properties/column-width.html": [
[
"/css/css-typed-om/the-stylepropertymap/properties/column-width.html",
{}
]
],
"css/css-typed-om/the-stylepropertymap/properties/direction.html": [
[
"/css/css-typed-om/the-stylepropertymap/properties/direction.html",
@ -317852,6 +317911,12 @@
{}
]
],
"css/css-typed-om/the-stylepropertymap/properties/radius.html": [
[
"/css/css-typed-om/the-stylepropertymap/properties/radius.html",
{}
]
],
"css/css-typed-om/the-stylepropertymap/properties/resize.html": [
[
"/css/css-typed-om/the-stylepropertymap/properties/resize.html",
@ -361178,6 +361243,12 @@
{}
]
],
"service-workers/service-worker/navigation-timing.https.html": [
[
"/service-workers/service-worker/navigation-timing.https.html",
{}
]
],
"service-workers/service-worker/onactivate-script-error.https.html": [
[
"/service-workers/service-worker/onactivate-script-error.https.html",
@ -370170,6 +370241,12 @@
{}
]
],
"workers/modules/dedicated-worker-import-meta.html": [
[
"/workers/modules/dedicated-worker-import-meta.html",
{}
]
],
"workers/modules/dedicated-worker-import.html": [
[
"/workers/modules/dedicated-worker-import.html",
@ -502713,6 +502790,34 @@
"a25a85095781de557edde6dd02b82ee052642bf1",
"reftest"
],
"css/css-layout-api/position-fragment-htb-ltr.https.html": [
"761ed3e46d6485b1208953c292015432da5f99e0",
"reftest"
],
"css/css-layout-api/position-fragment-htb-rtl.https.html": [
"8a2684c25ef3603e498cf33d32dc8a2c4b4a50d5",
"reftest"
],
"css/css-layout-api/position-fragment-ref.html": [
"42b0dbfd4a950f8e72c2de942682565c91b06bd1",
"support"
],
"css/css-layout-api/position-fragment-vlr-ltr.https.html": [
"afe6dc92c2d732a81ae2ca2c1747a12ef421c073",
"reftest"
],
"css/css-layout-api/position-fragment-vlr-rtl.https.html": [
"9db1e576eabcfb88ab8fcee3355195533798a427",
"reftest"
],
"css/css-layout-api/position-fragment-vrl-ltr.https.html": [
"c6c5f3c2d2adb96f140ab02f8ffa0ee1724c2f2b",
"reftest"
],
"css/css-layout-api/position-fragment-vrl-rtl.https.html": [
"bfeb2a9f1c84ebe1423ca6b92d8751f5106f1275",
"reftest"
],
"css/css-layout-api/style-map-multi-ref.html": [
"d33f700e795484641d3cc7db1c26e09dca952209",
"support"
@ -502737,6 +502842,10 @@
"87af0bfedbe9d4ea23e904edc5b22382a5d5d56c",
"support"
],
"css/css-layout-api/support/layout-position-child-worklet.js": [
"7c05d553e6cba23d69bd40b9ad90e701440e9071",
"support"
],
"css/css-layout-api/supports.https.html": [
"be6b57f5a85f99a64e755da22411ace3fba2992f",
"testharness"
@ -505674,20 +505783,16 @@
"testharness"
],
"css/css-position/position-sticky-left.html": [
"2a04672cdac818a6887eac7d6824ea85d3d0559d",
"d28b5ee55d5fed4b263b130df700092e14b9e784",
"testharness"
],
"css/css-position/position-sticky-margins.html": [
"3f6bc9537adf2a4d477f99866d73f42b65c26db3",
"testharness"
],
"css/css-position/position-sticky-nested-bottom-ref.html": [
"59a8e46358a8a5bf8638a2d1982c63becef5bc77",
"support"
],
"css/css-position/position-sticky-nested-bottom.html": [
"3604a921be04927dd19b805b7c9abaed6d0e7c72",
"reftest"
"82b1bdada6bfc0c2b6fc04ee3fdd9036e807c1e4",
"testharness"
],
"css/css-position/position-sticky-nested-inline-ref.html": [
"8fb9378e91a20b71ef886b9aac0147b25d00a9a3",
@ -505697,21 +505802,13 @@
"50be9f2fb6ab9295081f6f13705be4853e48fdde",
"reftest"
],
"css/css-position/position-sticky-nested-left-ref.html": [
"52804c5589c3035818cd653c1801a70645a9fe99",
"support"
],
"css/css-position/position-sticky-nested-left.html": [
"c32881097147e285b6ee66e6239af4808d780c83",
"reftest"
],
"css/css-position/position-sticky-nested-right-ref.html": [
"5703ad6457deca332232e510dc479c39b7020d24",
"support"
"dabe2ee93d0f0078beacf5c715fd040558ad9c08",
"testharness"
],
"css/css-position/position-sticky-nested-right.html": [
"39683624316599779b0efcb347010b92694e02a6",
"reftest"
"023e0eea58b52a249c2313c533be38a033f40da0",
"testharness"
],
"css/css-position/position-sticky-nested-table-ref.html": [
"7b8956bc720e2e25e7ff0bc5889812c26837ab58",
@ -505721,13 +505818,9 @@
"87a80629bcfcace28d4f13bce99325d55d317574",
"reftest"
],
"css/css-position/position-sticky-nested-top-ref.html": [
"66ea8b8c72023089d52e6ebdf5bfff5d56259bfc",
"support"
],
"css/css-position/position-sticky-nested-top.html": [
"88e35164b6ede3adf9727989cf59ff9956bdbae7",
"reftest"
"ae24eeaea7f25860fa770141d0894abf9e961c5e",
"testharness"
],
"css/css-position/position-sticky-offset-overflow.html": [
"cab620b2008a9df57abc6907b1199e35a4099241",
@ -505754,7 +505847,7 @@
"reftest"
],
"css/css-position/position-sticky-right.html": [
"80caf6fb1e6c84dbf3e371a11166ac5b71bba687",
"8bd2ae1a53ade0a524d98f5c8b0fe2ebce66d338",
"testharness"
],
"css/css-position/position-sticky-root-scroller.html": [
@ -505862,7 +505955,7 @@
"reftest"
],
"css/css-position/resources/sticky-util.js": [
"c7b441a3a07276cad9528dd3ef7d82844d06e2d8",
"7f8a5b4d9047c07378473362acb3d001e70d5663",
"support"
],
"css/css-properties-values-api/register-property-syntax-parsing.html": [
@ -523049,6 +523142,10 @@
"276ec2870bc105b046669daa0bdbeffdb080479c",
"testharness"
],
"css/css-typed-om/the-stylepropertymap/properties/column-width.html": [
"3f6faf5b2371d8be9483148f3bfa562710c9c3ef",
"testharness"
],
"css/css-typed-om/the-stylepropertymap/properties/direction.html": [
"b7c49aba4e8785f819beeb444c113d937d441089",
"testharness"
@ -523265,6 +523362,10 @@
"4e3eccee58cec470febe4cd9a9149f4b4436487e",
"testharness"
],
"css/css-typed-om/the-stylepropertymap/properties/radius.html": [
"ae21056fb993efb7112e0bc42fe1269f6bc0c72e",
"testharness"
],
"css/css-typed-om/the-stylepropertymap/properties/resize.html": [
"533f287facbc82118469f75f9f88a1372848d3b2",
"testharness"
@ -572718,7 +572819,7 @@
"support"
],
"interfaces/payment-handler.idl": [
"ddd283da0dadaffb3403652651c30f0f59007331",
"6d9157e515e419c7a2fffc61a1f8e3b23a4550ba",
"support"
],
"interfaces/payment-request.idl": [
@ -582434,7 +582535,7 @@
"testharness"
],
"payment-handler/can-make-payment-event.https.html": [
"1433a0dcee409e808adc6ed5b65a532128a1d350",
"7a361f57439425d5ec5c583ad363d9acf9fa7e1d",
"testharness"
],
"payment-handler/interfaces.https.any.js": [
@ -582450,11 +582551,11 @@
"support"
],
"payment-handler/payment-instruments.https.html": [
"14a67dbd2670c661d61ac8dc61c950e572369279",
"372d636227a5be6ede37e7d67cf24d03030eccf5",
"testharness"
],
"payment-handler/payment-request-event.https.html": [
"f9556317297607b5e5f649343ae6f365a4df9552",
"37e76b630197399daa3eb5ea49e8a4150c61c29c",
"testharness"
],
"payment-handler/register-and-activate-service-worker.js": [
@ -593421,6 +593522,10 @@
"109f463deeaad2d60d4dab644c782ad633e97a7d",
"testharness"
],
"service-workers/service-worker/navigation-timing.https.html": [
"cf5224b43bf0ba01ec409bf07faeed65e50162ed",
"testharness"
],
"service-workers/service-worker/onactivate-script-error.https.html": [
"bfef14af67c3a21523b5a7283d7cf86ac288f081",
"testharness"
@ -594189,6 +594294,10 @@
"56447ddcf101a60c64b4d2f7168c21deb4b3c0a8",
"support"
],
"service-workers/service-worker/resources/navigation-timing-worker.js": [
"efe2c9dc9e63ee0f25a15ce1ed37f116e43e7255",
"support"
],
"service-workers/service-worker/resources/notification_icon.py": [
"ec72a4c120ccfac3a165576f59a0e02b945343b3",
"support"
@ -608605,6 +608714,10 @@
"6bffa3be83d81e2faa93119e710e4fee93fb855e",
"testharness"
],
"workers/modules/dedicated-worker-import-meta.html": [
"ba8b24064e23f018ffd3ac9e4184d6f856123bff",
"testharness"
],
"workers/modules/dedicated-worker-import.html": [
"752698b4f8f7298ca2ecc74d41887117a636118a",
"testharness"
@ -608617,10 +608730,18 @@
"f4df69196f64cd81e92705186325004ac94db659",
"support"
],
"workers/modules/resources/dynamic-import-given-url-worker.js": [
"372686abd1b2d2d09228a44f6420c646319e0bd1",
"support"
],
"workers/modules/resources/dynamic-import-worker.js": [
"444e313fe51923097e3672d88d0afd30aac5ecab",
"support"
],
"workers/modules/resources/import-meta-url-worker.js": [
"83f231a886c36543721c2b0204c18b97d10968f8",
"support"
],
"workers/modules/resources/nested-dynamic-import-worker.js": [
"4ee05f3be8a1b41a9e2fa3e24d40ec5103f67eac",
"support"

View file

@ -1,4 +0,0 @@
[010.html]
[Salvagability of document.opened document]
expected: FAIL

View file

@ -0,0 +1,8 @@
[dedicated-worker-import-meta.html]
expected: ERROR
[Test import.meta.url on the top-level module script.]
expected: TIMEOUT
[Test import.meta.url on the imported module script.]
expected: NOTRUN

View file

@ -0,0 +1,54 @@
<!DOCTYPE html>
<html class=reftest-wait>
<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#layoutfragment">
<link rel="match" href="position-fragment-ref.html">
<meta name="assert" content="This test checks that child fragments get positioned correctly." />
<style>
.test {
background: red;
width: 100px;
height: 100px;
}
.test {
writing-mode: horizontal-tb;
direction: ltr;
}
.child-1 {
background: rebeccapurple;
width: 10px;
height: 20px;
--inline-offset: 5;
--block-offset: 25;
}
.child-2 {
writing-mode: vertical-rl;
background: rebeccapurple;
width: 15px;
height: 25px;
--inline-offset: 50;
--block-offset: 60;
}
@supports (display: layout(test)) {
.test {
background: green;
display: layout(test);
}
}
</style>
<script src="/common/reftest-wait.js"></script>
<script src="/common/worklet-reftest.js"></script>
<div class="test">
<div class="child-1"></div>
<div class="child-2"></div>
</div>
<script>
importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/layout-position-child-worklet.js'});
</script>

View file

@ -0,0 +1,54 @@
<!DOCTYPE html>
<html class=reftest-wait>
<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#layoutfragment">
<link rel="match" href="position-fragment-ref.html">
<meta name="assert" content="This test checks that child fragments get positioned correctly." />
<style>
.test {
background: red;
width: 100px;
height: 100px;
}
.test {
writing-mode: horizontal-tb;
direction: rtl;
}
.child-1 {
background: rebeccapurple;
width: 10px;
height: 20px;
--inline-offset: 85;
--block-offset: 25;
}
.child-2 {
writing-mode: vertical-rl;
background: rebeccapurple;
width: 15px;
height: 25px;
--inline-offset: 35;
--block-offset: 60;
}
@supports (display: layout(test)) {
.test {
background: green;
display: layout(test);
}
}
</style>
<script src="/common/reftest-wait.js"></script>
<script src="/common/worklet-reftest.js"></script>
<div class="test">
<div class="child-1"></div>
<div class="child-2"></div>
</div>
<script>
importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/layout-position-child-worklet.js'});
</script>

View file

@ -0,0 +1,33 @@
<!DOCTYPE html>
<style>
.result {
position: relative;
background: green;
width: 100px;
height: 100px;
}
.result-child-1 {
background: rebeccapurple;
width: 10px;
height: 20px;
position: absolute;
top: 25px;
left: 5px;
}
.result-child-2 {
background: rebeccapurple;
width: 15px;
height: 25px;
position: absolute;
top: 60px;
left: 50px;
}
</style>
<div class="result">
<div class="result-child-1"></div>
<div class="result-child-2"></div>
</div>

View file

@ -0,0 +1,54 @@
<!DOCTYPE html>
<html class=reftest-wait>
<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#layoutfragment">
<link rel="match" href="position-fragment-ref.html">
<meta name="assert" content="This test checks that child fragments get positioned correctly." />
<style>
.test {
background: red;
width: 100px;
height: 100px;
}
.test {
writing-mode: vertical-lr;
direction: ltr;
}
.child-1 {
background: rebeccapurple;
width: 10px;
height: 20px;
--inline-offset: 25;
--block-offset: 5;
}
.child-2 {
writing-mode: vertical-rl;
background: rebeccapurple;
width: 15px;
height: 25px;
--inline-offset: 60;
--block-offset: 50;
}
@supports (display: layout(test)) {
.test {
background: green;
display: layout(test);
}
}
</style>
<script src="/common/reftest-wait.js"></script>
<script src="/common/worklet-reftest.js"></script>
<div class="test">
<div class="child-1"></div>
<div class="child-2"></div>
</div>
<script>
importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/layout-position-child-worklet.js'});
</script>

View file

@ -0,0 +1,54 @@
<!DOCTYPE html>
<html class=reftest-wait>
<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#layoutfragment">
<link rel="match" href="position-fragment-ref.html">
<meta name="assert" content="This test checks that child fragments get positioned correctly." />
<style>
.test {
background: red;
width: 100px;
height: 100px;
}
.test {
writing-mode: vertical-lr;
direction: rtl;
}
.child-1 {
background: rebeccapurple;
width: 10px;
height: 20px;
--inline-offset: 55;
--block-offset: 5;
}
.child-2 {
writing-mode: vertical-rl;
background: rebeccapurple;
width: 15px;
height: 25px;
--inline-offset: 15;
--block-offset: 50;
}
@supports (display: layout(test)) {
.test {
background: green;
display: layout(test);
}
}
</style>
<script src="/common/reftest-wait.js"></script>
<script src="/common/worklet-reftest.js"></script>
<div class="test">
<div class="child-1"></div>
<div class="child-2"></div>
</div>
<script>
importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/layout-position-child-worklet.js'});
</script>

View file

@ -0,0 +1,54 @@
<!DOCTYPE html>
<html class=reftest-wait>
<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#layoutfragment">
<link rel="match" href="position-fragment-ref.html">
<meta name="assert" content="This test checks that child fragments get positioned correctly." />
<style>
.test {
background: red;
width: 100px;
height: 100px;
}
.test {
writing-mode: vertical-rl;
direction: ltr;
}
.child-1 {
background: rebeccapurple;
width: 10px;
height: 20px;
--inline-offset: 25;
--block-offset: 85;
}
.child-2 {
writing-mode: vertical-rl;
background: rebeccapurple;
width: 15px;
height: 25px;
--inline-offset: 60;
--block-offset: 35;
}
@supports (display: layout(test)) {
.test {
background: green;
display: layout(test);
}
}
</style>
<script src="/common/reftest-wait.js"></script>
<script src="/common/worklet-reftest.js"></script>
<div class="test">
<div class="child-1"></div>
<div class="child-2"></div>
</div>
<script>
importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/layout-position-child-worklet.js'});
</script>

View file

@ -0,0 +1,54 @@
<!DOCTYPE html>
<html class=reftest-wait>
<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#layoutfragment">
<link rel="match" href="position-fragment-ref.html">
<meta name="assert" content="This test checks that child fragments get positioned correctly." />
<style>
.test {
background: red;
width: 100px;
height: 100px;
}
.test {
writing-mode: vertical-rl;
direction: rtl;
}
.child-1 {
background: rebeccapurple;
width: 10px;
height: 20px;
--inline-offset: 55;
--block-offset: 85;
}
.child-2 {
writing-mode: vertical-rl;
background: rebeccapurple;
width: 15px;
height: 25px;
--inline-offset: 15;
--block-offset: 35;
}
@supports (display: layout(test)) {
.test {
background: green;
display: layout(test);
}
}
</style>
<script src="/common/reftest-wait.js"></script>
<script src="/common/worklet-reftest.js"></script>
<div class="test">
<div class="child-1"></div>
<div class="child-2"></div>
</div>
<script>
importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: 'support/layout-position-child-worklet.js'});
</script>

View file

@ -0,0 +1,22 @@
registerLayout('test', class {
static get childInputProperties() {
return [
'--inline-offset',
'--block-offset',
];
}
*intrinsicSizes() {}
*layout(children, edges, constraints, styleMap) {
const childFragments = yield children.map((child) => {
return child.layoutNextFragment({});
});
for (let i = 0; i < children.length; i++) {
childFragments[i].inlineOffset = parseInt(children[i].styleMap.get('--inline-offset').toString());
childFragments[i].blockOffset = parseInt(children[i].styleMap.get('--block-offset').toString());
}
return {autoBlockSize: 0, childFragments};
}
});

View file

@ -12,29 +12,29 @@
<script>
test(() => {
const elements = setupStickyTest('left', 50, true);
const elements = setupStickyTest('left', 50);
elements.scroller.scrollLeft = 100;
const nonStickyLeftY = elements.container.offsetLeft +
const nonStickyLeftX = elements.container.offsetLeft +
elements.filler.clientWidth;
assert_equals(elements.sticky.offsetLeft, nonStickyLeftY);
assert_equals(elements.sticky.offsetLeft, nonStickyLeftX);
}, 'before reaching the sticking point the sticky box should not be offset');
test(() => {
const elements = setupStickyTest('left', 50, true);
const elements = setupStickyTest('left', 50);
elements.scroller.scrollLeft = 200;
// This math actually cancels to sticky.offsetLeft == (scroller.scrollLeft + 50),
// but for clarity the calculations are left explicit.
const nonStickyLeftY = elements.container.offsetLeft +
const nonStickyLeftX = elements.container.offsetLeft +
elements.filler.clientWidth;
const targetLeftY = elements.scroller.scrollLeft + 50;
const stickyOffset = targetLeftY - nonStickyLeftY;
const targetLeftX = elements.scroller.scrollLeft + 50;
const stickyOffset = targetLeftX - nonStickyLeftX;
assert_equals(elements.sticky.offsetLeft, nonStickyLeftY + stickyOffset);
assert_equals(elements.sticky.offsetLeft, nonStickyLeftX + stickyOffset);
}, 'after reaching the sticking point the sticky box should be offset');
test(() => {
const elements = setupStickyTest('left', 50, true);
const elements = setupStickyTest('left', 50);
elements.scroller.scrollLeft = 300;
const maxOffsetInContainer = elements.container.offsetLeft +
elements.container.clientWidth - elements.sticky.clientWidth;

View file

@ -1,76 +0,0 @@
<!DOCTYPE html>
<title>Reference for nested bottom-constrained position:sticky elements should render correctly</title>
<style>
.group {
display: inline-block;
position: relative;
width: 150px;
height: 250px;
}
.scroller {
position: relative;
width: 100px;
height: 200px;
overflow-x: hidden;
overflow-y: auto;
}
.contents {
height: 500px;
}
.outerIndicator {
background-color: green;
position: absolute;
left: 0;
width: 100%;
height: 100px;
}
.innerIndicator {
background-color: blue;
position: absolute;
left: 0;
width: 100%;
height: 50px;
}
</style>
<script>
window.addEventListener('load', function() {
document.getElementById('scroller1').scrollTop = 75;
document.getElementById('scroller2').scrollTop = 175;
document.getElementById('scroller3').scrollTop = 250;
});
</script>
<div class="group">
<div id="scroller1" class="scroller">
<div class="contents">
<div class="outerIndicator" style="top: 200px;"></div>
<div class="innerIndicator" style="top: 200px;"></div>
</div>
</div>
</div>
<div class="group">
<div id="scroller2" class="scroller">
<div class="contents">
<div class="outerIndicator" style="top: 250px;"></div>
<div class="innerIndicator" style="top: 290px;"></div>
</div>
</div>
</div>
<div class="group">
<div id="scroller3" class="scroller">
<div class="contents">
<div class="outerIndicator" style="top: 300px;"></div>
<div class="innerIndicator" style="top: 350px;"></div>
</div>
</div>
</div>
<div>You should see three green and three blue boxes above. No red should be visible.</div>

View file

@ -1,135 +1,68 @@
<!DOCTYPE html>
<title>Nested bottom-constrained position:sticky elements should render correctly</title>
<link rel="match" href="position-sticky-nested-bottom-ref.html" />
<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" />
<meta name="assert" content="This test checks that nested position:sticky elements with a bottom constraint render correctly" />
<style>
.group {
display: inline-block;
position: relative;
width: 150px;
height: 250px;
}
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
.scroller {
position: relative;
width: 100px;
height: 200px;
overflow-x: hidden;
overflow-y: auto;
}
<script src="resources/sticky-util.js"></script>
.contents {
height: 500px;
}
.prepadding {
height: 200px;
}
.container {
height: 200px;
}
.filler {
height: 100px;
}
.outerIndicator {
background-color: red;
position: absolute;
left: 0;
width: 100%;
height: 100px;
}
.innerIndicator {
background-color: red;
position: absolute;
left: 0;
width: 100%;
height: 50px;
}
.outerSticky {
background-color: green;
position: sticky;
bottom: 25px;
width: 100%;
height: 100px;
}
.innerFiller {
height: 50px;
}
.innerSticky {
background-color: blue;
position: sticky;
bottom: 35px;
width: 100%;
height: 50px;
}
</style>
<body></body>
<script>
window.addEventListener('load', function() {
document.getElementById('scroller1').scrollTop = 75;
document.getElementById('scroller2').scrollTop = 175;
document.getElementById('scroller3').scrollTop = 250;
});
test(() => {
const elements = setupNestedStickyTest('bottom', 25, 35);
elements.scroller.scrollTop = 300;
const nonStickyTopY = elements.container.offsetTop +
elements.filler.clientHeight;
assert_equals(elements.sticky.offsetTop, nonStickyTopY);
// The inner sticky should not be offset from the outer.
const nonStickyInnerTopY = elements.sticky.clientHeight -
elements.innerSticky.clientHeight;
assert_equals(elements.innerSticky.offsetTop, nonStickyInnerTopY);
}, 'before reaching the sticking point, neither sticky box should be offset');
test(() => {
const elements = setupNestedStickyTest('bottom', 25, 50);
elements.scroller.scrollTop = 150;
const nonStickyTopY = elements.container.offsetTop +
elements.filler.clientHeight;
assert_equals(elements.sticky.offsetTop, nonStickyTopY);
assert_equals(elements.innerSticky.offsetTop, 35);
}, 'the inner sticky can stick before the outer one if necessary');
test(() => {
const elements = setupNestedStickyTest('bottom', 25, 35);
elements.scroller.scrollTop = 100;
const nonStickyTopY = elements.container.offsetTop +
elements.filler.clientHeight;
const nonStickyBottomY = nonStickyTopY + elements.sticky.clientHeight;
const targetBottomY = elements.scroller.clientHeight +
elements.scroller.scrollTop - 25;
const stickyOffset = nonStickyBottomY - targetBottomY;
assert_equals(elements.sticky.offsetTop, nonStickyTopY - stickyOffset);
// The inner sticky has similar math, but its offsetTop is relative to the
// sticky element and in this test is (height - the difference between the
// top values).
assert_equals(elements.innerSticky.offsetTop, 40);
}, 'both sticky boxes can be stuck at the same time');
test(() => {
const elements = setupNestedStickyTest('bottom', 25, 35);
elements.scroller.scrollTop = 0;
assert_equals(elements.sticky.offsetTop, elements.container.offsetTop);
assert_equals(elements.innerSticky.offsetTop, 0);
}, 'neither sticky can escape their containing block');
test(() => {
const elements = setupNestedStickyTest('bottom', 25, 500);
elements.scroller.scrollTop = 200;
// It doesn't matter how big the inner sticky offset is, it cannot escape its
// containing block (the outer sticky).
assert_equals(elements.innerSticky.offsetTop, 0);
}, 'the inner sticky cannot be pushed outside the outer sticky');
</script>
<div class="group">
<div id="scroller1" class="scroller">
<div class="outerIndicator" style="top: 200px;"></div>
<div class="contents">
<div class="prepadding"></div>
<div class="container">
<div class="filler"></div>
<div class="outerSticky">
<div class="innerIndicator" style="top: 0;"></div>
<div class="innerFiller"></div>
<div class="innerSticky"></div>
</div>
</div>
</div>
</div>
</div>
<div class="group">
<div id="scroller2" class="scroller">
<div class="outerIndicator" style="top: 250px;"></div>
<div class="contents">
<div class="prepadding"></div>
<div class="container">
<div class="filler"></div>
<div class="outerSticky">
<div class="innerIndicator" style="top: 40px;"></div>
<div class="innerFiller"></div>
<div class="innerSticky"></div>
</div>
</div>
</div>
</div>
</div>
<div class="group">
<div id="scroller3" class="scroller">
<div class="outerIndicator" style="top: 300px;"></div>
<div class="contents">
<div class="prepadding"></div>
<div class="container">
<div class="filler"></div>
<div class="outerSticky">
<div class="innerIndicator" style="top: 50px;"></div>
<div class="innerFiller"></div>
<div class="innerSticky"></div>
</div>
</div>
</div>
</div>
</div>
<div>You should see three green and three blue boxes above. No red should be visible.</div>

View file

@ -1,76 +0,0 @@
<!DOCTYPE html>
<title>Reference for nested left-constrained position:sticky elements should render correctly</title>
<style>
.group {
position: relative;
width: 250px;
height: 150px;
}
.scroller {
position: relative;
width: 200px;
height: 100px;
overflow-x: auto;
overflow-y: hidden;
}
.contents {
height: 100%;
width: 500px;
}
.outerIndicator {
background-color: green;
position: absolute;
top: 0;
height: 100%;
width: 100px;
}
.innerIndicator {
background-color: blue;
position: absolute;
top: 0;
height: 100%;
width: 50px;
}
</style>
<script>
window.addEventListener('load', function() {
document.getElementById('scroller1').scrollLeft = 50;
document.getElementById('scroller2').scrollLeft = 125;
document.getElementById('scroller3').scrollLeft = 225;
});
</script>
<div class="group">
<div id="scroller1" class="scroller">
<div class="contents">
<div class="outerIndicator" style="left: 150px;"></div>
<div class="innerIndicator" style="left: 150px;"></div>
</div>
</div>
</div>
<div class="group">
<div id="scroller2" class="scroller">
<div class="contents">
<div class="outerIndicator" style="left: 175px;"></div>
<div class="innerIndicator" style="left: 185px;"></div>
</div>
</div>
</div>
<div class="group">
<div id="scroller3" class="scroller">
<div class="contents">
<div class="outerIndicator" style="left: 200px;"></div>
<div class="innerIndicator" style="left: 250px;"></div>
</div>
</div>
</div>
<div>You should see three green and three blue boxes above. No red should be visible.</div>

View file

@ -1,141 +1,75 @@
<!DOCTYPE html>
<title>Nested left-constrained position:sticky elements should render correctly</title>
<link rel="match" href="position-sticky-nested-left-ref.html" />
<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" />
<meta name="assert" content="This test checks that nested position:sticky elements with a left constraint render correctly" />
<style>
.group {
position: relative;
width: 250px;
height: 150px;
}
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
.scroller {
position: relative;
width: 200px;
height: 100px;
overflow-x: auto;
overflow-y: hidden;
}
<script src="resources/sticky-util.js"></script>
.contents {
height: 100%;
width: 500px;
/* Allow nice formatting of inline divs. Fonts are not used in this test. */
font-size: 0;
}
.prepadding {
display: inline-block;
height: 100%;
width: 100px;
}
.container {
display: inline-block;
height: 100%;
width: 200px;
}
.innerpadding {
display: inline-block;
height: 100%;
width: 50px;
}
.outerIndicator {
background-color: red;
position: absolute;
top: 0;
display: inline-block;
height: 100%;
width: 100px;
}
.innerIndicator {
background-color: red;
position: absolute;
top: 0;
display: inline-block;
height: 100%;
width: 50px;
}
.outerSticky {
background-color: green;
position: sticky;
left: 50px;
display: inline-block;
height: 100%;
width: 100px;
}
.innerSticky {
background-color: blue;
position: sticky;
left: 60px;
display: inline-block;
height: 100%;
width: 50px;
}
</style>
<body></body>
<script>
window.addEventListener('load', function() {
document.getElementById('scroller1').scrollLeft = 50;
document.getElementById('scroller2').scrollLeft = 125;
document.getElementById('scroller3').scrollLeft = 225;
});
test(() => {
const elements = setupNestedStickyTest('left', 50, 60);
elements.scroller.scrollLeft = 100;
const nonStickyLeftX = elements.container.offsetLeft +
elements.filler.clientWidth;
assert_equals(elements.sticky.offsetLeft, nonStickyLeftX);
// The inner sticky should not be offset from the outer.
assert_equals(elements.innerSticky.offsetLeft, 0);
}, 'before reaching the sticking point, neither sticky box should be offset');
test(() => {
const elements = setupNestedStickyTest('left', 50, 60);
elements.scroller.scrollLeft = 145;
const nonStickyLeftX = elements.container.offsetLeft +
elements.filler.clientWidth;
assert_equals(elements.sticky.offsetLeft, nonStickyLeftX);
assert_equals(elements.innerSticky.offsetLeft, 5);
}, 'the inner sticky can stick before the outer one if necessary');
test(() => {
const elements = setupNestedStickyTest('left', 50, 60);
elements.scroller.scrollLeft = 200;
// This math cancels to sticky.offsetLeft == (scroller.scrollLeft + 50), but
// for clarity the calculations are left explicit.
const nonStickyLeftX = elements.container.offsetLeft +
elements.filler.clientWidth;
const targetLeftX = elements.scroller.scrollLeft + 50;
const stickyOffset = targetLeftX - nonStickyLeftX;
assert_equals(elements.sticky.offsetLeft, nonStickyLeftX + stickyOffset);
// The inner sticky has similar math, but its offsetLeft is relative to the
// sticky element and in this test is the difference between the left values.
assert_equals(elements.innerSticky.offsetLeft, 10);
}, 'both sticky boxes can be stuck at the same time');
test(() => {
const elements = setupNestedStickyTest('left', 50, 60);
elements.scroller.scrollLeft = 300;
const maxOffsetInContainer = elements.container.offsetLeft +
elements.container.clientWidth - elements.sticky.clientWidth;
assert_equals(elements.sticky.offsetLeft, maxOffsetInContainer);
const maxOffsetInOuterSticky = elements.sticky.clientWidth -
elements.innerSticky.clientWidth;
assert_equals(elements.innerSticky.offsetLeft, maxOffsetInOuterSticky);
}, 'neither sticky can escape their containing block');
test(() => {
const elements = setupNestedStickyTest('left', 50, 300);
elements.scroller.scrollLeft = 100;
// The outer sticky has not stuck yet.
const nonStickyLeftX = elements.container.offsetLeft +
elements.filler.clientWidth;
assert_equals(elements.sticky.offsetLeft, nonStickyLeftX);
// But the inner sticky still cannot escape the outer sticky (as it is the
// containing block).
const maxOffsetInOuterSticky = elements.sticky.clientWidth -
elements.innerSticky.clientWidth;
assert_equals(elements.innerSticky.offsetLeft, maxOffsetInOuterSticky);
}, 'the inner sticky cannot be pushed outside the outer sticky');
</script>
<div class="group">
<div id="scroller1" class="scroller">
<div class="outerIndicator" style="left: 150px;"></div>
<div class="contents">
<div class="prepadding"></div>
<div class="container">
<div class="innerpadding"></div>
<div class="outerSticky">
<div class="innerIndicator" style="left: 0;"></div>
<div class="innerSticky"></div>
</div>
</div>
</div>
</div>
</div>
<div class="group">
<div id="scroller2" class="scroller">
<div class="outerIndicator" style="left: 175px;"></div>
<div class="contents">
<div class="prepadding"></div>
<div class="container">
<div class="innerpadding">
</div><div class="outerSticky">
<div class="innerIndicator" style="left: 10px;"></div>
<div class="innerSticky"></div>
</div>
</div>
</div>
</div>
</div>
<div class="group">
<div id="scroller3" class="scroller">
<div class="outerIndicator" style="left: 200px;"></div>
<div class="contents">
<div class="prepadding"></div>
<div class="container">
<div class="innerpadding"></div>
<div class="outerSticky">
<div class="innerIndicator" style="left: 50px;"></div>
<div class="innerSticky"></div>
</div>
</div>
</div>
</div>
</div>
<div>You should see three green and three blue boxes above. No red should be visible.</div>

View file

@ -1,76 +0,0 @@
<!DOCTYPE html>
<title>Reference for position:sticky elements should respect the right constraint</title>
<style>
.group {
position: relative;
width: 250px;
height: 150px;
}
.scroller {
position: relative;
width: 200px;
height: 100px;
overflow-x: auto;
overflow-y: hidden;
}
.contents {
height: 100%;
width: 500px;
}
.outerIndicator {
background-color: green;
position: absolute;
top: 0;
height: 100%;
width: 100px;
}
.innerIndicator {
background-color: blue;
position: absolute;
top: 0;
height: 100%;
width: 50px;
}
</style>
<script>
window.addEventListener('load', function() {
document.getElementById('scroller1').scrollLeft = 75;
document.getElementById('scroller2').scrollLeft = 175;
document.getElementById('scroller3').scrollLeft = 250;
});
</script>
<div class="group">
<div id="scroller1" class="scroller">
<div class="contents">
<div class="outerIndicator" style="left: 200px;"></div>
<div class="innerIndicator" style="left: 200px;"></div>
</div>
</div>
</div>
<div class="group">
<div id="scroller2" class="scroller">
<div class="contents">
<div class="outerIndicator" style="left: 250px;"></div>
<div class="innerIndicator" style="left: 290px;"></div>
</div>
</div>
</div>
<div class="group">
<div id="scroller3" class="scroller">
<div class="contents">
<div class="outerIndicator" style="left: 300px;"></div>
<div class="innerIndicator" style="left: 350px;"></div>
</div>
</div>
</div>
<div>You should see three green and three blue boxes above. No red should be visible.</div>

View file

@ -1,149 +1,69 @@
<!DOCTYPE html>
<title>Nested right-constrained position:sticky elements should render correctly</title>
<link rel="match" href="position-sticky-nested-right-ref.html" />
<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" />
<meta name="assert" content="This test checks that nested position:sticky elements with a right constraint render correctly" />
<style>
.group {
position: relative;
width: 250px;
height: 150px;
}
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
.scroller {
position: relative;
width: 200px;
height: 100px;
overflow-x: auto;
overflow-y: hidden;
}
<script src="resources/sticky-util.js"></script>
.contents {
height: 100%;
width: 500px;
/* Allow nice formatting of inline divs. Fonts are not used in this test. */
font-size: 0;
}
.prepadding {
display: inline-block;
height: 100%;
width: 200px;
}
.container {
display: inline-block;
height: 100%;
width: 200px;
}
.filler {
display: inline-block;
height: 100%;
width: 100px;
}
.outerIndicator {
background-color: red;
position: absolute;
top: 0;
display: inline-block;
height: 100%;
width: 100px;
}
.innerIndicator {
background-color: red;
position: absolute;
top: 0;
display: inline-block;
height: 100%;
width: 50px;
}
.outerSticky {
background-color: green;
position: sticky;
right: 25px;
display: inline-block;
height: 100%;
width: 100px;
}
.innerFiller {
display: inline-block;
height: 100%;
width: 50px;
}
.innerSticky {
background-color: blue;
position: sticky;
right: 35px;
display: inline-block;
height: 100%;
width: 50px;
}
</style>
<body></body>
<script>
window.addEventListener('load', function() {
document.getElementById('scroller1').scrollLeft = 75;
document.getElementById('scroller2').scrollLeft = 175;
document.getElementById('scroller3').scrollLeft = 250;
});
test(() => {
const elements = setupNestedStickyTest('right', 25, 35);
elements.scroller.scrollLeft = 200;
const nonStickyLeftX = elements.container.offsetLeft +
elements.filler.clientWidth;
assert_equals(elements.sticky.offsetLeft, nonStickyLeftX);
// The inner sticky should not be offset from the outer.
const nonStickyInnerLeftX = elements.sticky.clientWidth -
elements.innerSticky.clientWidth;
assert_equals(elements.innerSticky.offsetLeft, nonStickyInnerLeftX);
}, 'before reaching the sticking point, neither sticky box should be offset');
test(() => {
const elements = setupNestedStickyTest('right', 25, 50);
elements.scroller.scrollLeft = 150;
const nonStickyLeftX = elements.container.offsetLeft +
elements.filler.clientWidth;
assert_equals(elements.sticky.offsetLeft, nonStickyLeftX);
assert_equals(elements.innerSticky.offsetLeft, 35);
}, 'the inner sticky can stick before the outer one if necessary');
test(() => {
const elements = setupNestedStickyTest('right', 25, 35);
elements.scroller.scrollLeft = 100;
const nonStickyLeftX = elements.container.offsetLeft +
elements.filler.clientWidth;
const nonStickyBottomX = nonStickyLeftX + elements.sticky.clientWidth;
const targetBottomX = elements.scroller.clientWidth +
elements.scroller.scrollLeft - 25;
const stickyOffset = nonStickyBottomX - targetBottomX;
assert_equals(elements.sticky.offsetLeft, nonStickyLeftX - stickyOffset);
// The inner sticky has similar math, but its offsetLeft is relative to the
// sticky element and in this test is (height - the difference between the
// top values).
assert_equals(elements.innerSticky.offsetLeft, 40);
}, 'both sticky boxes can be stuck at the same time');
test(() => {
const elements = setupNestedStickyTest('right', 25, 35);
elements.scroller.scrollLeft = 0;
assert_equals(elements.sticky.offsetLeft, elements.container.offsetLeft);
assert_equals(elements.innerSticky.offsetLeft, 0);
}, 'neither sticky can escape their containing block');
test(() => {
const elements = setupNestedStickyTest('right', 25, 500);
elements.scroller.scrollLeft = 200;
// It doesn't matter how big the inner sticky offset is, it cannot escape its
// containing block (the outer sticky).
assert_equals(elements.innerSticky.offsetLeft, 0);
}, 'the inner sticky cannot be pushed outside the outer sticky');
</script>
<div class="group">
<div id="scroller1" class="scroller">
<div class="outerIndicator" style="left: 200px;"></div>
<div class="contents">
<div class="prepadding"></div>
<div class="container">
<div class="filler"></div>
<div class="outerSticky">
<div class="innerIndicator" style="left: 0;"></div>
<div class="innerFiller"></div>
<div class="innerSticky"></div>
</div>
</div>
</div>
</div>
</div>
<div class="group">
<div id="scroller2" class="scroller">
<div class="outerIndicator" style="left: 250px;"></div>
<div class="contents">
<div class="prepadding"></div>
<div class="container">
<div class="filler"></div>
<div class="outerSticky">
<div class="innerIndicator" style="left: 40px;"></div>
<div class="innerFiller"></div>
<div class="innerSticky"></div>
</div>
</div>
</div>
</div>
</div>
<div class="group">
<div id="scroller3" class="scroller">
<div class="outerIndicator" style="left: 300px;"></div>
<div class="contents">
<div class="prepadding"></div>
<div class="container">
<div class="filler"></div>
<div class="outerSticky">
<div class="innerIndicator" style="left: 50px;"></div>
<div class="innerFiller"></div>
<div class="innerSticky"></div>
</div>
</div>
</div>
</div>
</div>
<div>You should see three green and three blue boxes above. No red should be visible.</div>

View file

@ -1,83 +0,0 @@
<!DOCTYPE html>
<title>Reference for nested top-constrained position:sticky elements should render correctly</title>
<style>
.group {
display: inline-block;
position: relative;
width: 150px;
height: 250px;
}
.scroller {
position: relative;
width: 100px;
height: 200px;
overflow-x: hidden;
overflow-y: auto;
}
.contents {
height: 500px;
}
.green {
background-color: green;
}
.blue {
background-color: blue;
}
.indicator {
position: absolute;
left: 0;
}
.bigBox {
width: 100%;
height: 100px;
}
.smallBox {
width: 100%;
height: 50px;
}
</style>
<script>
window.addEventListener('load', function() {
document.getElementById('scroller1').scrollTop = 50;
document.getElementById('scroller2').scrollTop = 125;
document.getElementById('scroller3').scrollTop = 225;
});
</script>
<div class="group">
<div id="scroller1" class="scroller">
<div class="contents">
<div class="green indicator bigBox" style="top: 150px;"></div>
<div class="blue indicator smallBox" style="top: 150px;"></div>
</div>
</div>
</div>
<div class="group">
<div id="scroller2" class="scroller">
<div class="contents">
<div class="green indicator bigBox" style="top: 175px;"></div>
<div class="blue indicator smallBox" style="top: 185px;"></div>
</div>
</div>
</div>
<div class="group">
<div id="scroller3" class="scroller">
<div class="contents">
<div class="green indicator bigBox" style="top: 200px;"></div>
<div class="blue indicator smallBox" style="top: 250px;"></div>
</div>
</div>
</div>
<div>You should see three green and three blue boxes above. No red should be visible.</div>

View file

@ -1,128 +1,74 @@
<!DOCTYPE html>
<title>Nested top-constrainted position:sticky elements should render correctly</title>
<link rel="match" href="position-sticky-nested-top-ref.html" />
<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" />
<meta name="assert" content="This test checks that nested position:sticky elements with a top constraint render correctly" />
<style>
.group {
display: inline-block;
position: relative;
width: 150px;
height: 250px;
}
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
.scroller {
position: relative;
width: 100px;
height: 200px;
overflow-x: hidden;
overflow-y: auto;
}
<script src="resources/sticky-util.js"></script>
.contents {
height: 500px;
}
.prepadding {
height: 100px;
}
.container {
height: 200px;
}
.innerpadding {
height: 50px;
}
.outerIndicator {
background-color: red;
position: absolute;
left: 0;
height: 100px;
width: 100%;
}
.innerIndicator {
background-color: red;
position: absolute;
left: 0;
height: 50px;
width: 100%;
}
.outerSticky {
background-color: green;
position: sticky;
top: 50px;
width: 100%;
height: 100px;
}
.innerSticky {
background-color: blue;
position: sticky;
top: 60px;
width: 100%;
height: 50px;
}
</style>
<body></body>
<script>
window.addEventListener('load', function() {
document.getElementById('scroller1').scrollTop = 50;
document.getElementById('scroller2').scrollTop = 125;
document.getElementById('scroller3').scrollTop = 225;
});
test(() => {
const elements = setupNestedStickyTest('top', 50, 60);
elements.scroller.scrollTop = 100;
const nonStickyTopY = elements.container.offsetTop +
elements.filler.clientHeight;
assert_equals(elements.sticky.offsetTop, nonStickyTopY);
// The inner sticky should not be offset from the outer.
assert_equals(elements.innerSticky.offsetTop, 0);
}, 'before reaching the sticking point, neither sticky box should be offset');
test(() => {
const elements = setupNestedStickyTest('top', 50, 60);
elements.scroller.scrollTop = 145;
const nonStickyTopY = elements.container.offsetTop +
elements.filler.clientHeight;
assert_equals(elements.sticky.offsetTop, nonStickyTopY);
assert_equals(elements.innerSticky.offsetTop, 5);
}, 'the inner sticky can stick before the outer one if necessary');
test(() => {
const elements = setupNestedStickyTest('top', 50, 60);
elements.scroller.scrollTop = 200;
// This math cancels to sticky.offsetTop == (scroller.scrollTop + 50), but
// for clarity the calculations are left explicit.
const nonStickyTopY = elements.container.offsetTop +
elements.filler.clientHeight;
const targetTopY = elements.scroller.scrollTop + 50;
const stickyOffset = targetTopY - nonStickyTopY;
assert_equals(elements.sticky.offsetTop, nonStickyTopY + stickyOffset);
// The inner sticky has similar math, but its offsetTop is relative to the
// sticky element and in this test is the difference between the top values.
assert_equals(elements.innerSticky.offsetTop, 10);
}, 'both sticky boxes can be stuck at the same time');
test(() => {
const elements = setupNestedStickyTest('top', 50, 60);
elements.scroller.scrollTop = 300;
const maxOffsetInContainer = elements.container.offsetTop +
elements.container.clientHeight - elements.sticky.clientHeight;
assert_equals(elements.sticky.offsetTop, maxOffsetInContainer);
const maxOffsetInOuterSticky = elements.sticky.clientHeight -
elements.innerSticky.clientHeight;
assert_equals(elements.innerSticky.offsetTop, maxOffsetInOuterSticky);
}, 'neither sticky can escape their containing block');
test(() => {
const elements = setupNestedStickyTest('top', 50, 300);
elements.scroller.scrollTop = 100;
// The outer sticky has not stuck yet.
const nonStickyTopY = elements.container.offsetTop +
elements.filler.clientHeight;
assert_equals(elements.sticky.offsetTop, nonStickyTopY);
// But the inner sticky still cannot escape the outer sticky (as it is the
// containing block).
const maxOffsetInOuterSticky = elements.sticky.clientHeight -
elements.innerSticky.clientHeight;
assert_equals(elements.innerSticky.offsetTop, maxOffsetInOuterSticky);
}, 'the inner sticky cannot be pushed outside the outer sticky');
</script>
<div class="group">
<div id="scroller1" class="scroller">
<div class="outerIndicator" style="top: 150px;"></div>
<div class="contents">
<div class="prepadding"></div>
<div class="container">
<div class="innerpadding"></div>
<div class="outerSticky">
<div class="innerIndicator" style="top: 0;"></div>
<div class="innerSticky"></div>
</div>
</div>
</div>
</div>
</div>
<div class="group">
<div id="scroller2" class="scroller">
<div class="outerIndicator" style="top: 175px;"></div>
<div class="contents">
<div class="prepadding"></div>
<div class="container">
<div class="innerpadding"></div>
<div class="outerSticky">
<div class="innerIndicator" style="top: 10px;"></div>
<div class="innerSticky"></div>
</div>
</div>
</div>
</div>
</div>
<div class="group">
<div id="scroller3" class="scroller">
<div class="outerIndicator" style="top: 200px;"></div>
<div class="contents">
<div class="prepadding"></div>
<div class="container">
<div class="innerpadding"></div>
<div class="outerSticky">
<div class="innerIndicator" style="top: 50px;"></div>
<div class="innerSticky"></div>
</div>
</div>
</div>
</div>
</div>
<div>You should see three green and three blue boxes above. No red should be visible.</div>

View file

@ -12,29 +12,29 @@
<script>
test(() => {
const elements = setupStickyTest('right', 25, true);
const elements = setupStickyTest('right', 25);
elements.scroller.scrollLeft = 200;
const nonStickyLeftY = elements.container.offsetLeft +
const nonStickyLeftX = elements.container.offsetLeft +
elements.filler.clientWidth;
assert_equals(elements.sticky.offsetLeft, nonStickyLeftY);
assert_equals(elements.sticky.offsetLeft, nonStickyLeftX);
}, 'before reaching the sticking point the sticky box should not be offset');
test(() => {
const elements = setupStickyTest('right', 25, true);
const elements = setupStickyTest('right', 25);
elements.scroller.scrollLeft = 75;
const nonStickyLeftY = elements.container.offsetLeft +
const nonStickyLeftX = elements.container.offsetLeft +
elements.filler.clientWidth;
const nonStickyBottomY = nonStickyLeftY + elements.sticky.clientWidth;
const targetBottomY = elements.scroller.clientWidth +
const nonStickyRightX = nonStickyLeftX + elements.sticky.clientWidth;
const targetRightX = elements.scroller.clientWidth +
elements.scroller.scrollLeft - 25;
const stickyOffset = nonStickyBottomY - targetBottomY;
const stickyOffset = nonStickyRightX - targetRightX;
assert_equals(elements.sticky.offsetLeft, nonStickyLeftY - stickyOffset);
assert_equals(elements.sticky.offsetLeft, nonStickyLeftX - stickyOffset);
}, 'after reaching the sticking point the sticky box should be offset');
test(() => {
const elements = setupStickyTest('right', 25, true);
const elements = setupStickyTest('right', 25);
elements.scroller.scrollLeft = 15;
assert_equals(elements.sticky.offsetLeft, elements.container.offsetLeft);
}, 'the sticky box should not be pushed outside its containing block');

View file

@ -11,14 +11,15 @@
* </div>
* </div>
*
* If 'inline' is true, the necessary blocks will be marked as inline-block,
* and the dimensions above are flipped.
* If the sticky direction is 'left' or 'right', the necessary blocks will be
* marked as inline-block and the dimensions above are flipped.
*
* Returns an 'elements' object which has each of the above elements as an
* accessible property.
*/
function setupStickyTest(stickyDirection, stickyOffset, inline = false) {
function setupStickyTest(stickyDirection, stickyOffset) {
const elements = {};
const inline = stickyDirection === 'left' || stickyDirection === 'right';
elements.scroller = document.createElement('div');
elements.scroller.style.position = 'relative';
@ -67,3 +68,39 @@ function setupStickyTest(stickyDirection, stickyOffset, inline = false) {
return elements;
}
/**
* Similar to above, but nests a second sticky (named innerSticky) inside the
* sticky element.
*
* In the 'bottom' and 'right' cases, we also inject some padding before the
* innerSticky element, to give it something to push into. This inner padding is
* not exposed.
*/
function setupNestedStickyTest(stickyDirection, outerStickyOffset,
innerStickyOffset) {
const elements = setupStickyTest(stickyDirection, outerStickyOffset);
const inline = stickyDirection === 'left' || stickyDirection === 'right';
if (stickyDirection === 'bottom' || stickyDirection === 'right') {
const innerPadding = document.createElement('div');
innerPadding.style.height = (inline ? '100%' : '50px');
innerPadding.style.width = (inline ? '50px' : '100%');
if (inline)
innerPadding.style.display = 'inline-block';
elements.sticky.appendChild(innerPadding);
}
elements.innerSticky = document.createElement('div');
elements.innerSticky.style = `${stickyDirection}: ${innerStickyOffset}px;`;
elements.innerSticky.style.position = 'sticky';
elements.innerSticky.style.height = (inline ? '100%' : '50px');
elements.innerSticky.style.width = (inline ? '50px' : '100%');
elements.innerSticky.style.backgroundColor = 'blue';
if (inline)
elements.innerSticky.style.display = 'inline-block';
elements.sticky.appendChild(elements.innerSticky);
return elements;
}

View file

@ -0,0 +1,24 @@
<!doctype html>
<meta charset="utf-8">
<title>'column-width' property</title>
<link rel="help" href="https://drafts.css-houdini.org/css-typed-om/#dom-stylepropertymapreadonly-get">
<link rel="help" href="https://drafts.css-houdini.org/css-typed-om/#dom-stylepropertymap-set">
<link rel="help" href="https://drafts.css-houdini.org/css-typed-om/#reify-stylevalue">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../../resources/testhelper.js"></script>
<script src="resources/testsuite.js"></script>
<body>
<div id="log"></div>
<script>
'use strict';
runPropertyTests('column-width', [
{ syntax: 'auto' },
{
syntax: '<length>',
specified: assert_is_equal_with_range_handling
},
]);
</script>

View file

@ -0,0 +1,51 @@
<!doctype html>
<meta charset="utf-8">
<title>'radius' property</title>
<link rel="help" href="https://drafts.css-houdini.org/css-typed-om-1/#dom-stylepropertymap-get">
<link rel="help" href="https://drafts.css-houdini.org/css-typed-om-1/#dom-stylepropertymap-set">
<link rel="help" href="https://drafts.css-houdini.org/css-typed-om-1/#property-stle-value-normalization">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../../resources/testhelper.js"></script>
<script src="resources/testsuite.js"></script>
<body>
<div id="log"></div>
<script>
'use strict';
runPropertyTests('r', [
{
syntax: '<percentage>',
specified: assert_is_equal_with_range_handling
},
{
syntax: '<length>',
specified: assert_is_equal_with_range_handling
},
]);
runPropertyTests('rx', [
{ syntax: 'auto' },
{
syntax: '<percentage>',
specified: assert_is_equal_with_range_handling
},
{
syntax: '<length>',
specified: assert_is_equal_with_range_handling
},
]);
runPropertyTests('ry', [
{ syntax: 'auto' },
{
syntax: '<percentage>',
specified: assert_is_equal_with_range_handling
},
{
syntax: '<length>',
specified: assert_is_equal_with_range_handling
},
]);
</script>

View file

@ -19,7 +19,7 @@ interface PaymentInstruments {
dictionary PaymentInstrument {
required DOMString name;
sequence<ImageObject> icons;
sequence<DOMString> enabledMethods;
DOMString method;
object capabilities;
};
dictionary ImageObject {

View file

@ -24,7 +24,7 @@ async function registerApp(methodName) {
}
await registration.paymentManager.instruments.set(instrumentKey, {
name: 'Test Payment Method',
enabledMethods: [methodName],
method: methodName,
});
return registration;
}
@ -310,7 +310,7 @@ promise_test(async t => {
const registration = await registerApp(methodName);
await registration.paymentManager.instruments.set(instrumentKey, {
name: 'Test Payment Method',
enabledMethods: [methodName],
method: methodName,
capabilities: {
supportedTypes: [cardType],
supportedNetworks: [cardNetwork],
@ -360,7 +360,7 @@ promise_test(async t => {
const registration = await registerApp(methodName);
await registration.paymentManager.instruments.set(instrumentKey, {
name: 'Test Payment Method',
enabledMethods: [methodName],
method: methodName,
capabilities: {
supportedTypes: [cardType],
supportedNetworks: [cardNetwork],

View file

@ -76,7 +76,7 @@ function runTests(registration) {
type: 'image/png',
},
],
enabledMethods: ['basic-card'],
method: 'basic-card',
capabilities: {supportedNetworks: ['mir'], supportedTypes: ['prepaid']},
},
);
@ -103,7 +103,7 @@ function runTests(registration) {
icons: [
{src: '/images/green-16x16.png', sizes: '16x16', type: 'image/png'},
],
enabledMethods: ['basic-card'],
method: 'basic-card',
capabilities: {supportedNetworks: ['mir'], supportedTypes: ['prepaid']},
},
);
@ -118,7 +118,7 @@ function runTests(registration) {
);
assert_equals(result.icons[0].sizes, '16x16');
assert_equals(result.icons[0].type, 'image/png');
assert_array_equals(result.enabledMethods, ['basic-card']);
assert_equals(result.method, 'basic-card');
assert_array_equals(result.capabilities.supportedNetworks, ['mir']);
assert_array_equals(result.capabilities.supportedTypes, ['prepaid']);
await registration.paymentManager.instruments.set(
@ -132,7 +132,7 @@ function runTests(registration) {
type: 'image/png',
},
],
enabledMethods: ['basic-card'],
method: 'basic-card',
capabilities: {supportedNetworks: ['visa'], supportedTypes: ['credit']},
},
);
@ -147,7 +147,7 @@ function runTests(registration) {
);
assert_equals(result.icons[0].sizes, '256x256');
assert_equals(result.icons[0].type, 'image/png');
assert_array_equals(result.enabledMethods, ['basic-card']);
assert_equals(result.method, 'basic-card');
assert_array_equals(result.capabilities.supportedNetworks, ['visa']);
assert_array_equals(result.capabilities.supportedTypes, ['credit']);
}, 'Resetting an existing instrument updates the instrument');
@ -165,7 +165,7 @@ function runTests(registration) {
type: 'image/png',
},
],
enabledMethods: ['basic-card'],
method: 'basic-card',
capabilities: {supportedNetworks: ['mir'], supportedTypes: ['prepaid']},
},
);
@ -189,7 +189,7 @@ function runTests(registration) {
type: 'image/jif',
},
],
enabledMethods: ['basic-card'],
method: 'basic-card',
},
);
return promise_rejects(t, new TypeError(), setPromise);
@ -208,7 +208,7 @@ function runTests(registration) {
type: 'image/pn' + 'g'.repeat(1000),
},
],
enabledMethods: ['basic-card'],
method: 'basic-card',
},
);
return promise_rejects(t, new TypeError(), setPromise);
@ -225,7 +225,7 @@ function runTests(registration) {
type: 'image/png',
},
],
enabledMethods: ['basic-card'],
method: 'basic-card',
});
}, "Don't crash when registering an instrument with a very long icon size 888...x888...");
@ -242,7 +242,7 @@ function runTests(registration) {
type: 'image/png',
},
],
enabledMethods: ['basic-card'],
method: 'basic-card',
},
);
return promise_rejects(t, new TypeError(), setPromise);
@ -261,7 +261,7 @@ function runTests(registration) {
type: 'image/png',
},
],
enabledMethods: ['basic-card'],
method: 'basic-card',
},
);
return promise_rejects(t, new TypeError(), setPromise);
@ -280,7 +280,7 @@ function runTests(registration) {
type: 'image/png',
},
],
enabledMethods: ['basic-card'],
method: 'basic-card',
},
);
return promise_rejects(t, new TypeError(), setPromise);
@ -300,7 +300,7 @@ function runTests(registration) {
type: 'image/gif',
},
],
enabledMethods: ['basic-card'],
method: 'basic-card',
},
);
return promise_rejects(t, new TypeError(), setPromise);
@ -313,7 +313,7 @@ function runTests(registration) {
icons: [
{src: '/images/rgrg-256x256.png', sizes: '256x256', type: 'image/png'},
],
enabledMethods: [existingKey],
method: existingKey,
capabilities: {aCapabilityName: existingKey},
});
const hasExistingInstrument = await registration.paymentManager.instruments.has(

View file

@ -15,7 +15,7 @@ async function setInstrumentsAndRunTests(registration) {
icons: [
{src: '/images/rgrg-256x256.png', sizes: '256x256', type: 'image/png'},
],
enabledMethods: ['basic-card'],
method: 'basic-card',
capabilities: {supportedNetworks: ['mir'], supportedTypes: ['prepaid']},
});
runTests();

View file

@ -0,0 +1,111 @@
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/test-helpers.sub.js"></script>
<script>
const timingEventOrder = [
'startTime',
'workerStart',
'fetchStart',
'requestStart',
'responseStart',
'responseEnd',
];
function verify(timing) {
for (let i = 0; i < timingEventOrder.length - 1; i++) {
assert_true(timing[timingEventOrder[i]] <= timing[timingEventOrder[i + 1]],
`Expected ${timingEventOrder[i]} <= ${timingEventOrder[i + 1]}`);
}
}
function navigate_in_frame(frame, url) {
frame.contentWindow.location = url;
return new Promise((resolve) => {
frame.addEventListener('load', () => {
const timing = frame.contentWindow.performance.getEntriesByType('navigation')[0];
resolve(timing);
});
});
}
const worker_url = 'resources/navigation-timing-worker.js';
promise_test(t => {
const scope = 'resources/empty.html';
let frame;
return service_worker_unregister_and_register(t, worker_url, scope)
.then(r => {
return wait_for_state(t, r.installing, 'activated');
})
.then(() => with_iframe(scope))
.then(f => {
frame = f;
return navigate_in_frame(frame, 'resources/empty.html');
})
.then(timing => {
verify(timing);
})
.catch(unreached_rejection(t))
.then(() => {
if (frame)
frame.remove();
return service_worker_unregister(t, scope);
});
}, 'Service worker controlled navigation timing');
promise_test(t => {
const scope = 'resources/empty.html?network-fallback';
let frame;
return service_worker_unregister_and_register(t, worker_url, scope)
.then(r => {
return wait_for_state(t, r.installing, 'activated');
})
.then(() => with_iframe(scope))
.then(f => {
frame = f;
return navigate_in_frame(frame, 'resources/empty.html?network-fallback');
})
.then(timing => {
verify(timing);
})
.catch(unreached_rejection(t))
.then(() => {
if (frame)
frame.remove();
return service_worker_unregister(t, scope);
});
}, 'Service worker controlled navigation timing network fallback');
promise_test(t => {
const scope = 'resources/redirect.py?Redirect=empty.html';
let frame;
return service_worker_unregister_and_register(t, worker_url, scope)
.then(r => {
return wait_for_state(t, r.installing, 'activated');
})
.then(() => with_iframe(scope))
.then(f => {
frame = f;
return navigate_in_frame(frame, 'resources/redirect.py?Redirect=empty.html');
})
.then(timing => {
verify(timing);
// Additional checks for redirected navigation.
assert_true(timing.redirectStart <= timing.redirectEnd,
'Expected redirectStart <= redirectEnd');
assert_true(timing.redirectEnd <= timing.fetchStart,
'Expected redirectEnd <= fetchStart');
})
.catch(unreached_rejection(t))
.then(() => {
if (frame)
frame.remove();
return service_worker_unregister(t, scope);
});
}, 'Service worker controlled navigation timing redirect');
</script>

View file

@ -0,0 +1,15 @@
self.addEventListener('fetch', (event) => {
const url = event.request.url;
// Network fallback.
if (url.indexOf('network-fallback') >= 0) {
return;
}
// Don't intercept redirect.
if (url.indexOf('redirect.py') >= 0) {
return;
}
event.respondWith(fetch(url));
});

View file

@ -0,0 +1,23 @@
<!DOCTYPE html>
<title>DedicatedWorker: import.meta</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
promise_test(() => {
const script_url = 'resources/import-meta-url-worker.js';
const worker = new Worker(script_url, { type: 'module' });
return new Promise(resolve => worker.onmessage = resolve)
.then(msg_event => assert_true(msg_event.data.endsWith(script_url)));
}, 'Test import.meta.url on the top-level module script.');
promise_test(() => {
const script_url = 'import-meta-url-worker.js';
const worker = new Worker('resources/dynamic-import-given-url-worker.js',
{ type: 'module' });
worker.postMessage('./' + script_url);
return new Promise(resolve => worker.onmessage = resolve)
.then(msg_event => assert_true(msg_event.data.endsWith(script_url)));
}, 'Test import.meta.url on the imported module script.');
</script>

View file

@ -0,0 +1,4 @@
// Dynamically import the script URL sent by postMessage().
self.addEventListener('message', e => {
import(e.data);
});

View file

@ -0,0 +1 @@
postMessage(import.meta.url);