mirror of
https://github.com/servo/servo.git
synced 2025-07-03 05:23:38 +01:00
Auto merge of #20510 - servo-wpt-sync:wpt_update_02-04-2018, r=jdm
Sync WPT with upstream (02-04-2018) Automated downstream sync of changes from upstream as of 02-04-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/20510) <!-- Reviewable:end -->
This commit is contained in:
commit
20db733f8e
94 changed files with 2583 additions and 2211 deletions
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,2 @@
|
||||||
|
[vh_not_refreshing_on_chrome.html]
|
||||||
|
expected: FAIL
|
|
@ -0,0 +1,4 @@
|
||||||
|
[img-mime-types-coverage.tentative.sub.html]
|
||||||
|
[Untitled]
|
||||||
|
expected: FAIL
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
[preload-image-png-mislabeled-as-html-nosniff.tentative.sub.html]
|
||||||
|
expected: TIMEOUT
|
||||||
|
[Untitled]
|
||||||
|
expected: TIMEOUT
|
||||||
|
|
4
tests/wpt/metadata/fetch/nosniff/image.html.ini
Normal file
4
tests/wpt/metadata/fetch/nosniff/image.html.ini
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
[image.html]
|
||||||
|
[URL query: image/svg+xml]
|
||||||
|
expected: FAIL
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
[010.html]
|
||||||
|
[Salvagability of document.opened document]
|
||||||
|
expected: FAIL
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
[context-release-with-workers.html]
|
||||||
|
expected: TIMEOUT
|
||||||
|
[Overall test]
|
||||||
|
expected: NOTRUN
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
[atan_001_to_008.html]
|
||||||
|
expected: TIMEOUT
|
||||||
|
[Overall test]
|
||||||
|
expected: NOTRUN
|
||||||
|
|
|
@ -423,7 +423,7 @@ is [archived][ircarchive].
|
||||||
|
|
||||||
[contributing]: https://github.com/w3c/web-platform-tests/blob/master/CONTRIBUTING.md
|
[contributing]: https://github.com/w3c/web-platform-tests/blob/master/CONTRIBUTING.md
|
||||||
[ircw3org]: https://www.w3.org/wiki/IRC
|
[ircw3org]: https://www.w3.org/wiki/IRC
|
||||||
[ircarchive]: http://logs.glob.uno/?c=w3%23testing
|
[ircarchive]: https://w3.logbot.info/testing
|
||||||
[mailarchive]: https://lists.w3.org/Archives/Public/public-test-infra/
|
[mailarchive]: https://lists.w3.org/Archives/Public/public-test-infra/
|
||||||
|
|
||||||
Documentation
|
Documentation
|
||||||
|
|
|
@ -1,2 +1,28 @@
|
||||||
This directory contains tests for the
|
This directory contains tests for the
|
||||||
[Async Cookies API](https://github.com/WICG/cookie-store).
|
[Async Cookies API](https://github.com/WICG/cookie-store).
|
||||||
|
|
||||||
|
## Note on cookie naming conventions
|
||||||
|
|
||||||
|
A simple origin cookie is a cookie named with the `__Host-` prefix
|
||||||
|
which is always secure-flagged, always implicit-domain, always
|
||||||
|
`/`-scoped, and hence always unambiguous in the cookie jar serialization
|
||||||
|
and origin-scoped. It can be treated as a simple key/value pair.
|
||||||
|
|
||||||
|
`"LEGACY"` in a cookie name here means it is an old-style unprefixed
|
||||||
|
cookie name, so you can't tell e.g. whether it is Secure-flagged or
|
||||||
|
`/`-pathed just by looking at it, and its flags, domain and path may
|
||||||
|
vary even in a single cookie jar serialization leading to apparent
|
||||||
|
duplicate entries, ambiguities, and complexity (i.e. it cannot be
|
||||||
|
treated as a simple key/value pair.)
|
||||||
|
|
||||||
|
Cookie names used in the tests are intended to be
|
||||||
|
realistic. Traditional session cookie names are typically
|
||||||
|
all-upper-case for broad framework compatibility. The more modern
|
||||||
|
`"__Host-"` prefix has only one allowed casing. An expected upgrade
|
||||||
|
path from traditional "legacy" cookie names to simple origin cookie
|
||||||
|
names is simply to prefix the traditional name with the `"__Host-"`
|
||||||
|
prefix.
|
||||||
|
|
||||||
|
Many of the used cookie names are non-ASCII to ensure
|
||||||
|
straightforward internationalization is possible at every API surface.
|
||||||
|
These work in many modern browsers, though not yet all of them.
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="timeout" content="long">
|
|
||||||
<title>Async Cookies: Basic tests for cookieStore</title>
|
|
||||||
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
|
|
||||||
<script src="/resources/testharness.js"></script>
|
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
|
||||||
<script src="resources/testharness-helpers.js"></script>
|
|
||||||
<script src="resources/cookie-store-tests.js"></script>
|
|
||||||
<script>
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
suite();
|
|
||||||
</script>
|
|
|
@ -1,14 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="timeout" content="long">
|
|
||||||
<title>Async Cookies: Basic tests for cookieStore (HTTPS)</title>
|
|
||||||
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
|
|
||||||
<script src="/resources/testharness.js"></script>
|
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
|
||||||
<script src="resources/testharness-helpers.js"></script>
|
|
||||||
<script src="resources/cookie-store-tests.js"></script>
|
|
||||||
<script>
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
suite();
|
|
||||||
</script>
|
|
|
@ -1,14 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="timeout" content="long">
|
|
||||||
<title>Async Cookies: Basic tests for cookieStore (Static)</title>
|
|
||||||
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
|
|
||||||
<script src="/resources/testharness.js"></script>
|
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
|
||||||
<script src="resources/testharness-helpers.js"></script>
|
|
||||||
<script src="resources/cookie-store-tests.js"></script>
|
|
||||||
<script>
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
suite();
|
|
||||||
</script>
|
|
|
@ -1,14 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="timeout" content="long">
|
|
||||||
<title>Async Cookies: Basic tests for cookieStore (Static; HTTPS)</title>
|
|
||||||
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
|
|
||||||
<script src="/resources/testharness.js"></script>
|
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
|
||||||
<script src="resources/testharness-helpers.js"></script>
|
|
||||||
<script src="resources/cookie-store-tests.js"></script>
|
|
||||||
<script>
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
suite();
|
|
||||||
</script>
|
|
|
@ -1,14 +1,8 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="timeout" content="long">
|
|
||||||
<title>Async Cookies: delete cookies</title>
|
<title>Async Cookies: delete cookies</title>
|
||||||
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
|
<meta name="help" href="https://github.com/WICG/cookie-store/">
|
||||||
<script src="/resources/testharness.js"></script>
|
<script src="/resources/testharness.js"></script>
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
<script src="resources/testharness-helpers.js"></script>
|
<script src="resources/cookie-test-helpers.js"></script>
|
||||||
<script src="resources/cookie-store-tests.js"></script>
|
<script src="resources/delete_cookies.js"></script>
|
||||||
<script>
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
suite({testName: 'testDeleteCookies'});
|
|
||||||
</script>
|
|
||||||
|
|
|
@ -1,14 +1,8 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="timeout" content="long">
|
|
||||||
<title>Async Cookies: delete cookies (HTTPS)</title>
|
<title>Async Cookies: delete cookies (HTTPS)</title>
|
||||||
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
|
<meta name="help" href="https://github.com/WICG/cookie-store/">
|
||||||
<script src="/resources/testharness.js"></script>
|
<script src="/resources/testharness.js"></script>
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
<script src="resources/testharness-helpers.js"></script>
|
<script src="resources/cookie-test-helpers.js"></script>
|
||||||
<script src="resources/cookie-store-tests.js"></script>
|
<script src="resources/delete_cookies.js"></script>
|
||||||
<script>
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
suite({testName: 'testDeleteCookies'});
|
|
||||||
</script>
|
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="timeout" content="long">
|
|
||||||
<title>Async Cookies: delete cookies (Static)</title>
|
|
||||||
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
|
|
||||||
<script src="/resources/testharness.js"></script>
|
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
|
||||||
<script src="resources/testharness-helpers.js"></script>
|
|
||||||
<script src="resources/cookie-store-tests.js"></script>
|
|
||||||
<script>
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
suite({testName: 'testDeleteCookies'});
|
|
||||||
</script>
|
|
|
@ -1,14 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="timeout" content="long">
|
|
||||||
<title>Async Cookies: delete cookies (Static; HTTPS)</title>
|
|
||||||
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
|
|
||||||
<script src="/resources/testharness.js"></script>
|
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
|
||||||
<script src="resources/testharness-helpers.js"></script>
|
|
||||||
<script src="resources/cookie-store-tests.js"></script>
|
|
||||||
<script>
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
suite({testName: 'testDeleteCookies'});
|
|
||||||
</script>
|
|
|
@ -1,14 +1,8 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="timeout" content="long">
|
|
||||||
<title>Async Cookies: document.cookie</title>
|
<title>Async Cookies: document.cookie</title>
|
||||||
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
|
<meta name="help" href="https://github.com/WICG/cookie-store/">
|
||||||
<script src="/resources/testharness.js"></script>
|
<script src="/resources/testharness.js"></script>
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
<script src="resources/testharness-helpers.js"></script>
|
<script src="resources/cookie-test-helpers.js"></script>
|
||||||
<script src="resources/cookie-store-tests.js"></script>
|
<script src="resources/document_cookie.js"></script>
|
||||||
<script>
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
suite({testName: 'testDocumentCookie'});
|
|
||||||
</script>
|
|
||||||
|
|
|
@ -1,14 +1,8 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="timeout" content="long">
|
|
||||||
<title>Async Cookies: document.cookie (HTTPS)</title>
|
<title>Async Cookies: document.cookie (HTTPS)</title>
|
||||||
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
|
<meta name="help" href="https://github.com/WICG/cookie-store/">
|
||||||
<script src="/resources/testharness.js"></script>
|
<script src="/resources/testharness.js"></script>
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
<script src="resources/testharness-helpers.js"></script>
|
<script src="resources/cookie-test-helpers.js"></script>
|
||||||
<script src="resources/cookie-store-tests.js"></script>
|
<script src="resources/document_cookie.js"></script>
|
||||||
<script>
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
suite({testName: 'testDocumentCookie'});
|
|
||||||
</script>
|
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="timeout" content="long">
|
|
||||||
<title>Async Cookies: document.cookie (Static)</title>
|
|
||||||
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
|
|
||||||
<script src="/resources/testharness.js"></script>
|
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
|
||||||
<script src="resources/testharness-helpers.js"></script>
|
|
||||||
<script src="resources/cookie-store-tests.js"></script>
|
|
||||||
<script>
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
suite({testName: 'testDocumentCookie'});
|
|
||||||
</script>
|
|
|
@ -1,14 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="timeout" content="long">
|
|
||||||
<title>Async Cookies: document.cookie (Static; HTTPS)</title>
|
|
||||||
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
|
|
||||||
<script src="/resources/testharness.js"></script>
|
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
|
||||||
<script src="resources/testharness-helpers.js"></script>
|
|
||||||
<script src="resources/cookie-store-tests.js"></script>
|
|
||||||
<script>
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
suite({testName: 'testDocumentCookie'});
|
|
||||||
</script>
|
|
|
@ -1,14 +1,8 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="timeout" content="long">
|
|
||||||
<title>Async Cookies: expiration</title>
|
<title>Async Cookies: expiration</title>
|
||||||
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
|
<meta name="help" href="https://github.com/WICG/cookie-store/">
|
||||||
<script src="/resources/testharness.js"></script>
|
<script src="/resources/testharness.js"></script>
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
<script src="resources/testharness-helpers.js"></script>
|
<script src="resources/cookie-test-helpers.js"></script>
|
||||||
<script src="resources/cookie-store-tests.js"></script>
|
<script src="resources/expiration.js"></script>
|
||||||
<script>
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
suite({testName: 'testExpiration'});
|
|
||||||
</script>
|
|
||||||
|
|
|
@ -1,14 +1,8 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="timeout" content="long">
|
|
||||||
<title>Async Cookies: expiration (HTTPS)</title>
|
<title>Async Cookies: expiration (HTTPS)</title>
|
||||||
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
|
<meta name="help" href="https://github.com/WICG/cookie-store/">
|
||||||
<script src="/resources/testharness.js"></script>
|
<script src="/resources/testharness.js"></script>
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
<script src="resources/testharness-helpers.js"></script>
|
<script src="resources/cookie-test-helpers.js"></script>
|
||||||
<script src="resources/cookie-store-tests.js"></script>
|
<script src="resources/expiration.js"></script>
|
||||||
<script>
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
suite({testName: 'testExpiration'});
|
|
||||||
</script>
|
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="timeout" content="long">
|
|
||||||
<title>Async Cookies: expiration (Static)</title>
|
|
||||||
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
|
|
||||||
<script src="/resources/testharness.js"></script>
|
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
|
||||||
<script src="resources/testharness-helpers.js"></script>
|
|
||||||
<script src="resources/cookie-store-tests.js"></script>
|
|
||||||
<script>
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
suite({testName: 'testExpiration'});
|
|
||||||
</script>
|
|
|
@ -1,14 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="timeout" content="long">
|
|
||||||
<title>Async Cookies: expiration (Static; HTTPS)</title>
|
|
||||||
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
|
|
||||||
<script src="/resources/testharness.js"></script>
|
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
|
||||||
<script src="resources/testharness-helpers.js"></script>
|
|
||||||
<script src="resources/cookie-store-tests.js"></script>
|
|
||||||
<script>
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
suite({testName: 'testExpiration'});
|
|
||||||
</script>
|
|
|
@ -1,14 +1,8 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="timeout" content="long">
|
|
||||||
<title>Async Cookies: get, set, getAll</title>
|
<title>Async Cookies: get, set, getAll</title>
|
||||||
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
|
<meta name="help" href="https://github.com/WICG/cookie-store/">
|
||||||
<script src="/resources/testharness.js"></script>
|
<script src="/resources/testharness.js"></script>
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
<script src="resources/testharness-helpers.js"></script>
|
<script src="resources/cookie-test-helpers.js"></script>
|
||||||
<script src="resources/cookie-store-tests.js"></script>
|
<script src="resources/get_set_get_all.js"></script>
|
||||||
<script>
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
suite({testName: 'testGetSetGetAll'});
|
|
||||||
</script>
|
|
||||||
|
|
|
@ -1,14 +1,8 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="timeout" content="long">
|
|
||||||
<title>Async Cookies: get, set, getAll (HTTPS)</title>
|
<title>Async Cookies: get, set, getAll (HTTPS)</title>
|
||||||
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
|
<meta name="help" href="https://github.com/WICG/cookie-store/">
|
||||||
<script src="/resources/testharness.js"></script>
|
<script src="/resources/testharness.js"></script>
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
<script src="resources/testharness-helpers.js"></script>
|
<script src="resources/cookie-test-helpers.js"></script>
|
||||||
<script src="resources/cookie-store-tests.js"></script>
|
<script src="resources/get_set_get_all.js"></script>
|
||||||
<script>
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
suite({testName: 'testGetSetGetAll'});
|
|
||||||
</script>
|
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="timeout" content="long">
|
|
||||||
<title>Async Cookies: get, set, getAll (Static)</title>
|
|
||||||
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
|
|
||||||
<script src="/resources/testharness.js"></script>
|
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
|
||||||
<script src="resources/testharness-helpers.js"></script>
|
|
||||||
<script src="resources/cookie-store-tests.js"></script>
|
|
||||||
<script>
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
suite({testName: 'testGetSetGetAll'});
|
|
||||||
</script>
|
|
|
@ -1,14 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="timeout" content="long">
|
|
||||||
<title>Async Cookies: get, set, getAll (Static; HTTPS)</title>
|
|
||||||
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
|
|
||||||
<script src="/resources/testharness.js"></script>
|
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
|
||||||
<script src="resources/testharness-helpers.js"></script>
|
|
||||||
<script src="resources/cookie-store-tests.js"></script>
|
|
||||||
<script>
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
suite({testName: 'testGetSetGetAll'});
|
|
||||||
</script>
|
|
|
@ -1,14 +1,8 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="timeout" content="long">
|
|
||||||
<title>Async Cookies: HTTP Cookie and Set-Cookie headers</title>
|
<title>Async Cookies: HTTP Cookie and Set-Cookie headers</title>
|
||||||
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
|
<meta name="help" href="https://github.com/WICG/cookie-store/">
|
||||||
<script src="/resources/testharness.js"></script>
|
<script src="/resources/testharness.js"></script>
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
<script src="resources/testharness-helpers.js"></script>
|
<script src="resources/cookie-test-helpers.js"></script>
|
||||||
<script src="resources/cookie-store-tests.js"></script>
|
<script src="resources/http_cookie_and_set_cookie_headers.js"></script>
|
||||||
<script>
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
suite({testName: 'testHttpCookieAndSetCookieHeaders'});
|
|
||||||
</script>
|
|
||||||
|
|
|
@ -1,14 +1,8 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="timeout" content="long">
|
|
||||||
<title>Async Cookies: HTTP Cookie and Set-Cookie headers (HTTPS)</title>
|
<title>Async Cookies: HTTP Cookie and Set-Cookie headers (HTTPS)</title>
|
||||||
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
|
<meta name="help" href="https://github.com/WICG/cookie-store/">
|
||||||
<script src="/resources/testharness.js"></script>
|
<script src="/resources/testharness.js"></script>
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
<script src="resources/testharness-helpers.js"></script>
|
<script src="resources/cookie-test-helpers.js"></script>
|
||||||
<script src="resources/cookie-store-tests.js"></script>
|
<script src="resources/http_cookie_and_set_cookie_headers.js"></script>
|
||||||
<script>
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
suite({testName: 'testHttpCookieAndSetCookieHeaders'});
|
|
||||||
</script>
|
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="timeout" content="long">
|
|
||||||
<title>Async Cookies: <title>Async Cookies: document.cookie</title>lt;Meta Http-Equiv="Set-Cookie" ... <title>Async Cookies: document.cookie</title>gt;</title>
|
|
||||||
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
|
|
||||||
<script src="/resources/testharness.js"></script>
|
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
|
||||||
<script src="resources/testharness-helpers.js"></script>
|
|
||||||
<script src="resources/cookie-store-tests.js"></script>
|
|
||||||
<script>
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
suite({testName: 'testMetaHttpEquivSetCookie'});
|
|
||||||
</script>
|
|
|
@ -1,14 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="timeout" content="long">
|
|
||||||
<title>Async Cookies: <title>Async Cookies: document.cookie</title>lt;Meta Http-Equiv="Set-Cookie" ... <title>Async Cookies: document.cookie</title>gt; (HTTPS)</title>
|
|
||||||
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
|
|
||||||
<script src="/resources/testharness.js"></script>
|
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
|
||||||
<script src="resources/testharness-helpers.js"></script>
|
|
||||||
<script src="resources/cookie-store-tests.js"></script>
|
|
||||||
<script>
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
suite({testName: 'testMetaHttpEquivSetCookie'});
|
|
||||||
</script>
|
|
|
@ -1,14 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="timeout" content="long">
|
|
||||||
<title>Async Cookies: <title>Async Cookies: document.cookie</title>lt;Meta Http-Equiv="Set-Cookie" ... <title>Async Cookies: document.cookie</title>gt; (Static)</title>
|
|
||||||
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
|
|
||||||
<script src="/resources/testharness.js"></script>
|
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
|
||||||
<script src="resources/testharness-helpers.js"></script>
|
|
||||||
<script src="resources/cookie-store-tests.js"></script>
|
|
||||||
<script>
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
suite({testName: 'testMetaHttpEquivSetCookie'});
|
|
||||||
</script>
|
|
|
@ -1,14 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="timeout" content="long">
|
|
||||||
<title>Async Cookies: <title>Async Cookies: document.cookie</title>lt;Meta Http-Equiv="Set-Cookie" ... <title>Async Cookies: document.cookie</title>gt; (Static; HTTPS)</title>
|
|
||||||
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
|
|
||||||
<script src="/resources/testharness.js"></script>
|
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
|
||||||
<script src="resources/testharness-helpers.js"></script>
|
|
||||||
<script src="resources/cookie-store-tests.js"></script>
|
|
||||||
<script>
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
suite({testName: 'testMetaHttpEquivSetCookie'});
|
|
||||||
</script>
|
|
|
@ -1,14 +1,8 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="timeout" content="long">
|
|
||||||
<title>Async Cookies: Test No Name and No Value</title>
|
<title>Async Cookies: Test No Name and No Value</title>
|
||||||
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
|
<meta name="help" href="https://github.com/WICG/cookie-store/">
|
||||||
<script src="/resources/testharness.js"></script>
|
<script src="/resources/testharness.js"></script>
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
<script src="resources/testharness-helpers.js"></script>
|
<script src="resources/cookie-test-helpers.js"></script>
|
||||||
<script src="resources/cookie-store-tests.js"></script>
|
<script src="resources/no_name_and_no_value.js"></script>
|
||||||
<script>
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
suite({testName: 'testNoNameAndNoValue'});
|
|
||||||
</script>
|
|
||||||
|
|
|
@ -1,14 +1,8 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="timeout" content="long">
|
|
||||||
<title>Async Cookies: Test No Name and No Value (HTTPS)</title>
|
<title>Async Cookies: Test No Name and No Value (HTTPS)</title>
|
||||||
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
|
<meta name="help" href="https://github.com/WICG/cookie-store/">
|
||||||
<script src="/resources/testharness.js"></script>
|
<script src="/resources/testharness.js"></script>
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
<script src="resources/testharness-helpers.js"></script>
|
<script src="resources/cookie-test-helpers.js"></script>
|
||||||
<script src="resources/cookie-store-tests.js"></script>
|
<script src="resources/no_name_and_no_value.js"></script>
|
||||||
<script>
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
suite({testName: 'testNoNameAndNoValue'});
|
|
||||||
</script>
|
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="timeout" content="long">
|
|
||||||
<title>Async Cookies: Test No Name and No Value (Static)</title>
|
|
||||||
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
|
|
||||||
<script src="/resources/testharness.js"></script>
|
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
|
||||||
<script src="resources/testharness-helpers.js"></script>
|
|
||||||
<script src="resources/cookie-store-tests.js"></script>
|
|
||||||
<script>
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
suite({testName: 'testNoNameAndNoValue'});
|
|
||||||
</script>
|
|
|
@ -1,14 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="timeout" content="long">
|
|
||||||
<title>Async Cookies: Test No Name and No Value (Static; HTTPS)</title>
|
|
||||||
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
|
|
||||||
<script src="/resources/testharness.js"></script>
|
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
|
||||||
<script src="resources/testharness-helpers.js"></script>
|
|
||||||
<script src="resources/cookie-store-tests.js"></script>
|
|
||||||
<script>
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
suite({testName: 'testNoNameAndNoValue'});
|
|
||||||
</script>
|
|
|
@ -1,14 +1,8 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="timeout" content="long">
|
|
||||||
<title>Async Cookies: Test No Name, '=' in Value</title>
|
<title>Async Cookies: Test No Name, '=' in Value</title>
|
||||||
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
|
<meta name="help" href="https://github.com/WICG/cookie-store/">
|
||||||
<script src="/resources/testharness.js"></script>
|
<script src="/resources/testharness.js"></script>
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
<script src="resources/testharness-helpers.js"></script>
|
<script src="resources/cookie-test-helpers.js"></script>
|
||||||
<script src="resources/cookie-store-tests.js"></script>
|
<script src="resources/no_name_equals_in_value.js"></script>
|
||||||
<script>
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
suite({testName: 'testNoNameEqualsInValue'});
|
|
||||||
</script>
|
|
||||||
|
|
|
@ -1,14 +1,8 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="timeout" content="long">
|
|
||||||
<title>Async Cookies: Test No Name, '=' in Value (HTTPS)</title>
|
<title>Async Cookies: Test No Name, '=' in Value (HTTPS)</title>
|
||||||
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
|
<meta name="help" href="https://github.com/WICG/cookie-store/">
|
||||||
<script src="/resources/testharness.js"></script>
|
<script src="/resources/testharness.js"></script>
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
<script src="resources/testharness-helpers.js"></script>
|
<script src="resources/cookie-test-helpers.js"></script>
|
||||||
<script src="resources/cookie-store-tests.js"></script>
|
<script src="resources/no_name_equals_in_value.js"></script>
|
||||||
<script>
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
suite({testName: 'testNoNameEqualsInValue'});
|
|
||||||
</script>
|
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="timeout" content="long">
|
|
||||||
<title>Async Cookies: Test No Name, '=' in Value (Static)</title>
|
|
||||||
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
|
|
||||||
<script src="/resources/testharness.js"></script>
|
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
|
||||||
<script src="resources/testharness-helpers.js"></script>
|
|
||||||
<script src="resources/cookie-store-tests.js"></script>
|
|
||||||
<script>
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
suite({testName: 'testNoNameEqualsInValue'});
|
|
||||||
</script>
|
|
|
@ -1,14 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="timeout" content="long">
|
|
||||||
<title>Async Cookies: Test No Name, '=' in Value (Static; HTTPS)</title>
|
|
||||||
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
|
|
||||||
<script src="/resources/testharness.js"></script>
|
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
|
||||||
<script src="resources/testharness-helpers.js"></script>
|
|
||||||
<script src="resources/cookie-store-tests.js"></script>
|
|
||||||
<script>
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
suite({testName: 'testNoNameEqualsInValue'});
|
|
||||||
</script>
|
|
|
@ -1,14 +1,8 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="timeout" content="long">
|
|
||||||
<title>Async Cookies: Test No Name, Multiple Values</title>
|
<title>Async Cookies: Test No Name, Multiple Values</title>
|
||||||
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
|
<meta name="help" href="https://github.com/WICG/cookie-store/">
|
||||||
<script src="/resources/testharness.js"></script>
|
<script src="/resources/testharness.js"></script>
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
<script src="resources/testharness-helpers.js"></script>
|
<script src="resources/cookie-test-helpers.js"></script>
|
||||||
<script src="resources/cookie-store-tests.js"></script>
|
<script src="resources/no_name_multiple_values.js"></script>
|
||||||
<script>
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
suite({testName: 'testNoNameMultipleValues'});
|
|
||||||
</script>
|
|
||||||
|
|
|
@ -1,14 +1,8 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="timeout" content="long">
|
|
||||||
<title>Async Cookies: Test No Name, Multiple Values (HTTPS)</title>
|
<title>Async Cookies: Test No Name, Multiple Values (HTTPS)</title>
|
||||||
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
|
<meta name="help" href="https://github.com/WICG/cookie-store/">
|
||||||
<script src="/resources/testharness.js"></script>
|
<script src="/resources/testharness.js"></script>
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
<script src="resources/testharness-helpers.js"></script>
|
<script src="resources/cookie-test-helpers.js"></script>
|
||||||
<script src="resources/cookie-store-tests.js"></script>
|
<script src="resources/no_name_multiple_values.js"></script>
|
||||||
<script>
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
suite({testName: 'testNoNameMultipleValues'});
|
|
||||||
</script>
|
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="timeout" content="long">
|
|
||||||
<title>Async Cookies: Test No Name, Multiple Values (Static)</title>
|
|
||||||
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
|
|
||||||
<script src="/resources/testharness.js"></script>
|
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
|
||||||
<script src="resources/testharness-helpers.js"></script>
|
|
||||||
<script src="resources/cookie-store-tests.js"></script>
|
|
||||||
<script>
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
suite({testName: 'testNoNameMultipleValues'});
|
|
||||||
</script>
|
|
|
@ -1,14 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="timeout" content="long">
|
|
||||||
<title>Async Cookies: Test No Name, Multiple Values (Static; HTTPS)</title>
|
|
||||||
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
|
|
||||||
<script src="/resources/testharness.js"></script>
|
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
|
||||||
<script src="resources/testharness-helpers.js"></script>
|
|
||||||
<script src="resources/cookie-store-tests.js"></script>
|
|
||||||
<script>
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
suite({testName: 'testNoNameMultipleValues'});
|
|
||||||
</script>
|
|
|
@ -1,14 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="timeout" content="long">
|
|
||||||
<title>Async Cookies: Test Observation</title>
|
|
||||||
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
|
|
||||||
<script src="/resources/testharness.js"></script>
|
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
|
||||||
<script src="resources/testharness-helpers.js"></script>
|
|
||||||
<script src="resources/cookie-store-tests.js"></script>
|
|
||||||
<script>
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
suite({testName: 'testObservation'});
|
|
||||||
</script>
|
|
|
@ -1,14 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="timeout" content="long">
|
|
||||||
<title>Async Cookies: Test Observation (HTTPS)</title>
|
|
||||||
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
|
|
||||||
<script src="/resources/testharness.js"></script>
|
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
|
||||||
<script src="resources/testharness-helpers.js"></script>
|
|
||||||
<script src="resources/cookie-store-tests.js"></script>
|
|
||||||
<script>
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
suite({testName: 'testObservation'});
|
|
||||||
</script>
|
|
|
@ -1,14 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="timeout" content="long">
|
|
||||||
<title>Async Cookies: Test Observation (Static)</title>
|
|
||||||
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
|
|
||||||
<script src="/resources/testharness.js"></script>
|
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
|
||||||
<script src="resources/testharness-helpers.js"></script>
|
|
||||||
<script src="resources/cookie-store-tests.js"></script>
|
|
||||||
<script>
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
suite({testName: 'testObservation'});
|
|
||||||
</script>
|
|
|
@ -1,14 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="timeout" content="long">
|
|
||||||
<title>Async Cookies: Test Observation (Static; HTTPS)</title>
|
|
||||||
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
|
|
||||||
<script src="/resources/testharness.js"></script>
|
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
|
||||||
<script src="resources/testharness-helpers.js"></script>
|
|
||||||
<script src="resources/cookie-store-tests.js"></script>
|
|
||||||
<script>
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
suite({testName: 'testObservation'});
|
|
||||||
</script>
|
|
|
@ -1,14 +1,8 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="timeout" content="long">
|
|
||||||
<title>Async Cookies: One simple origin cookie</title>
|
<title>Async Cookies: One simple origin cookie</title>
|
||||||
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
|
<meta name="help" href="https://github.com/WICG/cookie-store/">
|
||||||
<script src="/resources/testharness.js"></script>
|
<script src="/resources/testharness.js"></script>
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
<script src="resources/testharness-helpers.js"></script>
|
<script src="resources/cookie-test-helpers.js"></script>
|
||||||
<script src="resources/cookie-store-tests.js"></script>
|
<script src="resources/one_simple_origin_cookie.js"></script>
|
||||||
<script>
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
suite({testName: 'testOneSimpleOriginCookie'});
|
|
||||||
</script>
|
|
||||||
|
|
|
@ -1,14 +1,8 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="timeout" content="long">
|
|
||||||
<title>Async Cookies: One simple origin cookie (HTTPS)</title>
|
<title>Async Cookies: One simple origin cookie (HTTPS)</title>
|
||||||
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
|
<meta name="help" href="https://github.com/WICG/cookie-store/">
|
||||||
<script src="/resources/testharness.js"></script>
|
<script src="/resources/testharness.js"></script>
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
<script src="resources/testharness-helpers.js"></script>
|
<script src="resources/cookie-test-helpers.js"></script>
|
||||||
<script src="resources/cookie-store-tests.js"></script>
|
<script src="resources/one_simple_origin_cookie.js"></script>
|
||||||
<script>
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
suite({testName: 'testOneSimpleOriginCookie'});
|
|
||||||
</script>
|
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="timeout" content="long">
|
|
||||||
<title>Async Cookies: One simple origin cookie (Static)</title>
|
|
||||||
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
|
|
||||||
<script src="/resources/testharness.js"></script>
|
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
|
||||||
<script src="resources/testharness-helpers.js"></script>
|
|
||||||
<script src="resources/cookie-store-tests.js"></script>
|
|
||||||
<script>
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
suite({testName: 'testOneSimpleOriginCookie'});
|
|
||||||
</script>
|
|
|
@ -1,14 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="timeout" content="long">
|
|
||||||
<title>Async Cookies: One simple origin cookie (Static; HTTPS)</title>
|
|
||||||
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
|
|
||||||
<script src="/resources/testharness.js"></script>
|
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
|
||||||
<script src="resources/testharness-helpers.js"></script>
|
|
||||||
<script src="resources/cookie-store-tests.js"></script>
|
|
||||||
<script>
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
suite({testName: 'testOneSimpleOriginCookie'});
|
|
||||||
</script>
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Async Cookies: ordering (HTTPS)</title>
|
||||||
|
<meta name="help" href="https://github.com/WICG/cookie-store/">
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script src="resources/cookie-test-helpers.js"></script>
|
||||||
|
<script src="resources/ordering.js"></script>
|
File diff suppressed because it is too large
Load diff
|
@ -1,71 +1,14 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
// Length of final setTimeout when observer callback has not fired.
|
// TODO(jsbell): Once ServiceWorker is supported, add arbitrary path coverage.
|
||||||
//
|
const kPath = location.pathname.replace(/[^/]+$/, '');
|
||||||
const kExtraObserverDelay = 0; // For builtin implementation
|
|
||||||
|
|
||||||
// NOTE: A polyfill was used for pre-implementation testing. To revive
|
|
||||||
// it uncomment these and comment out the preceding line:
|
|
||||||
//
|
|
||||||
// const kExtraObserverDelay = 200; // Polyfill when not running on battery
|
|
||||||
// // const kExtraObserverDelay = 5000; // ... when running on battery
|
|
||||||
// document.open();
|
|
||||||
// document.write(`
|
|
||||||
// <script>delete cookieStore</script>
|
|
||||||
// <script src="https://wicg.github.io/cookie-store/cookies.js">
|
|
||||||
// </script>
|
|
||||||
// `);
|
|
||||||
// document.close()
|
|
||||||
|
|
||||||
// See https://github.com/whatwg/html/pull/3011#issuecomment-331187136
|
|
||||||
// and https://www.chromestatus.com/feature/6170540112871424
|
|
||||||
const kMetaHttpEquivSetCookieIsGone = true;
|
|
||||||
|
|
||||||
// True when running in a document context as opposed to a worker context
|
// True when running in a document context as opposed to a worker context
|
||||||
const kHasDocument = typeof document !== 'undefined';
|
const kHasDocument = typeof document !== 'undefined';
|
||||||
|
|
||||||
// Override for named test inclusion. Set by suite().
|
|
||||||
let testOverride = undefined;
|
|
||||||
|
|
||||||
// Determines whether the named test should be included in this run of the
|
|
||||||
// suite. Only usable in a test runner context as this uses assert_equals.
|
|
||||||
//
|
|
||||||
// Parameters:
|
|
||||||
//
|
|
||||||
// - testName: (string) test name; must be an identifier starting with 'test'
|
|
||||||
// - opt_excludeFromAll: (optional; boolean) if true, explicit or implicit
|
|
||||||
// #...&test=all (which is the default) will not activate this test.
|
|
||||||
const includeTest = (testName, opt_excludeFromAll) => {
|
|
||||||
assert_equals(!!testName.match(/^test\w+/), true, 'includeTest: ' + testName);
|
|
||||||
assert_equals(typeof eval(testName), 'function', 'includeTest: ' + testName);
|
|
||||||
let testParams =
|
|
||||||
(location.hash || '#').substr(1).split('&').filter(
|
|
||||||
x => x.match(/^test=/)).map(x => decodeURIComponent(x));
|
|
||||||
if (!testParams.length) {
|
|
||||||
testParams = ['test=all'];
|
|
||||||
if (testOverride !== undefined) {
|
|
||||||
testParams = ['test=' + testOverride];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const filterSet =
|
|
||||||
testParams.map(x => x.split('=', 2)[1]).join(',').split(',').reduce(
|
|
||||||
(set, name) => Object.assign(set, {[name]: true}), {});
|
|
||||||
for (let name in filterSet) {
|
|
||||||
if (name === 'all' || !filterSet.hasOwnProperty(name)) continue;
|
|
||||||
assert_equals(!!name.match(/^test\w+/), true, '#test=' + testName);
|
|
||||||
assert_equals(typeof eval(name), 'function', '#test=' + testName);
|
|
||||||
}
|
|
||||||
return (filterSet.all && !opt_excludeFromAll) ||
|
|
||||||
filterSet.hasOwnProperty(testName) && filterSet[testName];
|
|
||||||
}
|
|
||||||
|
|
||||||
// True when running on unsecured 'http:' rather than secured 'https:'.
|
// True when running on unsecured 'http:' rather than secured 'https:'.
|
||||||
const kIsUnsecured = location.protocol !== 'https:';
|
const kIsUnsecured = location.protocol !== 'https:';
|
||||||
|
|
||||||
// True when no CGI/no active wptserve handlers should be used.
|
|
||||||
const kIsStatic = !!((location.hash || '#').match(/(^#|&)static=true(&|$)/) ||
|
|
||||||
location.pathname.match(/_static\./));
|
|
||||||
|
|
||||||
const kCookieHelperCgi = 'resources/cookie_helper.py';
|
const kCookieHelperCgi = 'resources/cookie_helper.py';
|
||||||
|
|
||||||
// Async wrapper for an async function or promise that is expected
|
// Async wrapper for an async function or promise that is expected
|
||||||
|
@ -79,13 +22,13 @@ const kCookieHelperCgi = 'resources/cookie_helper.py';
|
||||||
// - promise: (thenable) test code
|
// - promise: (thenable) test code
|
||||||
// - message: (optional; string) message to forward to promise_rejects in
|
// - message: (optional; string) message to forward to promise_rejects in
|
||||||
// unsecured context
|
// unsecured context
|
||||||
const promise_rejects_when_unsecured = async (
|
async function promise_rejects_when_unsecured(
|
||||||
testCase,
|
testCase,
|
||||||
code,
|
code,
|
||||||
promise,
|
promise,
|
||||||
message = 'Feature unavailable from unsecured contexts'
|
message = 'Feature unavailable from unsecured contexts') {
|
||||||
) => {
|
if (kIsUnsecured)
|
||||||
if (kIsUnsecured) await promise_rejects(testCase, code, promise, message);
|
await promise_rejects(testCase, code, promise, message);
|
||||||
else await promise;
|
else await promise;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -97,9 +40,11 @@ const promise_rejects_when_unsecured = async (
|
||||||
//
|
//
|
||||||
// Returns a string serializing the records, or undefined if no records were
|
// Returns a string serializing the records, or undefined if no records were
|
||||||
// given.
|
// given.
|
||||||
const cookieString = cookies => cookies.length ? cookies.map((
|
function cookieString(cookies) {
|
||||||
|
return cookies.length ? cookies.map((
|
||||||
{name, value}) => (name ? (name + '=') : '') + value).join('; ') :
|
{name, value}) => (name ? (name + '=') : '') + value).join('; ') :
|
||||||
undefined;
|
undefined;
|
||||||
|
}
|
||||||
|
|
||||||
// Approximate async equivalent to the document.cookie getter but with
|
// Approximate async equivalent to the document.cookie getter but with
|
||||||
// important differences: optional additional getAll arguments are
|
// important differences: optional additional getAll arguments are
|
||||||
|
@ -110,7 +55,7 @@ const cookieString = cookies => cookies.length ? cookies.map((
|
||||||
// assert_equals in failing cases than assert_object_equals would
|
// assert_equals in failing cases than assert_object_equals would
|
||||||
// using parsed cookie jar contents and also allows expectations to be
|
// using parsed cookie jar contents and also allows expectations to be
|
||||||
// written more compactly.
|
// written more compactly.
|
||||||
const getCookieString = async (...args) => {
|
async function getCookieString(...args) {
|
||||||
return cookieString(await cookieStore.getAll(...args));
|
return cookieString(await cookieStore.getAll(...args));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,8 +65,7 @@ const getCookieString = async (...args) => {
|
||||||
//
|
//
|
||||||
// Unlike document.cookie, this returns undefined when no cookies are
|
// Unlike document.cookie, this returns undefined when no cookies are
|
||||||
// present.
|
// present.
|
||||||
const getCookieStringHttp = async (extraPath = null) => {
|
async function getCookieStringHttp(extraPath = null) {
|
||||||
if (kIsStatic) throw 'CGI not available in static HTML test';
|
|
||||||
const url =
|
const url =
|
||||||
kCookieHelperCgi + ((extraPath == null) ? '' : ('/' + extraPath));
|
kCookieHelperCgi + ((extraPath == null) ? '' : ('/' + extraPath));
|
||||||
const response = await fetch(url, { credentials: 'include' });
|
const response = await fetch(url, { credentials: 'include' });
|
||||||
|
@ -134,7 +78,8 @@ const getCookieStringHttp = async (extraPath = null) => {
|
||||||
response.headers.get('content-type'),
|
response.headers.get('content-type'),
|
||||||
'text/plain; charset=utf-8',
|
'text/plain; charset=utf-8',
|
||||||
'CGI did not return UTF-8 text in getCookieStringHttp');
|
'CGI did not return UTF-8 text in getCookieStringHttp');
|
||||||
if (text === '') return undefined;
|
if (text === '')
|
||||||
|
return undefined;
|
||||||
assert_equals(
|
assert_equals(
|
||||||
text.indexOf('cookie='),
|
text.indexOf('cookie='),
|
||||||
0,
|
0,
|
||||||
|
@ -148,8 +93,7 @@ const getCookieStringHttp = async (extraPath = null) => {
|
||||||
//
|
//
|
||||||
// Unlike document.cookie, this returns undefined when no cookies are
|
// Unlike document.cookie, this returns undefined when no cookies are
|
||||||
// present.
|
// present.
|
||||||
const getCookieBinaryHttp = async (extraPath = null) => {
|
async function getCookieBinaryHttp(extraPath = null) {
|
||||||
if (kIsStatic) throw 'CGI not available in static HTML test';
|
|
||||||
const url =
|
const url =
|
||||||
kCookieHelperCgi +
|
kCookieHelperCgi +
|
||||||
((extraPath == null) ?
|
((extraPath == null) ?
|
||||||
|
@ -165,7 +109,8 @@ const getCookieBinaryHttp = async (extraPath = null) => {
|
||||||
response.headers.get('content-type'),
|
response.headers.get('content-type'),
|
||||||
'text/plain; charset=iso-8859-1',
|
'text/plain; charset=iso-8859-1',
|
||||||
'CGI did not return ISO 8859-1 text in getCookieBinaryHttp');
|
'CGI did not return ISO 8859-1 text in getCookieBinaryHttp');
|
||||||
if (text === '') return undefined;
|
if (text === '')
|
||||||
|
return undefined;
|
||||||
assert_equals(
|
assert_equals(
|
||||||
text.indexOf('cookie='),
|
text.indexOf('cookie='),
|
||||||
0,
|
0,
|
||||||
|
@ -175,8 +120,7 @@ const getCookieBinaryHttp = async (extraPath = null) => {
|
||||||
|
|
||||||
// Approximate async equivalent to the document.cookie setter but from
|
// Approximate async equivalent to the document.cookie setter but from
|
||||||
// the server's point of view.
|
// the server's point of view.
|
||||||
const setCookieStringHttp = async setCookie => {
|
async function setCookieStringHttp(setCookie) {
|
||||||
if (kIsStatic) throw 'CGI not available in static HTML test';
|
|
||||||
const encodedSetCookie = encodeURIComponent(setCookie);
|
const encodedSetCookie = encodeURIComponent(setCookie);
|
||||||
const url = kCookieHelperCgi;
|
const url = kCookieHelperCgi;
|
||||||
const headers = new Headers();
|
const headers = new Headers();
|
||||||
|
@ -205,13 +149,12 @@ const setCookieStringHttp = async setCookie => {
|
||||||
text,
|
text,
|
||||||
'set-cookie=' + encodedSetCookie,
|
'set-cookie=' + encodedSetCookie,
|
||||||
'CGI did not faithfully echo the set-cookie value');
|
'CGI did not faithfully echo the set-cookie value');
|
||||||
};
|
}
|
||||||
|
|
||||||
// Approximate async equivalent to the document.cookie setter but from
|
// Approximate async equivalent to the document.cookie setter but from
|
||||||
// the server's point of view. This version sets a binary cookie rather
|
// the server's point of view. This version sets a binary cookie rather
|
||||||
// than a UTF-8 one.
|
// than a UTF-8 one.
|
||||||
const setCookieBinaryHttp = async setCookie => {
|
async function setCookieBinaryHttp(setCookie) {
|
||||||
if (kIsStatic) throw 'CGI not available in static HTML test';
|
|
||||||
const encodedSetCookie = escape(setCookie).split('/').join('%2F');
|
const encodedSetCookie = escape(setCookie).split('/').join('%2F');
|
||||||
const url = kCookieHelperCgi + '?charset=iso-8859-1';
|
const url = kCookieHelperCgi + '?charset=iso-8859-1';
|
||||||
const headers = new Headers();
|
const headers = new Headers();
|
||||||
|
@ -238,49 +181,90 @@ const setCookieBinaryHttp = async setCookie => {
|
||||||
text,
|
text,
|
||||||
'set-cookie=' + encodedSetCookie,
|
'set-cookie=' + encodedSetCookie,
|
||||||
'CGI did not faithfully echo the set-cookie value');
|
'CGI did not faithfully echo the set-cookie value');
|
||||||
};
|
}
|
||||||
|
|
||||||
// Approximate async equivalent to the document.cookie setter but using
|
|
||||||
// <meta http-equiv="set-cookie" content="..."> written into a temporary
|
|
||||||
// IFRAME. Merely appending the node to HEAD works in some browsers (e.g.
|
|
||||||
// Chromium) but not others (e.g. Firefox.)
|
|
||||||
const setCookieStringMeta = async setCookie => {
|
|
||||||
if (document.readyState !== 'complete') {
|
|
||||||
await new Promise(resolve => addEventListener('load', resolve, true));
|
|
||||||
}
|
|
||||||
const meta = Object.assign(document.createElement('meta'), {
|
|
||||||
httpEquiv: 'set-cookie',
|
|
||||||
content: setCookie
|
|
||||||
});
|
|
||||||
const ifr = document.createElement('iframe');
|
|
||||||
await new Promise(resolve => document.body.appendChild(Object.assign(
|
|
||||||
ifr,
|
|
||||||
{
|
|
||||||
onload: resolve
|
|
||||||
})));
|
|
||||||
try {
|
|
||||||
ifr.contentWindow.document.open('text/html; charset=utf-8');
|
|
||||||
ifr.contentWindow.document.write([
|
|
||||||
'<!DOCTYPE html>',
|
|
||||||
'<meta charset="utf-8">',
|
|
||||||
meta.outerHTML
|
|
||||||
].join('\r\n'));
|
|
||||||
ifr.contentWindow.document.close();
|
|
||||||
} finally {
|
|
||||||
if (ifr.parentNode) ifr.parentNode.removeChild(ifr);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Async document.cookie getter; converts '' to undefined which loses
|
// Async document.cookie getter; converts '' to undefined which loses
|
||||||
// information in the edge case where a single ''-valued anonymous
|
// information in the edge case where a single ''-valued anonymous
|
||||||
// cookie is visible.
|
// cookie is visible.
|
||||||
const getCookieStringDocument = async () => {
|
async function getCookieStringDocument() {
|
||||||
if (!kHasDocument) throw 'document.cookie not available in this context';
|
if (!kHasDocument)
|
||||||
|
throw 'document.cookie not available in this context';
|
||||||
return String(document.cookie || '') || undefined;
|
return String(document.cookie || '') || undefined;
|
||||||
};
|
}
|
||||||
|
|
||||||
// Async document.cookie setter
|
// Async document.cookie setter
|
||||||
const setCookieStringDocument = async setCookie => {
|
async function setCookieStringDocument(setCookie) {
|
||||||
if (!kHasDocument) throw 'document.cookie not available in this context';
|
if (!kHasDocument)
|
||||||
|
throw 'document.cookie not available in this context';
|
||||||
document.cookie = setCookie;
|
document.cookie = setCookie;
|
||||||
};
|
}
|
||||||
|
|
||||||
|
// Observe the next 'change' event on the cookieStore. Typical usage:
|
||||||
|
//
|
||||||
|
// const eventPromise = observeNextCookieChangeEvent();
|
||||||
|
// await /* something that modifies cookies */
|
||||||
|
// await verifyCookieChangeEvent(
|
||||||
|
// eventPromise, {changed: [{name: 'name', value: 'value'}]});
|
||||||
|
//
|
||||||
|
function observeNextCookieChangeEvent() {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
cookieStore.addEventListener('change', e => resolve(e), {once: true});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function verifyCookieChangeEvent(eventPromise, expected, description) {
|
||||||
|
description = description ? description + ': ' : '';
|
||||||
|
expected = Object.assign({changed:[], deleted:[]}, expected);
|
||||||
|
const event = await eventPromise;
|
||||||
|
assert_equals(event.changed.length, expected.changed.length,
|
||||||
|
description + 'number of changed cookies');
|
||||||
|
for (let i = 0; i < event.changed.length; ++i) {
|
||||||
|
assert_equals(event.changed[i].name, expected.changed[i].name,
|
||||||
|
description + 'changed cookie name');
|
||||||
|
assert_equals(event.changed[i].value, expected.changed[i].value,
|
||||||
|
description + 'changed cookie value');
|
||||||
|
}
|
||||||
|
assert_equals(event.deleted.length, expected.deleted.length,
|
||||||
|
description + 'number of deleted cookies');
|
||||||
|
for (let i = 0; i < event.deleted.length; ++i) {
|
||||||
|
assert_equals(event.deleted[i].name, expected.deleted[i].name,
|
||||||
|
description + 'deleted cookie name');
|
||||||
|
assert_equals(event.deleted[i].value, expected.deleted[i].value,
|
||||||
|
description + 'deleted cookie value');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function for promise_test with cookies; cookies
|
||||||
|
// named in these tests are cleared before/after the test
|
||||||
|
// body function is executed.
|
||||||
|
async function cookie_test(func, description) {
|
||||||
|
|
||||||
|
// Wipe cookies used by tests before and after the test.
|
||||||
|
async function deleteTestCookies() {
|
||||||
|
await cookieStore.delete('');
|
||||||
|
await cookieStore.delete('TEST');
|
||||||
|
await cookieStore.delete('META-🍪');
|
||||||
|
await cookieStore.delete('DOCUMENT-🍪');
|
||||||
|
await cookieStore.delete('HTTP-🍪');
|
||||||
|
await setCookieStringHttp(
|
||||||
|
'HTTPONLY-🍪=DELETED; path=/; max-age=0; httponly');
|
||||||
|
if (!kIsUnsecured) {
|
||||||
|
await cookieStore.delete('__Host-COOKIENAME');
|
||||||
|
await cookieStore.delete('__Host-1🍪');
|
||||||
|
await cookieStore.delete('__Host-2🌟');
|
||||||
|
await cookieStore.delete('__Host-3🌱');
|
||||||
|
await cookieStore.delete('__Host-unordered1🍪');
|
||||||
|
await cookieStore.delete('__Host-unordered2🌟');
|
||||||
|
await cookieStore.delete('__Host-unordered3🌱');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return promise_test(async t => {
|
||||||
|
await deleteTestCookies();
|
||||||
|
try {
|
||||||
|
return await func(t);
|
||||||
|
} finally {
|
||||||
|
await deleteTestCookies();
|
||||||
|
}
|
||||||
|
}, description);
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
cookie_test(async testCase => {
|
||||||
|
// TODO: This test doesn't create cookies and doesn't assert
|
||||||
|
// the behavior of delete(). Improve or remove it.
|
||||||
|
|
||||||
|
await cookieStore.delete('');
|
||||||
|
await cookieStore.delete('TEST');
|
||||||
|
await cookieStore.delete('META-🍪');
|
||||||
|
await cookieStore.delete('DOCUMENT-🍪');
|
||||||
|
await cookieStore.delete('HTTP-🍪');
|
||||||
|
|
||||||
|
await setCookieStringHttp(
|
||||||
|
'HTTPONLY-🍪=DELETED; path=/; max-age=0; httponly');
|
||||||
|
|
||||||
|
await promise_rejects_when_unsecured(
|
||||||
|
testCase,
|
||||||
|
new TypeError(),
|
||||||
|
cookieStore.delete('__Host-COOKIENAME'));
|
||||||
|
await promise_rejects_when_unsecured(
|
||||||
|
testCase,
|
||||||
|
new TypeError(),
|
||||||
|
cookieStore.delete('__Host-1🍪'));
|
||||||
|
await promise_rejects_when_unsecured(
|
||||||
|
testCase,
|
||||||
|
new TypeError(),
|
||||||
|
cookieStore.delete('__Host-2🌟'));
|
||||||
|
await promise_rejects_when_unsecured(
|
||||||
|
testCase,
|
||||||
|
new TypeError(),
|
||||||
|
cookieStore.delete('__Host-3🌱'));
|
||||||
|
await promise_rejects_when_unsecured(
|
||||||
|
testCase,
|
||||||
|
new TypeError(),
|
||||||
|
cookieStore.delete('__Host-unordered1🍪'));
|
||||||
|
await promise_rejects_when_unsecured(
|
||||||
|
testCase,
|
||||||
|
new TypeError(),
|
||||||
|
cookieStore.delete('__Host-unordered2🌟'));
|
||||||
|
await promise_rejects_when_unsecured(
|
||||||
|
testCase,
|
||||||
|
new TypeError(),
|
||||||
|
cookieStore.delete('__Host-unordered3🌱'));
|
||||||
|
}, 'Test cookieStore.delete');
|
|
@ -0,0 +1,43 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
cookie_test(async t => {
|
||||||
|
let eventPromise = observeNextCookieChangeEvent();
|
||||||
|
await setCookieStringDocument('DOCUMENT-🍪=🔵; path=/');
|
||||||
|
assert_equals(
|
||||||
|
await getCookieString(),
|
||||||
|
'DOCUMENT-🍪=🔵',
|
||||||
|
'Cookie we wrote using document.cookie in cookie jar');
|
||||||
|
assert_equals(
|
||||||
|
await getCookieStringHttp(),
|
||||||
|
'DOCUMENT-🍪=🔵',
|
||||||
|
'Cookie we wrote using document.cookie in HTTP cookie jar');
|
||||||
|
assert_equals(
|
||||||
|
await getCookieStringDocument(),
|
||||||
|
'DOCUMENT-🍪=🔵',
|
||||||
|
'Cookie we wrote using document.cookie in document.cookie');
|
||||||
|
await verifyCookieChangeEvent(
|
||||||
|
eventPromise, {changed: [{name: 'DOCUMENT-🍪', value: '🔵'}]},
|
||||||
|
'Cookie we wrote using document.cookie is observed');
|
||||||
|
|
||||||
|
eventPromise = observeNextCookieChangeEvent();
|
||||||
|
await setCookieStringDocument('DOCUMENT-🍪=DELETED; path=/; max-age=0');
|
||||||
|
assert_equals(
|
||||||
|
await getCookieString(),
|
||||||
|
undefined,
|
||||||
|
'Empty cookie jar after document.cookie' +
|
||||||
|
' cookie-clearing using max-age=0');
|
||||||
|
assert_equals(
|
||||||
|
await getCookieStringHttp(),
|
||||||
|
undefined,
|
||||||
|
'Empty HTTP cookie jar after document.cookie' +
|
||||||
|
' cookie-clearing using max-age=0');
|
||||||
|
assert_equals(
|
||||||
|
await getCookieStringDocument(),
|
||||||
|
undefined,
|
||||||
|
'Empty document.cookie cookie jar after document.cookie' +
|
||||||
|
' cookie-clearing using max-age=0');
|
||||||
|
await verifyCookieChangeEvent(
|
||||||
|
eventPromise, {deleted: [{name: 'DOCUMENT-🍪'}]},
|
||||||
|
'Deletion observed after document.cookie cookie-clearing' +
|
||||||
|
' using max-age=0');
|
||||||
|
}, 'Verify interoperability of document.cookie with other APIs.');
|
|
@ -0,0 +1,89 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
// Set the secure example.org-domain cookie __Secure-COOKIENAME with
|
||||||
|
// value cookie-value on path /cgi-bin/ and 24 hour duration; domain
|
||||||
|
// and path will be rewritten below.
|
||||||
|
//
|
||||||
|
// This uses a Date object for expiration.
|
||||||
|
async function setOneDaySecureCookieWithDate() {
|
||||||
|
// one day ahead, ignoring a possible leap-second
|
||||||
|
let inTwentyFourHours = new Date(Date.now() + 24 * 60 * 60 * 1000);
|
||||||
|
await cookieStore.set('__Secure-COOKIENAME', 'cookie-value', {
|
||||||
|
path: kPath,
|
||||||
|
expires: inTwentyFourHours,
|
||||||
|
secure: true,
|
||||||
|
domain: location.hostname
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the secured example.org-domain cookie __Secure-COOKIENAME with
|
||||||
|
// value cookie-value on path /cgi-bin/ and expiration in June of next
|
||||||
|
// year; domain and path will be rewritten below.
|
||||||
|
//
|
||||||
|
// This uses an HTTP-style date string for expiration.
|
||||||
|
async function setSecureCookieWithHttpLikeExpirationString() {
|
||||||
|
const year = (new Date()).getUTCFullYear() + 1;
|
||||||
|
const date = new Date('07 Jun ' + year + ' 07:07:07 UTC');
|
||||||
|
const day = ('Sun Mon Tue Wed Thu Fri Sat'.split(' '))[date.getUTCDay()];
|
||||||
|
await cookieStore.set('__Secure-COOKIENAME', 'cookie-value', {
|
||||||
|
path: kPath,
|
||||||
|
expires: day + ', 07 Jun ' + year + ' 07:07:07 GMT',
|
||||||
|
secure: true,
|
||||||
|
domain: location.hostname
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the unsecured example.org-domain cookie LEGACYCOOKIENAME with
|
||||||
|
// value cookie-value on path /cgi-bin/ and 24 hour duration; domain
|
||||||
|
// and path will be rewritten below.
|
||||||
|
//
|
||||||
|
// This uses milliseconds since the start of the Unix epoch for
|
||||||
|
// expiration.
|
||||||
|
async function setOneDayUnsecuredCookieWithMillisecondsSinceEpoch() {
|
||||||
|
// one day ahead, ignoring a possible leap-second
|
||||||
|
let inTwentyFourHours = Date.now() + 24 * 60 * 60 * 1000;
|
||||||
|
await cookieStore.set('LEGACYCOOKIENAME', 'cookie-value', {
|
||||||
|
path: kPath,
|
||||||
|
expires: inTwentyFourHours,
|
||||||
|
secure: false,
|
||||||
|
domain: location.hostname
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete the cookie written by
|
||||||
|
// setOneDayUnsecuredCookieWithMillisecondsSinceEpoch.
|
||||||
|
async function deleteUnsecuredCookieWithDomainAndPath() {
|
||||||
|
await cookieStore.delete('LEGACYCOOKIENAME', {
|
||||||
|
path: kPath,
|
||||||
|
secure: false,
|
||||||
|
domain: location.hostname
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
cookie_test(async testCase => {
|
||||||
|
await promise_rejects_when_unsecured(
|
||||||
|
testCase,
|
||||||
|
new TypeError(),
|
||||||
|
setOneDaySecureCookieWithDate(),
|
||||||
|
'Secure cookies only writable from secure contexts');
|
||||||
|
|
||||||
|
const eventPromise = observeNextCookieChangeEvent();
|
||||||
|
|
||||||
|
await setOneDayUnsecuredCookieWithMillisecondsSinceEpoch();
|
||||||
|
assert_equals(
|
||||||
|
await getCookieString('LEGACYCOOKIENAME'),
|
||||||
|
'LEGACYCOOKIENAME=cookie-value',
|
||||||
|
'Ensure unsecured cookie we set is visible');
|
||||||
|
|
||||||
|
await verifyCookieChangeEvent(
|
||||||
|
eventPromise,
|
||||||
|
{changed: [{name: 'LEGACYCOOKIENAME', value: 'cookie-value'}]},
|
||||||
|
'Ensure unsecured cookie we set is visible to observer');
|
||||||
|
|
||||||
|
await deleteUnsecuredCookieWithDomainAndPath();
|
||||||
|
await promise_rejects_when_unsecured(
|
||||||
|
testCase,
|
||||||
|
new TypeError(),
|
||||||
|
setSecureCookieWithHttpLikeExpirationString(),
|
||||||
|
'Secure cookies only writable from secure contexts');
|
||||||
|
}, 'expiration');
|
|
@ -0,0 +1,74 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
cookie_test(async t => {
|
||||||
|
let eventPromise = observeNextCookieChangeEvent();
|
||||||
|
await cookieStore.set('TEST', 'value0');
|
||||||
|
assert_equals(
|
||||||
|
await getCookieString(),
|
||||||
|
'TEST=value0',
|
||||||
|
'Cookie jar contains only cookie we set');
|
||||||
|
assert_equals(
|
||||||
|
await getCookieStringHttp(),
|
||||||
|
'TEST=value0',
|
||||||
|
'HTTP cookie jar contains only cookie we set');
|
||||||
|
await verifyCookieChangeEvent(
|
||||||
|
eventPromise,
|
||||||
|
{changed: [{name: 'TEST', value: 'value0'}]},
|
||||||
|
'Observed value that was set');
|
||||||
|
|
||||||
|
eventPromise = observeNextCookieChangeEvent();
|
||||||
|
await cookieStore.set('TEST', 'value');
|
||||||
|
assert_equals(
|
||||||
|
await getCookieString(),
|
||||||
|
'TEST=value',
|
||||||
|
'Cookie jar contains only cookie we overwrote');
|
||||||
|
await verifyCookieChangeEvent(
|
||||||
|
eventPromise,
|
||||||
|
{changed: [{name: 'TEST', value: 'value'}]},
|
||||||
|
'Observed value that was overwritten');
|
||||||
|
|
||||||
|
let allCookies = await cookieStore.getAll();
|
||||||
|
assert_equals(
|
||||||
|
allCookies[0].name,
|
||||||
|
'TEST',
|
||||||
|
'First entry in allCookies should be named TEST');
|
||||||
|
assert_equals(
|
||||||
|
allCookies[0].value,
|
||||||
|
'value',
|
||||||
|
'First entry in allCookies should have value "value"');
|
||||||
|
assert_equals(
|
||||||
|
allCookies.length,
|
||||||
|
1,
|
||||||
|
'Only one cookie should exist in allCookies');
|
||||||
|
let firstCookie = await cookieStore.get();
|
||||||
|
assert_equals(
|
||||||
|
firstCookie.name,
|
||||||
|
'TEST',
|
||||||
|
'First cookie should be named TEST');
|
||||||
|
assert_equals(
|
||||||
|
firstCookie.value,
|
||||||
|
'value',
|
||||||
|
'First cookie should have value "value"');
|
||||||
|
let allCookies_TEST = await cookieStore.getAll('TEST');
|
||||||
|
assert_equals(
|
||||||
|
allCookies_TEST[0].name,
|
||||||
|
'TEST',
|
||||||
|
'First entry in allCookies_TEST should be named TEST');
|
||||||
|
assert_equals(
|
||||||
|
allCookies_TEST[0].value,
|
||||||
|
'value',
|
||||||
|
'First entry in allCookies_TEST should have value "value"');
|
||||||
|
assert_equals(
|
||||||
|
allCookies_TEST.length,
|
||||||
|
1,
|
||||||
|
'Only one cookie should exist in allCookies_TEST');
|
||||||
|
let firstCookie_TEST = await cookieStore.get('TEST');
|
||||||
|
assert_equals(
|
||||||
|
firstCookie_TEST.name,
|
||||||
|
'TEST',
|
||||||
|
'First TEST cookie should be named TEST');
|
||||||
|
assert_equals(
|
||||||
|
firstCookie_TEST.value,
|
||||||
|
'value',
|
||||||
|
'First TEST cookie should have value "value"');
|
||||||
|
}, 'Get/set/get all cookies in store');
|
|
@ -0,0 +1,112 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
cookie_test(async t => {
|
||||||
|
let eventPromise = observeNextCookieChangeEvent();
|
||||||
|
await setCookieStringHttp('HTTP-🍪=🔵; path=/');
|
||||||
|
assert_equals(
|
||||||
|
await getCookieString(),
|
||||||
|
'HTTP-🍪=🔵',
|
||||||
|
'Cookie we wrote using HTTP in cookie jar');
|
||||||
|
assert_equals(
|
||||||
|
await getCookieStringHttp(),
|
||||||
|
'HTTP-🍪=🔵',
|
||||||
|
'Cookie we wrote using HTTP in HTTP cookie jar');
|
||||||
|
await verifyCookieChangeEvent(
|
||||||
|
eventPromise, {changed: [{name: 'HTTP-🍪', value: '🔵'}]},
|
||||||
|
'Cookie we wrote using HTTP is observed');
|
||||||
|
|
||||||
|
eventPromise = observeNextCookieChangeEvent();
|
||||||
|
await setCookieStringHttp('HTTP-🍪=DELETED; path=/; max-age=0');
|
||||||
|
assert_equals(
|
||||||
|
await getCookieString(),
|
||||||
|
undefined,
|
||||||
|
'Empty cookie jar after HTTP cookie-clearing using max-age=0');
|
||||||
|
assert_equals(
|
||||||
|
await getCookieStringHttp(),
|
||||||
|
undefined,
|
||||||
|
'Empty HTTP cookie jar after HTTP cookie-clearing using max-age=0');
|
||||||
|
await verifyCookieChangeEvent(
|
||||||
|
eventPromise, {deleted: [{name: 'HTTP-🍪'}]},
|
||||||
|
'Deletion observed after HTTP cookie-clearing using max-age=0');
|
||||||
|
await cookieStore.delete('HTTP-🍪');
|
||||||
|
}, 'Interoperability of HTTP Set-Cookie: with other APIs');
|
||||||
|
|
||||||
|
cookie_test(async t => {
|
||||||
|
let eventPromise = observeNextCookieChangeEvent();
|
||||||
|
await setCookieStringHttp('HTTPONLY-🍪=🔵; path=/; httponly');
|
||||||
|
assert_equals(
|
||||||
|
await getCookieString(),
|
||||||
|
undefined,
|
||||||
|
'HttpOnly cookie we wrote using HTTP in cookie jar' +
|
||||||
|
' is invisible to script');
|
||||||
|
assert_equals(
|
||||||
|
await getCookieStringHttp(),
|
||||||
|
'HTTPONLY-🍪=🔵',
|
||||||
|
'HttpOnly cookie we wrote using HTTP in HTTP cookie jar');
|
||||||
|
|
||||||
|
eventPromise = observeNextCookieChangeEvent();
|
||||||
|
await setCookieStringHttp(
|
||||||
|
'HTTPONLY-🍪=DELETED; path=/; max-age=0; httponly');
|
||||||
|
assert_equals(
|
||||||
|
await getCookieString(),
|
||||||
|
undefined,
|
||||||
|
'Empty cookie jar after HTTP cookie-clearing using max-age=0');
|
||||||
|
assert_equals(
|
||||||
|
await getCookieStringHttp(),
|
||||||
|
undefined,
|
||||||
|
'Empty HTTP cookie jar after HTTP cookie-clearing using max-age=0');
|
||||||
|
|
||||||
|
// HTTPONLY cookie changes should not have been observed; perform
|
||||||
|
// a dummy change to verify that nothing else was queued up.
|
||||||
|
await cookieStore.set('TEST', 'dummy');
|
||||||
|
await verifyCookieChangeEvent(
|
||||||
|
eventPromise, {changed: [{name: 'TEST', value: 'dummy'}]},
|
||||||
|
'HttpOnly cookie deletion was not observed');
|
||||||
|
}, 'HttpOnly cookies are not observed');
|
||||||
|
|
||||||
|
cookie_test(async t => {
|
||||||
|
// Non-UTF-8 byte sequences cause the Set-Cookie to be dropped.
|
||||||
|
let eventPromise = observeNextCookieChangeEvent();
|
||||||
|
await setCookieBinaryHttp(
|
||||||
|
unescape(encodeURIComponent('HTTP-🍪=🔵')) + '\xef\xbf\xbd; path=/');
|
||||||
|
assert_equals(
|
||||||
|
await getCookieString(),
|
||||||
|
'HTTP-🍪=🔵\ufffd',
|
||||||
|
'Binary cookie we wrote using HTTP in cookie jar');
|
||||||
|
assert_equals(
|
||||||
|
await getCookieStringHttp(),
|
||||||
|
'HTTP-🍪=🔵\ufffd',
|
||||||
|
'Binary cookie we wrote using HTTP in HTTP cookie jar');
|
||||||
|
assert_equals(
|
||||||
|
decodeURIComponent(escape(await getCookieBinaryHttp())),
|
||||||
|
'HTTP-🍪=🔵\ufffd',
|
||||||
|
'Binary cookie we wrote in binary HTTP cookie jar');
|
||||||
|
assert_equals(
|
||||||
|
await getCookieBinaryHttp(),
|
||||||
|
unescape(encodeURIComponent('HTTP-🍪=🔵')) + '\xef\xbf\xbd',
|
||||||
|
'Binary cookie we wrote in binary HTTP cookie jar');
|
||||||
|
await verifyCookieChangeEvent(
|
||||||
|
eventPromise, {changed: [{name: 'HTTP-🍪', value: '🔵\ufffd'}]},
|
||||||
|
'Binary cookie we wrote using HTTP is observed');
|
||||||
|
|
||||||
|
eventPromise = observeNextCookieChangeEvent();
|
||||||
|
await setCookieBinaryHttp(
|
||||||
|
unescape(encodeURIComponent('HTTP-🍪=DELETED; path=/; max-age=0')));
|
||||||
|
assert_equals(
|
||||||
|
await getCookieString(),
|
||||||
|
undefined,
|
||||||
|
'Empty cookie jar after binary HTTP cookie-clearing using max-age=0');
|
||||||
|
assert_equals(
|
||||||
|
await getCookieStringHttp(),
|
||||||
|
undefined,
|
||||||
|
'Empty HTTP cookie jar after' +
|
||||||
|
' binary HTTP cookie-clearing using max-age=0');
|
||||||
|
assert_equals(
|
||||||
|
await getCookieBinaryHttp(),
|
||||||
|
undefined,
|
||||||
|
'Empty binary HTTP cookie jar after' +
|
||||||
|
' binary HTTP cookie-clearing using max-age=0');
|
||||||
|
await verifyCookieChangeEvent(
|
||||||
|
eventPromise, {deleted: [{name: 'HTTP-🍪'}]},
|
||||||
|
'Deletion observed after binary HTTP cookie-clearing using max-age=0');
|
||||||
|
}, 'Binary HTTP cookies');
|
|
@ -0,0 +1,45 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
cookie_test(async t => {
|
||||||
|
let eventPromise = observeNextCookieChangeEvent();
|
||||||
|
await cookieStore.set('', 'first-value');
|
||||||
|
const actual1 =
|
||||||
|
(await cookieStore.getAll('')).map(({ value }) => value).join(';');
|
||||||
|
const expected1 = 'first-value';
|
||||||
|
assert_equals(actual1, expected1);
|
||||||
|
await verifyCookieChangeEvent(
|
||||||
|
eventPromise, {changed: [{name: '', value: 'first-value'}]},
|
||||||
|
'Observed no-name change');
|
||||||
|
|
||||||
|
eventPromise = observeNextCookieChangeEvent();
|
||||||
|
await cookieStore.set('', '');
|
||||||
|
const actual2 =
|
||||||
|
(await cookieStore.getAll('')).map(({ value }) => value).join(';');
|
||||||
|
const expected2 = '';
|
||||||
|
assert_equals(actual2, expected2);
|
||||||
|
await verifyCookieChangeEvent(
|
||||||
|
eventPromise, {changed: [{name: '', value: ''}]},
|
||||||
|
'Observed no-name change');
|
||||||
|
|
||||||
|
eventPromise = observeNextCookieChangeEvent();
|
||||||
|
await cookieStore.delete('');
|
||||||
|
await verifyCookieChangeEvent(
|
||||||
|
eventPromise, {deleted: [{name: ''}]},
|
||||||
|
'Observed no-name deletion');
|
||||||
|
|
||||||
|
assert_equals(
|
||||||
|
await getCookieString(),
|
||||||
|
undefined,
|
||||||
|
'Empty cookie jar');
|
||||||
|
assert_equals(
|
||||||
|
await getCookieStringHttp(),
|
||||||
|
undefined,
|
||||||
|
'Empty HTTP cookie jar');
|
||||||
|
if (kHasDocument) {
|
||||||
|
assert_equals(
|
||||||
|
await getCookieStringDocument(),
|
||||||
|
undefined,
|
||||||
|
'Empty document.cookie cookie jar');
|
||||||
|
}
|
||||||
|
|
||||||
|
}, 'Verify behavior of no-name and no-value cookies.');
|
|
@ -0,0 +1,46 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
cookie_test(async t => {
|
||||||
|
let eventPromise = observeNextCookieChangeEvent();
|
||||||
|
await cookieStore.set('', 'first-value');
|
||||||
|
const actual1 =
|
||||||
|
(await cookieStore.getAll('')).map(({ value }) => value).join(';');
|
||||||
|
const expected1 = 'first-value';
|
||||||
|
assert_equals(actual1, expected1);
|
||||||
|
await verifyCookieChangeEvent(
|
||||||
|
eventPromise, {changed: [{name: '', value: 'first-value'}]},
|
||||||
|
'Observed no-name change');
|
||||||
|
|
||||||
|
await promise_rejects(
|
||||||
|
t,
|
||||||
|
new TypeError(),
|
||||||
|
cookieStore.set('', 'suspicious-value=resembles-name-and-value'),
|
||||||
|
'Expected promise rejection when setting a cookie with' +
|
||||||
|
' no name and "=" in value');
|
||||||
|
|
||||||
|
const actual2 =
|
||||||
|
(await cookieStore.getAll('')).map(({ value }) => value).join(';');
|
||||||
|
const expected2 = 'first-value';
|
||||||
|
assert_equals(actual2, expected2);
|
||||||
|
assert_equals(
|
||||||
|
await getCookieString(),
|
||||||
|
'first-value',
|
||||||
|
'Earlier cookie jar after rejected');
|
||||||
|
|
||||||
|
eventPromise = observeNextCookieChangeEvent();
|
||||||
|
await cookieStore.delete('');
|
||||||
|
await verifyCookieChangeEvent(
|
||||||
|
eventPromise, {deleted: [{name: '', value: ''}]},
|
||||||
|
'Observed no-name deletion');
|
||||||
|
|
||||||
|
assert_equals(
|
||||||
|
await getCookieString(),
|
||||||
|
undefined,
|
||||||
|
'Empty cookie jar after cleanup');
|
||||||
|
assert_equals(
|
||||||
|
await getCookieStringHttp(),
|
||||||
|
undefined,
|
||||||
|
'Empty HTTP cookie jar after cleanup');
|
||||||
|
|
||||||
|
}, "Verify that attempting to set a cookie with no name and with '=' in" +
|
||||||
|
" the value does not work.");
|
|
@ -0,0 +1,38 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
cookie_test(async t => {
|
||||||
|
let eventPromise = observeNextCookieChangeEvent();
|
||||||
|
await cookieStore.set('', 'first-value');
|
||||||
|
let actual1 =
|
||||||
|
(await cookieStore.getAll('')).map(({ value }) => value).join(';');
|
||||||
|
let expected1 = 'first-value';
|
||||||
|
assert_equals(actual1, expected1);
|
||||||
|
await verifyCookieChangeEvent(
|
||||||
|
eventPromise, {changed: [{name: '', value: 'first-value'}]},
|
||||||
|
'Observed no-name change');
|
||||||
|
|
||||||
|
eventPromise = observeNextCookieChangeEvent();
|
||||||
|
await cookieStore.set('', 'second-value');
|
||||||
|
let actual2 =
|
||||||
|
(await cookieStore.getAll('')).map(({ value }) => value).join(';');
|
||||||
|
let expected2 = 'second-value';
|
||||||
|
assert_equals(actual2, expected2);
|
||||||
|
await verifyCookieChangeEvent(
|
||||||
|
eventPromise, {changed: [{name: '', value: 'second-value'}]},
|
||||||
|
'Observed no-name change');
|
||||||
|
|
||||||
|
eventPromise = observeNextCookieChangeEvent();
|
||||||
|
await cookieStore.delete('');
|
||||||
|
await verifyCookieChangeEvent(
|
||||||
|
eventPromise, {deleted: [{name: ''}]},
|
||||||
|
'Observed no-name change');
|
||||||
|
|
||||||
|
assert_equals(
|
||||||
|
await getCookieString(),
|
||||||
|
undefined,
|
||||||
|
'Empty cookie jar after testNoNameMultipleValues');
|
||||||
|
assert_equals(
|
||||||
|
await getCookieStringHttp(),
|
||||||
|
undefined,
|
||||||
|
'Empty HTTP cookie jar after testNoNameMultipleValues');
|
||||||
|
}, 'Verify behavior of multiple no-name cookies');
|
|
@ -0,0 +1,57 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
// Helper to verify first-of-name get using async/await.
|
||||||
|
//
|
||||||
|
// Returns the first script-visible value of the __Host-COOKIENAME cookie or
|
||||||
|
// undefined if no matching cookies are script-visible.
|
||||||
|
async function getOneSimpleOriginCookie() {
|
||||||
|
let cookie = await cookieStore.get('__Host-COOKIENAME');
|
||||||
|
if (!cookie) return undefined;
|
||||||
|
return cookie.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the number of script-visible cookies whose names start with
|
||||||
|
// __Host-COOKIEN
|
||||||
|
async function countMatchingSimpleOriginCookies() {
|
||||||
|
let cookieList = await cookieStore.getAll({
|
||||||
|
name: '__Host-COOKIEN',
|
||||||
|
matchType: 'startsWith'
|
||||||
|
});
|
||||||
|
return cookieList.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the secure implicit-domain cookie __Host-COOKIENAME with value
|
||||||
|
// cookie-value on path / and session duration.
|
||||||
|
async function setOneSimpleOriginSessionCookie() {
|
||||||
|
await cookieStore.set('__Host-COOKIENAME', 'cookie-value');
|
||||||
|
};
|
||||||
|
|
||||||
|
cookie_test(async testCase => {
|
||||||
|
await promise_rejects_when_unsecured(
|
||||||
|
testCase,
|
||||||
|
new TypeError(),
|
||||||
|
setOneSimpleOriginSessionCookie(),
|
||||||
|
'__Host- prefix only writable from secure contexts');
|
||||||
|
if (!kIsUnsecured) {
|
||||||
|
assert_equals(
|
||||||
|
await getOneSimpleOriginCookie(),
|
||||||
|
'cookie-value',
|
||||||
|
'__Host-COOKIENAME cookie should be found in a secure context');
|
||||||
|
} else {
|
||||||
|
assert_equals(
|
||||||
|
await getOneSimpleOriginCookie(),
|
||||||
|
undefined,
|
||||||
|
'__Host-COOKIENAME cookie should not be found in an unsecured context');
|
||||||
|
}
|
||||||
|
if (kIsUnsecured) {
|
||||||
|
assert_equals(
|
||||||
|
await countMatchingSimpleOriginCookies(),
|
||||||
|
0,
|
||||||
|
'No __Host-COOKIEN* cookies should be found in an unsecured context');
|
||||||
|
} else {
|
||||||
|
assert_equals(
|
||||||
|
await countMatchingSimpleOriginCookies(),
|
||||||
|
1,
|
||||||
|
'One __Host-COOKIEN* cookie should be found in a secure context');
|
||||||
|
}
|
||||||
|
}, 'One simple origin cookie');
|
|
@ -0,0 +1,41 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
// TODO(jsbell): Does this test really need simple origin ('__Host-') cookies?
|
||||||
|
|
||||||
|
cookie_test(async t => {
|
||||||
|
await cookieStore.set('__Host-1🍪', '🔵cookie-value1🔴');
|
||||||
|
await cookieStore.set('__Host-2🌟', '🌠cookie-value2🌠');
|
||||||
|
await cookieStore.set('__Host-3🌱', '🔶cookie-value3🔷');
|
||||||
|
// NOTE: this assumes no concurrent writes from elsewhere; it also
|
||||||
|
// uses three separate cookie jar read operations where a single getAll
|
||||||
|
// would be more efficient, but this way the CookieStore does the filtering
|
||||||
|
// for us.
|
||||||
|
const matchingValues = await Promise.all([ '1🍪', '2🌟', '3🌱' ].map(
|
||||||
|
async suffix => (await cookieStore.get('__Host-' + suffix)).value));
|
||||||
|
const actual = matchingValues.join(';');
|
||||||
|
const expected = '🔵cookie-value1🔴;🌠cookie-value2🌠;🔶cookie-value3🔷';
|
||||||
|
assert_equals(actual, expected);
|
||||||
|
}, 'Set three simple origin session cookies sequentially and ensure ' +
|
||||||
|
'they all end up in the cookie jar in order.');
|
||||||
|
|
||||||
|
cookie_test(async t => {
|
||||||
|
await Promise.all([
|
||||||
|
cookieStore.set('__Host-unordered1🍪', '🔵unordered-cookie-value1🔴'),
|
||||||
|
cookieStore.set('__Host-unordered2🌟', '🌠unordered-cookie-value2🌠'),
|
||||||
|
cookieStore.set('__Host-unordered3🌱', '🔶unordered-cookie-value3🔷')
|
||||||
|
]);
|
||||||
|
// NOTE: this assumes no concurrent writes from elsewhere; it also
|
||||||
|
// uses three separate cookie jar read operations where a single getAll
|
||||||
|
// would be more efficient, but this way the CookieStore does the filtering
|
||||||
|
// for us and we do not need to sort.
|
||||||
|
const matchingCookies = await Promise.all([ '1🍪', '2🌟', '3🌱' ].map(
|
||||||
|
suffix => cookieStore.get('__Host-unordered' + suffix)));
|
||||||
|
const actual = matchingCookies.map(({ value }) => value).join(';');
|
||||||
|
const expected =
|
||||||
|
'🔵unordered-cookie-value1🔴;' +
|
||||||
|
'🌠unordered-cookie-value2🌠;' +
|
||||||
|
'🔶unordered-cookie-value3🔷';
|
||||||
|
assert_equals(actual, expected);
|
||||||
|
}, 'Set three simple origin session cookies in undefined order using ' +
|
||||||
|
'Promise.all and ensure they all end up in the cookie jar in any ' +
|
||||||
|
'order. ');
|
|
@ -0,0 +1,46 @@
|
||||||
|
|
||||||
|
cookie_test(async t => {
|
||||||
|
const theVeryRecentPast = Date.now();
|
||||||
|
const expiredCookieSentinelValue = 'EXPIRED';
|
||||||
|
await promise_rejects_when_unsecured(
|
||||||
|
t,
|
||||||
|
new TypeError(),
|
||||||
|
cookieStore.set('__Secure-COOKIENAME', expiredCookieSentinelValue, {
|
||||||
|
path: kPath,
|
||||||
|
expires: theVeryRecentPast,
|
||||||
|
secure: true,
|
||||||
|
domain: location.hostname
|
||||||
|
}),
|
||||||
|
'Secure cookies only writable from secure contexts');
|
||||||
|
|
||||||
|
}, 'Set an already-expired secure cookie');
|
||||||
|
|
||||||
|
['__Host-', '__Secure-'].forEach(prefix => {
|
||||||
|
cookie_test(async t => {
|
||||||
|
const name = prefix + 'COOKIENAME';
|
||||||
|
const value = 'cookie-value';
|
||||||
|
|
||||||
|
await promise_rejects_when_unsecured(
|
||||||
|
t,
|
||||||
|
new TypeError(),
|
||||||
|
cookieStore.set(name, value),
|
||||||
|
`Setting ${prefix} cookies should fail in non-secure contexts`);
|
||||||
|
|
||||||
|
// Getting does not produce an exception, even in non-secure contexts.
|
||||||
|
const pair = await cookieStore.get(name);
|
||||||
|
|
||||||
|
if (kIsUnsecured) {
|
||||||
|
assert_equals(pair, null);
|
||||||
|
} else {
|
||||||
|
assert_equals(pair.value, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
await promise_rejects_when_unsecured(
|
||||||
|
t,
|
||||||
|
new TypeError(),
|
||||||
|
cookieStore.delete(name),
|
||||||
|
`Deleting ${prefix} cookies should fail in non-secure contexts`);
|
||||||
|
|
||||||
|
assert_equals(await cookieStore.get(name), null);
|
||||||
|
}, `${prefix} cookies only writable from secure context`);
|
||||||
|
});
|
|
@ -0,0 +1,8 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Async Cookies: __Secure- and __Host- cookies</title>
|
||||||
|
<meta name="help" href="https://github.com/WICG/cookie-store/">
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script src="resources/cookie-test-helpers.js"></script>
|
||||||
|
<script src="resources/secure_cookies.js"></script>
|
|
@ -0,0 +1,8 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Async Cookies: __Secure- and __Host- cookies (HTTPS)</title>
|
||||||
|
<meta name="help" href="https://github.com/WICG/cookie-store/">
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script src="resources/cookie-test-helpers.js"></script>
|
||||||
|
<script src="resources/secure_cookies.js"></script>
|
|
@ -0,0 +1,95 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>CSS Grid Layout Test: Grid items with percentage margins</title>
|
||||||
|
<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
|
||||||
|
<link rel="help" href="https://drafts.csswg.org/css-grid-1/#item-margins">
|
||||||
|
<meta name="assert" content="Checks grid items percentage margins are resolved against the inline size of their grid area (in a fixed size track).">
|
||||||
|
<link rel="stylesheet" href="support/grid.css">
|
||||||
|
<style>
|
||||||
|
.grid {
|
||||||
|
font: 10px/1 Ahem;
|
||||||
|
grid-template-columns: 100px;
|
||||||
|
width: 500px;
|
||||||
|
justify-items: start;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid > div:nth-child(1) { background: cyan; }
|
||||||
|
.grid > div:nth-child(2) {
|
||||||
|
background: magenta;
|
||||||
|
width: 100%;
|
||||||
|
height: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.marginLeft50Percent { margin-left: 50%; }
|
||||||
|
.marginRight50Percent { margin-right: 50%; }
|
||||||
|
.marginTop50Percent { margin-top: 50%; }
|
||||||
|
.marginBottom50Percent { margin-bottom: 50%; }
|
||||||
|
</style>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script src="/resources/check-layout-th.js"></script>
|
||||||
|
|
||||||
|
<body onload="checkLayout('.grid')">
|
||||||
|
|
||||||
|
<div id="log"></div>
|
||||||
|
|
||||||
|
<h3>Direction LTR</h3>
|
||||||
|
|
||||||
|
<pre>Item margin-left: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid">
|
||||||
|
<div class="marginLeft50Percent" data-expected-margin-left="50" data-offset-x="50" data-expected-width="10" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="0" data-offset-y="10" data-expected-width="100" data-expected-height="10"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item margin-right: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid">
|
||||||
|
<div class="marginRight50Percent" data-expected-margin-right="50" data-offset-x="0" data-expected-width="10" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="0" data-offset-y="10" data-expected-width="100" data-expected-height="10"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item margin-top: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid">
|
||||||
|
<div class="marginTop50Percent" data-expected-margin-top="50" data-offset-y="50" data-expected-width="10" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="0" data-offset-y="60" data-expected-width="100" data-expected-height="10"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item margin-bottom: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid">
|
||||||
|
<div class="marginBottom50Percent" data-expected-margin-bottom="50" data-offset-y="0" data-expected-width="10" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="0" data-offset-y="60" data-expected-width="100" data-expected-height="10"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h3>Direction RTL</h3>
|
||||||
|
|
||||||
|
<pre>Item margin-left: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid directionRTL">
|
||||||
|
<div class="marginLeft50Percent" data-expected-margin-left="50" data-offset-x="490" data-expected-width="10" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="400" data-offset-y="10" data-expected-width="100" data-expected-height="10"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item margin-right: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid directionRTL">
|
||||||
|
<div class="marginRight50Percent" data-expected-margin-right="50" data-offset-x="440" data-expected-width="10" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="400" data-offset-y="10" data-expected-width="100" data-expected-height="10"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item margin-top: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid directionRTL">
|
||||||
|
<div class="marginTop50Percent" data-expected-margin-top="50" data-offset-y="50" data-expected-width="10" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="400" data-offset-y="60" data-expected-width="100" data-expected-height="10"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item margin-bottom: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid directionRTL">
|
||||||
|
<div class="marginBottom50Percent" data-expected-margin-bottom="50" data-offset-y="0" data-expected-width="10" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="400" data-offset-y="60" data-expected-width="100" data-expected-height="10"></div>
|
||||||
|
</div>
|
|
@ -0,0 +1,95 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>CSS Grid Layout Test: Grid items with percentage margins</title>
|
||||||
|
<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
|
||||||
|
<link rel="help" href="https://drafts.csswg.org/css-grid-1/#item-margins">
|
||||||
|
<meta name="assert" content="Checks grid items percentage margins are resolved against the inline size of their grid area (in a track with fixed max sizing function and intrinsic min).">
|
||||||
|
<link rel="stylesheet" href="support/grid.css">
|
||||||
|
<style>
|
||||||
|
.grid {
|
||||||
|
font: 10px/1 Ahem;
|
||||||
|
grid-template-columns: minmax(auto, 100px);
|
||||||
|
width: 500px;
|
||||||
|
justify-items: start;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid > div:nth-child(1) { background: cyan; }
|
||||||
|
.grid > div:nth-child(2) {
|
||||||
|
background: magenta;
|
||||||
|
width: 100%;
|
||||||
|
height: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.marginLeft50Percent { margin-left: 50%; }
|
||||||
|
.marginRight50Percent { margin-right: 50%; }
|
||||||
|
.marginTop50Percent { margin-top: 50%; }
|
||||||
|
.marginBottom50Percent { margin-bottom: 50%; }
|
||||||
|
</style>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script src="/resources/check-layout-th.js"></script>
|
||||||
|
|
||||||
|
<body onload="checkLayout('.grid')">
|
||||||
|
|
||||||
|
<div id="log"></div>
|
||||||
|
|
||||||
|
<h3>Direction LTR</h3>
|
||||||
|
|
||||||
|
<pre>Item margin-left: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid">
|
||||||
|
<div class="marginLeft50Percent" data-expected-margin-left="50" data-offset-x="50" data-expected-width="10" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="0" data-offset-y="10" data-expected-width="100" data-expected-height="10"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item margin-right: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid">
|
||||||
|
<div class="marginRight50Percent" data-expected-margin-right="50" data-offset-x="0" data-expected-width="10" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="0" data-offset-y="10" data-expected-width="100" data-expected-height="10"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item margin-top: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid">
|
||||||
|
<div class="marginTop50Percent" data-expected-margin-top="50" data-offset-y="50" data-expected-width="10" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="0" data-offset-y="60" data-expected-width="100" data-expected-height="10"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item margin-bottom: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid">
|
||||||
|
<div class="marginBottom50Percent" data-expected-margin-bottom="50" data-offset-y="0" data-expected-width="10" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="0" data-offset-y="60" data-expected-width="100" data-expected-height="10"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h3>Direction RTL</h3>
|
||||||
|
|
||||||
|
<pre>Item margin-left: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid directionRTL">
|
||||||
|
<div class="marginLeft50Percent" data-expected-margin-left="50" data-offset-x="490" data-expected-width="10" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="400" data-offset-y="10" data-expected-width="100" data-expected-height="10"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item margin-right: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid directionRTL">
|
||||||
|
<div class="marginRight50Percent" data-expected-margin-right="50" data-offset-x="440" data-expected-width="10" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="400" data-offset-y="10" data-expected-width="100" data-expected-height="10"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item margin-top: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid directionRTL">
|
||||||
|
<div class="marginTop50Percent" data-expected-margin-top="50" data-offset-y="50" data-expected-width="10" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="400" data-offset-y="60" data-expected-width="100" data-expected-height="10"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item margin-bottom: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid directionRTL">
|
||||||
|
<div class="marginBottom50Percent" data-expected-margin-bottom="50" data-offset-y="0" data-expected-width="10" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="400" data-offset-y="60" data-expected-width="100" data-expected-height="10"></div>
|
||||||
|
</div>
|
|
@ -0,0 +1,96 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>CSS Grid Layout Test: Grid items with percentage margins vertical-lr</title>
|
||||||
|
<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
|
||||||
|
<link rel="help" href="https://drafts.csswg.org/css-grid-1/#item-margins">
|
||||||
|
<meta name="assert" content="Checks grid items percentage margins are resolved against the inline size of their grid area (in a fixed size track) in a vertical-lr grid container.">
|
||||||
|
<link rel="stylesheet" href="support/grid.css">
|
||||||
|
<style>
|
||||||
|
.grid {
|
||||||
|
font: 10px/1 Ahem;
|
||||||
|
grid-template-columns: 100px;
|
||||||
|
height: 500px;
|
||||||
|
justify-items: start;
|
||||||
|
position: relative;
|
||||||
|
writing-mode: vertical-lr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid > div:nth-child(1) { background: cyan; }
|
||||||
|
.grid > div:nth-child(2) {
|
||||||
|
background: magenta;
|
||||||
|
width: 10px;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.marginLeft50Percent { margin-left: 50%; }
|
||||||
|
.marginRight50Percent { margin-right: 50%; }
|
||||||
|
.marginTop50Percent { margin-top: 50%; }
|
||||||
|
.marginBottom50Percent { margin-bottom: 50%; }
|
||||||
|
</style>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script src="/resources/check-layout-th.js"></script>
|
||||||
|
|
||||||
|
<body onload="checkLayout('.grid')">
|
||||||
|
|
||||||
|
<div id="log"></div>
|
||||||
|
|
||||||
|
<h3>Direction LTR</h3>
|
||||||
|
|
||||||
|
<pre>Item margin-left: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid">
|
||||||
|
<div class="marginLeft50Percent" data-expected-margin-left="50" data-offset-x="50" data-expected-width="10" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="60" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item margin-right: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid">
|
||||||
|
<div class="marginRight50Percent" data-expected-margin-right="50" data-offset-x="0" data-expected-width="10" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="60" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item margin-top: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid">
|
||||||
|
<div class="marginTop50Percent" data-expected-margin-top="50" data-offset-y="50" data-expected-width="10" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="10" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item margin-bottom: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid">
|
||||||
|
<div class="marginBottom50Percent" data-expected-margin-bottom="50" data-offset-y="0" data-expected-width="10" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="10" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h3>Direction RTL</h3>
|
||||||
|
|
||||||
|
<pre>Item margin-left: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid directionRTL">
|
||||||
|
<div class="marginLeft50Percent" data-expected-margin-left="50" data-offset-x="50" data-expected-width="10" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="60" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item margin-right: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid directionRTL">
|
||||||
|
<div class="marginRight50Percent" data-expected-margin-right="50" data-offset-x="0" data-expected-width="10" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="60" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item margin-top: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid directionRTL">
|
||||||
|
<div class="marginTop50Percent" data-expected-margin-top="50" data-offset-y="490" data-expected-width="10" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="10" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item margin-bottom: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid directionRTL">
|
||||||
|
<div class="marginBottom50Percent" data-expected-margin-bottom="50" data-offset-y="440" data-expected-width="10" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="10" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
|
@ -0,0 +1,96 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>CSS Grid Layout Test: Grid items with percentage margins vertical-lr</title>
|
||||||
|
<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
|
||||||
|
<link rel="help" href="https://drafts.csswg.org/css-grid-1/#item-margins">
|
||||||
|
<meta name="assert" content="Checks grid items percentage margins are resolved against the inline size of their grid area (in a track with fixed max sizing function and intrinsic min) in a vertical-lr grid container.">
|
||||||
|
<link rel="stylesheet" href="support/grid.css">
|
||||||
|
<style>
|
||||||
|
.grid {
|
||||||
|
font: 10px/1 Ahem;
|
||||||
|
grid-template-columns: minmax(auto, 100px);
|
||||||
|
height: 500px;
|
||||||
|
justify-items: start;
|
||||||
|
position: relative;
|
||||||
|
writing-mode: vertical-lr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid > div:nth-child(1) { background: cyan; }
|
||||||
|
.grid > div:nth-child(2) {
|
||||||
|
background: magenta;
|
||||||
|
width: 10px;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.marginLeft50Percent { margin-left: 50%; }
|
||||||
|
.marginRight50Percent { margin-right: 50%; }
|
||||||
|
.marginTop50Percent { margin-top: 50%; }
|
||||||
|
.marginBottom50Percent { margin-bottom: 50%; }
|
||||||
|
</style>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script src="/resources/check-layout-th.js"></script>
|
||||||
|
|
||||||
|
<body onload="checkLayout('.grid')">
|
||||||
|
|
||||||
|
<div id="log"></div>
|
||||||
|
|
||||||
|
<h3>Direction LTR</h3>
|
||||||
|
|
||||||
|
<pre>Item margin-left: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid">
|
||||||
|
<div class="marginLeft50Percent" data-expected-margin-left="50" data-offset-x="50" data-expected-width="10" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="60" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item margin-right: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid">
|
||||||
|
<div class="marginRight50Percent" data-expected-margin-right="50" data-offset-x="0" data-expected-width="10" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="60" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item margin-top: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid">
|
||||||
|
<div class="marginTop50Percent" data-expected-margin-top="50" data-offset-y="50" data-expected-width="10" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="10" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item margin-bottom: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid">
|
||||||
|
<div class="marginBottom50Percent" data-expected-margin-bottom="50" data-offset-y="0" data-expected-width="10" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="10" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h3>Direction RTL</h3>
|
||||||
|
|
||||||
|
<pre>Item margin-left: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid directionRTL">
|
||||||
|
<div class="marginLeft50Percent" data-expected-margin-left="50" data-offset-x="50" data-expected-width="10" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="60" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item margin-right: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid directionRTL">
|
||||||
|
<div class="marginRight50Percent" data-expected-margin-right="50" data-offset-x="0" data-expected-width="10" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="60" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item margin-top: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid directionRTL">
|
||||||
|
<div class="marginTop50Percent" data-expected-margin-top="50" data-offset-y="490" data-expected-width="10" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="10" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item margin-bottom: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid directionRTL">
|
||||||
|
<div class="marginBottom50Percent" data-expected-margin-bottom="50" data-offset-y="440" data-expected-width="10" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="10" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
|
@ -0,0 +1,96 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>CSS Grid Layout Test: Grid items with percentage margins vertical-rl</title>
|
||||||
|
<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
|
||||||
|
<link rel="help" href="https://drafts.csswg.org/css-grid-1/#item-margins">
|
||||||
|
<meta name="assert" content="Checks grid items percentage margins are resolved against the inline size of their grid area (in a fixed size track) in a vertical-rl grid container.">
|
||||||
|
<link rel="stylesheet" href="support/grid.css">
|
||||||
|
<style>
|
||||||
|
.grid {
|
||||||
|
font: 10px/1 Ahem;
|
||||||
|
grid-template-columns: 100px;
|
||||||
|
height: 500px;
|
||||||
|
justify-items: start;
|
||||||
|
position: relative;
|
||||||
|
writing-mode: vertical-rl;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid > div:nth-child(1) { background: cyan; }
|
||||||
|
.grid > div:nth-child(2) {
|
||||||
|
background: magenta;
|
||||||
|
width: 10px;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.marginLeft50Percent { margin-left: 50%; }
|
||||||
|
.marginRight50Percent { margin-right: 50%; }
|
||||||
|
.marginTop50Percent { margin-top: 50%; }
|
||||||
|
.marginBottom50Percent { margin-bottom: 50%; }
|
||||||
|
</style>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script src="/resources/check-layout-th.js"></script>
|
||||||
|
|
||||||
|
<body onload="checkLayout('.grid')">
|
||||||
|
|
||||||
|
<div id="log"></div>
|
||||||
|
|
||||||
|
<h3>Direction LTR</h3>
|
||||||
|
|
||||||
|
<pre>Item margin-left: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid">
|
||||||
|
<div class="marginLeft50Percent" data-expected-margin-left="50" data-offset-x="60" data-expected-width="10" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="0" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item margin-right: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid">
|
||||||
|
<div class="marginRight50Percent" data-expected-margin-right="50" data-offset-x="10" data-expected-width="10" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="0" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item margin-top: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid">
|
||||||
|
<div class="marginTop50Percent" data-expected-margin-top="50" data-offset-y="50" data-expected-width="10" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="0" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item margin-bottom: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid">
|
||||||
|
<div class="marginBottom50Percent" data-expected-margin-bottom="50" data-offset-y="0" data-expected-width="10" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="0" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h3>Direction RTL</h3>
|
||||||
|
|
||||||
|
<pre>Item margin-left: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid directionRTL">
|
||||||
|
<div class="marginLeft50Percent" data-expected-margin-left="50" data-expected-x="60" data-expected-width="10" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="0" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item margin-right: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid directionRTL">
|
||||||
|
<div class="marginRight50Percent" data-expected-margin-right="50" data-expected-x="10" data-expected-width="10" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="0" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item margin-top: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid directionRTL">
|
||||||
|
<div class="marginTop50Percent" data-expected-margin-top="50" data-expected-y="490" data-expected-width="10" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="0" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item margin-bottom: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid directionRTL">
|
||||||
|
<div class="marginBottom50Percent" data-expected-margin-bottom="50" data-expected-y="440" data-expected-width="10" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="0" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
|
@ -0,0 +1,96 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>CSS Grid Layout Test: Grid items with percentage margins vertical-rl</title>
|
||||||
|
<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
|
||||||
|
<link rel="help" href="https://drafts.csswg.org/css-grid-1/#item-margins">
|
||||||
|
<meta name="assert" content="Checks grid items percentage margins are resolved against the inline size of their grid area (in a track with fixed max sizing function and intrinsic min) in a vertical-rl grid container.">
|
||||||
|
<link rel="stylesheet" href="support/grid.css">
|
||||||
|
<style>
|
||||||
|
.grid {
|
||||||
|
font: 10px/1 Ahem;
|
||||||
|
grid-template-columns: minmax(auto, 100px);
|
||||||
|
height: 500px;
|
||||||
|
justify-items: start;
|
||||||
|
position: relative;
|
||||||
|
writing-mode: vertical-rl;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid > div:nth-child(1) { background: cyan; }
|
||||||
|
.grid > div:nth-child(2) {
|
||||||
|
background: magenta;
|
||||||
|
width: 10px;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.marginLeft50Percent { margin-left: 50%; }
|
||||||
|
.marginRight50Percent { margin-right: 50%; }
|
||||||
|
.marginTop50Percent { margin-top: 50%; }
|
||||||
|
.marginBottom50Percent { margin-bottom: 50%; }
|
||||||
|
</style>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script src="/resources/check-layout-th.js"></script>
|
||||||
|
|
||||||
|
<body onload="checkLayout('.grid')">
|
||||||
|
|
||||||
|
<div id="log"></div>
|
||||||
|
|
||||||
|
<h3>Direction LTR</h3>
|
||||||
|
|
||||||
|
<pre>Item margin-left: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid">
|
||||||
|
<div class="marginLeft50Percent" data-expected-margin-left="50" data-offset-x="60" data-expected-width="10" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="0" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item margin-right: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid">
|
||||||
|
<div class="marginRight50Percent" data-expected-margin-right="50" data-offset-x="10" data-expected-width="10" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="0" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item margin-top: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid">
|
||||||
|
<div class="marginTop50Percent" data-expected-margin-top="50" data-offset-y="50" data-expected-width="10" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="0" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item margin-bottom: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid">
|
||||||
|
<div class="marginBottom50Percent" data-expected-margin-bottom="50" data-offset-y="0" data-expected-width="10" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="0" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h3>Direction RTL</h3>
|
||||||
|
|
||||||
|
<pre>Item margin-left: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid directionRTL">
|
||||||
|
<div class="marginLeft50Percent" data-expected-margin-left="50" data-expected-x="60" data-expected-width="10" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="0" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item margin-right: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid directionRTL">
|
||||||
|
<div class="marginRight50Percent" data-expected-margin-right="50" data-expected-x="10" data-expected-width="10" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="0" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item margin-top: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid directionRTL">
|
||||||
|
<div class="marginTop50Percent" data-expected-margin-top="50" data-expected-y="490" data-expected-width="10" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="0" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item margin-bottom: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid directionRTL">
|
||||||
|
<div class="marginBottom50Percent" data-expected-margin-bottom="50" data-expected-y="440" data-expected-width="10" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="0" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
|
@ -0,0 +1,95 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>CSS Grid Layout Test: Grid items with percentage paddings</title>
|
||||||
|
<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
|
||||||
|
<link rel="help" href="https://drafts.csswg.org/css-grid-1/#item-margins">
|
||||||
|
<meta name="assert" content="Checks grid items percentage paddings are resolved against the inline size of their grid area (in a fixed size track).">
|
||||||
|
<link rel="stylesheet" href="support/grid.css">
|
||||||
|
<style>
|
||||||
|
.grid {
|
||||||
|
font: 10px/1 Ahem;
|
||||||
|
grid-template-columns: 100px;
|
||||||
|
width: 500px;
|
||||||
|
justify-items: start;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid > div:nth-child(1) { background: cyan; }
|
||||||
|
.grid > div:nth-child(2) {
|
||||||
|
background: magenta;
|
||||||
|
width: 100%;
|
||||||
|
height: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.paddingLeft50Percent { padding-left: 50%; }
|
||||||
|
.paddingRight50Percent { padding-right: 50%; }
|
||||||
|
.paddingTop50Percent { padding-top: 50%; }
|
||||||
|
.paddingBottom50Percent { padding-bottom: 50%; }
|
||||||
|
</style>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script src="/resources/check-layout-th.js"></script>
|
||||||
|
|
||||||
|
<body onload="checkLayout('.grid')">
|
||||||
|
|
||||||
|
<div id="log"></div>
|
||||||
|
|
||||||
|
<h3>Direction LTR</h3>
|
||||||
|
|
||||||
|
<pre>Item padding-left: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid">
|
||||||
|
<div class="paddingLeft50Percent" data-expected-padding-left="50" data-expected-width="60" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="0" data-offset-y="10" data-expected-width="100" data-expected-height="10"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item padding-right: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid">
|
||||||
|
<div class="paddingRight50Percent" data-expected-padding-right="50" data-expected-width="60" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="0" data-offset-y="10" data-expected-width="100" data-expected-height="10"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item padding-top: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid">
|
||||||
|
<div class="paddingTop50Percent" data-expected-padding-top="50" data-expected-width="10" data-expected-height="60">X</div>
|
||||||
|
<div data-offset-x="0" data-offset-y="60" data-expected-width="100" data-expected-height="10"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item padding-bottom: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid">
|
||||||
|
<div class="paddingBottom50Percent" data-expected-padding-bottom="50" data-expected-width="10" data-expected-height="60">X</div>
|
||||||
|
<div data-offset-x="0" data-offset-y="60" data-expected-width="100" data-expected-height="10"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h3>Direction RTL</h3>
|
||||||
|
|
||||||
|
<pre>Item padding-left: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid directionRTL">
|
||||||
|
<div class="paddingLeft50Percent" data-expected-padding-left="50" data-expected-width="60" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="400" data-offset-y="10" data-expected-width="100" data-expected-height="10"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item padding-right: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid directionRTL">
|
||||||
|
<div class="paddingRight50Percent" data-expected-padding-right="50" data-expected-width="60" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="400" data-offset-y="10" data-expected-width="100" data-expected-height="10"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item padding-top: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid directionRTL">
|
||||||
|
<div class="paddingTop50Percent" data-expected-padding-top="50" data-expected-width="10" data-expected-height="60">X</div>
|
||||||
|
<div data-offset-x="400" data-offset-y="60" data-expected-width="100" data-expected-height="10"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item padding-bottom: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid directionRTL">
|
||||||
|
<div class="paddingBottom50Percent" data-expected-padding-bottom="50" data-expected-width="10" data-expected-height="60">X</div>
|
||||||
|
<div data-offset-x="400" data-offset-y="60" data-expected-width="100" data-expected-height="10"></div>
|
||||||
|
</div>
|
|
@ -0,0 +1,95 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>CSS Grid Layout Test: Grid items with percentage paddings</title>
|
||||||
|
<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
|
||||||
|
<link rel="help" href="https://drafts.csswg.org/css-grid-1/#item-margins">
|
||||||
|
<meta name="assert" content="Checks grid items percentage paddings are resolved against the inline size of their grid area (in a track with fixed max sizing function and intrinsic min).">
|
||||||
|
<link rel="stylesheet" href="support/grid.css">
|
||||||
|
<style>
|
||||||
|
.grid {
|
||||||
|
font: 10px/1 Ahem;
|
||||||
|
grid-template-columns: minmax(auto, 100px);
|
||||||
|
width: 500px;
|
||||||
|
justify-items: start;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid > div:nth-child(1) { background: cyan; }
|
||||||
|
.grid > div:nth-child(2) {
|
||||||
|
background: magenta;
|
||||||
|
width: 100%;
|
||||||
|
height: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.paddingLeft50Percent { padding-left: 50%; }
|
||||||
|
.paddingRight50Percent { padding-right: 50%; }
|
||||||
|
.paddingTop50Percent { padding-top: 50%; }
|
||||||
|
.paddingBottom50Percent { padding-bottom: 50%; }
|
||||||
|
</style>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script src="/resources/check-layout-th.js"></script>
|
||||||
|
|
||||||
|
<body onload="checkLayout('.grid')">
|
||||||
|
|
||||||
|
<div id="log"></div>
|
||||||
|
|
||||||
|
<h3>Direction LTR</h3>
|
||||||
|
|
||||||
|
<pre>Item padding-left: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid">
|
||||||
|
<div class="paddingLeft50Percent" data-expected-padding-left="50" data-expected-width="60" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="0" data-offset-y="10" data-expected-width="100" data-expected-height="10"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item padding-right: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid">
|
||||||
|
<div class="paddingRight50Percent" data-expected-padding-right="50" data-expected-width="60" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="0" data-offset-y="10" data-expected-width="100" data-expected-height="10"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item padding-top: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid">
|
||||||
|
<div class="paddingTop50Percent" data-expected-padding-top="50" data-expected-width="10" data-expected-height="60">X</div>
|
||||||
|
<div data-offset-x="0" data-offset-y="60" data-expected-width="100" data-expected-height="10"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item padding-bottom: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid">
|
||||||
|
<div class="paddingBottom50Percent" data-expected-padding-bottom="50" data-expected-width="10" data-expected-height="60">X</div>
|
||||||
|
<div data-offset-x="0" data-offset-y="60" data-expected-width="100" data-expected-height="10"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h3>Direction RTL</h3>
|
||||||
|
|
||||||
|
<pre>Item padding-left: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid directionRTL">
|
||||||
|
<div class="paddingLeft50Percent" data-expected-padding-left="50" data-expected-width="60" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="400" data-offset-y="10" data-expected-width="100" data-expected-height="10"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item padding-right: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid directionRTL">
|
||||||
|
<div class="paddingRight50Percent" data-expected-padding-right="50" data-expected-width="60" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="400" data-offset-y="10" data-expected-width="100" data-expected-height="10"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item padding-top: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid directionRTL">
|
||||||
|
<div class="paddingTop50Percent" data-expected-padding-top="50" data-expected-width="10" data-expected-height="60">X</div>
|
||||||
|
<div data-offset-x="400" data-offset-y="60" data-expected-width="100" data-expected-height="10"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item padding-bottom: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid directionRTL">
|
||||||
|
<div class="paddingBottom50Percent" data-expected-padding-bottom="50" data-expected-width="10" data-expected-height="60">X</div>
|
||||||
|
<div data-offset-x="400" data-offset-y="60" data-expected-width="100" data-expected-height="10"></div>
|
||||||
|
</div>
|
|
@ -0,0 +1,96 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>CSS Grid Layout Test: Grid items with percentage paddings vertical-lr</title>
|
||||||
|
<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
|
||||||
|
<link rel="help" href="https://drafts.csswg.org/css-grid-1/#item-margins">
|
||||||
|
<meta name="assert" content="Checks grid items percentage paddings are resolved against the inline size of their grid area (in a fixed size track) in a vertical-lr grid container.">
|
||||||
|
<link rel="stylesheet" href="support/grid.css">
|
||||||
|
<style>
|
||||||
|
.grid {
|
||||||
|
font: 10px/1 Ahem;
|
||||||
|
grid-template-columns: 100px;
|
||||||
|
height: 500px;
|
||||||
|
justify-items: start;
|
||||||
|
position: relative;
|
||||||
|
writing-mode: vertical-lr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid > div:nth-child(1) { background: cyan; }
|
||||||
|
.grid > div:nth-child(2) {
|
||||||
|
background: magenta;
|
||||||
|
width: 10px;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.paddingLeft50Percent { padding-left: 50%; }
|
||||||
|
.paddingRight50Percent { padding-right: 50%; }
|
||||||
|
.paddingTop50Percent { padding-top: 50%; }
|
||||||
|
.paddingBottom50Percent { padding-bottom: 50%; }
|
||||||
|
</style>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script src="/resources/check-layout-th.js"></script>
|
||||||
|
|
||||||
|
<body onload="checkLayout('.grid')">
|
||||||
|
|
||||||
|
<div id="log"></div>
|
||||||
|
|
||||||
|
<h3>Direction LTR</h3>
|
||||||
|
|
||||||
|
<pre>Item padding-left: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid">
|
||||||
|
<div class="paddingLeft50Percent" data-expected-padding-left="50" data-expected-width="60" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="60" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item padding-right: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid">
|
||||||
|
<div class="paddingRight50Percent" data-expected-padding-right="50" data-expected-width="60" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="60" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item padding-top: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid">
|
||||||
|
<div class="paddingTop50Percent" data-expected-padding-top="50" data-expected-width="10" data-expected-height="60">X</div>
|
||||||
|
<div data-offset-x="10" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item padding-bottom: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid">
|
||||||
|
<div class="paddingBottom50Percent" data-expected-padding-bottom="50" data-expected-width="10" data-expected-height="60">X</div>
|
||||||
|
<div data-offset-x="10" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h3>Direction RTL</h3>
|
||||||
|
|
||||||
|
<pre>Item padding-left: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid directionRTL">
|
||||||
|
<div class="paddingLeft50Percent" data-expected-padding-left="50" data-expected-width="60" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="60" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item padding-right: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid directionRTL">
|
||||||
|
<div class="paddingRight50Percent" data-expected-padding-right="50" data-expected-width="60" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="60" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item padding-top: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid directionRTL">
|
||||||
|
<div class="paddingTop50Percent" data-expected-padding-top="50" data-expected-width="10" data-expected-height="60">X</div>
|
||||||
|
<div data-offset-x="10" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item padding-bottom: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid directionRTL">
|
||||||
|
<div class="paddingBottom50Percent" data-expected-padding-bottom="50" data-expected-width="10" data-expected-height="60">X</div>
|
||||||
|
<div data-offset-x="10" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
|
@ -0,0 +1,96 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>CSS Grid Layout Test: Grid items with percentage paddings vertical-lr</title>
|
||||||
|
<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
|
||||||
|
<link rel="help" href="https://drafts.csswg.org/css-grid-1/#item-margins">
|
||||||
|
<meta name="assert" content="Checks grid items percentage paddings are resolved against the inline size of their grid area (in a track with fixed max sizing function and intrinsic min) in a vertical-lr grid container.">
|
||||||
|
<link rel="stylesheet" href="support/grid.css">
|
||||||
|
<style>
|
||||||
|
.grid {
|
||||||
|
font: 10px/1 Ahem;
|
||||||
|
grid-template-columns: minmax(auto, 100px);
|
||||||
|
height: 500px;
|
||||||
|
justify-items: start;
|
||||||
|
position: relative;
|
||||||
|
writing-mode: vertical-lr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid > div:nth-child(1) { background: cyan; }
|
||||||
|
.grid > div:nth-child(2) {
|
||||||
|
background: magenta;
|
||||||
|
width: 10px;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.paddingLeft50Percent { padding-left: 50%; }
|
||||||
|
.paddingRight50Percent { padding-right: 50%; }
|
||||||
|
.paddingTop50Percent { padding-top: 50%; }
|
||||||
|
.paddingBottom50Percent { padding-bottom: 50%; }
|
||||||
|
</style>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script src="/resources/check-layout-th.js"></script>
|
||||||
|
|
||||||
|
<body onload="checkLayout('.grid')">
|
||||||
|
|
||||||
|
<div id="log"></div>
|
||||||
|
|
||||||
|
<h3>Direction LTR</h3>
|
||||||
|
|
||||||
|
<pre>Item padding-left: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid">
|
||||||
|
<div class="paddingLeft50Percent" data-expected-padding-left="50" data-expected-width="60" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="60" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item padding-right: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid">
|
||||||
|
<div class="paddingRight50Percent" data-expected-padding-right="50" data-expected-width="60" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="60" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item padding-top: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid">
|
||||||
|
<div class="paddingTop50Percent" data-expected-padding-top="50" data-expected-width="10" data-expected-height="60">X</div>
|
||||||
|
<div data-offset-x="10" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item padding-bottom: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid">
|
||||||
|
<div class="paddingBottom50Percent" data-expected-padding-bottom="50" data-expected-width="10" data-expected-height="60">X</div>
|
||||||
|
<div data-offset-x="10" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h3>Direction RTL</h3>
|
||||||
|
|
||||||
|
<pre>Item padding-left: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid directionRTL">
|
||||||
|
<div class="paddingLeft50Percent" data-expected-padding-left="50" data-expected-width="60" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="60" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item padding-right: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid directionRTL">
|
||||||
|
<div class="paddingRight50Percent" data-expected-padding-right="50" data-expected-width="60" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="60" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item padding-top: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid directionRTL">
|
||||||
|
<div class="paddingTop50Percent" data-expected-padding-top="50" data-expected-width="10" data-expected-height="60">X</div>
|
||||||
|
<div data-offset-x="10" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item padding-bottom: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid directionRTL">
|
||||||
|
<div class="paddingBottom50Percent" data-expected-padding-bottom="50" data-expected-width="10" data-expected-height="60">X</div>
|
||||||
|
<div data-offset-x="10" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
|
@ -0,0 +1,96 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>CSS Grid Layout Test: Grid items with percentage paddings vertical-rl</title>
|
||||||
|
<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
|
||||||
|
<link rel="help" href="https://drafts.csswg.org/css-grid-1/#item-margins">
|
||||||
|
<meta name="assert" content="Checks grid items percentage paddings are resolved against the inline size of their grid area (in a fixed size track) in a vertical-rl grid container.">
|
||||||
|
<link rel="stylesheet" href="support/grid.css">
|
||||||
|
<style>
|
||||||
|
.grid {
|
||||||
|
font: 10px/1 Ahem;
|
||||||
|
grid-template-columns: 100px;
|
||||||
|
height: 500px;
|
||||||
|
justify-items: start;
|
||||||
|
position: relative;
|
||||||
|
writing-mode: vertical-rl;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid > div:nth-child(1) { background: cyan; }
|
||||||
|
.grid > div:nth-child(2) {
|
||||||
|
background: magenta;
|
||||||
|
width: 10px;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.paddingLeft50Percent { padding-left: 50%; }
|
||||||
|
.paddingRight50Percent { padding-right: 50%; }
|
||||||
|
.paddingTop50Percent { padding-top: 50%; }
|
||||||
|
.paddingBottom50Percent { padding-bottom: 50%; }
|
||||||
|
</style>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script src="/resources/check-layout-th.js"></script>
|
||||||
|
|
||||||
|
<body onload="checkLayout('.grid')">
|
||||||
|
|
||||||
|
<div id="log"></div>
|
||||||
|
|
||||||
|
<h3>Direction LTR</h3>
|
||||||
|
|
||||||
|
<pre>Item padding-left: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid">
|
||||||
|
<div class="paddingLeft50Percent" data-expected-padding-left="50" data-expected-width="60" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="0" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item padding-right: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid">
|
||||||
|
<div class="paddingRight50Percent" data-expected-padding-right="50" data-expected-width="60" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="0" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item padding-top: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid">
|
||||||
|
<div class="paddingTop50Percent" data-expected-padding-top="50" data-expected-width="10" data-expected-height="60">X</div>
|
||||||
|
<div data-offset-x="0" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item padding-bottom: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid">
|
||||||
|
<div class="paddingBottom50Percent" data-expected-padding-bottom="50" data-expected-width="10" data-expected-height="60">X</div>
|
||||||
|
<div data-offset-x="0" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h3>Direction RTL</h3>
|
||||||
|
|
||||||
|
<pre>Item padding-left: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid directionRTL">
|
||||||
|
<div class="paddingLeft50Percent" data-expected-padding-left="50" data-expected-width="60" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="0" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item padding-right: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid directionRTL">
|
||||||
|
<div class="paddingRight50Percent" data-expected-padding-right="50" data-expected-width="60" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="0" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item padding-top: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid directionRTL">
|
||||||
|
<div class="paddingTop50Percent" data-expected-padding-top="50" data-expected-width="10" data-expected-height="60">X</div>
|
||||||
|
<div data-offset-x="0" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item padding-bottom: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid directionRTL">
|
||||||
|
<div class="paddingBottom50Percent" data-expected-padding-bottom="50" data-expected-width="10" data-expected-height="60">X</div>
|
||||||
|
<div data-offset-x="0" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
|
@ -0,0 +1,96 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>CSS Grid Layout Test: Grid items with percentage paddings vertical-rl</title>
|
||||||
|
<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
|
||||||
|
<link rel="help" href="https://drafts.csswg.org/css-grid-1/#item-margins">
|
||||||
|
<meta name="assert" content="Checks grid items percentage paddings are resolved against the inline size of their grid area (in a track with fixed max sizing function and intrinsic min) in a vertical-rl grid container.">
|
||||||
|
<link rel="stylesheet" href="support/grid.css">
|
||||||
|
<style>
|
||||||
|
.grid {
|
||||||
|
font: 10px/1 Ahem;
|
||||||
|
grid-template-columns: minmax(auto, 100px);
|
||||||
|
height: 500px;
|
||||||
|
justify-items: start;
|
||||||
|
position: relative;
|
||||||
|
writing-mode: vertical-rl;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid > div:nth-child(1) { background: cyan; }
|
||||||
|
.grid > div:nth-child(2) {
|
||||||
|
background: magenta;
|
||||||
|
width: 10px;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.paddingLeft50Percent { padding-left: 50%; }
|
||||||
|
.paddingRight50Percent { padding-right: 50%; }
|
||||||
|
.paddingTop50Percent { padding-top: 50%; }
|
||||||
|
.paddingBottom50Percent { padding-bottom: 50%; }
|
||||||
|
</style>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script src="/resources/check-layout-th.js"></script>
|
||||||
|
|
||||||
|
<body onload="checkLayout('.grid')">
|
||||||
|
|
||||||
|
<div id="log"></div>
|
||||||
|
|
||||||
|
<h3>Direction LTR</h3>
|
||||||
|
|
||||||
|
<pre>Item padding-left: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid">
|
||||||
|
<div class="paddingLeft50Percent" data-expected-padding-left="50" data-expected-width="60" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="0" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item padding-right: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid">
|
||||||
|
<div class="paddingRight50Percent" data-expected-padding-right="50" data-expected-width="60" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="0" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item padding-top: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid">
|
||||||
|
<div class="paddingTop50Percent" data-expected-padding-top="50" data-expected-width="10" data-expected-height="60">X</div>
|
||||||
|
<div data-offset-x="0" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item padding-bottom: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid">
|
||||||
|
<div class="paddingBottom50Percent" data-expected-padding-bottom="50" data-expected-width="10" data-expected-height="60">X</div>
|
||||||
|
<div data-offset-x="0" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h3>Direction RTL</h3>
|
||||||
|
|
||||||
|
<pre>Item padding-left: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid directionRTL">
|
||||||
|
<div class="paddingLeft50Percent" data-expected-padding-left="50" data-expected-width="60" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="0" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item padding-right: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid directionRTL">
|
||||||
|
<div class="paddingRight50Percent" data-expected-padding-right="50" data-expected-width="60" data-expected-height="10">X</div>
|
||||||
|
<div data-offset-x="0" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item padding-top: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid directionRTL">
|
||||||
|
<div class="paddingTop50Percent" data-expected-padding-top="50" data-expected-width="10" data-expected-height="60">X</div>
|
||||||
|
<div data-offset-x="0" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>Item padding-bottom: 50%;</pre>
|
||||||
|
|
||||||
|
<div class="grid directionRTL">
|
||||||
|
<div class="paddingBottom50Percent" data-expected-padding-bottom="50" data-expected-width="10" data-expected-height="60">X</div>
|
||||||
|
<div data-offset-x="0" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
|
||||||
|
</div>
|
|
@ -84,10 +84,9 @@
|
||||||
assert_readonly(styleSheet, "parentStyleSheet");
|
assert_readonly(styleSheet, "parentStyleSheet");
|
||||||
assert_readonly(styleSheet, "href");
|
assert_readonly(styleSheet, "href");
|
||||||
assert_readonly(styleSheet, "title");
|
assert_readonly(styleSheet, "title");
|
||||||
assert_readonly(styleSheet, "media");
|
|
||||||
}, "StyleSheet_properties",
|
}, "StyleSheet_properties",
|
||||||
{ assert: [ "type, disabled, ownerNode, parentStyleSheet, href, title, and media properties exist on StyleSheet",
|
{ assert: [ "type, disabled, ownerNode, parentStyleSheet, href, title, and media properties exist on StyleSheet",
|
||||||
"type, ownerNode, parentStyleSheet, href, title, media properties are read only" ] });
|
"type, ownerNode, parentStyleSheet, href, and title properties are read only" ] });
|
||||||
|
|
||||||
test(function() {
|
test(function() {
|
||||||
assert_equals(styleSheet.type, "text/css");
|
assert_equals(styleSheet.type, "text/css");
|
||||||
|
|
|
@ -145,10 +145,13 @@ test(() => {
|
||||||
|
|
||||||
customElements.upgrade(template.content);
|
customElements.upgrade(template.content);
|
||||||
|
|
||||||
assert_true(el1 instanceof Element1, "element 1 must now be upgraded");
|
// Template contents owner documents don't have a browsing context, so
|
||||||
assert_true(el2 instanceof Element2, "element 2 must now be upgraded");
|
// https://html.spec.whatwg.org/multipage/custom-elements.html#look-up-a-custom-element-definition does not find any
|
||||||
assert_true(el3 instanceof Element3, "element 3 must now be upgraded");
|
// custom element definition.
|
||||||
assert_true(el4 instanceof Element4, "element 4 must now be upgraded");
|
assert_false(el1 instanceof Element1, "element 1 must still not be upgraded after upgrading the template contents");
|
||||||
assert_true(el5 instanceof Element5, "element 5 must now be upgraded");
|
assert_false(el2 instanceof Element2, "element 2 must still not be upgraded after upgrading the template contents");
|
||||||
|
assert_false(el3 instanceof Element3, "element 3 must still not be upgraded after upgrading the template contents");
|
||||||
|
assert_false(el4 instanceof Element4, "element 4 must still not be upgraded after upgrading the template contents");
|
||||||
|
assert_false(el5 instanceof Element5, "element 5 must still not be upgraded after upgrading the template contents");
|
||||||
}, "Elements inside a template contents DocumentFragment node");
|
}, "Elements inside a template contents DocumentFragment node");
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
<meta name="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org">
|
<meta name="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org">
|
||||||
<meta name="assert" content="HTML parser must set the attributes and append the children on a custom element">
|
<meta name="assert" content="HTML parser must set the attributes and append the children on a custom element">
|
||||||
<link rel="help" href="https://html.spec.whatwg.org/#create-an-element-for-the-token">
|
<link rel="help" href="https://html.spec.whatwg.org/#create-an-element-for-the-token">
|
||||||
|
<link rel="help" href="https://html.spec.whatwg.org/multipage/parsing.html#insert-a-foreign-element">
|
||||||
<link rel="help" href="https://dom.spec.whatwg.org/#concept-create-element">
|
<link rel="help" href="https://dom.spec.whatwg.org/#concept-create-element">
|
||||||
<script src="/resources/testharness.js"></script>
|
<script src="/resources/testharness.js"></script>
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
@ -14,8 +15,10 @@
|
||||||
<div id="log"></div>
|
<div id="log"></div>
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
var numberOfAttributesInConstructor;
|
var numberOfAttributesInConstructor = 0;
|
||||||
var numberOfChildNodesInConstructor;
|
var numberOfChildNodesInConstructor = 0;
|
||||||
|
var numberOfChildNodesInAttributeChangedCallback = 0;
|
||||||
|
var numberOfChildNodesInConnectedCallback = 0;
|
||||||
var attributesChangedCalls = [];
|
var attributesChangedCalls = [];
|
||||||
|
|
||||||
class MyCustomElement extends HTMLElement {
|
class MyCustomElement extends HTMLElement {
|
||||||
|
@ -27,11 +30,16 @@ class MyCustomElement extends HTMLElement {
|
||||||
|
|
||||||
attributeChangedCallback(...args) {
|
attributeChangedCallback(...args) {
|
||||||
attributesChangedCalls.push(create_attribute_changed_callback_log(this, ...args));
|
attributesChangedCalls.push(create_attribute_changed_callback_log(this, ...args));
|
||||||
|
numberOfChildNodesInAttributeChangedCallback = this.childNodes.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
static get observedAttributes() {
|
static get observedAttributes() {
|
||||||
return ['id', 'class'];
|
return ['id', 'class'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
connectedCallback() {
|
||||||
|
numberOfChildNodesInConnectedCallback = this.childNodes.length;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
customElements.define('my-custom-element', MyCustomElement);
|
customElements.define('my-custom-element', MyCustomElement);
|
||||||
|
|
||||||
|
@ -64,10 +72,22 @@ test(function () {
|
||||||
assert_equals(numberOfChildNodesInConstructor, 0, 'HTML parser must not append child nodes to a custom element before invoking the constructor');
|
assert_equals(numberOfChildNodesInConstructor, 0, 'HTML parser must not append child nodes to a custom element before invoking the constructor');
|
||||||
}, 'HTML parser must set the attributes or append children before calling constructor');
|
}, 'HTML parser must set the attributes or append children before calling constructor');
|
||||||
|
|
||||||
|
test(function () {
|
||||||
|
// https://html.spec.whatwg.org/multipage/parsing.html#insert-a-foreign-element
|
||||||
|
// 3.3. Pop the element queue from the custom element reactions
|
||||||
|
// stack, and invoke custom element reactions in that queue.
|
||||||
|
assert_equals(numberOfChildNodesInConnectedCallback, 0);
|
||||||
|
}, 'HTML parser should call connectedCallback before appending child nodes.');
|
||||||
|
|
||||||
test(function () {
|
test(function () {
|
||||||
assert_equals(attributesChangedCalls.length, 2);
|
assert_equals(attributesChangedCalls.length, 2);
|
||||||
assert_attribute_log_entry(attributesChangedCalls[0], {name: 'id', oldValue: null, newValue: 'custom-element-id', namespace: null});
|
assert_attribute_log_entry(attributesChangedCalls[0], {name: 'id', oldValue: null, newValue: 'custom-element-id', namespace: null});
|
||||||
assert_attribute_log_entry(attributesChangedCalls[1], {name: 'class', oldValue: null, newValue: 'class1 class2', namespace: null});
|
assert_attribute_log_entry(attributesChangedCalls[1], {name: 'class', oldValue: null, newValue: 'class1 class2', namespace: null});
|
||||||
|
// https://html.spec.whatwg.org/multipage/parsing.html#create-an-element-for-the-token
|
||||||
|
// 9.2. Invoke custom element reactions in queue.
|
||||||
|
assert_equals(numberOfChildNodesInAttributeChangedCallback, 0,
|
||||||
|
'attributeChangedCallback should be called ' +
|
||||||
|
'before appending a child');
|
||||||
}, 'HTML parser must enqueue attributeChanged reactions');
|
}, 'HTML parser must enqueue attributeChanged reactions');
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
<!-- Test verifies that cross-origin, nosniff images are 1) blocked when their
|
||||||
|
MIME type is covered by CORB and 2) allowed otherwise.
|
||||||
|
|
||||||
|
This test is very similar to fetch/nosniff/images.html, except that
|
||||||
|
1) it deals with cross-origin images (CORB ignores same-origin fetches),
|
||||||
|
2) it focuses on MIME types relevant to CORB.
|
||||||
|
There are opportunities to unify the test here with nosniff tests *if*
|
||||||
|
we can also start blocking same-origin (or cors-allowed) images. We
|
||||||
|
should try to gather data to quantify the impact of such change.
|
||||||
|
-->
|
||||||
|
<script src=/resources/testharness.js></script>
|
||||||
|
<script src=/resources/testharnessreport.js></script>
|
||||||
|
<div id=log></div>
|
||||||
|
<script>
|
||||||
|
var passes = [
|
||||||
|
// Empty or non-sensical MIME types
|
||||||
|
null, "", "x", "x/x",
|
||||||
|
|
||||||
|
// MIME-types not protected by CORB
|
||||||
|
"image/gif", "image/png", "image/png;blah", "image/svg+xml",
|
||||||
|
"application/javascript", "application/jsonp",
|
||||||
|
|
||||||
|
// MIME types that may seem to be JSON or XML, but really aren't - i.e.
|
||||||
|
// these MIME types are not covered by:
|
||||||
|
// - https://mimesniff.spec.whatwg.org/#json-mime-type
|
||||||
|
// - https://mimesniff.spec.whatwg.org/#xml-mime-type
|
||||||
|
// - https://tools.ietf.org/html/rfc6839
|
||||||
|
// - https://tools.ietf.org/html/rfc7303
|
||||||
|
"text/x-json", "text/json+blah", "application/json+blah",
|
||||||
|
"text/xml+blah", "application/xml+blah",
|
||||||
|
"application/blahjson", "text/blahxml",
|
||||||
|
|
||||||
|
var fails = [
|
||||||
|
// CORB-protected MIME-types - i.e. ones covered by:
|
||||||
|
// - https://mimesniff.spec.whatwg.org/#html-mime-type
|
||||||
|
// - https://mimesniff.spec.whatwg.org/#json-mime-type
|
||||||
|
// - https://mimesniff.spec.whatwg.org/#xml-mime-type
|
||||||
|
"text/html",
|
||||||
|
"text/json", "application/json", "text/xml", "application/xml",
|
||||||
|
"application/blah+json", "text/blah+json",
|
||||||
|
"application/blah+xml", "text/blah+xml",
|
||||||
|
"TEXT/HTML", "TEXT/JSON", "TEXT/BLAH+JSON", "APPLICATION/BLAH+XML"]
|
||||||
|
|
||||||
|
const get_url = (mime) => {
|
||||||
|
// www1 is cross-origin, so the HTTP response is CORB-eligible -->
|
||||||
|
url = "http://{{domains[www1]}}:{{ports[http][0]}}"
|
||||||
|
url = url + "/fetch/nosniff/resources/image.py"
|
||||||
|
if (mime != null) {
|
||||||
|
url += "?type=" + encodeURIComponent(mime)
|
||||||
|
}
|
||||||
|
return url
|
||||||
|
}
|
||||||
|
|
||||||
|
passes.forEach(function(mime) {
|
||||||
|
async_test(function(t) {
|
||||||
|
var img = document.createElement("img")
|
||||||
|
img.onerror = t.unreached_func("Unexpected error event")
|
||||||
|
img.onload = t.step_func_done(function(){
|
||||||
|
assert_equals(img.width, 96)
|
||||||
|
})
|
||||||
|
img.src = get_url(mime)
|
||||||
|
document.body.appendChild(img)
|
||||||
|
}, "CORB should allow the response if Content-Type is: '" + mime + "'. ")
|
||||||
|
})
|
||||||
|
|
||||||
|
fails.forEach(function(mime) {
|
||||||
|
async_test(function(t) {
|
||||||
|
var img = document.createElement("img")
|
||||||
|
img.onerror = t.step_func_done()
|
||||||
|
img.onload = t.unreached_func("Unexpected load event")
|
||||||
|
img.src = get_url(mime)
|
||||||
|
document.body.appendChild(img)
|
||||||
|
}, "CORB should block the response if Content-Type is: '" + mime + "'. ")
|
||||||
|
})
|
||||||
|
</script>
|
|
@ -0,0 +1,24 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<!-- This test verifies observable CORB impact on <link rel="preload"> elements.
|
||||||
|
-->
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<div id=log></div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
async_test(function(t) {
|
||||||
|
// With CORB the link.onerror event will be reached
|
||||||
|
// (because CORB will block the cross-origin preload).
|
||||||
|
window.preloadErrorEvent = t.step_func_done();
|
||||||
|
|
||||||
|
// Without CORB the link.onload event will be reached.
|
||||||
|
window.preloadLoadEvent = t.unreached_func("link/preload onload event reached.");
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- www1 is cross-origin, so the HTTP response is CORB-eligible -->
|
||||||
|
<link rel="preload" as="image"
|
||||||
|
onerror="window.preloadErrorEvent()"
|
||||||
|
onload="window.preloadLoadEvent()"
|
||||||
|
href="http://{{domains[www1]}}:{{ports[http][0]}}/fetch/corb/resources/png-mislabeled-as-html-nosniff.png">
|
|
@ -3,7 +3,19 @@
|
||||||
<div id=log></div>
|
<div id=log></div>
|
||||||
<script>
|
<script>
|
||||||
// Note: images get always sniffed, nosniff doesn't do anything
|
// Note: images get always sniffed, nosniff doesn't do anything
|
||||||
var passes = [null, "", "x", "x/x", "image/gif", "image/png", "image/png;blah"]
|
// (but note the tentative Cross-Origin Read Blocking (CORB) tests
|
||||||
|
// - for example wpt/fetch/corb/img-mime-types-coverage.tentative.sub.html).
|
||||||
|
var passes = [
|
||||||
|
// Empty or non-sensical MIME types
|
||||||
|
null, "", "x", "x/x",
|
||||||
|
|
||||||
|
// Image MIME types
|
||||||
|
"image/gif", "image/png", "image/png;blah", "image/svg+xml",
|
||||||
|
|
||||||
|
// CORB-protected MIME types (but note that CORB doesn't apply here,
|
||||||
|
// because CORB ignores same-origin requests).
|
||||||
|
"text/html", "application/xml", "application/blah+xml"
|
||||||
|
]
|
||||||
|
|
||||||
const get_url = (mime) => {
|
const get_url = (mime) => {
|
||||||
let url = "resources/image.py"
|
let url = "resources/image.py"
|
||||||
|
|
|
@ -3,7 +3,13 @@ import os.path
|
||||||
def main(request, response):
|
def main(request, response):
|
||||||
type = request.GET.first("type", None)
|
type = request.GET.first("type", None)
|
||||||
|
|
||||||
body = open(os.path.join(os.path.dirname(__file__), "../../../images/blue96x96.png"), "rb").read()
|
if type != None and "svg" in type:
|
||||||
|
filename = "green-96x96.svg"
|
||||||
|
else:
|
||||||
|
filename = "blue96x96.png"
|
||||||
|
|
||||||
|
path = os.path.join(os.path.dirname(__file__), "../../../images", filename)
|
||||||
|
body = open(path, "rb").read()
|
||||||
|
|
||||||
response.add_required_headers = False
|
response.add_required_headers = False
|
||||||
response.writer.write_status(200)
|
response.writer.write_status(200)
|
||||||
|
|
3
tests/wpt/web-platform-tests/images/green-96x96.svg
Normal file
3
tests/wpt/web-platform-tests/images/green-96x96.svg
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="96" height="96">
|
||||||
|
<rect fill="lime" width="96" height="96"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 116 B |
|
@ -0,0 +1,41 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<title>Service Worker: Synchronous XHR on Worker is intercepted</title>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script src="resources/test-helpers.sub.js"></script>
|
||||||
|
<script>
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
promise_test((t) => {
|
||||||
|
const url = 'resources/fetch-request-xhr-sync-on-worker-worker.js';
|
||||||
|
const scope = 'resources/fetch-request-xhr-sync-on-worker-scope/';
|
||||||
|
const non_existent_file = 'non-existent-file.txt';
|
||||||
|
|
||||||
|
// In Chromium, the service worker scope matching for workers is based on
|
||||||
|
// the URL of the parent HTML. So this test creates an iframe which is
|
||||||
|
// controlled by the service worker first, and creates a worker from the
|
||||||
|
// iframe.
|
||||||
|
return service_worker_unregister_and_register(t, url, scope)
|
||||||
|
.then((registration) => {
|
||||||
|
t.add_cleanup(() => registration.unregister());
|
||||||
|
return wait_for_state(t, registration.installing, 'activated');
|
||||||
|
})
|
||||||
|
.then(() => { return with_iframe(scope + 'iframe_page'); })
|
||||||
|
.then((frame) => {
|
||||||
|
t.add_cleanup(() => frame.remove());
|
||||||
|
return frame.contentWindow.performSyncXHROnWorker(non_existent_file);
|
||||||
|
})
|
||||||
|
.then((result) => {
|
||||||
|
assert_equals(
|
||||||
|
result.status,
|
||||||
|
200,
|
||||||
|
'HTTP response status code for intercepted request'
|
||||||
|
);
|
||||||
|
assert_equals(
|
||||||
|
result.responseText,
|
||||||
|
'Response from service worker',
|
||||||
|
'HTTP response text for intercepted request'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}, 'Verify SyncXHR on Worker is intercepted');
|
||||||
|
</script>
|
|
@ -0,0 +1,41 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
self.onfetch = function(event) {
|
||||||
|
if (event.request.url.indexOf('non-existent-file.txt') !== -1) {
|
||||||
|
event.respondWith(new Response('Response from service worker'));
|
||||||
|
} else if (event.request.url.indexOf('/iframe_page') !== -1) {
|
||||||
|
event.respondWith(new Response(
|
||||||
|
'<!DOCTYPE html>\n' +
|
||||||
|
'<script>\n' +
|
||||||
|
'function performSyncXHROnWorker(url) {\n' +
|
||||||
|
' return new Promise((resolve) => {\n' +
|
||||||
|
' var worker =\n' +
|
||||||
|
' new Worker(\'./worker_script\');\n' +
|
||||||
|
' worker.addEventListener(\'message\', (msg) => {\n' +
|
||||||
|
' resolve(msg.data);\n' +
|
||||||
|
' });\n' +
|
||||||
|
' worker.postMessage({\n' +
|
||||||
|
' url: url\n' +
|
||||||
|
' });\n' +
|
||||||
|
' });\n' +
|
||||||
|
'}\n' +
|
||||||
|
'</script>',
|
||||||
|
{
|
||||||
|
headers: [['content-type', 'text/html']]
|
||||||
|
}));
|
||||||
|
} else if (event.request.url.indexOf('/worker_script') !== -1) {
|
||||||
|
event.respondWith(new Response(
|
||||||
|
'self.onmessage = (msg) => {' +
|
||||||
|
' const syncXhr = new XMLHttpRequest();' +
|
||||||
|
' syncXhr.open(\'GET\', msg.data.url, false);' +
|
||||||
|
' syncXhr.send();' +
|
||||||
|
' self.postMessage({' +
|
||||||
|
' status: syncXhr.status,' +
|
||||||
|
' responseText: syncXhr.responseText' +
|
||||||
|
' });' +
|
||||||
|
'}',
|
||||||
|
{
|
||||||
|
headers: [['content-type', 'application/javascript']]
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
};
|
Loading…
Add table
Add a link
Reference in a new issue