summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/css/mediaqueries
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/css/mediaqueries')
-rw-r--r--testing/web-platform/tests/css/mediaqueries/META.yml5
-rw-r--r--testing/web-platform/tests/css/mediaqueries/aspect-ratio-001.html26
-rw-r--r--testing/web-platform/tests/css/mediaqueries/aspect-ratio-002.html24
-rw-r--r--testing/web-platform/tests/css/mediaqueries/aspect-ratio-003.html26
-rw-r--r--testing/web-platform/tests/css/mediaqueries/aspect-ratio-004.html24
-rw-r--r--testing/web-platform/tests/css/mediaqueries/aspect-ratio-005.html25
-rw-r--r--testing/web-platform/tests/css/mediaqueries/aspect-ratio-006.html25
-rw-r--r--testing/web-platform/tests/css/mediaqueries/aspect-ratio-serialization.html13
-rw-r--r--testing/web-platform/tests/css/mediaqueries/device-aspect-ratio-001.html25
-rw-r--r--testing/web-platform/tests/css/mediaqueries/device-aspect-ratio-002.html25
-rw-r--r--testing/web-platform/tests/css/mediaqueries/device-aspect-ratio-003.html24
-rw-r--r--testing/web-platform/tests/css/mediaqueries/device-aspect-ratio-004.html24
-rw-r--r--testing/web-platform/tests/css/mediaqueries/device-aspect-ratio-005.html24
-rw-r--r--testing/web-platform/tests/css/mediaqueries/device-aspect-ratio-006.html24
-rw-r--r--testing/web-platform/tests/css/mediaqueries/dynamic-range.html36
-rw-r--r--testing/web-platform/tests/css/mediaqueries/forced-colors.html24
-rw-r--r--testing/web-platform/tests/css/mediaqueries/media-queries-001.xht21
-rw-r--r--testing/web-platform/tests/css/mediaqueries/media-queries-002.xht19
-rw-r--r--testing/web-platform/tests/css/mediaqueries/media-queries-003.xht19
-rw-r--r--testing/web-platform/tests/css/mediaqueries/media-query-matches-in-iframe.html104
-rw-r--r--testing/web-platform/tests/css/mediaqueries/min-width-001.xht29
-rw-r--r--testing/web-platform/tests/css/mediaqueries/min-width-tables-001.html42
-rw-r--r--testing/web-platform/tests/css/mediaqueries/mq-calc-001.html25
-rw-r--r--testing/web-platform/tests/css/mediaqueries/mq-calc-002.html36
-rw-r--r--testing/web-platform/tests/css/mediaqueries/mq-calc-003.html36
-rw-r--r--testing/web-platform/tests/css/mediaqueries/mq-calc-004.html33
-rw-r--r--testing/web-platform/tests/css/mediaqueries/mq-calc-005.html33
-rw-r--r--testing/web-platform/tests/css/mediaqueries/mq-calc-006.html20
-rw-r--r--testing/web-platform/tests/css/mediaqueries/mq-calc-007.html20
-rw-r--r--testing/web-platform/tests/css/mediaqueries/mq-calc-008.html28
-rw-r--r--testing/web-platform/tests/css/mediaqueries/mq-case-insensitive-001.html45
-rw-r--r--testing/web-platform/tests/css/mediaqueries/mq-deprecated-001.html31
-rw-r--r--testing/web-platform/tests/css/mediaqueries/mq-dynamic-empty-children.html40
-rw-r--r--testing/web-platform/tests/css/mediaqueries/mq-gamut-001.html23
-rw-r--r--testing/web-platform/tests/css/mediaqueries/mq-gamut-002.html24
-rw-r--r--testing/web-platform/tests/css/mediaqueries/mq-gamut-003.html25
-rw-r--r--testing/web-platform/tests/css/mediaqueries/mq-gamut-004.html24
-rw-r--r--testing/web-platform/tests/css/mediaqueries/mq-gamut-005.html24
-rw-r--r--testing/web-platform/tests/css/mediaqueries/mq-invalid-media-type-001.html31
-rw-r--r--testing/web-platform/tests/css/mediaqueries/mq-invalid-media-type-002.html31
-rw-r--r--testing/web-platform/tests/css/mediaqueries/mq-invalid-media-type-003.html31
-rw-r--r--testing/web-platform/tests/css/mediaqueries/mq-invalid-media-type-004.html31
-rw-r--r--testing/web-platform/tests/css/mediaqueries/mq-invalid-media-type-005.html45
-rw-r--r--testing/web-platform/tests/css/mediaqueries/mq-invalid-media-type-layer-001.html31
-rw-r--r--testing/web-platform/tests/css/mediaqueries/mq-invalid-media-type-layer-002.html27
-rw-r--r--testing/web-platform/tests/css/mediaqueries/mq-negative-range-001.html39
-rw-r--r--testing/web-platform/tests/css/mediaqueries/mq-negative-range-002.html39
-rw-r--r--testing/web-platform/tests/css/mediaqueries/mq-range-001.html26
-rw-r--r--testing/web-platform/tests/css/mediaqueries/mq-unknown-feature-custom-property.html13
-rw-r--r--testing/web-platform/tests/css/mediaqueries/navigation-controls.tentative.html17
-rw-r--r--testing/web-platform/tests/css/mediaqueries/negation-001.html40
-rw-r--r--testing/web-platform/tests/css/mediaqueries/negation-002.html44
-rw-r--r--testing/web-platform/tests/css/mediaqueries/prefers-color-scheme-svg-image-normal-ref.html23
-rw-r--r--testing/web-platform/tests/css/mediaqueries/prefers-color-scheme-svg-image-normal-with-meta-dark-ref.html14
-rw-r--r--testing/web-platform/tests/css/mediaqueries/prefers-color-scheme-svg-image-normal-with-meta-dark.html17
-rw-r--r--testing/web-platform/tests/css/mediaqueries/prefers-color-scheme-svg-image-normal-with-meta-light-ref.html13
-rw-r--r--testing/web-platform/tests/css/mediaqueries/prefers-color-scheme-svg-image-normal-with-meta-light.html17
-rw-r--r--testing/web-platform/tests/css/mediaqueries/prefers-color-scheme-svg-image-normal.html16
-rw-r--r--testing/web-platform/tests/css/mediaqueries/prefers-color-scheme-svg-image-ref.html17
-rw-r--r--testing/web-platform/tests/css/mediaqueries/prefers-color-scheme-svg-image.html23
-rw-r--r--testing/web-platform/tests/css/mediaqueries/prefers-color-scheme.html24
-rw-r--r--testing/web-platform/tests/css/mediaqueries/prefers-contrast.html36
-rw-r--r--testing/web-platform/tests/css/mediaqueries/prefers-reduced-data.html30
-rw-r--r--testing/web-platform/tests/css/mediaqueries/prefers-reduced-motion.html27
-rw-r--r--testing/web-platform/tests/css/mediaqueries/reference/ref-green-body.xht18
-rw-r--r--testing/web-platform/tests/css/mediaqueries/relative-units-001.html36
-rw-r--r--testing/web-platform/tests/css/mediaqueries/relative-units-002.html36
-rw-r--r--testing/web-platform/tests/css/mediaqueries/relative-units-003.html36
-rw-r--r--testing/web-platform/tests/css/mediaqueries/relative-units-004.html36
-rw-r--r--testing/web-platform/tests/css/mediaqueries/relative-units-005.html29
-rw-r--r--testing/web-platform/tests/css/mediaqueries/resources/matchmedia-utils.js76
-rw-r--r--testing/web-platform/tests/css/mediaqueries/resources/prefers-color-scheme-dark.svg6
-rw-r--r--testing/web-platform/tests/css/mediaqueries/resources/prefers-color-scheme-light.svg6
-rw-r--r--testing/web-platform/tests/css/mediaqueries/resources/prefers-color-scheme.svg9
-rw-r--r--testing/web-platform/tests/css/mediaqueries/support/media_queries_iframe.html16
-rw-r--r--testing/web-platform/tests/css/mediaqueries/support/min-width-tables-001-iframe.html59
-rw-r--r--testing/web-platform/tests/css/mediaqueries/test_media_queries.html714
-rw-r--r--testing/web-platform/tests/css/mediaqueries/viewport-script-dynamic-ref.html9
-rw-r--r--testing/web-platform/tests/css/mediaqueries/viewport-script-dynamic.html20
79 files changed, 2883 insertions, 0 deletions
diff --git a/testing/web-platform/tests/css/mediaqueries/META.yml b/testing/web-platform/tests/css/mediaqueries/META.yml
new file mode 100644
index 0000000000..f277097263
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/META.yml
@@ -0,0 +1,5 @@
+spec: https://drafts.csswg.org/mediaqueries/
+suggested_reviewers:
+ - dbaron
+ - plinss
+ - frivoal
diff --git a/testing/web-platform/tests/css/mediaqueries/aspect-ratio-001.html b/testing/web-platform/tests/css/mediaqueries/aspect-ratio-001.html
new file mode 100644
index 0000000000..9307b9a15f
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/aspect-ratio-001.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Media Queries Test: min-aspect-ratio - 59/79 ('aspect-ratio' property with prefix 'min')</title>
+<link rel="author" title="Intel" href="http://www.intel.com/">
+<link name="author" title="Xin Liu" href="mailto:xinx.liu@intel.com">
+<link rel="help" title="4.6. aspect-ratio" href="http://www.w3.org/TR/css3-mediaqueries/#aspect-ratio">
+<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+<meta name="assert" content="The 'aspect-ratio' property with prefix 'min' set '59/79' means that the minimum of ratio is '59/79',
+only and only if the value of the 'width' to the value of the 'height' is greater than value of 'min-aspect-ratio', the style sheet will be applied.
+The test runner will run this test in a 800/600 viewport (https://github.com/web-platform-tests/wpt/pull/12695).">
+<style>
+ div {
+ background-color: red;
+ height: 100px;
+ width: 100px;
+ }
+ @media screen and (min-aspect-ratio: 59/79) {
+ div {
+ background-color: green;
+ }
+ }
+</style>
+<body>
+ <p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+ <div></div>
+</body>
diff --git a/testing/web-platform/tests/css/mediaqueries/aspect-ratio-002.html b/testing/web-platform/tests/css/mediaqueries/aspect-ratio-002.html
new file mode 100644
index 0000000000..3b34de9225
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/aspect-ratio-002.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Media Queries Test: min-aspect-ratio - 0/0 ('aspect-ratio' property with prefix 'min')</title>
+<link rel="author" title="Intel" href="http://www.intel.com/">
+<link name="author" title="Xin Liu" href="mailto:xinx.liu@intel.com">
+<link rel="help" title="4.6. aspect-ratio" href="http://www.w3.org/TR/css3-mediaqueries/#aspect-ratio">
+<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+<meta name="assert" content="The 'aspect-ratio' property with prefix 'min' set '0/0' (which is converted into '1/0') is infinite that means the style sheet specified by 'min-aspect-ratio' will not be applied.">
+<style>
+ div {
+ background-color: green;
+ height: 100px;
+ width: 100px;
+ }
+ @media screen and (min-aspect-ratio: 0/0) {
+ div {
+ background-color: red;
+ }
+ }
+</style>
+<body>
+ <p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+ <div></div>
+</body>
diff --git a/testing/web-platform/tests/css/mediaqueries/aspect-ratio-003.html b/testing/web-platform/tests/css/mediaqueries/aspect-ratio-003.html
new file mode 100644
index 0000000000..4212e8197c
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/aspect-ratio-003.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Media Queries Test: max-aspect-ratio - 1280/720 ('aspect-ratio' property with prefix 'max')</title>
+<link rel="author" title="Intel" href="http://www.intel.com/">
+<link name="author" title="Xin Liu" href="mailto:xinx.liu@intel.com">
+<link rel="help" title="4.6. aspect-ratio" href="http://www.w3.org/TR/css3-mediaqueries/#aspect-ratio">
+<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+<meta name="assert" content="The 'aspect-ratio' property with prefix 'max' set '1280/720' means that the maximum of ratio is '1280/720',
+only and only if the value of the 'width' to the value of the 'height' is lower than value of 'max-aspect-ratio', the style sheet will be applied.
+The test runner will run this test in a 800/600 viewport (https://github.com/web-platform-tests/wpt/pull/12695)">
+<style>
+ div {
+ background-color: red;
+ height: 100px;
+ width: 100px;
+ }
+ @media screen and (max-aspect-ratio: 1280/720) {
+ div {
+ background-color: green;
+ }
+ }
+</style>
+<body>
+ <p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+ <div></div>
+</body>
diff --git a/testing/web-platform/tests/css/mediaqueries/aspect-ratio-004.html b/testing/web-platform/tests/css/mediaqueries/aspect-ratio-004.html
new file mode 100644
index 0000000000..bf2d261725
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/aspect-ratio-004.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Media Queries Test: max-aspect-ratio - 0/0 ('aspect-ratio' property with prefix 'max')</title>
+<link rel="author" title="Intel" href="http://www.intel.com/">
+<link name="author" title="Xin Liu" href="mailto:xinx.liu@intel.com">
+<link rel="help" title="4.6. aspect-ratio" href="http://www.w3.org/TR/css3-mediaqueries/#aspect-ratio">
+<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+<meta name="assert" content="The 'aspect-ratio' property with prefix 'max' set '0/0' (which is converted into '1/0') is infinite that means the style sheet specified by 'max-aspect-ratio' will be applied.">
+<style>
+ div {
+ background-color: red;
+ height: 100px;
+ width: 100px;
+ }
+ @media screen and (max-aspect-ratio: 0/0) {
+ div {
+ background-color: green;
+ }
+ }
+</style>
+<body>
+ <p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+ <div></div>
+</body>
diff --git a/testing/web-platform/tests/css/mediaqueries/aspect-ratio-005.html b/testing/web-platform/tests/css/mediaqueries/aspect-ratio-005.html
new file mode 100644
index 0000000000..12c9a080e5
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/aspect-ratio-005.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Media Queries Test: max-aspect-ratio - 1280.1/720.01 ('aspect-ratio' property with prefix 'max')</title>
+<link rel="author" title="Joel Olsson" href="mailto:joel_1st@hotmail.com">
+<link rel="help" title="aspect-ratio" href="https://drafts.csswg.org/mediaqueries-4/#aspect-ratio">
+<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+<meta name="assert" content="The 'aspect-ratio' property with prefix 'max' set 1280.1/720.01. Only and only if the value of the 'width'
+to the value of the 'height' is lower than value of 'max-aspect-ratio', the style sheet will be applied.
+The test runner will run this test in a 800/600 viewport (https://github.com/web-platform-tests/wpt/pull/12695)">
+<style>
+ div {
+ background-color: red;
+ height: 100px;
+ width: 100px;
+ }
+ @media screen and (max-aspect-ratio: 1280.1/720.01) {
+ div {
+ background-color: green;
+ }
+ }
+</style>
+<body>
+ <p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+ <div></div>
+</body>
diff --git a/testing/web-platform/tests/css/mediaqueries/aspect-ratio-006.html b/testing/web-platform/tests/css/mediaqueries/aspect-ratio-006.html
new file mode 100644
index 0000000000..59901b1aad
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/aspect-ratio-006.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Media Queries Test: min-aspect-ratio - 0.7 ('aspect-ratio' property with prefix 'min')</title>
+<link rel="author" title="Joel Olsson" href="mailto:joel_1st@hotmail.com">
+<link rel="help" title="aspect-ratio" href="https://drafts.csswg.org/mediaqueries-4/#aspect-ratio">
+<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+<meta name="assert" content="The 'aspect-ratio' property with prefix 'min' set '0.7' means that the minimum of ratio is '0.7',
+only and only if the value of the 'width' to the value of the 'height' is greater than value of 'min-aspect-ratio', the style sheet will be applied.
+The test runner will run this test in a 800/600 viewport (https://github.com/web-platform-tests/wpt/pull/12695)">
+<style>
+ div {
+ background-color: red;
+ height: 100px;
+ width: 100px;
+ }
+ @media screen and (min-aspect-ratio: 0.2) {
+ div {
+ background-color: green;
+ }
+ }
+</style>
+<body>
+ <p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+ <div></div>
+</body>
diff --git a/testing/web-platform/tests/css/mediaqueries/aspect-ratio-serialization.html b/testing/web-platform/tests/css/mediaqueries/aspect-ratio-serialization.html
new file mode 100644
index 0000000000..cce3559288
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/aspect-ratio-serialization.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Media Queries Test: 'aspect-ratio' serializes with spaces around ' / '.</title>
+<link rel="help" href="https://drafts.csswg.org/cssom/#serialize-a-css-component-value">
+<link rel="author" href="mailto:emilio@crisal.io" title="Emilio Cobos Álvarez">
+<link rel="author" href="https://mozilla.org" title="Mozilla">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+test(function() {
+ assert_equals(matchMedia("(aspect-ratio: 1/3)").media, "(aspect-ratio: 1 / 3)");
+}, "<ratio> serializes with spaces around the integer.");
+</script>
diff --git a/testing/web-platform/tests/css/mediaqueries/device-aspect-ratio-001.html b/testing/web-platform/tests/css/mediaqueries/device-aspect-ratio-001.html
new file mode 100644
index 0000000000..8fe99c2f3a
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/device-aspect-ratio-001.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Media Queries Test: max-device-aspect-ratio - 1281/1024 ('device-aspect-ratio' property with prefix 'max')</title>
+<link rel="author" title="Intel" href="http://www.intel.com/">
+<link rel="author" title="Xin Liu" href="mailto:xinx.liu@intel.com">
+<link rel="help" title="4.7. device-aspect-ratio" href="http://www.w3.org/TR/css3-mediaqueries/#device-aspect-ratio">
+<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+<meta name="assert" content="The 'device-aspect-ratio' property with prefix 'max' set '1281/1024' means that the maximum of ratio is '1281/1024', only and only if the device value of 'width' to value of 'height' is lower than value of 'max-device-aspect-ratio', the style sheet will be applied.">
+<style>
+ div {
+ background-color: red;
+ height: 100px;
+ width: 100px;
+ }
+ @media screen and (max-device-aspect-ratio: 1281/1024) {
+ div {
+ background-color: green;
+ }
+ }
+</style>
+<body>
+ <p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+ <div></div>
+</body>
+
diff --git a/testing/web-platform/tests/css/mediaqueries/device-aspect-ratio-002.html b/testing/web-platform/tests/css/mediaqueries/device-aspect-ratio-002.html
new file mode 100644
index 0000000000..dd0f0a1b49
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/device-aspect-ratio-002.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Media Queries Test: max-device-aspect-ratio - 0/0 ('device-aspect-ratio' property with prefix 'max')</title>
+<link rel="author" title="Intel" href="http://www.intel.com/">
+<link rel="author" title="Xin Liu" href="mailto:xinx.liu@intel.com">
+<link rel="help" title="4.7. device-aspect-ratio" href="http://www.w3.org/TR/css3-mediaqueries/#device-aspect-ratio">
+<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+<meta name="assert" content="The 'device-aspect-ratio' property with prefix 'max' set '0/0' (which is converted into '1/0') is infinite that means the style sheet specified by 'max-device-aspect-ratio' will be applied.">
+<style>
+ div {
+ background-color: red;
+ height: 100px;
+ width: 100px;
+ }
+ @media screen and (max-device-aspect-ratio: 0/0) {
+ div {
+ background-color: green;
+ }
+ }
+</style>
+<body>
+ <p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+ <div></div>
+</body>
+
diff --git a/testing/web-platform/tests/css/mediaqueries/device-aspect-ratio-003.html b/testing/web-platform/tests/css/mediaqueries/device-aspect-ratio-003.html
new file mode 100644
index 0000000000..23014f5bfb
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/device-aspect-ratio-003.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Media Queries Test: min-device-aspect-ratio - 1279/1024 ('device-aspect-ratio' property with prefix 'min')</title>
+<link rel="author" title="Intel" href="http://www.intel.com/">
+<link rel="author" title="Xin Liu" href="mailto:xinx.liu@intel.com">
+<link rel="help" title="4.7. device-aspect-ratio" href="http://www.w3.org/TR/css3-mediaqueries/#device-aspect-ratio">
+<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+<meta name="assert" content="The 'device-aspect-ratio' property with prefix 'min' set '1279/1024' means that the minimum of ratio is '1279/1024', only and only if the device value of 'width' to value of 'height' is greater than value of 'min-device-aspect-ratio', the style sheet will be applied.">
+<style>
+ div {
+ background-color: red;
+ height: 100px;
+ width: 100px;
+ }
+ @media screen and (min-device-aspect-ratio: 1279/1024) {
+ div {
+ background-color: green;
+ }
+ }
+</style>
+<body>
+ <p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+ <div></div>
+</body>
diff --git a/testing/web-platform/tests/css/mediaqueries/device-aspect-ratio-004.html b/testing/web-platform/tests/css/mediaqueries/device-aspect-ratio-004.html
new file mode 100644
index 0000000000..42e3c069e1
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/device-aspect-ratio-004.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Media Queries Test: min-device-aspect-ratio - 0/0 ('device-aspect-ratio' property with prefix 'min')</title>
+<link rel="author" title="Intel" href="http://www.intel.com/">
+<link rel="author" title="Xin Liu" href="mailto:xinx.liu@intel.com">
+<link rel="help" title="4.7. device-aspect-ratio" href="http://www.w3.org/TR/css3-mediaqueries/#device-aspect-ratio">
+<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+<meta name="assert" content="The 'device-aspect-ratio' property with prefix 'min' set '0/0' (which is converted into '1/0') is infinite that means the style sheet specified by 'min-device-aspect-ratio' will not be applied.">
+<style>
+ div {
+ background-color: green;
+ height: 100px;
+ width: 100px;
+ }
+ @media screen and (min-device-aspect-ratio: 0/0) {
+ div {
+ background-color: red;
+ }
+ }
+</style>
+<body>
+ <p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+ <div></div>
+</body>
diff --git a/testing/web-platform/tests/css/mediaqueries/device-aspect-ratio-005.html b/testing/web-platform/tests/css/mediaqueries/device-aspect-ratio-005.html
new file mode 100644
index 0000000000..5a310bba45
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/device-aspect-ratio-005.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Media Queries Test: device-aspect-ratio - 1280/1024 (basic)</title>
+<link rel="author" title="Intel" href="http://www.intel.com/">
+<link rel="author" title="Xin Liu" href="mailto:xinx.liu@intel.com">
+<link rel="help" title="4.7. device-aspect-ratio" href="http://www.w3.org/TR/css3-mediaqueries/#device-aspect-ratio">
+<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+<meta name="assert" content="The 'device-aspect-ratio' property set '1280/1024' means that the ratio is '1280/1024', only and only if the device value of 'width' to value of 'height' is equals with value of 'device-aspect-ratio', the style sheet will be applied.">
+<style>
+ div {
+ background-color: red;
+ height: 100px;
+ width: 100px;
+ }
+ @media screen and (device-aspect-ratio: 1280/1024) {
+ div {
+ background-color: green;
+ }
+ }
+</style>
+<body>
+ <p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+ <div></div>
+</body>
diff --git a/testing/web-platform/tests/css/mediaqueries/device-aspect-ratio-006.html b/testing/web-platform/tests/css/mediaqueries/device-aspect-ratio-006.html
new file mode 100644
index 0000000000..681558349e
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/device-aspect-ratio-006.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Media Queries Test: device-aspect-ratio - 0/0 (invalid)</title>
+<link rel="author" title="Intel" href="http://www.intel.com/">
+<link rel="author" title="Xin Liu" href="mailto:xinx.liu@intel.com">
+<link rel="help" title="4.7. device-aspect-ratio" href="http://www.w3.org/TR/css3-mediaqueries/#device-aspect-ratio">
+<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+<meta name="assert" content="The 'device-aspect-ratio' property set '0/0' is invalid that means the style sheet specified by 'device-aspect-ratio' will not be applied.">
+<style>
+ div {
+ background-color: green;
+ height: 100px;
+ width: 100px;
+ }
+ @media screen and (device-aspect-ratio: 0/0) {
+ div {
+ background-color: red;
+ }
+ }
+</style>
+<body>
+ <p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+ <div></div>
+</body>
diff --git a/testing/web-platform/tests/css/mediaqueries/dynamic-range.html b/testing/web-platform/tests/css/mediaqueries/dynamic-range.html
new file mode 100644
index 0000000000..babe1b9f0d
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/dynamic-range.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<link rel="help" title="6.5 dynamic-range" href="https://www.w3.org/TR/mediaqueries-5/#dynamic-range">
+<script type="text/javascript" src="/resources/testharness.js"></script>
+<script type="text/javascript" src="/resources/testharnessreport.js"></script>
+<script type="text/javascript" src="resources/matchmedia-utils.js"></script>
+
+<script>
+query_should_be_known("(dynamic-range: standard)");
+query_should_be_known("(dynamic-range: high)");
+query_should_be_known("(video-dynamic-range: standard)");
+query_should_be_known("(video-dynamic-range: high)");
+
+query_should_be_unknown("(dynamic-range)");
+query_should_be_unknown("(dynamic-range: 0)");
+query_should_be_unknown("(dynamic-range: 10px)");
+query_should_be_unknown("(dynamic-range: invalid)");
+query_should_be_unknown("(video-dynamic-range)");
+query_should_be_unknown("(video-dynamic-range: 0)");
+query_should_be_unknown("(video-dynamic-range: 10px)");
+query_should_be_unknown("(video-dynamic-range: invalid)");
+
+test(() => {
+ let match_standard = window.matchMedia("(dynamic-range: standard)");
+ assert_true(match_standard.matches);
+}, "Check that dynamic-range always matches 'standard'");
+
+test(() => {
+ let match_standard = window.matchMedia("(video-dynamic-range: standard)");
+ assert_true(match_standard.matches);
+}, "Check that video-dynamic-range always matches 'standard'");
+
+test(() => {
+ let match_invalid = window.matchMedia("(video-dynamic-range: invalid)");
+ assert_false(match_invalid.matches);
+}, "Check that video-dynamic-range is not 'invalid'");
+</script>
diff --git a/testing/web-platform/tests/css/mediaqueries/forced-colors.html b/testing/web-platform/tests/css/mediaqueries/forced-colors.html
new file mode 100644
index 0000000000..ac917c916f
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/forced-colors.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/mediaqueries-5/#forced-colors" />
+<script type="text/javascript" src="/resources/testharness.js"></script>
+<script type="text/javascript" src="/resources/testharnessreport.js"></script>
+
+<script type="text/javascript" src="resources/matchmedia-utils.js"></script>
+<script>
+query_should_be_known("(forced-colors)");
+query_should_be_known("(forced-colors: none)");
+query_should_be_known("(forced-colors: active)");
+
+query_should_be_unknown("(forced-colors: 0)");
+query_should_be_unknown("(forced-colors: no-preference)");
+query_should_be_unknown("(forced-colors: 10px)");
+query_should_be_unknown("(forced-colors: active 0)");
+query_should_be_unknown("(forced-colors: none active)");
+query_should_be_unknown("(forced-colors: active/none)");
+
+test(() => {
+ let booleanContext = window.matchMedia("(forced-colors)");
+ let none = window.matchMedia("(forced-colors: none)");
+ assert_equals(booleanContext.matches, !none.matches);
+}, "Check that none evaluates to false in the boolean context");
+</script>
diff --git a/testing/web-platform/tests/css/mediaqueries/media-queries-001.xht b/testing/web-platform/tests/css/mediaqueries/media-queries-001.xht
new file mode 100644
index 0000000000..ae8736e9d4
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/media-queries-001.xht
@@ -0,0 +1,21 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <title>Basic media queries test</title>
+ <link rel="author" title="Ian Hickson" href="mailto:ian@hixie.ch"/>
+ <link rel="alternate" href="http://www.hixie.ch/tests/adhoc/css/media/queries/001.html"/>
+ <link rel="help" href="https://www.w3.org/TR/css3-mediaqueries/#media0"/>
+ <style type="text/css"><![CDATA[
+ @media only screen {
+ .a, .b { color: green; }
+ }
+ @media not only screen {
+ .b { color: red; }
+ }
+ ]]></style>
+ </head>
+ <body>
+ <p class="a"> This line should be green. </p>
+ <p class="b"> This line should be green. </p>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/css/mediaqueries/media-queries-002.xht b/testing/web-platform/tests/css/mediaqueries/media-queries-002.xht
new file mode 100644
index 0000000000..756600a6ad
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/media-queries-002.xht
@@ -0,0 +1,19 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <title>The 'width' media feature (for visual devices with desktop viewport widths)</title>
+ <link rel="author" title="Ian Hickson" href="mailto:ian@hixie.ch"/>
+ <link rel="alternate" href="http://www.hixie.ch/tests/adhoc/css/media/queries/002.html"/>
+ <link rel="help" href="https://www.w3.org/TR/css3-mediaqueries/#width"/>
+ <style type="text/css"><![CDATA[
+ @media screen and (width) { .a { color: green; } }
+ @media screen and (min-width: 1em) { .b { color: green; } }
+ @media screen and (max-width: 1000000em) { .c { color: green; } }
+ ]]></style>
+ </head>
+ <body>
+ <p class="a"> This line should be green. </p>
+ <p class="b"> This line should be green. </p>
+ <p class="c"> This line should be green. </p>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/css/mediaqueries/media-queries-003.xht b/testing/web-platform/tests/css/mediaqueries/media-queries-003.xht
new file mode 100644
index 0000000000..85c285acad
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/media-queries-003.xht
@@ -0,0 +1,19 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <title>The 'color' media feature (for color devices with bit depth less than 4096 bits per pixel)</title>
+ <link rel="author" title="Ian Hickson" href="mailto:ian@hixie.ch"/>
+ <link rel="alternate" href="http://www.hixie.ch/tests/adhoc/css/media/queries/003.html"/>
+ <link rel="help" href="https://www.w3.org/TR/css3-mediaqueries/#color"/>
+ <style type="text/css"><![CDATA[
+ @media screen and (color) { .a { color: green; } }
+ @media screen and (min-color: 1) { .b { color: green; } }
+ @media screen and (max-color: 4096) { .c { color: green; } }
+ ]]></style>
+ </head>
+ <body>
+ <p class="a"> This line should be green. </p>
+ <p class="b"> This line should be green. </p>
+ <p class="c"> This line should be green. </p>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/css/mediaqueries/media-query-matches-in-iframe.html b/testing/web-platform/tests/css/mediaqueries/media-query-matches-in-iframe.html
new file mode 100644
index 0000000000..5828936732
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/media-query-matches-in-iframe.html
@@ -0,0 +1,104 @@
+<!DOCTYPE html>
+<html>
+<body>
+<link rel="help" href="https://drafts.csswg.org/mediaqueries-4/#mf-dimensions">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+
+async function createFrameAndUpdateLayout(test) {
+ const iframe = await new Promise((resolve) => {
+ const iframe = document.createElement('iframe');
+ iframe.style.width = '100px';
+ iframe.style.height = '100px';
+ iframe.onload = () => resolve(iframe);
+ document.body.appendChild(iframe);
+ test.add_cleanup(() => iframe.remove());
+ });
+ iframe.contentDocument.body.innerHTML = '<span>some content</span>';
+ window.preventOptimization1 = iframe.getBoundingClientRect();
+ window.preventOptimization2 = iframe.contentDocument.querySelector('span').getBoundingClientRect();
+ return iframe;
+}
+
+for (const query of ['(max-width: 150px)', '(width: 100px)', '(orientation: portrait)', '(aspect-ratio: 1/1)', '(max-aspect-ratio: 4/3)']) {
+ promise_test(async function () {
+ const iframe = await createFrameAndUpdateLayout(this);
+ const mediaQuery = iframe.contentWindow.matchMedia(query);
+ assert_true(mediaQuery.matches);
+ iframe.style.width = '200px';
+ assert_false(mediaQuery.matches);
+ }, `matchMedia('${query}').matches should update immediately`);
+}
+
+for (const query of ['(height: 100px)', '(max-height: 150px)', '(min-aspect-ratio: 3/4)']) {
+ promise_test(async function () {
+ const iframe = await createFrameAndUpdateLayout(this);
+ const mediaQuery = iframe.contentWindow.matchMedia(query);
+ assert_true(mediaQuery.matches);
+ iframe.style.height = '200px';
+ assert_false(mediaQuery.matches);
+ }, `matchMedia('${query}').matches should update immediately`);
+}
+
+for (const query of ['(min-height: 150px)', '(aspect-ratio: 1/2)']) {
+ promise_test(async function () {
+ const iframe = await createFrameAndUpdateLayout(this);
+ const mediaQuery = iframe.contentWindow.matchMedia(query);
+ assert_false(mediaQuery.matches);
+ iframe.style.height = '200px';
+ assert_true(mediaQuery.matches);
+ }, `matchMedia('${query}').matches should update immediately`);
+}
+
+for (const query of ['(min-width: 150px)', '(min-aspect-ratio: 4/3)']) {
+ promise_test(async function () {
+ const iframe = await createFrameAndUpdateLayout(this);
+ const mediaQuery = iframe.contentWindow.matchMedia(query);
+ assert_false(mediaQuery.matches);
+ iframe.style.width = '200px';
+ assert_true(mediaQuery.matches);
+ }, `matchMedia('${query}').matches should update immediately`);
+}
+
+for (const query of ['(max-width: 150px)', '(width: 100px)', '(orientation: portrait)', '(aspect-ratio: 1/1)', '(max-aspect-ratio: 4/3)']) {
+ promise_test(async function () {
+ const iframe = await createFrameAndUpdateLayout(this);
+ const mediaQuery = iframe.contentWindow.matchMedia(query);
+ let changes = 0;
+ mediaQuery.addEventListener('change', () => ++changes);
+ assert_true(mediaQuery.matches);
+ assert_equals(changes, 0);
+ iframe.style.width = '200px';
+ assert_false(mediaQuery.matches);
+ assert_equals(changes, 0);
+ await new Promise(requestAnimationFrame);
+ assert_false(mediaQuery.matches);
+ assert_equals(changes, 1);
+ }, `matchMedia('${query}') should not receive a change event until update the rendering step of HTML5 event loop`);
+}
+
+for (const query of ['(max-width: 150px)', '(width: 100px)', '(orientation: portrait)', '(aspect-ratio: 1/1)', '(max-aspect-ratio: 4/3)']) {
+ promise_test(async function () {
+ const iframe = await createFrameAndUpdateLayout(this);
+ const mediaQuery = iframe.contentWindow.matchMedia(query);
+ const events = [];
+ iframe.contentWindow.addEventListener('resize', () => {
+ assert_array_equals(events, []);
+ events.push('resize');
+ });
+ mediaQuery.addEventListener('change', () => events.push('change'));
+ assert_true(mediaQuery.matches);
+ assert_array_equals(events, []);
+ iframe.style.width = '200px';
+ assert_false(mediaQuery.matches);
+ assert_array_equals(events, []);
+ await new Promise(requestAnimationFrame);
+ assert_false(mediaQuery.matches);
+ assert_array_equals(events, ['resize', 'change']);
+ }, `matchMedia('${query}') should receive a change event after resize event on the window but before a requestAnimationFrame callback is called`);
+}
+
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/mediaqueries/min-width-001.xht b/testing/web-platform/tests/css/mediaqueries/min-width-001.xht
new file mode 100644
index 0000000000..9dc01c68d8
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/min-width-001.xht
@@ -0,0 +1,29 @@
+<!DOCTYPE html SYSTEM "about:legacy-compat">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+ <meta charset="utf-8" />
+ <title>CSS Media Queries Test: min-width length value approximation</title>
+ <link rel="author" title="Chris Rebert" href="http://chrisrebert.com" />
+ <link rel="help" href="http://www.w3.org/TR/css3-mediaqueries/#width" />
+ <link rel="help" href="http://www.w3.org/TR/mediaqueries-4/#width" />
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#length-value" />
+ <link rel="match" href="../reference/ref-filled-green-100px-square.xht" />
+ <meta name="assert" content="min-width length values that are too large to be supported must be clamped, rounded to infinity, or approximated, but not overflowed to a small or negative value." />
+ <style>
+div {
+ width: 100px;
+ height: 100px;
+ background-color: green;
+}
+@media (min-width: 9999999999px) {
+ div {
+ background-color: red;
+ }
+}
+ </style>
+</head>
+<body>
+ <p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+ <div></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/mediaqueries/min-width-tables-001.html b/testing/web-platform/tests/css/mediaqueries/min-width-tables-001.html
new file mode 100644
index 0000000000..dc430ccb18
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/min-width-tables-001.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+ <meta charset="utf-8">
+ <title>CSS Test: Table Layout and Viewport Resizing</title>
+ <link rel="author" title="Chris Rebert" href="http://chrisrebert.com">
+ <link rel="help" href="https://drafts.csswg.org/css2/tables.html#auto-table-layout">
+ <link rel="help" href="https://drafts.csswg.org/mediaqueries-3/#width">
+ <link rel="help" href="https://drafts.csswg.org/mediaqueries-4/#width">
+ <link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+ <meta name="flags" content="dom">
+ <meta name="assert" content="Resizing a page which toggles the `display` of elements between `block` and `table-cell` based on the viewport width should not cause unnecessary wrapping of the table.">
+ <style>
+iframe {
+ border: 0;
+}
+ </style>
+</head>
+<body>
+ <p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+ <iframe id="toy" width="100" height="300" src="support/min-width-tables-001-iframe.html"></iframe>
+ <!-- See min-width-tables-001-iframe.html for the derivation of the 100px value -->
+ <!-- We use 300px height so the incorrect stacking is visible in failure cases -->
+ <!-- This test is not about iframes specifically. It's just that resizing an iframe is more reliable than resizing the window, given browser security restrictions. -->
+ <script>
+ window.addEventListener('load', function () {
+ var PAINT_MS = 250;/* Assume the browser takes about this long to layout/paint this whole page */
+ var iframe = document.getElementById('toy');
+ window.setTimeout(function () {
+ iframe.width = 64;/* <100px ; toggle media query off */
+ window.setTimeout(function () {
+ iframe.width = 100;/* >=100px ; toggle media query on; back to initial width */
+ // Take the reftest screenshot after the last relayout/repaint finishes
+ window.setTimeout(function () {
+ document.documentElement.className = '';
+ }, PAINT_MS);
+ }, PAINT_MS);
+ }, PAINT_MS);
+ }, false);
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/mediaqueries/mq-calc-001.html b/testing/web-platform/tests/css/mediaqueries/mq-calc-001.html
new file mode 100644
index 0000000000..a4e4d4d9c6
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/mq-calc-001.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Test: support for calc in Media Queries</title>
+ <link rel="author" title="Florian Rivoal" href="http://florian.rivoal.net/">
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#calc-notation">
+ <link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+ <meta name="assert" content="calc can be used in Media Queries">
+ <style>
+ div {
+ width: 100px;
+ height: 100px;
+ background-color: red;
+ }
+ @media (min-width: calc(1px - 1px)){
+ div { background-color: green; }
+ }
+ </style>
+ </head>
+ <body>
+ <p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+ <div></div>
+ </body>
+</html>
+
diff --git a/testing/web-platform/tests/css/mediaqueries/mq-calc-002.html b/testing/web-platform/tests/css/mediaqueries/mq-calc-002.html
new file mode 100644
index 0000000000..9c04b181d7
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/mq-calc-002.html
@@ -0,0 +1,36 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Test: evaluation of em in calc in Media Queries</title>
+ <link rel="author" title="Florian Rivoal" href="http://florian.rivoal.net/">
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#calc-notation">
+ <link rel="help" href="http://www.w3.org/TR/css3-mediaqueries/#units">
+ <link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+ <meta name="assert" content="The size in pixels of the 'em' unit used in calc inside a media query does not depend on declarations and use the initial value.">
+ <style>
+ :root { font-size: 30000px; }
+ p { font-size: 16px; }
+ div {
+ width: 100px;
+ height: 100px;
+ background-color: red;
+ }
+ @media (min-width: calc(1em)){
+ div { background-color: green; }
+ }
+ </style>
+ </head>
+ <body>
+ <p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+ <div></div>
+ <script>
+ document.body.offsetTop;
+ </script>
+ <style>
+ @media (min-width: calc(1em)){
+ div { background-color: green; }
+ }
+ </style>
+ </body>
+</html>
+
diff --git a/testing/web-platform/tests/css/mediaqueries/mq-calc-003.html b/testing/web-platform/tests/css/mediaqueries/mq-calc-003.html
new file mode 100644
index 0000000000..a60adcfb5c
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/mq-calc-003.html
@@ -0,0 +1,36 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Test: evaluation of ex in calc in Media Queries</title>
+ <link rel="author" title="Florian Rivoal" href="http://florian.rivoal.net/">
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#calc-notation">
+ <link rel="help" href="http://www.w3.org/TR/css3-mediaqueries/#units">
+ <link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+ <meta name="assert" content="The size in pixels of the 'ex' unit used in calc inside a media query does not depend on declarations and use the initial value.">
+ <style>
+ :root { font-size: 30000px; }
+ p { font-size: 16px; }
+ div {
+ width: 100px;
+ height: 100px;
+ background-color: red;
+ }
+ @media (min-width: calc(1ex)){
+ div { background-color: green; }
+ }
+ </style>
+ </head>
+ <body>
+ <p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+ <div></div>
+ <script>
+ document.body.offsetTop;
+ </script>
+ <style>
+ @media (min-width: calc(1ex)){
+ div { background-color: green; }
+ }
+ </style>
+ </body>
+</html>
+
diff --git a/testing/web-platform/tests/css/mediaqueries/mq-calc-004.html b/testing/web-platform/tests/css/mediaqueries/mq-calc-004.html
new file mode 100644
index 0000000000..428a34c82e
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/mq-calc-004.html
@@ -0,0 +1,33 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Test: evaluation of ch in calc in Media Queries</title>
+ <link rel="author" title="Florian Rivoal" href="http://florian.rivoal.net/">
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#calc-notation">
+ <link rel="help" href="http://www.w3.org/TR/css3-mediaqueries/#units">
+ <link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+ <meta name="assert" content="The size in pixels of the 'ch' unit used in calc inside a media query does not depend on declarations and use the initial value.">
+ <style>
+ :root { font-size: 30000px; }
+ p { font-size: 16px; }
+ div {
+ width: 100px;
+ height: 100px;
+ background-color: red;
+ }
+ </style>
+ </head>
+ <body>
+ <p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+ <div></div>
+ <script>
+ document.body.offsetTop;
+ </script>
+ <style>
+ @media (min-width: calc(1ch)){
+ div { background-color: green; }
+ }
+ </style>
+ </body>
+</html>
+
diff --git a/testing/web-platform/tests/css/mediaqueries/mq-calc-005.html b/testing/web-platform/tests/css/mediaqueries/mq-calc-005.html
new file mode 100644
index 0000000000..dc33f1e85d
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/mq-calc-005.html
@@ -0,0 +1,33 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Test: evaluation of rem in calc in Media Queries</title>
+ <link rel="author" title="Florian Rivoal" href="http://florian.rivoal.net/">
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#calc-notation">
+ <link rel="help" href="http://www.w3.org/TR/css3-mediaqueries/#units">
+ <link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+ <meta name="assert" content="The size in pixels of the 'rem' unit used in calc inside a media query does not depend on declarations and use the initial value.">
+ <style>
+ :root { font-size: 30000px; }
+ p { font-size: 16px; }
+ div {
+ width: 100px;
+ height: 100px;
+ background-color: red;
+ }
+ </style>
+ </head>
+ <body>
+ <p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+ <div></div>
+ <script>
+ document.body.offsetTop;
+ </script>
+ <style>
+ @media (min-width: calc(1rem)){
+ div { background-color: green; }
+ }
+ </style>
+ </body>
+</html>
+
diff --git a/testing/web-platform/tests/css/mediaqueries/mq-calc-006.html b/testing/web-platform/tests/css/mediaqueries/mq-calc-006.html
new file mode 100644
index 0000000000..8f3ac37b05
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/mq-calc-006.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<link rel="author" title="Xiaocheng Hu" href="xiaochengh@chromium.org">
+<link rel="help" href="http://www.w3.org/TR/css3-values/#calc-notation">
+<link rel="help" href="https://www.w3.org/TR/css3-mediaqueries/#units">
+<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+<meta name="assert" content="The 'in' unit used in calc is not mistaken as 'px'.">
+<style>
+p { font-size: 16px; }
+#target {
+ width: 100px;
+ height: 100px;
+ background-color: green;
+}
+@media (min-width: calc(100in)) {
+ /* Should not be selected */
+ #target { background-color: red }
+}
+</style>
+<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+<div id=target></div>
diff --git a/testing/web-platform/tests/css/mediaqueries/mq-calc-007.html b/testing/web-platform/tests/css/mediaqueries/mq-calc-007.html
new file mode 100644
index 0000000000..5f846ca083
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/mq-calc-007.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<title>Test: evaluation of mixed-unit calc in Media Queries</title>
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#calc-func">
+<link rel="help" href="https://drafts.csswg.org/mediaqueries-4/#units">
+<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+<style>
+ :root { font-size: 30000px; }
+ p { font-size: 16px; }
+ div {
+ width: 100px;
+ height: 100px;
+ background-color: red;
+ }
+ @media (min-width: calc(1px + 1rem)) {
+ div { background-color: green; }
+ }
+</style>
+<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+<div>
+</div>
diff --git a/testing/web-platform/tests/css/mediaqueries/mq-calc-008.html b/testing/web-platform/tests/css/mediaqueries/mq-calc-008.html
new file mode 100644
index 0000000000..e9a6413b5b
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/mq-calc-008.html
@@ -0,0 +1,28 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Test: support for calc in Media Queries</title>
+ <link rel="author" title="Romain Menke" href="https://github.com/romainmenke">
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#calc-notation">
+ <link rel="help" href="https://drafts.csswg.org/css-values-4/#ratios">
+ <link rel="help" href="https://github.com/w3c/csswg-drafts/issues/3757">
+ <link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+ <meta name="assert" content="calc can be used in Media Queries">
+ <style>
+ div {
+ background-color: red;
+ height: 100px;
+ width: 100px;
+ }
+ @media screen and (min-aspect-ratio: calc(59/79)) {
+ div {
+ background-color: green;
+ }
+ }
+ </style>
+ </head>
+ <body>
+ <p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+ <div></div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/css/mediaqueries/mq-case-insensitive-001.html b/testing/web-platform/tests/css/mediaqueries/mq-case-insensitive-001.html
new file mode 100644
index 0000000000..c851662343
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/mq-case-insensitive-001.html
@@ -0,0 +1,45 @@
+<!doctype html>
+<meta charset="utf-8">
+<html>
+ <head>
+ <title>Test: ASCII-case-insensitivity of media queries</title>
+ <link rel="author" title="Gerald Squelart" href="mailto:gerald@mozilla.com">
+ <link rel="help" href="http://www.w3.org/TR/CSS21/syndata.html#characters">
+ <link rel="help" href="https://drafts.csswg.org/mediaqueries-4/#mq-syntax">
+ <link rel="help" href="https://drafts.csswg.org/css-syntax/#rule-defs">
+ <link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+ <style type="text/css">
+
+ div {
+ width: 100px;
+ height: 100px;
+ }
+
+ @media all and (height) and (min-width:0) and (orientation:landscape) {
+ div { background-color: red; }
+ }
+ @media all and (height) and (min-width:0) and (orientation:portrait) {
+ div { background-color: red; }
+ }
+
+ @MeDIa aLL and (Height) and (mIN-Width:0cM) and (orienTAtion:LandScape) {
+ div { background-color: green; }
+ }
+ @MeDIa All and (heiGHt) and (Min-widtH:0MM) and (Orientation:porTrait) {
+ div { background-color: green; }
+ }
+
+ /* In some languages Non-ASCII 'İ' (Latin capital I with dot above) may be
+ lowercased to ASCII 'i'; This would make "heİght" compare the same as
+ "height", which would be incorrect. */
+ @media all and (heİght) {
+ div { background-color: red; }
+ }
+
+ </style>
+ </head>
+ <body>
+ <p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+ <div></div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/css/mediaqueries/mq-deprecated-001.html b/testing/web-platform/tests/css/mediaqueries/mq-deprecated-001.html
new file mode 100644
index 0000000000..cb02c3f316
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/mq-deprecated-001.html
@@ -0,0 +1,31 @@
+<!doctype html>
+<title>Test: deprecated media types</title>
+<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/">
+<link rel="help" href="https://drafts.csswg.org/mediaqueries-4/#media-types">
+<link rel="help" href="https://drafts.csswg.org/mediaqueries-4/#ref-for-media-type%E2%91%A0%E2%91%A6">
+<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+<meta name="assert" content="deprecated media types must not match">
+<style>
+div {
+ width: 100px;
+ height: 100px;
+ background-color: green;
+}
+
+@media
+ tty,
+ tv,
+ projection,
+ handheld,
+ braille,
+ embossed,
+ aural,
+ speech
+{
+ div { background-color: red; }
+}
+</style>
+
+<p>Test passes if there is a filled green square and <strong>no red</strong>.
+
+<div></div>
diff --git a/testing/web-platform/tests/css/mediaqueries/mq-dynamic-empty-children.html b/testing/web-platform/tests/css/mediaqueries/mq-dynamic-empty-children.html
new file mode 100644
index 0000000000..3edda870ef
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/mq-dynamic-empty-children.html
@@ -0,0 +1,40 @@
+<!doctype html>
+<title>Dynamic evaluation of media queries works fine in presence of empty media rule</title>
+<link rel="author" href="mailto:emilio@crisal.io" title="Emilio Cobos Álvarez">
+<link rel="author" href="https://mozilla.org" title="Mozilla">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1669600">
+<link rel="help" href="https://drafts.csswg.org/mediaqueries-4/">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<iframe width=500 height=300 frameborder=0></iframe>
+<script>
+let iframe = document.querySelector("iframe");
+promise_test(async function (t) {
+ await new Promise(resolve => {
+ window.addEventListener("load", resolve);
+ });
+ let frameLoaded = new Promise(resolve => {
+ iframe.addEventListener("load", resolve);
+ });
+ iframe.srcdoc = `
+ <style>
+ :root { background-color: red; }
+ /* This one should never apply */
+ @media (min-width: 1500px) {}
+ /* This one should change and start matching */
+ @media (max-width: 400px) {
+ :root { background-color: lime; }
+ }
+ </style>
+ `;
+ await frameLoaded;
+
+ function getColor() {
+ return iframe.contentWindow.getComputedStyle(iframe.contentDocument.documentElement).backgroundColor;
+ }
+
+ assert_equals(getColor(), "rgb(255, 0, 0)", "Should start red");
+ iframe.width = 400;
+ assert_equals(getColor(), "rgb(0, 255, 0)", "Should turn green");
+});
+</script>
diff --git a/testing/web-platform/tests/css/mediaqueries/mq-gamut-001.html b/testing/web-platform/tests/css/mediaqueries/mq-gamut-001.html
new file mode 100644
index 0000000000..9e98236f09
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/mq-gamut-001.html
@@ -0,0 +1,23 @@
+<!doctype html>
+<title>Test: srgb color gamut</title>
+<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/">
+<link rel="help" href="https://www.w3.org/TR/mediaqueries-4/#color-gamut">
+<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+<meta name="assert" content="the srgb color-gamut is syntactically supported">
+<style>
+div {
+ width: 100px;
+ height: 100px;
+ background-color: red;
+}
+
+@media (color-gamut: srgb),
+ not (color-gamut: srgb)
+{
+ div { background-color: green; }
+}
+</style>
+
+<p>Test passes if there is a filled green square and <strong>no red</strong>.
+
+<div></div>
diff --git a/testing/web-platform/tests/css/mediaqueries/mq-gamut-002.html b/testing/web-platform/tests/css/mediaqueries/mq-gamut-002.html
new file mode 100644
index 0000000000..abc3ac48a4
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/mq-gamut-002.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<title>Test: p3 color gamut</title>
+<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/">
+<link rel="help" href="https://www.w3.org/TR/mediaqueries-4/#color-gamut">
+<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/276">
+<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+<meta name="assert" content="the p3 color-gamut is syntactically supported">
+<style>
+div {
+ width: 100px;
+ height: 100px;
+ background-color: red;
+}
+
+@media (color-gamut: p3),
+ not (color-gamut: p3)
+{
+ div { background-color: green; }
+}
+</style>
+
+<p>Test passes if there is a filled green square and <strong>no red</strong>.
+
+<div></div>
diff --git a/testing/web-platform/tests/css/mediaqueries/mq-gamut-003.html b/testing/web-platform/tests/css/mediaqueries/mq-gamut-003.html
new file mode 100644
index 0000000000..c0980a93ca
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/mq-gamut-003.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<title>Test: p3 color gamut (old name)</title>
+<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/">
+<link rel="help" href="https://www.w3.org/TR/mediaqueries-4/#color-gamut">
+<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/4535">
+<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/276">
+<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+<meta name="assert" content="the dci-p3 (old name for p3) color-gamut is not syntactically supported">
+<style>
+div {
+ width: 100px;
+ height: 100px;
+ background-color: green;
+}
+
+@media (color-gamut: dci-p3),
+ not (color-gamut: dci-p3)
+{
+ div { background-color: red; }
+}
+</style>
+
+<p>Test passes if there is a filled green square and <strong>no red</strong>.
+
+<div></div>
diff --git a/testing/web-platform/tests/css/mediaqueries/mq-gamut-004.html b/testing/web-platform/tests/css/mediaqueries/mq-gamut-004.html
new file mode 100644
index 0000000000..3cc1c757bf
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/mq-gamut-004.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<title>Test: rec2020 color gamut</title>
+<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/">
+<link rel="help" href="https://www.w3.org/TR/mediaqueries-4/#color-gamut">
+<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/4535">
+<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+<meta name="assert" content="the rec2020 color-gamut is syntactically supported">
+<style>
+div {
+ width: 100px;
+ height: 100px;
+ background-color: red;
+}
+
+@media (color-gamut: rec2020),
+ not (color-gamut: rec2020)
+{
+ div { background-color: green; }
+}
+</style>
+
+<p>Test passes if there is a filled green square and <strong>no red</strong>.
+
+<div></div>
diff --git a/testing/web-platform/tests/css/mediaqueries/mq-gamut-005.html b/testing/web-platform/tests/css/mediaqueries/mq-gamut-005.html
new file mode 100644
index 0000000000..aa5db52a77
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/mq-gamut-005.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<title>Test: rec2020 color gamut(old name)</title>
+<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/">
+<link rel="help" href="https://www.w3.org/TR/mediaqueries-4/#color-gamut">
+<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/4535">
+<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+<meta name="assert" content="the rec-2020 (old name for rec2020) color-gamut is not syntactically supported">
+<style>
+div {
+ width: 100px;
+ height: 100px;
+ background-color: green;
+}
+
+@media (color-gamut: rec-2020),
+ not (color-gamut: rec-2020)
+{
+ div { background-color: red; }
+}
+</style>
+
+<p>Test passes if there is a filled green square and <strong>no red</strong>.
+
+<div></div>
diff --git a/testing/web-platform/tests/css/mediaqueries/mq-invalid-media-type-001.html b/testing/web-platform/tests/css/mediaqueries/mq-invalid-media-type-001.html
new file mode 100644
index 0000000000..a88f18173e
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/mq-invalid-media-type-001.html
@@ -0,0 +1,31 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Test: syntax error handling in Media Queries</title>
+ <link rel="author" title="Florian Rivoal" href="http://florian.rivoal.net/">
+ <link rel="help" href="https://drafts.csswg.org/mediaqueries4/#error-handling">
+ <link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+ <meta name="assert" content="'and' is an invalid media type">
+ <meta name="flags" content="invalid">
+ <style>
+ div {
+ width: 100px;
+ height: 100px;
+ }
+ @media all {
+ div { background-color: green; }
+ }
+ @media not and {
+ div { background-color: red; }
+ }
+ @media and {
+ div { background-color: red; }
+ }
+ </style>
+ </head>
+ <body>
+ <p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+ <div></div>
+ </body>
+</html>
+
diff --git a/testing/web-platform/tests/css/mediaqueries/mq-invalid-media-type-002.html b/testing/web-platform/tests/css/mediaqueries/mq-invalid-media-type-002.html
new file mode 100644
index 0000000000..763a7f2920
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/mq-invalid-media-type-002.html
@@ -0,0 +1,31 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Test: syntax error handling in Media Queries</title>
+ <link rel="author" title="Florian Rivoal" href="http://florian.rivoal.net/">
+ <link rel="help" href="https://drafts.csswg.org/mediaqueries4/#error-handling">
+ <link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+ <meta name="assert" content="'or' is an invalid media type">
+ <meta name="flags" content="invalid">
+ <style>
+ div {
+ width: 100px;
+ height: 100px;
+ }
+ @media all {
+ div { background-color: green; }
+ }
+ @media not or {
+ div { background-color: red; }
+ }
+ @media or {
+ div { background-color: red; }
+ }
+ </style>
+ </head>
+ <body>
+ <p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+ <div></div>
+ </body>
+</html>
+
diff --git a/testing/web-platform/tests/css/mediaqueries/mq-invalid-media-type-003.html b/testing/web-platform/tests/css/mediaqueries/mq-invalid-media-type-003.html
new file mode 100644
index 0000000000..acc524ca98
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/mq-invalid-media-type-003.html
@@ -0,0 +1,31 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Test: syntax error handling in Media Queries</title>
+ <link rel="author" title="Florian Rivoal" href="http://florian.rivoal.net/">
+ <link rel="help" href="https://drafts.csswg.org/mediaqueries4/#error-handling">
+ <link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+ <meta name="assert" content="'not' is an invalid media type">
+ <meta name="flags" content="invalid">
+ <style>
+ div {
+ width: 100px;
+ height: 100px;
+ }
+ @media all {
+ div { background-color: green; }
+ }
+ @media not not {
+ div { background-color: red; }
+ }
+ @media not {
+ div { background-color: red; }
+ }
+ </style>
+ </head>
+ <body>
+ <p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+ <div></div>
+ </body>
+</html>
+
diff --git a/testing/web-platform/tests/css/mediaqueries/mq-invalid-media-type-004.html b/testing/web-platform/tests/css/mediaqueries/mq-invalid-media-type-004.html
new file mode 100644
index 0000000000..689c8d1a78
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/mq-invalid-media-type-004.html
@@ -0,0 +1,31 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Test: syntax error handling in Media Queries</title>
+ <link rel="author" title="Florian Rivoal" href="http://florian.rivoal.net/">
+ <link rel="help" href="https://drafts.csswg.org/mediaqueries4/#error-handling">
+ <link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+ <meta name="assert" content="'only' is an invalid media type">
+ <meta name="flags" content="invalid">
+ <style>
+ div {
+ width: 100px;
+ height: 100px;
+ }
+ @media all {
+ div { background-color: green; }
+ }
+ @media not only {
+ div { background-color: red; }
+ }
+ @media only {
+ div { background-color: red; }
+ }
+ </style>
+ </head>
+ <body>
+ <p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+ <div></div>
+ </body>
+</html>
+
diff --git a/testing/web-platform/tests/css/mediaqueries/mq-invalid-media-type-005.html b/testing/web-platform/tests/css/mediaqueries/mq-invalid-media-type-005.html
new file mode 100644
index 0000000000..3e25a248b3
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/mq-invalid-media-type-005.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<html>
+<meta charset="utf-8">
+<title>Mediaqueries-3 test: parsing hanging-punctuation with invalid values</title>
+<link rel="help" href="https://www.w3.org/TR/css3-mediaqueries/#error-handling">
+<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/">
+<meta name="flags" content="invalid">
+<meta name="assert" content="media types ''not'', ''and'', ''only'' and ''or'' must not be treated as unknown media types, but rather trigger the malformed query clause.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+ @media not and {
+ div { background-color: red; }
+ }
+ @media and {
+ div { background-color: red; }
+ }
+ @media not or {
+ div { background-color: red; }
+ }
+ @media or {
+ div { background-color: red; }
+ }
+ @media not not {
+ div { background-color: red; }
+ }
+ @media not {
+ div { background-color: red; }
+ }
+ @media not only {
+ div { background-color: red; }
+ }
+ @media only {
+ div { background-color: red; }
+ }
+</style>
+<script>
+var queries = document.styleSheets[0].cssRules;
+test(() => {
+ for (const query of queries) {
+ assert_equals(query.conditionText, "not all");
+ }
+ assert_equals(queries.length, 8, "invalid rules must be treated as 'not all', not dropped");
+ }, "syntactical MQ keywords used as media types are a syntax error");
+</script>
diff --git a/testing/web-platform/tests/css/mediaqueries/mq-invalid-media-type-layer-001.html b/testing/web-platform/tests/css/mediaqueries/mq-invalid-media-type-layer-001.html
new file mode 100644
index 0000000000..ef3fc48ca8
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/mq-invalid-media-type-layer-001.html
@@ -0,0 +1,31 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Test: syntax error handling in Media Queries</title>
+ <link rel="author" title="Florian Rivoal" href="http://florian.rivoal.net/">
+ <link rel="help" href="https://drafts.csswg.org/mediaqueries4/#error-handling">
+ <link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+ <meta name="assert" content="'layer' is an invalid media type">
+ <meta name="flags" content="invalid">
+ <style>
+ div {
+ width: 100px;
+ height: 100px;
+ }
+ @media all {
+ div { background-color: green; }
+ }
+ @media not layer {
+ div { background-color: red; }
+ }
+ @media layer {
+ div { background-color: red; }
+ }
+ </style>
+ </head>
+ <body>
+ <p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+ <div></div>
+ </body>
+</html>
+
diff --git a/testing/web-platform/tests/css/mediaqueries/mq-invalid-media-type-layer-002.html b/testing/web-platform/tests/css/mediaqueries/mq-invalid-media-type-layer-002.html
new file mode 100644
index 0000000000..3f8b719bfa
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/mq-invalid-media-type-layer-002.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+<meta charset="utf-8">
+<title>Mediaqueries-3 test: parsing hanging-punctuation with invalid values</title>
+<link rel="help" href="https://www.w3.org/TR/css3-mediaqueries/#error-handling">
+<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/">
+<meta name="flags" content="invalid">
+<meta name="assert" content="'layer' must not be treated as an unknown media type, but rather trigger the malformed query clause.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+ @media not layer {
+ body { background-color: red; }
+ }
+ @media layer {
+ body { background-color: red; }
+ }
+</style>
+<script>
+var queries = document.styleSheets[0].cssRules;
+test(() => {
+ for (const query of queries) {
+ assert_equals(query.conditionText, "not all");
+ }
+ assert_equals(queries.length, 2, "invalid rules must be treated as 'not all', not dropped");
+ }, "'layer' used as media types is a syntax error");
+</script>
diff --git a/testing/web-platform/tests/css/mediaqueries/mq-negative-range-001.html b/testing/web-platform/tests/css/mediaqueries/mq-negative-range-001.html
new file mode 100644
index 0000000000..f311463877
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/mq-negative-range-001.html
@@ -0,0 +1,39 @@
+<!doctype html>
+<title>Test: false in the negative range</title>
+<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/">
+<link rel="help" href="https://drafts.csswg.org/mediaqueries-4/#mq-syntax">
+<link rel="help" href="https://www.w3.org/TR/mediaqueries-4/#false-in-the-negative-range">
+<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/1454">
+<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+<meta name="assert" content="features that are 'false in the negative range' should still parse with negative values">
+<style>
+div {
+ width: 100px;
+ height: 100px;
+ background-color: red;
+}
+
+@media
+ (min-width: -100px)
+ and
+ (min-height: -100px)
+ and
+ (min-resolution: -1dpi)
+ and
+ (min-color: -10)
+ and
+ (min-color-index: -10)
+ and
+ (min-monochrome: -10)
+ and
+ (min-device-width: -100px)
+ and
+ (min-device-height: -100px)
+{
+ div { background-color: green; }
+}
+</style>
+
+<p>Test passes if there is a filled green square and <strong>no red</strong>.
+
+<div></div>
diff --git a/testing/web-platform/tests/css/mediaqueries/mq-negative-range-002.html b/testing/web-platform/tests/css/mediaqueries/mq-negative-range-002.html
new file mode 100644
index 0000000000..59a58a1d5c
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/mq-negative-range-002.html
@@ -0,0 +1,39 @@
+<!doctype html>
+<title>Test: false in the negative range</title>
+<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/">
+<link rel="help" href="https://drafts.csswg.org/mediaqueries-4/#mq-syntax">
+<link rel="help" href="https://www.w3.org/TR/mediaqueries-4/#false-in-the-negative-range">
+<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/1454">
+<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+<meta name="assert" content="features that are 'false in the negative range' should still parse with negative values">
+<style>
+div {
+ width: 100px;
+ height: 100px;
+ background-color: red;
+}
+
+@media
+ (not (max-width: -100px))
+ and
+ (not (max-height: -100px))
+ and
+ (not (max-resolution: -1dpi))
+ and
+ (not (max-color: -10))
+ and
+ (not (max-color-index: -10))
+ and
+ (not (max-monochrome: -10))
+ and
+ (not (max-device-width: -100px))
+ and
+ (not (max-device-height: -100px))
+{
+ div { background-color: green; }
+}
+</style>
+
+<p>Test passes if there is a filled green square and <strong>no red</strong>.
+
+<div></div>
diff --git a/testing/web-platform/tests/css/mediaqueries/mq-range-001.html b/testing/web-platform/tests/css/mediaqueries/mq-range-001.html
new file mode 100644
index 0000000000..0aacc17564
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/mq-range-001.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<title>Test: invalid range syntax</title>
+<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/">
+<link rel="help" href="https://drafts.csswg.org/mediaqueries-4/#mq-syntax">
+<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/2790">
+<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+<meta name="assert" content="range syntax without operator isn't valid syntax, unlike what some earlier iteration of the spec claimed">
+<style>
+div {
+ width: 100px;
+ height: 100px;
+ background-color: red;
+}
+
+/* if the syntax is accepted, whether (width 500px) is true or not doesn't matter,
+ as the second part of the "or" clause will be true,
+ but if the syntax is rejected, then the whole thing is ignored.
+*/
+@media (width 500px) or (min-width: 0) {
+ div { background-color: green; }
+}
+</style>
+
+<p>Test passes if there is a filled green square and <strong>no red</strong>.
+
+<div></div>
diff --git a/testing/web-platform/tests/css/mediaqueries/mq-unknown-feature-custom-property.html b/testing/web-platform/tests/css/mediaqueries/mq-unknown-feature-custom-property.html
new file mode 100644
index 0000000000..48ad5b4f51
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/mq-unknown-feature-custom-property.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<title>Media Queries Test: Custom property name as media feature name</title>
+<link rel="help" href="https://drafts.csswg.org/mediaqueries-4/#mq-syntax">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style id="media_sheet">
+ @media (--FOO: bar) {}
+</style>
+<script>
+ test(() => {
+ assert_equals(media_sheet.sheet.cssRules[0].conditionText, "(--FOO: bar)")
+ }, "Serialization of <mf-name> : <mf-value> with custom property feature name and ident value");
+</script>
diff --git a/testing/web-platform/tests/css/mediaqueries/navigation-controls.tentative.html b/testing/web-platform/tests/css/mediaqueries/navigation-controls.tentative.html
new file mode 100644
index 0000000000..5be0b78ab8
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/navigation-controls.tentative.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<link rel="help" href="https://github.com/fallaciousreasoning/backbutton-mediaquery/blob/master/explainer.md" />
+<script type="text/javascript" src="/resources/testharness.js"></script>
+<script type="text/javascript" src="/resources/testharnessreport.js"></script>
+<script type="text/javascript" src="resources/matchmedia-utils.js"></script>
+<script>
+ query_should_be_known("(navigation-controls)");
+ query_should_be_known("(navigation-controls: none)");
+ query_should_be_known("(navigation-controls: back-button)");
+ query_should_be_unknown("(navigation-controls: none back-button)");
+ query_should_be_unknown("(navigation-controls: back-button/none)");
+ test(() => {
+ let booleanContext = window.matchMedia("(navigation-controls)");
+ let none = window.matchMedia("(navigation-controls: none)");
+ assert_equals(booleanContext.matches, !none.matches);
+ }, "Check that none evaluates to false in the boolean context");
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/mediaqueries/negation-001.html b/testing/web-platform/tests/css/mediaqueries/negation-001.html
new file mode 100644
index 0000000000..9badf8ee17
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/negation-001.html
@@ -0,0 +1,40 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Test: support for negated conditions in Media Queries</title>
+ <link rel="author" title="Romain Menke" href="https://github.com/romainmenke">
+ <link rel="help" href="https://www.w3.org/TR/mediaqueries-4/#media-conditions">
+ <link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+ <meta name="assert" content="Test passes if negated conditions are correctly evaluated.">
+ <style>
+ div {
+ background-color: red;
+ height: 20px;
+ width: 100px;
+ }
+ @media not print {
+ .test1 { background: green; }
+ }
+ @media not (monochrome) {
+ .test2 { background: green; }
+ }
+ @media (not (monochrome)) {
+ .test3 { background: green; }
+ }
+ @media not (not (color)) {
+ .test4 { background: green; }
+ }
+ @media not ((unknown) or (monochrome)) {
+ .test5 { background: green; }
+ }
+ </style>
+ </head>
+ <body>
+ <p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+ <div class="test1"></div>
+ <div class="test2"></div>
+ <div class="test3"></div>
+ <div class="test4"></div>
+ <div class="test5"></div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/css/mediaqueries/negation-002.html b/testing/web-platform/tests/css/mediaqueries/negation-002.html
new file mode 100644
index 0000000000..ca5fb74dfb
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/negation-002.html
@@ -0,0 +1,44 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Test: It is invalid to mix "and" and "or" and "not" at the same level of a media query.</title>
+ <link rel="author" title="Romain Menke" href="https://github.com/romainmenke">
+ <link rel="help" href="https://www.w3.org/TR/mediaqueries-4/#media-conditions">
+ <link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+ <meta name="assert" content="Test passes if invalid combinations with 'not' do not apply.">
+ <style>
+ div {
+ background-color: red;
+ height: 25px;
+ width: 100px;
+ }
+
+ @media ((color) and (color)) {
+ /* Only green when the browser supports the general syntax */
+ div {
+ background-color: green;
+ }
+ }
+
+ @media (not (monochrome) and (color)) {
+ .test1 { background: red; }
+ }
+ @media (not (monochrome) or (color)) {
+ .test2 { background: red; }
+ }
+ @media ((color) and not (monochrome)) {
+ .test3 { background: red; }
+ }
+ @media ((color) or not (monochrome)) {
+ .test4 { background: red; }
+ }
+ </style>
+ </head>
+ <body>
+ <p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+ <div class="test1"></div>
+ <div class="test2"></div>
+ <div class="test3"></div>
+ <div class="test4"></div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/css/mediaqueries/prefers-color-scheme-svg-image-normal-ref.html b/testing/web-platform/tests/css/mediaqueries/prefers-color-scheme-svg-image-normal-ref.html
new file mode 100644
index 0000000000..ef7fa1b366
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/prefers-color-scheme-svg-image-normal-ref.html
@@ -0,0 +1,23 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>CSS prefers-color-scheme affects SVG images - color-scheme 'normal', no &lt;meta> (reference)</title>
+<style>
+ .background {
+ width: 32px;
+ height: 32px;
+ }
+ #light { display: revert }
+ #dark { display: none }
+ @media (prefers-color-scheme: dark) {
+ #light { display: none }
+ #dark { display: revert }
+ }
+</style>
+<div id="light">
+ <img src="resources/prefers-color-scheme-light.svg">
+ <div class="background" style="background-image: url(resources/prefers-color-scheme-light.svg)"></div>
+</div>
+<div id="dark">
+ <img src="resources/prefers-color-scheme-dark.svg">
+ <div class="background" style="background-image: url(resources/prefers-color-scheme-dark.svg)"></div>
+</div>
diff --git a/testing/web-platform/tests/css/mediaqueries/prefers-color-scheme-svg-image-normal-with-meta-dark-ref.html b/testing/web-platform/tests/css/mediaqueries/prefers-color-scheme-svg-image-normal-with-meta-dark-ref.html
new file mode 100644
index 0000000000..008c66e47d
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/prefers-color-scheme-svg-image-normal-with-meta-dark-ref.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<meta charset="utf-8">
+<meta name="color-scheme" content="dark only">
+<title>CSS prefers-color-scheme affects SVG images - color-scheme 'normal', &lt;meta> 'dark only' (reference)</title>
+<style>
+ .background {
+ width: 32px;
+ height: 32px;
+ }
+</style>
+<div>
+ <img src="resources/prefers-color-scheme-dark.svg">
+ <div class="background" style="background-image: url(resources/prefers-color-scheme-dark.svg)"></div>
+</div>
diff --git a/testing/web-platform/tests/css/mediaqueries/prefers-color-scheme-svg-image-normal-with-meta-dark.html b/testing/web-platform/tests/css/mediaqueries/prefers-color-scheme-svg-image-normal-with-meta-dark.html
new file mode 100644
index 0000000000..be633826ec
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/prefers-color-scheme-svg-image-normal-with-meta-dark.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<meta charset="utf-8">
+<meta name="color-scheme" content="dark only">
+<title>CSS prefers-color-scheme affects SVG images - color-scheme 'normal', &lt;meta> 'dark only'</title>
+<link rel="help" href="https://drafts.csswg.org/mediaqueries-5/#prefers-color-scheme">
+<link rel="match" href="prefers-color-scheme-svg-image-normal-with-meta-dark-ref.html">
+<style>
+ .background {
+ width: 32px;
+ height: 32px;
+ background-image: url(resources/prefers-color-scheme.svg);
+ }
+</style>
+<div>
+ <img src="resources/prefers-color-scheme.svg">
+ <div class="background"></div>
+</div>
diff --git a/testing/web-platform/tests/css/mediaqueries/prefers-color-scheme-svg-image-normal-with-meta-light-ref.html b/testing/web-platform/tests/css/mediaqueries/prefers-color-scheme-svg-image-normal-with-meta-light-ref.html
new file mode 100644
index 0000000000..4b47a7fd6e
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/prefers-color-scheme-svg-image-normal-with-meta-light-ref.html
@@ -0,0 +1,13 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>CSS prefers-color-scheme affects SVG images - color-scheme 'normal', &lt;meta> 'light only' (reference)</title>
+<style>
+ .background {
+ width: 32px;
+ height: 32px;
+ }
+</style>
+<div>
+ <img src="resources/prefers-color-scheme-light.svg">
+ <div class="background" style="background-image: url(resources/prefers-color-scheme-light.svg)"></div>
+</div>
diff --git a/testing/web-platform/tests/css/mediaqueries/prefers-color-scheme-svg-image-normal-with-meta-light.html b/testing/web-platform/tests/css/mediaqueries/prefers-color-scheme-svg-image-normal-with-meta-light.html
new file mode 100644
index 0000000000..ca73ddafde
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/prefers-color-scheme-svg-image-normal-with-meta-light.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<meta charset="utf-8">
+<meta name="color-scheme" content="light only">
+<title>CSS prefers-color-scheme affects SVG images - color-scheme 'normal', &lt;meta> 'light only'</title>
+<link rel="help" href="https://drafts.csswg.org/mediaqueries-5/#prefers-color-scheme">
+<link rel="match" href="prefers-color-scheme-svg-image-normal-with-meta-light-ref.html">
+<style>
+ .background {
+ width: 32px;
+ height: 32px;
+ background-image: url(resources/prefers-color-scheme.svg);
+ }
+</style>
+<div>
+ <img src="resources/prefers-color-scheme.svg">
+ <div class="background"></div>
+</div>
diff --git a/testing/web-platform/tests/css/mediaqueries/prefers-color-scheme-svg-image-normal.html b/testing/web-platform/tests/css/mediaqueries/prefers-color-scheme-svg-image-normal.html
new file mode 100644
index 0000000000..9b68142e91
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/prefers-color-scheme-svg-image-normal.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>CSS prefers-color-scheme affects SVG images - color-scheme 'normal', no &lt;meta></title>
+<link rel="help" href="https://drafts.csswg.org/mediaqueries-5/#prefers-color-scheme">
+<link rel="match" href="prefers-color-scheme-svg-image-normal-ref.html">
+<style>
+ .background {
+ width: 32px;
+ height: 32px;
+ background-image: url(resources/prefers-color-scheme.svg);
+ }
+</style>
+<div>
+ <img src="resources/prefers-color-scheme.svg">
+ <div class="background"></div>
+</div>
diff --git a/testing/web-platform/tests/css/mediaqueries/prefers-color-scheme-svg-image-ref.html b/testing/web-platform/tests/css/mediaqueries/prefers-color-scheme-svg-image-ref.html
new file mode 100644
index 0000000000..7da496cf88
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/prefers-color-scheme-svg-image-ref.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>CSS Test Reference</title>
+<style>
+ .background {
+ width: 32px;
+ height: 32px;
+ }
+</style>
+<div style="color-scheme: light">
+ <img src="resources/prefers-color-scheme-light.svg">
+ <div class="background" style="background-image: url(resources/prefers-color-scheme-light.svg)"></div>
+</div>
+<div style="color-scheme: dark">
+ <img src="resources/prefers-color-scheme-dark.svg">
+ <div class="background" style="background-image: url(resources/prefers-color-scheme-dark.svg)"></div>
+</div>
diff --git a/testing/web-platform/tests/css/mediaqueries/prefers-color-scheme-svg-image.html b/testing/web-platform/tests/css/mediaqueries/prefers-color-scheme-svg-image.html
new file mode 100644
index 0000000000..ce7babe631
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/prefers-color-scheme-svg-image.html
@@ -0,0 +1,23 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>CSS prefers-color-scheme affects SVG images</title>
+<link rel="author" href="mailto:emilio@crisal.io" title="Emilio Cobos Álvarez">
+<link rel="author" href="https://mozilla.org" title="Mozilla">
+<link rel="help" href="https://drafts.csswg.org/mediaqueries-5/#prefers-color-scheme">
+<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/7213">
+<link rel="match" href="prefers-color-scheme-svg-image-ref.html">
+<style>
+ .background {
+ width: 32px;
+ height: 32px;
+ background-image: url(resources/prefers-color-scheme.svg);
+ }
+</style>
+<div style="color-scheme: light">
+ <img src="resources/prefers-color-scheme.svg">
+ <div class="background"></div>
+</div>
+<div style="color-scheme: dark">
+ <img src="resources/prefers-color-scheme.svg">
+ <div class="background"></div>
+</div>
diff --git a/testing/web-platform/tests/css/mediaqueries/prefers-color-scheme.html b/testing/web-platform/tests/css/mediaqueries/prefers-color-scheme.html
new file mode 100644
index 0000000000..87c5add67f
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/prefers-color-scheme.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/mediaqueries-5/#prefers-color-scheme" />
+<script type="text/javascript" src="/resources/testharness.js"></script>
+<script type="text/javascript" src="/resources/testharnessreport.js"></script>
+
+<script type="text/javascript" src="resources/matchmedia-utils.js"></script>
+<script>
+query_should_be_known("(prefers-color-scheme)");
+query_should_be_known("(prefers-color-scheme: light)");
+query_should_be_known("(prefers-color-scheme: dark)");
+
+query_should_be_unknown("(prefers-color-scheme: 0)");
+query_should_be_unknown("(prefers-color-scheme: none)");
+query_should_be_unknown("(prefers-color-scheme: 10px)");
+query_should_be_unknown("(prefers-color-scheme: dark 0)");
+query_should_be_unknown("(prefers-color-scheme: dark light)");
+query_should_be_unknown("(prefers-color-scheme: light/dark)");
+query_should_be_unknown("(prefers-color-scheme: no-preference)");
+
+test(() => {
+ let booleanContext = window.matchMedia("(prefers-color-scheme)");
+ assert_true(booleanContext.matches);
+}, "Check that prefer-color-scheme evaluates to true in the boolean context");
+</script>
diff --git a/testing/web-platform/tests/css/mediaqueries/prefers-contrast.html b/testing/web-platform/tests/css/mediaqueries/prefers-contrast.html
new file mode 100644
index 0000000000..b0a67e96e4
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/prefers-contrast.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/mediaqueries-5/#prefers-contrast" />
+<script type="text/javascript" src="/resources/testharness.js"></script>
+<script type="text/javascript" src="/resources/testharnessreport.js"></script>
+
+<script type="text/javascript" src="resources/matchmedia-utils.js"></script>
+<script>
+query_should_be_known("(prefers-contrast)");
+query_should_be_known("(prefers-contrast: no-preference)");
+query_should_be_known("(prefers-contrast: more)");
+query_should_be_known("(prefers-contrast: less)");
+query_should_be_known("(prefers-contrast: custom)");
+
+query_should_be_unknown("(prefers-contrast: increase)");
+query_should_be_unknown("(prefers-contrast: none)");
+query_should_be_unknown("(prefers-contrast: forced high)");
+query_should_be_unknown("(prefers-contrast: forced low)");
+query_should_be_unknown("(prefers-contrast > increase)");
+query_should_be_unknown("(prefers-increased-contrast)");
+query_should_be_unknown("(prefers-decreased-contrast)");
+query_should_be_unknown("(prefers-contrast: high)");
+query_should_be_unknown("(prefers-contrast: low)");
+query_should_be_unknown("(prefers-contrast: forced)");
+
+test(() => {
+ // no-preference is the default and all other values evaluate to
+ // true in the boolean context. If no-preference matches, then
+ // boolean context should be false. If no-preference does not match
+ // then boolean context should be true. Therefore, these two values
+ // should always be each others inverse irrespective of OS level
+ // settings.
+ let booleanContext = window.matchMedia("(prefers-contrast)");
+ let noPref = window.matchMedia("(prefers-contrast: no-preference)");
+ assert_equals(noPref.matches, !booleanContext.matches);
+}, "Check boolean context evaluation.");
+</script>
diff --git a/testing/web-platform/tests/css/mediaqueries/prefers-reduced-data.html b/testing/web-platform/tests/css/mediaqueries/prefers-reduced-data.html
new file mode 100644
index 0000000000..bc44236d6e
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/prefers-reduced-data.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/mediaqueries-5/#prefers-reduced-data" />
+<script type="text/javascript" src="/resources/testharness.js"></script>
+<script type="text/javascript" src="/resources/testharnessreport.js"></script>
+
+<script type="text/javascript" src="resources/matchmedia-utils.js"></script>
+<script>
+query_should_be_known("(prefers-reduced-data)");
+query_should_be_known("(prefers-reduced-data: no-preference)");
+query_should_be_known("(prefers-reduced-data: reduce)");
+
+query_should_be_unknown("(prefers-reduced-data: 0)");
+query_should_be_unknown("(prefers-reduced-data: none)");
+query_should_be_unknown("(prefers-reduced-data: 10px)");
+query_should_be_unknown("(prefers-reduced-data: no-preference reduce)");
+query_should_be_unknown("(prefers-reduced-data: reduced)");
+query_should_be_unknown("(prefers-reduced-data: no-preference/reduce)");
+
+test(() => {
+ // https://drafts.csswg.org/mediaqueries-5/#boolean-context
+ let booleanContext = window.matchMedia("(prefers-reduced-data)");
+ let noPreference = window.matchMedia("(prefers-reduced-data: no-preference)");
+ assert_equals(booleanContext.matches, !noPreference.matches);
+}, "Check that no-preference evaluates to false in the boolean context");
+
+test(() => {
+ let invalid = window.matchMedia("(prefers-reduced-data: 10px)");
+ assert_equals(invalid.matches, false);
+}, "Check that invalid evaluates to false");
+</script>
diff --git a/testing/web-platform/tests/css/mediaqueries/prefers-reduced-motion.html b/testing/web-platform/tests/css/mediaqueries/prefers-reduced-motion.html
new file mode 100644
index 0000000000..f9a71f5c9f
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/prefers-reduced-motion.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/mediaqueries-5/#prefers-reduced-motion" />
+<script type="text/javascript" src="/resources/testharness.js"></script>
+<script type="text/javascript" src="/resources/testharnessreport.js"></script>
+
+<script type="text/javascript" src="resources/matchmedia-utils.js"></script>
+<script>
+query_should_be_known("(prefers-reduced-motion)");
+query_should_be_known("(prefers-reduced-motion: no-preference)");
+query_should_be_known("(prefers-reduced-motion: reduce)");
+
+query_should_be_unknown("(prefers-reduced-motion: 0)");
+query_should_be_unknown("(prefers-reduced-motion: none)");
+query_should_be_unknown("(prefers-reduced-motion: 10px)");
+query_should_be_unknown("(prefers-reduced-motion: no-preference reduce)");
+query_should_be_unknown("(prefers-reduced-motion: reduced)");
+query_should_be_unknown("(prefers-reduced-motion: no-preference/reduce)");
+
+test(() => {
+ // What this is saying is that 'no-preference' is not the default, so
+ // irregardless of the current OS settings, (prefers-reduced-motion).matches
+ // should not be equivalent to (prefers-reduced-motion: no-preference).matches.
+ let booleanContext = window.matchMedia("(prefers-reduced-motion)");
+ let noPreference = window.matchMedia("(prefers-reduced-motion: no-preference)");
+ assert_equals(booleanContext.matches, !noPreference.matches);
+}, "Check that no-preference evaluates to false in the boolean context");
+</script>
diff --git a/testing/web-platform/tests/css/mediaqueries/reference/ref-green-body.xht b/testing/web-platform/tests/css/mediaqueries/reference/ref-green-body.xht
new file mode 100644
index 0000000000..f79255de9c
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/reference/ref-green-body.xht
@@ -0,0 +1,18 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>CSS Reftest Reference</title>
+<link rel="author" title="Chris Rebert" href="http://chrisrebert.com" />
+<style type="text/css">
+body {
+ background: green;
+}
+p {
+ font-size: 24px;
+}
+</style>
+</head>
+<body>
+<p>This should have a green background.</p>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/mediaqueries/relative-units-001.html b/testing/web-platform/tests/css/mediaqueries/relative-units-001.html
new file mode 100644
index 0000000000..4e526fbf2e
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/relative-units-001.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>CSS Test: Font-relative length units (rem) in width media queries</title>
+ <link rel="author" title="Chris Rebert" href="http://chrisrebert.com">
+ <link rel="help" href="https://www.w3.org/TR/css3-mediaqueries/#units">
+ <link rel="help" href="https://www.w3.org/TR/mediaqueries-4/#units">
+ <link rel="match" href="reference/ref-green-body.xht">
+ <meta name="assert" content="Font-relative length units (such as 'rem') in media queries should be calculated based on the initial value of 'font-size', not based on author style declarations, such as: html { font-size: 200%; }">
+ <style>
+:root {
+ font-size: 100000px;/* ~87ft */
+}
+body {
+ background: red;
+}
+p {
+ font-size: 24px;
+}
+ </style>
+</head>
+<body>
+ <p>This should have a green background.</p>
+ <script>
+ document.body.offsetTop;
+ </script>
+ <style>
+ @media (min-width: 1rem) {
+ body {
+ background: green;
+ }
+ }
+ </style>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/mediaqueries/relative-units-002.html b/testing/web-platform/tests/css/mediaqueries/relative-units-002.html
new file mode 100644
index 0000000000..b0b533f81f
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/relative-units-002.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>CSS Test: Font-relative length units (em) in width media queries</title>
+ <link rel="author" title="Chris Rebert" href="http://chrisrebert.com">
+ <link rel="help" href="https://www.w3.org/TR/css3-mediaqueries/#units">
+ <link rel="help" href="https://www.w3.org/TR/mediaqueries-4/#units">
+ <link rel="match" href="reference/ref-green-body.xht">
+ <meta name="assert" content="Font-relative length units (such as 'em') in media queries should be calculated based on the initial value of 'font-size', not based on author style declarations, such as: html { font-size: 200%; }">
+ <style>
+:root {
+ font-size: 100000px;/* ~87ft */
+}
+body {
+ background: red;
+}
+p {
+ font-size: 24px;
+}
+ </style>
+</head>
+<body>
+ <p>This should have a green background.</p>
+ <script>
+ document.body.offsetTop;
+ </script>
+ <style>
+ @media (min-width: 1em) {
+ body {
+ background: green;
+ }
+ }
+ </style>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/mediaqueries/relative-units-003.html b/testing/web-platform/tests/css/mediaqueries/relative-units-003.html
new file mode 100644
index 0000000000..bfb3b79a92
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/relative-units-003.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>CSS Test: Font-relative length units (ex) in width media queries</title>
+ <link rel="author" title="Chris Rebert" href="http://chrisrebert.com">
+ <link rel="help" href="https://www.w3.org/TR/css3-mediaqueries/#units">
+ <link rel="help" href="https://www.w3.org/TR/mediaqueries-4/#units">
+ <link rel="match" href="reference/ref-green-body.xht">
+ <meta name="assert" content="Font-relative length units (such as 'ex') in media queries should be calculated based on the initial value of 'font-size', not based on author style declarations, such as: html { font-size: 200%; }">
+ <style>
+:root {
+ font-size: 100000px;/* ~87ft */
+}
+body {
+ background: red;
+}
+p {
+ font-size: 24px;
+}
+ </style>
+</head>
+<body>
+ <p>This should have a green background.</p>
+ <script>
+ document.body.offsetTop;
+ </script>
+ <style>
+ @media (min-width: 1ex) {
+ body {
+ background: green;
+ }
+ }
+ </style>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/mediaqueries/relative-units-004.html b/testing/web-platform/tests/css/mediaqueries/relative-units-004.html
new file mode 100644
index 0000000000..99b1fa6f18
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/relative-units-004.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>CSS Test: Font-relative length units (ch) in width media queries</title>
+ <link rel="author" title="Chris Rebert" href="http://chrisrebert.com">
+ <link rel="help" href="https://www.w3.org/TR/css3-mediaqueries/#units">
+ <link rel="help" href="https://www.w3.org/TR/mediaqueries-4/#units">
+ <link rel="match" href="reference/ref-green-body.xht">
+ <meta name="assert" content="Font-relative length units (such as 'ch') in media queries should be calculated based on the initial value of 'font-size', not based on author style declarations, such as: html { font-size: 200%; }">
+ <style>
+:root {
+ font-size: 100000px;/* ~87ft */
+}
+body {
+ background: red;
+}
+p {
+ font-size: 24px;
+}
+ </style>
+</head>
+<body>
+ <p>This should have a green background.</p>
+ <script>
+ document.body.offsetTop;
+ </script>
+ <style>
+ @media (min-width: 1ch) {
+ body {
+ background: green;
+ }
+ }
+ </style>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/mediaqueries/relative-units-005.html b/testing/web-platform/tests/css/mediaqueries/relative-units-005.html
new file mode 100644
index 0000000000..8b344743df
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/relative-units-005.html
@@ -0,0 +1,29 @@
+<!doctype html>
+<title>CSS Media Queries Test: ex, ch, and ic from initial font</title>
+<link rel="help" href="https://drafts.csswg.org/mediaqueries/#units">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="ex_ref" style="width: 100ex"></div>
+<div id="ch_ref" style="width: 100ch"></div>
+<div id="ic_ref" style="width: 100ic"></div>
+<script>
+ const viewport_width = document.documentElement.offsetWidth;
+
+ test(() => {
+ const viewport_ex = (viewport_width * 100) / ex_ref.offsetWidth;
+ const ex_query = `(min-width: ${viewport_ex-0.5}ex) and (max-width: ${viewport_ex+0.5}ex)`;
+ assert_true(matchMedia(ex_query).matches);
+ }, "ex unit in media queries should match initial font");
+
+ test(() => {
+ const viewport_ch = (viewport_width * 100) / ch_ref.offsetWidth;
+ const ch_query = `(min-width: ${viewport_ch-0.5}ch) and (max-width: ${viewport_ch+0.5}ch)`;
+ assert_true(matchMedia(ch_query).matches);
+ }, "ch unit in media queries should match initial font");
+
+ test(() => {
+ const viewport_ic = (viewport_width * 100) / ic_ref.offsetWidth;
+ const ic_query = `(min-width: ${viewport_ic-0.5}ic) and (max-width: ${viewport_ic+0.5}ic)`;
+ assert_true(matchMedia(ic_query).matches);
+ }, "ic unit in media queries should match initial font");
+</script>
diff --git a/testing/web-platform/tests/css/mediaqueries/resources/matchmedia-utils.js b/testing/web-platform/tests/css/mediaqueries/resources/matchmedia-utils.js
new file mode 100644
index 0000000000..327e8f69fe
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/resources/matchmedia-utils.js
@@ -0,0 +1,76 @@
+'use strict';
+
+function query_is_css_parseable(query) {
+ const style = document.createElement('style');
+ style.type = 'text/css';
+ document.head.appendChild(style);
+
+ const sheet = style.sheet;
+ try {
+ sheet.insertRule("@media " + query + "{}", 0);
+ return sheet.cssRules.length == 1 &&
+ sheet.cssRules[0].media.mediaText != "not all";
+ } finally {
+ while (sheet.cssRules.length)
+ sheet.deleteRule(0);
+ style.remove();
+ }
+}
+
+function query_should_be_css_parseable(query) {
+ test(() => {
+ assert_true(query_is_css_parseable(query));
+ }, "Should be parseable in a CSS stylesheet: '" + query + "'");
+}
+
+function query_should_not_be_css_parseable(query) {
+ test(() => {
+ assert_false(query_is_css_parseable(query));
+ }, "Should not be parseable in a CSS stylesheet: '" + query + "'");
+}
+
+function query_is_js_parseable(query) {
+ // We cannot rely on whether a given feature is on or off, so only check the
+ // 'media' member of the result.
+ const match = window.matchMedia(query);
+ return match.media == query;
+}
+
+function query_should_be_js_parseable(query) {
+ test(() => {
+ assert_true(query_is_js_parseable(query));
+ }, "Should be parseable in JS: '" + query + "'");
+}
+
+function query_should_not_be_js_parseable(query) {
+ test(() => {
+ assert_false(query_is_js_parseable(query));
+ }, "Should not be parseable in JS: '" + query + "'");
+}
+
+function query_is_known(query) {
+ return window.matchMedia(`${query}, not all and ${query}`).matches;
+}
+
+function query_is_unknown(query) {
+ return !window.matchMedia(`${query}, not all and ${query}`).matches;
+}
+
+function query_should_be_known(query) {
+ test(() => {
+ assert_true(query_is_js_parseable(query), "Can parse with JS");
+ assert_true(query_is_css_parseable(query), "Can parse with CSS");
+ assert_true(query_is_known(query));
+ }, "Should be known: '" + query + "'");
+}
+
+function query_should_be_unknown(query) {
+ test(() => {
+ assert_true(query_is_js_parseable(query), "Can parse with JS");
+ assert_true(query_is_css_parseable(query), "Can parse with CSS");
+ }, "Should be parseable: '" + query + "'");
+
+ test(() => {
+ assert_true(query_is_unknown(query));
+ }, "Should be unknown: '" + query + "'");
+}
diff --git a/testing/web-platform/tests/css/mediaqueries/resources/prefers-color-scheme-dark.svg b/testing/web-platform/tests/css/mediaqueries/resources/prefers-color-scheme-dark.svg
new file mode 100644
index 0000000000..f65fce76ec
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/resources/prefers-color-scheme-dark.svg
@@ -0,0 +1,6 @@
+<svg width="32" height="32" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
+ <style>
+ :root { color: purple }
+ </style>
+ <rect fill="currentColor" width="32" height="32"/>
+</svg>
diff --git a/testing/web-platform/tests/css/mediaqueries/resources/prefers-color-scheme-light.svg b/testing/web-platform/tests/css/mediaqueries/resources/prefers-color-scheme-light.svg
new file mode 100644
index 0000000000..23ac2ad949
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/resources/prefers-color-scheme-light.svg
@@ -0,0 +1,6 @@
+<svg width="32" height="32" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
+ <style>
+ :root { color: blue }
+ </style>
+ <rect fill="currentColor" width="32" height="32"/>
+</svg>
diff --git a/testing/web-platform/tests/css/mediaqueries/resources/prefers-color-scheme.svg b/testing/web-platform/tests/css/mediaqueries/resources/prefers-color-scheme.svg
new file mode 100644
index 0000000000..5523ff39fa
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/resources/prefers-color-scheme.svg
@@ -0,0 +1,9 @@
+<svg width="32" height="32" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
+ <style>
+ :root { color: blue }
+ @media (prefers-color-scheme: dark) {
+ :root { color: purple }
+ }
+ </style>
+ <rect fill="currentColor" width="32" height="32"/>
+</svg>
diff --git a/testing/web-platform/tests/css/mediaqueries/support/media_queries_iframe.html b/testing/web-platform/tests/css/mediaqueries/support/media_queries_iframe.html
new file mode 100644
index 0000000000..890eb6c461
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/support/media_queries_iframe.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
+ "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en-US">
+<head>
+ <title>Media Queries Test inner frame</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+ <link rel="author" title="L. David Baron" href="https://dbaron.org/">
+ <meta http-equiv="Content-Style-Type" content="text/css">
+ <style type="text/css" id="style" media="all">
+ body { text-decoration: underline; }
+ </style>
+</head>
+<body>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/mediaqueries/support/min-width-tables-001-iframe.html b/testing/web-platform/tests/css/mediaqueries/support/min-width-tables-001-iframe.html
new file mode 100644
index 0000000000..794c047b0a
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/support/min-width-tables-001-iframe.html
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>iframe containing the meat of the test</title>
+ <style>
+body {
+ margin: 0;
+ overflow: hidden;
+}
+/* green div that should cover the red divs */
+#green {
+ position: absolute;
+ left: 0;
+ top: 0;
+ background-color: green;
+ width: 100%;
+ height: 600px;
+}
+.spacer {
+ height: 98px;
+ width: 20px;
+}
+.item {
+ background-color: red;
+ display: block;/* property under test */
+ /* border to aid understanding of boundaries between items */
+ border-style: solid;
+ border-width: 1px;
+ border-color: red;/* Note: if you're trying to debug this, use a different color here */
+}
+/* 100px = 10*(1 + 8 + 1) */
+@media (min-width: 100px) {
+ #green {
+ width: 100px;
+ height: 100px;/* = 1 + 98 + 1 */
+ }
+ .item {
+ display: table-cell;/* property and value under test */
+ }
+}
+ </style>
+</head>
+<body>
+ <div>
+ <div class="item"><div class="spacer"></div></div>
+ <div class="item"><div class="spacer"></div></div>
+ <div class="item"><div class="spacer"></div></div>
+ <div class="item"><div class="spacer"></div></div>
+ <div class="item"><div class="spacer"></div></div>
+ <div class="item"><div class="spacer"></div></div>
+ <div class="item"><div class="spacer"></div></div>
+ <div class="item"><div class="spacer"></div></div>
+ <div class="item"><div class="spacer"></div></div>
+ <div class="item"><div class="spacer"></div></div>
+ </div>
+ <div id="green"></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/mediaqueries/test_media_queries.html b/testing/web-platform/tests/css/mediaqueries/test_media_queries.html
new file mode 100644
index 0000000000..06a9cd8cc5
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/test_media_queries.html
@@ -0,0 +1,714 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Media Queries Self-Contained Test Suite</title>
+ <link rel="author" title="L. David Baron" href="https://dbaron.org/">
+ <link rel="author" title="Anne van Kesteren" href="http://annevankesteren.nl/">
+ <link rel="author" title="Ms2ger" href="mailto:Ms2ger@gmail.com">
+ <link rel="help" href="https://www.w3.org/TR/css3-mediaqueries/#media0">
+ <script type="text/javascript" src="/resources/testharness.js"></script>
+ <script type="text/javascript" src="/resources/testharnessreport.js"></script>
+</head>
+<body onload="run()">
+<div id=log></div>
+<iframe id="subdoc" src="support/media_queries_iframe.html"></iframe>
+<div id="content" style="display: none"></div>
+
+<script type="text/javascript">
+setup({ "explicit_done": true });
+
+ function run() {
+ var subdoc = document.getElementById("subdoc").contentDocument;
+ var subwin = document.getElementById("subdoc").contentWindow;
+ var style = subdoc.getElementById("style");
+ var iframe_style = document.getElementById("subdoc").style;
+ var body_cs = subdoc.defaultView.getComputedStyle(subdoc.body, "");
+ var testGroup = "";
+
+ function query_applies(q) {
+ style.setAttribute("media", q);
+ return body_cs.getPropertyValue("text-decoration-line") == "underline";
+ }
+
+ function not(predicate) {
+ return (...args) => !predicate(...args);
+ }
+
+ function test_predicate(input, predicate, name) {
+ test(() => {
+ // lazily evaluate template string to avoid including device-specific data in test name
+ var escaped = JSON.stringify(input);
+ var evaled = eval("`" + escaped.substring(1, escaped.length - 1) + "`");
+ // Also avoid an assert message for the same reason. (Relevant for
+ // failing tests).
+ assert_true(predicate(evaled))
+ }, `${testGroup ? testGroup + ": " : ""}${name}: ${input}`);
+ }
+
+ function should_apply(q) {
+ test_predicate(q, query_applies, "should_apply");
+ }
+
+ function should_not_apply(q) {
+ test_predicate(q, not(query_applies), "should_not_apply");
+ }
+
+ /*
+ * Functions to test whether a query is parseable at all. (Should not
+ * be used for parse errors within expressions.)
+ */
+ var parse_test_style_element = document.createElement("style");
+ parse_test_style_element.type = "text/css";
+ parse_test_style_element.disabled = true; // for performance, hopefully
+ var parse_test_style_text = document.createTextNode("");
+ parse_test_style_element.appendChild(parse_test_style_text);
+ document.getElementsByTagName("head")[0]
+ .appendChild(parse_test_style_element);
+
+ function query_is_parseable(q) {
+ parse_test_style_text.data = "@media screen, " + q + " {}";
+ var sheet = parse_test_style_element.sheet; // XXX yikes, not live!
+ if (sheet.cssRules.length == 1 &&
+ sheet.cssRules[0].type == CSSRule.MEDIA_RULE)
+ return sheet.cssRules[0].media.mediaText != "screen, not all";
+
+ assert_unreached(
+ "unexpected result testing whether query " + q + " is parseable");
+ }
+
+ function query_should_be_parseable(q) {
+ test_predicate(q, query_is_parseable, "query_should_be_parseable");
+ }
+
+ function query_should_not_be_parseable(q) {
+ test_predicate(q, not(query_is_parseable), "query_should_not_be_parseable");
+ }
+
+ /*
+ * Functions to test whether a single media expression is "unknown" or not.
+ *
+ * https://drafts.csswg.org/mediaqueries-4/#evaluating
+ */
+
+ function expression_is_parseable(e) {
+ return query_is_parseable(`(${e})`);
+ }
+
+ function expression_is_known(e) {
+ return query_applies(`(${e}), not all and (${e})`);
+ }
+
+ function expression_should_be_known(e) {
+ // We don't bother with expression_is_parseable here, because it must be parseable to be known
+ test_predicate(e, expression_is_known, "expression_should_be_known");
+ }
+
+ function expression_should_be_unknown(e) {
+ test_predicate(e, expression_is_parseable, "expression_should_be_parseable");
+ test_predicate(e, not(expression_is_known), "expression_should_be_unknown");
+ }
+
+ // The no-type syntax doesn't mix with the not and only keywords.
+ query_should_be_parseable("(orientation)");
+ query_should_be_parseable("not (orientation)");
+ expression_should_be_known("(orientation)");
+ expression_should_be_known("not (orientation)");
+ query_should_not_be_parseable("only (orientation)");
+ query_should_be_parseable("all and (orientation)");
+ query_should_be_parseable("not all and (orientation)");
+ query_should_be_parseable("only all and (orientation)");
+
+ query_should_not_be_parseable("not not (orientation)");
+ query_should_be_parseable("(orientation) and (orientation)");
+ query_should_be_parseable("(orientation) or (orientation)");
+ query_should_be_parseable("(orientation) or ((orientation) and ((orientation) or (orientation) or (not (orientation))))");
+ expression_should_be_known("(orientation) and (orientation)");
+ expression_should_be_known("(orientation) or (orientation)");
+ expression_should_be_known("(orientation) or ((orientation) and ((orientation) or (orientation) or (not (orientation))))");
+
+ query_should_not_be_parseable("all and (orientation) or (orientation)");
+ query_should_be_parseable("all and (orientation) and (orientation)");
+
+ query_should_not_be_parseable("(orientation) and (orientation) or (orientation)");
+ query_should_not_be_parseable("(orientation) and not (orientation)");
+
+ var features = [ "width", "height", "device-width", "device-height" ];
+ var separators = [ ":", ">", ">=", "=", "<=", "<" ];
+ var feature;
+ var i;
+ for (i in features) {
+ feature = features[i];
+ expression_should_be_known(feature);
+ expression_should_be_unknown("min-" + feature);
+ expression_should_be_unknown("max-" + feature);
+ for (let separator of separators) {
+ expression_should_be_known(feature + " " + separator + " 0");
+ expression_should_be_known(feature + " " + separator + " 0px");
+ expression_should_be_known(feature + " " + separator + " 0em");
+ expression_should_be_known(feature + " " + separator + " -0");
+ expression_should_be_known(feature + " " + separator + " -0cm");
+ expression_should_be_known(feature + " " + separator + " 1px");
+ expression_should_be_known(feature + " " + separator + " 0.001mm");
+ expression_should_be_known(feature + " " + separator + " 100000px");
+ if (separator == ":") {
+ expression_should_be_known("min-" + feature + " " + separator + " -0");
+ expression_should_be_known("max-" + feature + " " + separator + " -0");
+ } else {
+ expression_should_be_unknown("min-" + feature + " " + separator + " -0");
+ expression_should_be_unknown("max-" + feature + " " + separator + " -0");
+ let multi_range = "0px " + separator + " " + feature + " " + separator + " 100000px"
+ if (separator == "=") {
+ expression_should_be_unknown(multi_range);
+ } else {
+ expression_should_be_known(multi_range);
+ }
+ }
+ if (separator == ">=") {
+ expression_should_be_unknown(feature + " > = 0px");
+ } else if (separator == "<=") {
+ expression_should_be_unknown(feature + " < = 0px");
+ }
+
+ expression_should_be_known(feature + " " + separator + " -1px");
+ if (separator == ":") {
+ expression_should_be_known("min-" + feature + " " + separator + " -1px");
+ expression_should_be_known("max-" + feature + " " + separator + " -1px");
+ } else {
+ expression_should_be_unknown("min-" + feature + " " + separator + " -1px");
+ expression_should_be_unknown("max-" + feature + " " + separator + " -1px");
+ }
+ expression_should_be_known(feature + " " + separator + " -0.00001mm");
+ expression_should_be_known(feature + " " + separator + " -100000em");
+
+ for (let separator2 of separators) {
+ // https://drafts.csswg.org/mediaqueries-4/#typedef-mf-range
+ if (separator[0] == separator2[0] && (separator[0] == '<' || separator[0] == '>')) {
+ expression_should_be_known(`0px ${separator} ${feature} ${separator2} 0px`);
+ } else {
+ expression_should_be_unknown(`0px ${separator} ${feature} ${separator2} 0px`);
+ }
+ }
+ }
+ }
+
+ var content_div = document.getElementById("content");
+ content_div.style.font = "medium sans-serif";
+ var em_size =
+ getComputedStyle(content_div, "").fontSize.match(/^(\d+)px$/)[1];
+
+ // in this test, assume the common underlying implementation is correct
+ var width_val = 117; // pick two not-too-round numbers
+ var height_val = 76;
+ iframe_style.width = width_val + "px";
+ iframe_style.height = height_val + "px";
+ var device_width = window.screen.width;
+ var device_height = window.screen.height;
+ features = {
+ "width": width_val,
+ "height": height_val,
+ "device-width": device_width,
+ "device-height": device_height
+ };
+ for (feature in features) {
+ var value = features[feature];
+ should_apply("all and (" + feature + ": ${value}px)");
+ should_apply("all and (" + feature + " = ${value}px)");
+ should_not_apply("all and (" + feature + ": ${value + 1}px)");
+ should_not_apply("all and (" + feature + ": ${value - 1}px)");
+ should_not_apply("all and (" + feature + " = ${value + 1}px)");
+ should_not_apply("all and (" + feature + " = ${value - 1}px)");
+
+ should_apply("all and (min-" + feature + ": ${value}px)");
+ should_not_apply("all and (min-" + feature + ": ${value + 1}px)");
+ should_apply("all and (min-" + feature + ": ${value - 1}px)");
+ should_apply("all and (max-" + feature + ": ${value}px)");
+ should_apply("all and (max-" + feature + ": ${value + 1}px)");
+ should_not_apply("all and (max-" + feature + ": ${value - 1}px)");
+ should_not_apply("all and (min-" + feature + ": ${Math.ceil(value/em_size) + 1}em)");
+ should_apply("all and (min-" + feature + ": ${Math.floor(value/em_size) - 1}em)");
+ should_apply("all and (max-" + feature + ": ${Math.ceil(value/em_size) + 1}em)");
+ should_not_apply("all and (max-" + feature + ": ${Math.floor(value/em_size) - 1}em)");
+
+ should_apply("(" + feature + " <= ${value}px)");
+ should_apply("(" + feature + " >= ${value}px)");
+
+ should_apply("(0px < " + feature + " <= ${value}px)");
+ should_apply("(${value}px >= " + feature + " > 0px)");
+
+ should_not_apply("(0px < " + feature + " < ${value}px)");
+ should_not_apply("(${value}px > " + feature + " > 0px)");
+
+ should_not_apply("(" + feature + " < ${value}px)");
+ should_not_apply("(" + feature + " > ${value}px)");
+
+ should_apply("(" + feature + " < ${value + 1}px)");
+ should_apply("(" + feature + " <= ${value + 1}px)");
+ should_not_apply("(" + feature + " > ${value + 1}px)");
+ should_not_apply("(" + feature + " >= ${value + 1}px)");
+
+ should_apply("(" + feature + " > ${value - 1}px)");
+ should_apply("(" + feature + " >= ${value - 1}px)");
+ should_not_apply("(" + feature + " < ${value - 1}px)");
+ should_not_apply("(" + feature + " <= ${value - 1}px)");
+
+ should_apply("(${value - 1}px < " + feature + ")");
+ should_apply("(${value - 1}px <= " + feature + ")");
+ should_not_apply("(${value - 1}px > " + feature + ")");
+ should_not_apply("(${value - 1}px >= " + feature + ")");
+
+ should_apply("(${value - 1}px < " + feature + " < ${value + 1}px)");
+ should_apply("(${value - 1}px < " + feature + " <= ${value}px)");
+ should_apply("(${value}px <= " + feature + " < ${value + 1}px)");
+ should_apply("(${value + 1}px > " + feature + " > ${value - 1}px)");
+ should_apply("(${value + 1}px > " + feature + " >= ${value}px)");
+ should_apply("(${value}px >= " + feature + " > ${value - 1}px)");
+ should_not_apply("(${value}px > " + feature + " > ${value - 1}px)");
+ should_not_apply("(${value + 1}px > " + feature + " > ${value}px)");
+ }
+
+ iframe_style.width = "0";
+ testGroup = "width = 0, height != 0";
+ should_apply("all and (height)");
+ should_not_apply("all and (width)");
+ iframe_style.height = "0";
+ testGroup = "width = 0, height = 0"
+ should_not_apply("all and (height)");
+ should_not_apply("all and (width)");
+ should_apply("all and (device-height)");
+ should_apply("all and (device-width)");
+ iframe_style.width = width_val + "px";
+ testGroup = "width != 0, height = 0";
+ should_not_apply("all and (height)");
+ should_apply("all and (width)");
+ iframe_style.height = height_val + "px";
+ testGroup = "width != 0, height != 0";
+ should_apply("all and (height)");
+ should_apply("all and (width)");
+ testGroup = "";
+
+ testGroup = "ratio that reduces to 59/40";
+ iframe_style.width = "236px";
+ iframe_style.height = "160px";
+ expression_should_be_known("orientation");
+ expression_should_be_known("orientation: portrait");
+ expression_should_be_known("orientation: landscape");
+ expression_should_be_unknown("min-orientation");
+ expression_should_be_unknown("min-orientation: portrait");
+ expression_should_be_unknown("min-orientation: landscape");
+ expression_should_be_unknown("max-orientation");
+ expression_should_be_unknown("max-orientation: portrait");
+ expression_should_be_unknown("max-orientation: landscape");
+ should_apply("(orientation)");
+ should_apply("(orientation: landscape)");
+ should_not_apply("(orientation: portrait)");
+ should_apply("not all and (orientation: portrait)");
+
+ testGroup = "ratio that reduces to 59/80";
+ iframe_style.height = "320px";
+ should_apply("(orientation)");
+ should_not_apply("(orientation: landscape)");
+ should_apply("not all and (orientation: landscape)");
+ should_apply("(orientation: portrait)");
+ testGroup = "";
+
+ should_apply("(aspect-ratio: 59/80)");
+ should_not_apply("(aspect-ratio: 58/80)");
+ should_not_apply("(aspect-ratio: 59/81)");
+ should_not_apply("(aspect-ratio: 60/80)");
+ should_not_apply("(aspect-ratio: 59/79)");
+ should_apply("(aspect-ratio: 177/240)");
+ should_apply("(aspect-ratio: 413/560)");
+ should_apply("(aspect-ratio: 5900/8000)");
+ should_not_apply("(aspect-ratio: 5901/8000)");
+ should_not_apply("(aspect-ratio: 5899/8000)");
+ should_not_apply("(aspect-ratio: 5900/8001)");
+ should_not_apply("(aspect-ratio: 5900/7999)");
+ should_apply("(aspect-ratio)");
+
+ should_apply("(min-aspect-ratio: 59/80)");
+ should_apply("(min-aspect-ratio: 58/80)");
+ should_apply("(min-aspect-ratio: 59/81)");
+ should_not_apply("(min-aspect-ratio: 60/80)");
+ should_not_apply("(min-aspect-ratio: 59/79)");
+ expression_should_be_unknown("min-aspect-ratio");
+
+ should_apply("(max-aspect-ratio: 59/80)");
+ should_not_apply("(max-aspect-ratio: 58/80)");
+ should_not_apply("(max-aspect-ratio: 59/81)");
+ should_apply("(max-aspect-ratio: 60/80)");
+ should_apply("(max-aspect-ratio: 59/79)");
+ expression_should_be_unknown("max-aspect-ratio");
+
+ var real_dar = device_width + "/" + device_height;
+ var high_dar_1 = (device_width + 1) + "/" + device_height;
+ var high_dar_2 = device_width + "/" + (device_height - 1);
+ var low_dar_1 = (device_width - 1) + "/" + device_height;
+ var low_dar_2 = device_width + "/" + (device_height + 1);
+ should_apply("(device-aspect-ratio: ${real_dar})");
+ should_apply("not all and (device-aspect-ratio: ${high_dar_1})");
+ should_not_apply("all and (device-aspect-ratio: ${high_dar_2})");
+ should_not_apply("all and (device-aspect-ratio: ${low_dar_1})");
+ should_apply("not all and (device-aspect-ratio: ${low_dar_2})");
+ should_apply("(device-aspect-ratio)");
+
+ should_apply("(min-device-aspect-ratio: ${real_dar})");
+ should_not_apply("all and (min-device-aspect-ratio: ${high_dar_1})");
+ should_apply("not all and (min-device-aspect-ratio: ${high_dar_2})");
+ should_not_apply("not all and (min-device-aspect-ratio: ${low_dar_1})");
+ should_apply("all and (min-device-aspect-ratio: ${low_dar_2})");
+ expression_should_be_unknown("min-device-aspect-ratio");
+
+ should_apply("all and (max-device-aspect-ratio: ${real_dar})");
+ should_apply("(max-device-aspect-ratio: ${high_dar_1})");
+ should_apply("(max-device-aspect-ratio: ${high_dar_2})");
+ should_not_apply("all and (max-device-aspect-ratio: ${low_dar_1})");
+ should_apply("not all and (max-device-aspect-ratio: ${low_dar_2})");
+ expression_should_be_unknown("max-device-aspect-ratio");
+
+ features = [ "max-aspect-ratio", "device-aspect-ratio" ];
+ for (i in features) {
+ feature = features[i];
+ expression_should_be_known(feature + ": 1/1");
+ expression_should_be_known(feature + ": 1 /1");
+ expression_should_be_known(feature + ": 1 / \t\n1");
+ expression_should_be_known(feature + ": 1/\r1");
+ expression_should_be_known(feature + ": 1");
+ expression_should_be_known(feature + ": 0.5");
+ expression_should_be_known(feature + ": 1.0/1");
+ expression_should_be_known(feature + ": 1/1.0");
+ expression_should_be_known(feature + ": 1.0/1.0");
+ expression_should_be_known(feature + ": 0/1");
+ expression_should_be_known(feature + ": 1/0");
+ expression_should_be_known(feature + ": 0/0");
+ expression_should_be_unknown(feature + ": -1/1");
+ expression_should_be_unknown(feature + ": 1/-1");
+ expression_should_be_unknown(feature + ": -1/-1");
+ expression_should_be_unknown(feature + ": invalid");
+ expression_should_be_unknown(feature + ": 1 / invalid");
+ expression_should_be_unknown(feature + ": 1 invalid");
+ }
+
+ var is_monochrome = query_applies("all and (min-monochrome: 1)");
+ var is_color = query_applies("all and (min-color: 1)");
+ test(function() {
+ assert_not_equals(is_monochrome, is_color, "should be either monochrome or color");
+ }, "monochrome_and_color");
+
+ function depth_query(prefix, depth) {
+ return "all and (" + prefix + (is_color ? "color" : "monochrome") +
+ ":" + depth + ")";
+ }
+
+ var depth = 0;
+ do {
+ if (depth > 50) {
+ break;
+ }
+ } while (query_applies(depth_query("min-", ++depth)));
+ test(function() {
+ assert_false(50 < depth);
+ }, "find_depth");
+ --depth;
+
+ should_apply(depth_query("", depth));
+ should_not_apply(depth_query("", depth - 1));
+ should_not_apply(depth_query("", depth + 1));
+ should_apply(depth_query("max-", depth));
+ should_not_apply(depth_query("max-", depth - 1));
+ should_apply(depth_query("max-", depth + 1));
+
+ (is_color ? should_apply : should_not_apply)("all and (color)");
+ expression_should_be_unknown("max-color");
+ expression_should_be_unknown("min-color");
+ (is_color ? should_not_apply : should_apply)("all and (monochrome)");
+ expression_should_be_unknown("max-monochrome");
+ expression_should_be_unknown("min-monochrome");
+ (is_color ? should_apply : should_not_apply)("not all and (monochrome)");
+ (is_color ? should_not_apply : should_apply)("not all and (color)");
+ (is_color ? should_apply : should_not_apply)("only all and (color)");
+ (is_color ? should_not_apply : should_apply)("only all and (monochrome)");
+
+ features = [ "color", "min-monochrome", "max-color-index" ];
+ for (i in features) {
+ feature = features[i];
+ expression_should_be_known(feature + ": 1");
+ expression_should_be_known(feature + ": 327");
+ expression_should_be_known(feature + ": 0");
+ expression_should_be_unknown(feature + ": 1.0");
+ expression_should_be_known(feature + ": -1");
+ expression_should_be_unknown(feature + ": 1/1");
+ }
+
+ // Presume that we never support indexed color (at least not usefully
+ // enough to call it indexed color).
+ should_apply("(color-index: 0)");
+ should_not_apply("(color-index: 1)");
+ should_apply("(min-color-index: 0)");
+ should_not_apply("(min-color-index: 1)");
+ should_apply("(max-color-index: 0)");
+ should_apply("(max-color-index: 1)");
+ should_apply("(max-color-index: 157)");
+
+ features = [ "resolution", "min-resolution", "max-resolution" ];
+ for (i in features) {
+ feature = features[i];
+ expression_should_be_known(feature + ": 3dpi");
+ expression_should_be_known(feature + ":3dpi");
+ expression_should_be_known(feature + ": 3.0dpi");
+ expression_should_be_known(feature + ": 3.4dpi");
+ expression_should_be_known(feature + "\t: 120dpcm");
+ expression_should_be_known(feature + ": 1dppx");
+ expression_should_be_known(feature + ": 1x");
+ expression_should_be_known(feature + ": 1.5dppx");
+ expression_should_be_known(feature + ": 1.5x");
+ expression_should_be_known(feature + ": 2.0dppx");
+ expression_should_be_known(feature + ": 0dpi");
+ expression_should_be_known(feature + ": -3dpi");
+ expression_should_be_known(feature + ": 0dppx");
+ expression_should_be_known(feature + ": 0x");
+ }
+
+ // Find the resolution using max-resolution
+ var resolution = 0;
+ do {
+ ++resolution;
+ if (resolution > 10000) {
+ break;
+ }
+ } while (!query_applies("(max-resolution: " + resolution + "dpi)"));
+ test(function() {
+ assert_false(10000 < resolution);
+ }, "find_resolution");
+
+ // resolution should now be Math.ceil() of the actual resolution.
+ var dpi_high;
+ var dpi_low = resolution - 1;
+ if (query_applies(`(min-resolution: ${resolution}dpi)`)) { // query_applies, so template literal!
+ // It's exact!
+ testGroup = "resolution is exact";
+ should_apply("(resolution: ${resolution}dpi)");
+ should_apply("(resolution: ${Math.floor(resolution/96)}dppx)");
+ should_apply("(resolution: ${Math.floor(resolution/96)}x)");
+ should_not_apply("(resolution: ${resolution + 1}dpi)");
+ should_not_apply("(resolution: ${resolution - 1}dpi)");
+ dpi_high = resolution + 1;
+ } else {
+ // We have no way to test resolution applying since it need not be
+ // an integer.
+ testGroup = "resolution is inexact";
+ should_not_apply("(resolution: ${resolution}dpi)");
+ should_not_apply("(resolution: ${resolution - 1}dpi)");
+ dpi_high = resolution;
+ }
+ testGroup = "";
+
+ should_apply("(min-resolution: ${dpi_low}dpi)");
+ should_not_apply("not all and (min-resolution: ${dpi_low}dpi)");
+ should_apply("not all and (min-resolution: ${dpi_high}dpi)");
+ should_not_apply("all and (min-resolution: ${dpi_high}dpi)");
+
+ // Test dpcm units based on what we computed in dpi.
+ var dpcm_high = Math.ceil(dpi_high / 2.54);
+ var dpcm_low = Math.floor(dpi_low / 2.54);
+ should_apply("(min-resolution: ${dpcm_low}dpcm)");
+ should_apply("(max-resolution: ${dpcm_high}dpcm)");
+ should_not_apply("(max-resolution: ${dpcm_low}dpcm)");
+ should_apply("not all and (min-resolution: ${dpcm_high}dpcm)");
+
+ expression_should_be_known("scan");
+ expression_should_be_known("scan: progressive");
+ expression_should_be_known("scan:interlace");
+ expression_should_be_unknown("min-scan:interlace");
+ expression_should_be_unknown("scan: 1");
+ expression_should_be_unknown("max-scan");
+ expression_should_be_unknown("max-scan: progressive");
+ // Assume we don't support tv devices.
+ should_not_apply("(scan)");
+ should_not_apply("(scan: progressive)");
+ should_not_apply("(scan: interlace)");
+ should_apply("not all and (scan)");
+ should_apply("not all and (scan: progressive)");
+ should_apply("not all and (scan: interlace)");
+
+ expression_should_be_known("grid");
+ expression_should_be_known("grid: 0");
+ expression_should_be_known("grid: 1");
+ expression_should_be_unknown("min-grid");
+ expression_should_be_unknown("min-grid:0");
+ expression_should_be_unknown("max-grid: 1");
+ expression_should_be_unknown("grid: 2");
+ expression_should_be_unknown("grid: -1");
+
+ // Assume we don't support grid devices
+ should_not_apply("(grid)");
+ should_apply("(grid: 0)");
+ should_not_apply("(grid: 1)");
+ should_not_apply("(grid: 2)");
+ should_not_apply("(grid: -1)");
+
+ // Parsing tests
+ // bug 454227
+ should_apply("(orientation");
+ should_not_apply("not all and (orientation");
+ should_not_apply("(orientation:");
+ should_not_apply("(orientation:)");
+ should_not_apply("(orientation: )");
+ should_apply("all,(orientation:");
+ should_not_apply("(orientation:,all");
+ should_apply("not all and (grid");
+ should_not_apply("only all and (grid");
+ should_not_apply("(grid");
+ should_apply("all,(grid");
+ should_not_apply("(grid,all");
+ // bug 454226
+ should_apply(",all");
+ should_apply("all,");
+ should_apply(",all,");
+ should_apply("all,badmedium");
+ should_apply("badmedium,all");
+ should_not_apply(",badmedium,");
+ should_apply("all,(badexpression)");
+ should_apply("(badexpression),all");
+ should_not_apply("(badexpression),badmedium");
+ should_not_apply("badmedium,(badexpression)");
+ should_apply("all,[badsyntax]");
+ should_apply("[badsyntax],all");
+ should_not_apply("badmedium,[badsyntax]");
+ should_not_apply("[badsyntax],badmedium");
+
+ // Parsing tests based on Acid3
+ query_should_not_be_parseable("all and color :");
+ query_should_not_be_parseable("all and color : 1");
+ should_not_apply("all and min-color : 1");
+ should_not_apply("(bogus)");
+ should_not_apply("not all and (bogus)")
+ should_not_apply("only all and (bogus)")
+
+ // Parsing tests for overflow-block from mediaqueries-4
+ expression_should_be_known("overflow-block")
+ expression_should_be_known("overflow-block: none")
+ expression_should_be_known("overflow-block: paged")
+ expression_should_be_known("overflow-block: scroll")
+ expression_should_be_known("overflow-block: optional-paged")
+ expression_should_be_unknown("overflow-block: some-random-invalid-thing")
+
+ // Sanity check for overflow-block
+ test(function() {
+ var any_overflow_block = query_applies("(overflow-block)");
+ var overflow_block_none = query_applies("(overflow-block: none)");
+ assert_not_equals(any_overflow_block, overflow_block_none, "overflow-block should be equivalent to not (overflow-block: none)");
+ }, "Sanity check for overflow-block");
+
+ // Parsing tests for overflow-inline from mediaqueries-4
+ expression_should_be_known("overflow-inline")
+ expression_should_be_known("overflow-inline: none")
+ expression_should_be_known("overflow-inline: scroll")
+ expression_should_be_unknown("overflow-inline: some-random-invalid-thing")
+
+ // Sanity check for overflow-inline
+ test(function() {
+ var any_overflow_inline = query_applies("(overflow-inline)");
+ var overflow_inline_none = query_applies("(overflow-inline: none)");
+ assert_not_equals(any_overflow_inline, overflow_inline_none, "overflow-inline should be equivalent to not (overflow-inline: none)");
+ }, "Sanity check for overflow-inline");
+
+ // Parsing tests for update from mediaqueries-4
+ expression_should_be_known("update")
+ expression_should_be_known("update: none")
+ expression_should_be_known("update: slow")
+ expression_should_be_known("update: fast")
+ expression_should_be_unknown("update: some-random-invalid-thing")
+
+ // Sanity check for update
+ test(function() {
+ var any_update = query_applies("(update)");
+ var update_none = query_applies("(update: none)");
+ assert_not_equals(any_update, update_none, "update should be equivalent to not (update: none)");
+ }, "Sanity check for update");
+
+ // Parsing tests for interaction media features.
+ expression_should_be_known("hover")
+ expression_should_be_known("hover: hover")
+ expression_should_be_known("hover: none")
+ expression_should_be_known("any-hover")
+ expression_should_be_known("any-hover: hover")
+ expression_should_be_known("any-hover: none")
+
+ test(function() {
+ assert_equals(query_applies("(hover)"), query_applies("(hover: hover)"));
+ } , "(hover) == (hover: hover)");
+
+ test(function() {
+ assert_not_equals(query_applies("(hover)"), query_applies("(hover: none)"));
+ }, "(hover) == not (hover: none)");
+
+ test(function() {
+ assert_equals(query_applies("(any-hover)"), query_applies("(any-hover: hover)"));
+ }, "(any-hover) == (any-hover: hover)");
+
+ test(function() {
+ assert_not_equals(query_applies("(any-hover)"), query_applies("(any-hover: none)"));
+ }, "(any-hover) == not (any-hover: none)");
+
+ expression_should_be_known("pointer")
+ expression_should_be_known("pointer: coarse")
+ expression_should_be_known("pointer: fine")
+ expression_should_be_known("pointer: none")
+ expression_should_be_known("any-pointer")
+ expression_should_be_known("any-pointer: coarse")
+ expression_should_be_known("any-pointer: fine")
+ expression_should_be_known("any-pointer: none")
+
+ test(function() {
+ assert_equals(query_applies("(pointer)"),
+ query_applies("(pointer: coarse)") || query_applies("(pointer: fine)"));
+ }, "(pointer) == (pointer: coarse) or (pointer: fine)");
+
+ test(function() {
+ assert_not_equals(query_applies("(pointer)"),
+ query_applies("(pointer: none)"));
+ }, "(pointer) == not (pointer: none)");
+
+ test(function() {
+ assert_equals(query_applies("(any-pointer)"),
+ query_applies("(any-pointer: coarse)") || query_applies("(any-pointer: fine)"));
+ }, "(any-pointer) == (any-pointer: coarse) or (any-pointer: fine)");
+
+ test(function() {
+ assert_not_equals(query_applies("(any-pointer)"),
+ query_applies("(any-pointer: none)"));
+ }, "(any-pointer) == not (any-pointer: none)");
+
+ iframe_style.width = '100px';
+ iframe_style.height = '0px';
+
+ testGroup = "'or' keyword"
+ should_not_apply("(height) or (height)");
+ should_apply("(width) or (height)");
+ should_apply("(height) or (width)");
+ should_apply("(height) or (width) or (height)");
+ query_should_not_be_parseable("screen or (width)");
+ query_should_not_be_parseable("screen and (width) or (height)");
+
+ testGroup = "nesting"
+ should_not_apply("((height))");
+ should_apply("((width))");
+ should_apply("(((((width)))))");
+ should_apply("(((((width");
+
+ testGroup = "'not' keyword"
+ should_not_apply("not (width)");
+ should_apply("not (height)");
+ should_apply("not ((width) and (height))");
+ should_not_apply("not ((width) or (height))");
+ should_not_apply("not ((width) and (not (height)))");
+ query_should_not_be_parseable("not (width) and not (height)");
+ query_should_not_be_parseable("not not (width)");
+
+ testGroup = ""
+ done();
+}
+
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/mediaqueries/viewport-script-dynamic-ref.html b/testing/web-platform/tests/css/mediaqueries/viewport-script-dynamic-ref.html
new file mode 100644
index 0000000000..e3f1c95d66
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/viewport-script-dynamic-ref.html
@@ -0,0 +1,9 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>CSS Test Reference</title>
+<link rel="author" href="mailto:emilio@crisal.io">
+<meta name="viewport" content="width=300">
+<style>
+p { color: green; }
+</style>
+<p>Should be green</p>
diff --git a/testing/web-platform/tests/css/mediaqueries/viewport-script-dynamic.html b/testing/web-platform/tests/css/mediaqueries/viewport-script-dynamic.html
new file mode 100644
index 0000000000..7433877972
--- /dev/null
+++ b/testing/web-platform/tests/css/mediaqueries/viewport-script-dynamic.html
@@ -0,0 +1,20 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>CSS Test: Meta viewport after a script and stylesheets</title>
+<link rel="author" href="mailto:emilio@crisal.io">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1424878">
+<link rel="help" href="https://drafts.csswg.org/mediaqueries/#mf-dimensions">
+<link rel="match" href="viewport-script-dynamic-ref.html">
+<style>
+p { color: green; }
+/* Ensure that we initially match it, and stop matching it afterwards */
+@media (min-width: 310px) {
+ p {
+ color: red;
+ }
+}
+</style>
+<!-- The broken script below is the point of the test, see the bugzilla bug. -->
+<script src="intentionally-broken-url.js"></script>
+<meta name="viewport" content="width=300">
+<p>Should be green</p>