1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/layout/style/test/test_media_queries.html Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,822 @@ 1.4 +<!DOCTYPE HTML> 1.5 +<html> 1.6 +<!-- 1.7 +https://bugzilla.mozilla.org/show_bug.cgi?id=156716 1.8 +--> 1.9 +<head> 1.10 + <title>Test for Bug 156716</title> 1.11 + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> 1.12 + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> 1.13 +</head> 1.14 +<body onload="run()"> 1.15 +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=156716">Mozilla Bug 156716</a> 1.16 +<iframe id="subdoc" src="media_queries_iframe.html"></iframe> 1.17 +<div id="content" style="display: none"> 1.18 + 1.19 +</div> 1.20 +<pre id="test"> 1.21 +<script class="testbody" type="application/javascript"> 1.22 + 1.23 +/** Test for Bug 156716 **/ 1.24 + 1.25 +// Note that many other tests are in test_acid3_test46.html . 1.26 + 1.27 +SimpleTest.waitForExplicitFinish(); 1.28 + 1.29 +var iframe; 1.30 + 1.31 +function getScreenPixelsPerCSSPixel() { 1.32 + return SpecialPowers.DOMWindowUtils.screenPixelsPerCSSPixel; 1.33 +} 1.34 + 1.35 +function run() { 1.36 + iframe = document.getElementById("subdoc"); 1.37 + var subdoc = iframe.contentDocument; 1.38 + var subwin = iframe.contentWindow; 1.39 + var style = subdoc.getElementById("style"); 1.40 + var iframe_style = iframe.style; 1.41 + var body_cs = subdoc.defaultView.getComputedStyle(subdoc.body, ""); 1.42 + 1.43 + function query_applies(q) { 1.44 + style.setAttribute("media", q); 1.45 + return body_cs.getPropertyValue("text-decoration") == "underline"; 1.46 + } 1.47 + 1.48 + function should_apply(q) { 1.49 + ok(query_applies(q), q + " should apply"); 1.50 + test_serialization(q, true, true); 1.51 + } 1.52 + 1.53 + function should_not_apply(q) { 1.54 + ok(!query_applies(q), q + " should not apply"); 1.55 + test_serialization(q, true, false); 1.56 + } 1.57 + 1.58 + /* for queries that are parseable standalone but not within CSS */ 1.59 + function should_apply_unbalanced(q) { 1.60 + ok(query_applies(q), q + " should apply"); 1.61 + } 1.62 + 1.63 + /* for queries that are parseable standalone but not within CSS */ 1.64 + function should_not_apply_unbalanced(q) { 1.65 + ok(!query_applies(q), q + " should not apply"); 1.66 + } 1.67 + 1.68 + /* 1.69 + * Functions to test whether a query is parseable at all. (Should not 1.70 + * be used for parse errors within expressions.) 1.71 + */ 1.72 + var parse_test_style_element = document.createElement("style"); 1.73 + parse_test_style_element.type = "text/css"; 1.74 + parse_test_style_element.disabled = true; // for performance, hopefully 1.75 + var parse_test_style_text = document.createTextNode(""); 1.76 + parse_test_style_element.appendChild(parse_test_style_text); 1.77 + document.getElementsByTagName("head")[0] 1.78 + .appendChild(parse_test_style_element); 1.79 + 1.80 + function query_is_parseable(q) { 1.81 + parse_test_style_text.data = "@media screen, " + q + " {}"; 1.82 + var sheet = parse_test_style_element.sheet; // XXX yikes, not live! 1.83 + if (sheet.cssRules.length == 1 && 1.84 + sheet.cssRules[0].type == CSSRule.MEDIA_RULE) 1.85 + return sheet.cssRules[0].media.mediaText != "screen, not all"; 1.86 + ok(false, "unexpected result testing whether query " + q + 1.87 + " is parseable"); 1.88 + return true; // doesn't matter, we already failed 1.89 + } 1.90 + 1.91 + function query_should_be_parseable(q) { 1.92 + ok(query_is_parseable(q), "query " + q + " should be parseable"); 1.93 + test_serialization(q, false, false); 1.94 + } 1.95 + 1.96 + function query_should_not_be_parseable(q) { 1.97 + ok(!query_is_parseable(q), "query " + q + " should not be parseable"); 1.98 + } 1.99 + 1.100 + /* 1.101 + * Functions to test whether a single media expression is parseable. 1.102 + */ 1.103 + function expression_is_parseable(e) { 1.104 + style.setAttribute("media", "all and (" + e + ")"); 1.105 + return style.sheet.media.mediaText != "not all"; 1.106 + } 1.107 + 1.108 + function expression_should_be_parseable(e) { 1.109 + ok(expression_is_parseable(e), 1.110 + "expression " + e + " should be parseable"); 1.111 + test_serialization("all and (" + e + ")", false, false); 1.112 + } 1.113 + 1.114 + function expression_should_not_be_parseable(e) { 1.115 + ok(!expression_is_parseable(e), 1.116 + "expression " + e + " should not be parseable"); 1.117 + } 1.118 + 1.119 + function test_serialization(q, test_application, should_apply) { 1.120 + style.setAttribute("media", q); 1.121 + var ser1 = style.sheet.media.mediaText; 1.122 + isnot(ser1, "", "serialization of '" + q + "' should not be empty"); 1.123 + style.setAttribute("media", ser1); 1.124 + var ser2 = style.sheet.media.mediaText; 1.125 + is(ser2, ser1, "parse+serialize of '" + q + "' should be idempotent"); 1.126 + if (test_application) { 1.127 + var applies = body_cs.getPropertyValue("text-decoration") == "underline"; 1.128 + is(applies, should_apply, 1.129 + "Media query '" + q + "' should " + (should_apply ? "" : "NOT ") + 1.130 + "apply after serialize + reparse"); 1.131 + } 1.132 + 1.133 + // Test cloning 1.134 + var sheet = "@media " + q + " { body { text-decoration: underline } }" 1.135 + var sheeturl = "data:text/css," + escape(sheet); 1.136 + var link = "<link rel='stylesheet' href='" + sheeturl + "'>"; 1.137 + var htmldoc = "<!DOCTYPE HTML>" + link + link + "<body>"; 1.138 + var docurl = "data:text/html," + escape(htmldoc); 1.139 + post_clone_test(docurl, function() { 1.140 + var clonedoc = iframe.contentDocument; 1.141 + var clonewin = iframe.contentWindow; 1.142 + var links = clonedoc.getElementsByTagName("link"); 1.143 + // cause a clone 1.144 + var clonedsheet = links[1].sheet; 1.145 + clonedsheet.insertRule("#nonexistent { color: purple}", 1); 1.146 + // remove the uncloned sheet 1.147 + links[0].parentNode.removeChild(links[0]); 1.148 + 1.149 + var ser3 = clonedsheet.cssRules[0].media.mediaText; 1.150 + is(ser3, ser1, "cloning query '" + q + "' should not change " + 1.151 + "serialization"); 1.152 + if (test_application) { 1.153 + var applies = clonewin.getComputedStyle(clonedoc.body, ""). 1.154 + textDecoration == "underline"; 1.155 + is(applies, should_apply, 1.156 + "Media query '" + q + "' should " + (should_apply ? "" : "NOT ") + 1.157 + "apply after cloning"); 1.158 + } 1.159 + }); 1.160 + } 1.161 + 1.162 + // The no-type syntax doesn't mix with the not and only keywords. 1.163 + query_should_be_parseable("(orientation)"); 1.164 + query_should_not_be_parseable("not (orientation)"); 1.165 + query_should_not_be_parseable("only (orientation)"); 1.166 + query_should_be_parseable("all and (orientation)"); 1.167 + query_should_be_parseable("not all and (orientation)"); 1.168 + query_should_be_parseable("only all and (orientation)"); 1.169 + 1.170 + query_should_be_parseable("(-moz-device-orientation)"); 1.171 + query_should_not_be_parseable("not (-moz-device-orientation)"); 1.172 + query_should_not_be_parseable("only (-moz-device-orientation)"); 1.173 + query_should_be_parseable("all and (-moz-device-orientation)"); 1.174 + query_should_be_parseable("not all and (-moz-device-orientation)"); 1.175 + query_should_be_parseable("only all and (-moz-device-orientation)"); 1.176 + 1.177 + // Test that the 'not', 'only', 'and', and 'or' keywords are not 1.178 + // allowed as media types. 1.179 + query_should_not_be_parseable("not"); 1.180 + query_should_not_be_parseable("and"); 1.181 + query_should_not_be_parseable("or"); 1.182 + query_should_not_be_parseable("only"); 1.183 + query_should_be_parseable("unknowntype"); 1.184 + query_should_not_be_parseable("not not"); 1.185 + query_should_not_be_parseable("not and"); 1.186 + query_should_not_be_parseable("not or"); 1.187 + query_should_not_be_parseable("not only"); 1.188 + query_should_be_parseable("not unknowntype"); 1.189 + query_should_not_be_parseable("only not"); 1.190 + query_should_not_be_parseable("only and"); 1.191 + query_should_not_be_parseable("only or"); 1.192 + query_should_not_be_parseable("only only"); 1.193 + query_should_be_parseable("only unknowntype"); 1.194 + query_should_not_be_parseable("not and (width)"); 1.195 + query_should_not_be_parseable("and and (width)"); 1.196 + query_should_not_be_parseable("or and (width)"); 1.197 + query_should_not_be_parseable("only and (width)"); 1.198 + query_should_be_parseable("unknowntype and (width)"); 1.199 + query_should_not_be_parseable("not not and (width)"); 1.200 + query_should_not_be_parseable("not and and (width)"); 1.201 + query_should_not_be_parseable("not or and (width)"); 1.202 + query_should_not_be_parseable("not only and (width)"); 1.203 + query_should_be_parseable("not unknowntype and (width)"); 1.204 + query_should_not_be_parseable("only not and (width)"); 1.205 + query_should_not_be_parseable("only and and (width)"); 1.206 + query_should_not_be_parseable("only or and (width)"); 1.207 + query_should_not_be_parseable("only only and (width)"); 1.208 + query_should_be_parseable("only unknowntype and (width)"); 1.209 + 1.210 + var features = [ "width", "height", "device-width", "device-height" ]; 1.211 + var feature; 1.212 + var i; 1.213 + for (i in features) { 1.214 + feature = features[i]; 1.215 + expression_should_be_parseable(feature); 1.216 + expression_should_be_parseable(feature + ": 0"); 1.217 + expression_should_be_parseable(feature + ": 0px"); 1.218 + expression_should_be_parseable(feature + ": 0em"); 1.219 + expression_should_be_parseable(feature + ": -0"); 1.220 + expression_should_be_parseable("min-" + feature + ": -0"); 1.221 + expression_should_be_parseable("max-" + feature + ": -0"); 1.222 + expression_should_be_parseable(feature + ": -0cm"); 1.223 + expression_should_be_parseable(feature + ": 1px"); 1.224 + expression_should_be_parseable(feature + ": 0.001mm"); 1.225 + expression_should_be_parseable(feature + ": 100000px"); 1.226 + expression_should_not_be_parseable(feature + ": -1px"); 1.227 + expression_should_not_be_parseable("min-" + feature + ": -1px"); 1.228 + expression_should_not_be_parseable("max-" + feature + ": -1px"); 1.229 + expression_should_not_be_parseable(feature + ": -0.00001mm"); 1.230 + expression_should_not_be_parseable(feature + ": -100000em"); 1.231 + expression_should_not_be_parseable("min-" + feature); 1.232 + expression_should_not_be_parseable("max-" + feature); 1.233 + } 1.234 + 1.235 + var content_div = document.getElementById("content"); 1.236 + content_div.style.font = "initial"; 1.237 + var em_size = 1.238 + getComputedStyle(content_div, "").fontSize.match(/^(\d+)px$/)[1]; 1.239 + 1.240 + // in this test, assume the common underlying implementation is correct 1.241 + var width_val = 117; // pick two not-too-round numbers 1.242 + var height_val = 76; 1.243 + change_state(function() { 1.244 + iframe_style.width = width_val + "px"; 1.245 + iframe_style.height = height_val + "px"; 1.246 + }); 1.247 + var device_width = window.screen.width; 1.248 + var device_height = window.screen.height; 1.249 + features = { "width": width_val, 1.250 + "height": height_val, 1.251 + "device-width": device_width, 1.252 + "device-height": device_height }; 1.253 + for (feature in features) { 1.254 + var value = features[feature]; 1.255 + should_apply("all and (" + feature + ": " + value + "px)"); 1.256 + should_not_apply("all and (" + feature + ": " + (value + 1) + "px)"); 1.257 + should_not_apply("all and (" + feature + ": " + (value - 1) + "px)"); 1.258 + should_apply("all and (min-" + feature + ": " + value + "px)"); 1.259 + should_not_apply("all and (min-" + feature + ": " + (value + 1) + "px)"); 1.260 + should_apply("all and (min-" + feature + ": " + (value - 1) + "px)"); 1.261 + should_apply("all and (max-" + feature + ": " + value + "px)"); 1.262 + should_apply("all and (max-" + feature + ": " + (value + 1) + "px)"); 1.263 + should_not_apply("all and (max-" + feature + ": " + (value - 1) + "px)"); 1.264 + should_not_apply("all and (min-" + feature + ": " + 1.265 + (Math.ceil(value/em_size) + 1) + "em)"); 1.266 + should_apply("all and (min-" + feature + ": " + 1.267 + (Math.floor(value/em_size) - 1) + "em)"); 1.268 + should_apply("all and (max-" + feature + ": " + 1.269 + (Math.ceil(value/em_size) + 1) + "em)"); 1.270 + should_not_apply("all and (max-" + feature + ": " + 1.271 + (Math.floor(value/em_size) - 1) + "em)"); 1.272 + should_not_apply("all and (min-" + feature + ": " + 1.273 + (Math.ceil(value/em_size) + 1) + "rem)"); 1.274 + should_apply("all and (min-" + feature + ": " + 1.275 + (Math.floor(value/em_size) - 1) + "rem)"); 1.276 + should_apply("all and (max-" + feature + ": " + 1.277 + (Math.ceil(value/em_size) + 1) + "rem)"); 1.278 + should_not_apply("all and (max-" + feature + ": " + 1.279 + (Math.floor(value/em_size) - 1) + "rem)"); 1.280 + } 1.281 + 1.282 + change_state(function() { 1.283 + iframe_style.width = "0"; 1.284 + }); 1.285 + should_apply("all and (height)"); 1.286 + should_not_apply("all and (width)"); 1.287 + change_state(function() { 1.288 + iframe_style.height = "0"; 1.289 + }); 1.290 + should_not_apply("all and (height)"); 1.291 + should_not_apply("all and (width)"); 1.292 + should_apply("all and (device-height)"); 1.293 + should_apply("all and (device-width)"); 1.294 + change_state(function() { 1.295 + iframe_style.width = width_val + "px"; 1.296 + }); 1.297 + should_not_apply("all and (height)"); 1.298 + should_apply("all and (width)"); 1.299 + change_state(function() { 1.300 + iframe_style.height = height_val + "px"; 1.301 + }); 1.302 + should_apply("all and (height)"); 1.303 + should_apply("all and (width)"); 1.304 + 1.305 + // ratio that reduces to 59/40 1.306 + change_state(function() { 1.307 + iframe_style.width = "236px"; 1.308 + iframe_style.height = "160px"; 1.309 + }); 1.310 + expression_should_be_parseable("orientation"); 1.311 + expression_should_be_parseable("orientation: portrait"); 1.312 + expression_should_be_parseable("orientation: landscape"); 1.313 + expression_should_not_be_parseable("min-orientation"); 1.314 + expression_should_not_be_parseable("min-orientation: portrait"); 1.315 + expression_should_not_be_parseable("min-orientation: landscape"); 1.316 + expression_should_not_be_parseable("max-orientation"); 1.317 + expression_should_not_be_parseable("max-orientation: portrait"); 1.318 + expression_should_not_be_parseable("max-orientation: landscape"); 1.319 + should_apply("(orientation)"); 1.320 + should_apply("(orientation: landscape)"); 1.321 + should_not_apply("(orientation: portrait)"); 1.322 + should_apply("not all and (orientation: portrait)"); 1.323 + // ratio that reduces to 59/80 1.324 + change_state(function() { 1.325 + iframe_style.height = "320px"; 1.326 + }); 1.327 + should_apply("(orientation)"); 1.328 + should_not_apply("(orientation: landscape)"); 1.329 + should_apply("not all and (orientation: landscape)"); 1.330 + should_apply("(orientation: portrait)"); 1.331 + 1.332 + expression_should_be_parseable("-moz-device-orientation"); 1.333 + expression_should_be_parseable("-moz-device-orientation: portrait"); 1.334 + expression_should_be_parseable("-moz-device-orientation: landscape"); 1.335 + expression_should_not_be_parseable("min--moz-device-orientation"); 1.336 + expression_should_not_be_parseable("min--moz-device-orientation: portrait"); 1.337 + expression_should_not_be_parseable("min--moz-device-orientation: landscape"); 1.338 + expression_should_not_be_parseable("max--moz-device-orientation"); 1.339 + expression_should_not_be_parseable("max--moz-device-orientation: portrait"); 1.340 + expression_should_not_be_parseable("max--moz-device-orientation: landscape"); 1.341 + 1.342 + // determine the actual configuration of the screen and test against it 1.343 + var device_orientation = (device_width > device_height) ? "landscape" : "portrait"; 1.344 + var not_device_orientation = (device_orientation == "landscape") ? "portrait" : "landscape"; 1.345 + should_apply("(-moz-device-orientation)"); 1.346 + should_apply("(-moz-device-orientation: " + device_orientation + ")"); 1.347 + should_not_apply("(-moz-device-orientation: " + not_device_orientation + ")"); 1.348 + should_apply("not all and (-moz-device-orientation: " + not_device_orientation + ")"); 1.349 + 1.350 + should_apply("(aspect-ratio: 59/80)"); 1.351 + should_not_apply("(aspect-ratio: 58/80)"); 1.352 + should_not_apply("(aspect-ratio: 59/81)"); 1.353 + should_not_apply("(aspect-ratio: 60/80)"); 1.354 + should_not_apply("(aspect-ratio: 59/79)"); 1.355 + should_apply("(aspect-ratio: 177/240)"); 1.356 + should_apply("(aspect-ratio: 413/560)"); 1.357 + should_apply("(aspect-ratio: 5900/8000)"); 1.358 + should_not_apply("(aspect-ratio: 5901/8000)"); 1.359 + should_not_apply("(aspect-ratio: 5899/8000)"); 1.360 + should_not_apply("(aspect-ratio: 5900/8001)"); 1.361 + should_not_apply("(aspect-ratio: 5900/7999)"); 1.362 + should_apply("(aspect-ratio)"); 1.363 + 1.364 + should_apply("(min-aspect-ratio: 59/80)"); 1.365 + should_apply("(min-aspect-ratio: 58/80)"); 1.366 + should_apply("(min-aspect-ratio: 59/81)"); 1.367 + should_not_apply("(min-aspect-ratio: 60/80)"); 1.368 + should_not_apply("(min-aspect-ratio: 59/79)"); 1.369 + expression_should_not_be_parseable("min-aspect-ratio"); 1.370 + 1.371 + should_apply("(max-aspect-ratio: 59/80)"); 1.372 + should_not_apply("(max-aspect-ratio: 58/80)"); 1.373 + should_not_apply("(max-aspect-ratio: 59/81)"); 1.374 + should_apply("(max-aspect-ratio: 60/80)"); 1.375 + should_apply("(max-aspect-ratio: 59/79)"); 1.376 + expression_should_not_be_parseable("max-aspect-ratio"); 1.377 + 1.378 + var real_dar = device_width + "/" + device_height; 1.379 + var high_dar_1 = (device_width + 1) + "/" + device_height; 1.380 + var high_dar_2 = device_width + "/" + (device_height - 1); 1.381 + var low_dar_1 = (device_width - 1) + "/" + device_height; 1.382 + var low_dar_2 = device_width + "/" + (device_height + 1); 1.383 + should_apply("(device-aspect-ratio: " + real_dar + ")"); 1.384 + should_apply("not all and (device-aspect-ratio: " + high_dar_1 + ")"); 1.385 + should_not_apply("all and (device-aspect-ratio: " + high_dar_2 + ")"); 1.386 + should_not_apply("all and (device-aspect-ratio: " + low_dar_1 + ")"); 1.387 + should_apply("not all and (device-aspect-ratio: " + low_dar_2 + ")"); 1.388 + should_apply("(device-aspect-ratio)"); 1.389 + 1.390 + should_apply("(min-device-aspect-ratio: " + real_dar + ")"); 1.391 + should_not_apply("all and (min-device-aspect-ratio: " + high_dar_1 + ")"); 1.392 + should_apply("not all and (min-device-aspect-ratio: " + high_dar_2 + ")"); 1.393 + should_not_apply("not all and (min-device-aspect-ratio: " + low_dar_1 + ")"); 1.394 + should_apply("all and (min-device-aspect-ratio: " + low_dar_2 + ")"); 1.395 + expression_should_not_be_parseable("min-device-aspect-ratio"); 1.396 + 1.397 + should_apply("all and (max-device-aspect-ratio: " + real_dar + ")"); 1.398 + should_apply("(max-device-aspect-ratio: " + high_dar_1 + ")"); 1.399 + should_apply("(max-device-aspect-ratio: " + high_dar_2 + ")"); 1.400 + should_not_apply("all and (max-device-aspect-ratio: " + low_dar_1 + ")"); 1.401 + should_apply("not all and (max-device-aspect-ratio: " + low_dar_2 + ")"); 1.402 + expression_should_not_be_parseable("max-device-aspect-ratio"); 1.403 + 1.404 + var real_dpr = 1.0 * getScreenPixelsPerCSSPixel(); 1.405 + var high_dpr = 1.1 * getScreenPixelsPerCSSPixel(); 1.406 + var low_dpr = 0.9 * getScreenPixelsPerCSSPixel(); 1.407 + should_apply("all and (max--moz-device-pixel-ratio: " + real_dpr + ")"); 1.408 + should_apply("all and (min--moz-device-pixel-ratio: " + real_dpr + ")"); 1.409 + should_not_apply("not all and (max--moz-device-pixel-ratio: " + real_dpr + ")"); 1.410 + should_not_apply("not all and (min--moz-device-pixel-ratio: " + real_dpr + ")"); 1.411 + should_apply("all and (min--moz-device-pixel-ratio: " + low_dpr + ")"); 1.412 + should_apply("all and (max--moz-device-pixel-ratio: " + high_dpr + ")"); 1.413 + should_not_apply("all and (max--moz-device-pixel-ratio: " + low_dpr + ")"); 1.414 + should_not_apply("all and (min--moz-device-pixel-ratio: " + high_dpr + ")"); 1.415 + should_apply("not all and (max--moz-device-pixel-ratio: " + low_dpr + ")"); 1.416 + should_apply("not all and (min--moz-device-pixel-ratio: " + high_dpr + ")"); 1.417 + should_apply("(-moz-device-pixel-ratio: " + real_dpr + ")"); 1.418 + should_not_apply("(-moz-device-pixel-ratio: " + high_dpr + ")"); 1.419 + should_not_apply("(-moz-device-pixel-ratio: " + low_dpr + ")"); 1.420 + should_apply("(-moz-device-pixel-ratio)"); 1.421 + expression_should_not_be_parseable("min--moz-device-pixel-ratio"); 1.422 + expression_should_not_be_parseable("max--moz-device-pixel-ratio"); 1.423 + 1.424 + features = [ "max-aspect-ratio", "device-aspect-ratio" ]; 1.425 + for (i in features) { 1.426 + feature = features[i]; 1.427 + expression_should_be_parseable(feature + ": 1/1"); 1.428 + expression_should_be_parseable(feature + ": 1 /1"); 1.429 + expression_should_be_parseable(feature + ": 1 / \t\n1"); 1.430 + expression_should_be_parseable(feature + ": 1/\r1"); 1.431 + expression_should_not_be_parseable(feature + ": 1"); 1.432 + expression_should_not_be_parseable(feature + ": 0.5"); 1.433 + expression_should_not_be_parseable(feature + ": 1.0/1"); 1.434 + expression_should_not_be_parseable(feature + ": 1/1.0"); 1.435 + expression_should_not_be_parseable(feature + ": 1.0/1.0"); 1.436 + expression_should_not_be_parseable(feature + ": 0/1"); 1.437 + expression_should_not_be_parseable(feature + ": 1/0"); 1.438 + expression_should_not_be_parseable(feature + ": 0/0"); 1.439 + expression_should_not_be_parseable(feature + ": -1/1"); 1.440 + expression_should_not_be_parseable(feature + ": 1/-1"); 1.441 + expression_should_not_be_parseable(feature + ": -1/-1"); 1.442 + } 1.443 + 1.444 + var is_monochrome = query_applies("all and (min-monochrome: 1)"); 1.445 + test_serialization("all and (min-monochrome: 1)", true, is_monochrome); 1.446 + var is_color = query_applies("all and (min-color: 1)"); 1.447 + test_serialization("all and (min-color: 1)", true, is_color); 1.448 + isnot(is_monochrome, is_color, "should be either monochrome or color"); 1.449 + 1.450 + function depth_query(prefix, depth) { 1.451 + return "all and (" + prefix + (is_color ? "color" : "monochrome") + 1.452 + ":" + depth + ")"; 1.453 + } 1.454 + 1.455 + var depth = 0; 1.456 + do { 1.457 + if (depth > 50) { 1.458 + ok(false, "breaking from loop, depth > 50"); 1.459 + break; 1.460 + } 1.461 + } while (query_applies(depth_query("min-", ++depth))); 1.462 + --depth; 1.463 + 1.464 + should_apply(depth_query("", depth)); 1.465 + should_not_apply(depth_query("", depth - 1)); 1.466 + should_not_apply(depth_query("", depth + 1)); 1.467 + should_apply(depth_query("max-", depth)); 1.468 + should_not_apply(depth_query("max-", depth - 1)); 1.469 + should_apply(depth_query("max-", depth + 1)); 1.470 + 1.471 + (is_color ? should_apply : should_not_apply)("all and (color)"); 1.472 + expression_should_not_be_parseable("max-color"); 1.473 + expression_should_not_be_parseable("min-color"); 1.474 + (is_color ? should_not_apply : should_apply)("all and (monochrome)"); 1.475 + expression_should_not_be_parseable("max-monochrome"); 1.476 + expression_should_not_be_parseable("min-monochrome"); 1.477 + (is_color ? should_apply : should_not_apply)("not all and (monochrome)"); 1.478 + (is_color ? should_not_apply : should_apply)("not all and (color)"); 1.479 + (is_color ? should_apply : should_not_apply)("only all and (color)"); 1.480 + (is_color ? should_not_apply : should_apply)("only all and (monochrome)"); 1.481 + 1.482 + features = [ "color", "min-monochrome", "max-color-index" ]; 1.483 + for (i in features) { 1.484 + feature = features[i]; 1.485 + expression_should_be_parseable(feature + ": 1"); 1.486 + expression_should_be_parseable(feature + ": 327"); 1.487 + expression_should_be_parseable(feature + ": 0"); 1.488 + expression_should_not_be_parseable(feature + ": 1.0"); 1.489 + expression_should_not_be_parseable(feature + ": -1"); 1.490 + expression_should_not_be_parseable(feature + ": 1/1"); 1.491 + } 1.492 + 1.493 + // Presume that we never support indexed color (at least not usefully 1.494 + // enough to call it indexed color). 1.495 + should_apply("(color-index: 0)"); 1.496 + should_not_apply("(color-index: 1)"); 1.497 + should_apply("(min-color-index: 0)"); 1.498 + should_not_apply("(min-color-index: 1)"); 1.499 + should_apply("(max-color-index: 0)"); 1.500 + should_apply("(max-color-index: 1)"); 1.501 + should_apply("(max-color-index: 157)"); 1.502 + 1.503 + features = [ "resolution", "min-resolution", "max-resolution" ]; 1.504 + for (i in features) { 1.505 + feature = features[i]; 1.506 + expression_should_be_parseable(feature + ": 3dpi"); 1.507 + expression_should_be_parseable(feature + ":3dpi"); 1.508 + expression_should_be_parseable(feature + ": 3.0dpi"); 1.509 + expression_should_be_parseable(feature + ": 3.4dpi"); 1.510 + expression_should_be_parseable(feature + "\t: 120dpcm"); 1.511 + expression_should_be_parseable(feature + ": 1dppx"); 1.512 + expression_should_be_parseable(feature + ": 1.5dppx"); 1.513 + expression_should_be_parseable(feature + ": 2.0dppx"); 1.514 + expression_should_not_be_parseable(feature + ": 0dpi"); 1.515 + expression_should_not_be_parseable(feature + ": -3dpi"); 1.516 + expression_should_not_be_parseable(feature + ": 0dppx"); 1.517 + } 1.518 + 1.519 + // Find the resolution using max-resolution 1.520 + var resolution = 0; 1.521 + do { 1.522 + ++resolution; 1.523 + if (resolution > 10000) { 1.524 + ok(false, "resolution greater than 10000dpi???"); 1.525 + break; 1.526 + } 1.527 + } while (!query_applies("(max-resolution: " + resolution + "dpi)")); 1.528 + 1.529 + // resolution should now be Math.ceil() of the actual resolution. 1.530 + var dpi_high; 1.531 + var dpi_low = resolution - 1; 1.532 + if (query_applies("(min-resolution: " + resolution + "dpi)")) { 1.533 + // It's exact! 1.534 + should_apply("(resolution: " + resolution + "dpi)"); 1.535 + should_apply("(resolution: " + Math.floor(resolution/96) + "dppx)"); 1.536 + should_not_apply("(resolution: " + (resolution + 1) + "dpi)"); 1.537 + should_not_apply("(resolution: " + (resolution - 1) + "dpi)"); 1.538 + dpi_high = resolution + 1; 1.539 + } else { 1.540 + // We have no way to test resolution applying since it need not be 1.541 + // an integer. 1.542 + should_not_apply("(resolution: " + resolution + "dpi)"); 1.543 + should_not_apply("(resolution: " + (resolution - 1) + "dpi)"); 1.544 + dpi_high = resolution; 1.545 + } 1.546 + 1.547 + should_apply("(min-resolution: " + dpi_low + "dpi)"); 1.548 + should_not_apply("not all and (min-resolution: " + dpi_low + "dpi)"); 1.549 + should_apply("not all and (min-resolution: " + dpi_high + "dpi)"); 1.550 + should_not_apply("all and (min-resolution: " + dpi_high + "dpi)"); 1.551 + 1.552 + // Test dpcm units based on what we computed in dpi. 1.553 + var dpcm_high = Math.ceil(dpi_high / 2.54); 1.554 + var dpcm_low = Math.floor(dpi_low / 2.54); 1.555 + should_apply("(min-resolution: " + dpcm_low + "dpcm)"); 1.556 + should_apply("(max-resolution: " + dpcm_high + "dpcm)"); 1.557 + should_not_apply("(max-resolution: " + dpcm_low + "dpcm)"); 1.558 + should_apply("not all and (min-resolution: " + dpcm_high + "dpcm)"); 1.559 + 1.560 + expression_should_be_parseable("scan"); 1.561 + expression_should_be_parseable("scan: progressive"); 1.562 + expression_should_be_parseable("scan:interlace"); 1.563 + expression_should_not_be_parseable("min-scan:interlace"); 1.564 + expression_should_not_be_parseable("scan: 1"); 1.565 + expression_should_not_be_parseable("max-scan"); 1.566 + expression_should_not_be_parseable("max-scan: progressive"); 1.567 + // Assume we don't support tv devices. 1.568 + should_not_apply("(scan)"); 1.569 + should_not_apply("(scan: progressive)"); 1.570 + should_not_apply("(scan: interlace)"); 1.571 + should_apply("not all and (scan)"); 1.572 + should_apply("not all and (scan: progressive)"); 1.573 + should_apply("not all and (scan: interlace)"); 1.574 + 1.575 + expression_should_be_parseable("grid"); 1.576 + expression_should_be_parseable("grid: 0"); 1.577 + expression_should_be_parseable("grid: 1"); 1.578 + expression_should_be_parseable("grid: 1"); 1.579 + expression_should_not_be_parseable("min-grid"); 1.580 + expression_should_not_be_parseable("min-grid:0"); 1.581 + expression_should_not_be_parseable("max-grid: 1"); 1.582 + expression_should_not_be_parseable("grid: 2"); 1.583 + expression_should_not_be_parseable("grid: -1"); 1.584 + 1.585 + // Assume we don't support grid devices 1.586 + should_not_apply("(grid)"); 1.587 + should_apply("(grid: 0)"); 1.588 + should_not_apply("(grid: 1)"); 1.589 + should_not_apply("(grid: 2)"); 1.590 + should_not_apply("(grid: -1)"); 1.591 + 1.592 + // System metrics 1.593 + expression_should_be_parseable("-moz-scrollbar-start-backward"); 1.594 + expression_should_be_parseable("-moz-scrollbar-start-forward"); 1.595 + expression_should_be_parseable("-moz-scrollbar-end-backward"); 1.596 + expression_should_be_parseable("-moz-scrollbar-end-forward"); 1.597 + expression_should_be_parseable("-moz-scrollbar-thumb-proportional"); 1.598 + expression_should_be_parseable("-moz-images-in-menus"); 1.599 + expression_should_be_parseable("-moz-images-in-buttons"); 1.600 + expression_should_be_parseable("-moz-overlay-scrollbars"); 1.601 + expression_should_be_parseable("-moz-windows-default-theme"); 1.602 + expression_should_be_parseable("-moz-mac-graphite-theme"); 1.603 + expression_should_be_parseable("-moz-mac-lion-theme"); 1.604 + expression_should_be_parseable("-moz-windows-compositor"); 1.605 + expression_should_be_parseable("-moz-windows-classic"); 1.606 + expression_should_be_parseable("-moz-windows-glass"); 1.607 + expression_should_be_parseable("-moz-touch-enabled"); 1.608 + expression_should_be_parseable("-moz-swipe-animation-enabled"); 1.609 + 1.610 + expression_should_be_parseable("-moz-scrollbar-start-backward: 0"); 1.611 + expression_should_be_parseable("-moz-scrollbar-start-forward: 0"); 1.612 + expression_should_be_parseable("-moz-scrollbar-end-backward: 0"); 1.613 + expression_should_be_parseable("-moz-scrollbar-end-forward: 0"); 1.614 + expression_should_be_parseable("-moz-scrollbar-thumb-proportional: 0"); 1.615 + expression_should_be_parseable("-moz-images-in-menus: 0"); 1.616 + expression_should_be_parseable("-moz-images-in-buttons: 0"); 1.617 + expression_should_be_parseable("-moz-overlay-scrollbars: 0"); 1.618 + expression_should_be_parseable("-moz-windows-default-theme: 0"); 1.619 + expression_should_be_parseable("-moz-mac-graphite-theme: 0"); 1.620 + expression_should_be_parseable("-moz-mac-lion-theme: 0"); 1.621 + expression_should_be_parseable("-moz-windows-compositor: 0"); 1.622 + expression_should_be_parseable("-moz-windows-classic: 0"); 1.623 + expression_should_be_parseable("-moz-windows-glass: 0"); 1.624 + expression_should_be_parseable("-moz-touch-enabled: 0"); 1.625 + expression_should_be_parseable("-moz-swipe-animation-enabled: 0"); 1.626 + 1.627 + expression_should_be_parseable("-moz-scrollbar-start-backward: 1"); 1.628 + expression_should_be_parseable("-moz-scrollbar-start-forward: 1"); 1.629 + expression_should_be_parseable("-moz-scrollbar-end-backward: 1"); 1.630 + expression_should_be_parseable("-moz-scrollbar-end-forward: 1"); 1.631 + expression_should_be_parseable("-moz-scrollbar-thumb-proportional: 1"); 1.632 + expression_should_be_parseable("-moz-images-in-menus: 1"); 1.633 + expression_should_be_parseable("-moz-images-in-buttons: 1"); 1.634 + expression_should_be_parseable("-moz-overlay-scrollbars: 1"); 1.635 + expression_should_be_parseable("-moz-windows-default-theme: 1"); 1.636 + expression_should_be_parseable("-moz-mac-graphite-theme: 1"); 1.637 + expression_should_be_parseable("-moz-mac-lion-theme: 1"); 1.638 + expression_should_be_parseable("-moz-windows-compositor: 1"); 1.639 + expression_should_be_parseable("-moz-windows-classic: 1"); 1.640 + expression_should_be_parseable("-moz-windows-glass: 1"); 1.641 + expression_should_be_parseable("-moz-touch-enabled: 1"); 1.642 + expression_should_be_parseable("-moz-swipe-animation-enabled: 1"); 1.643 + 1.644 + expression_should_not_be_parseable("-moz-scrollbar-start-backward: -1"); 1.645 + expression_should_not_be_parseable("-moz-scrollbar-start-forward: -1"); 1.646 + expression_should_not_be_parseable("-moz-scrollbar-end-backward: -1"); 1.647 + expression_should_not_be_parseable("-moz-scrollbar-end-forward: -1"); 1.648 + expression_should_not_be_parseable("-moz-scrollbar-thumb-proportional: -1"); 1.649 + expression_should_not_be_parseable("-moz-images-in-menus: -1"); 1.650 + expression_should_not_be_parseable("-moz-images-in-buttons: -1"); 1.651 + expression_should_not_be_parseable("-moz-overlay-scrollbars: -1"); 1.652 + expression_should_not_be_parseable("-moz-windows-default-theme: -1"); 1.653 + expression_should_not_be_parseable("-moz-mac-graphite-theme: -1"); 1.654 + expression_should_not_be_parseable("-moz-mac-lion-theme: -1"); 1.655 + expression_should_not_be_parseable("-moz-windows-compositor: -1"); 1.656 + expression_should_not_be_parseable("-moz-windows-classic: -1"); 1.657 + expression_should_not_be_parseable("-moz-windows-glass: -1"); 1.658 + expression_should_not_be_parseable("-moz-touch-enabled: -1"); 1.659 + expression_should_not_be_parseable("-moz-swipe-animation-enabled: -1"); 1.660 + 1.661 + expression_should_not_be_parseable("-moz-scrollbar-start-backward: true"); 1.662 + expression_should_not_be_parseable("-moz-scrollbar-start-forward: true"); 1.663 + expression_should_not_be_parseable("-moz-scrollbar-end-backward: true"); 1.664 + expression_should_not_be_parseable("-moz-scrollbar-end-forward: true"); 1.665 + expression_should_not_be_parseable("-moz-scrollbar-thumb-proportional: true"); 1.666 + expression_should_not_be_parseable("-moz-images-in-menus: true"); 1.667 + expression_should_not_be_parseable("-moz-images-in-buttons: true"); 1.668 + expression_should_not_be_parseable("-moz-overlay-scrollbars: true"); 1.669 + expression_should_not_be_parseable("-moz-windows-default-theme: true"); 1.670 + expression_should_not_be_parseable("-moz-mac-graphite-theme: true"); 1.671 + expression_should_not_be_parseable("-moz-mac-lion-theme: true"); 1.672 + expression_should_not_be_parseable("-moz-windows-compositor: true"); 1.673 + expression_should_not_be_parseable("-moz-windows-classic: true"); 1.674 + expression_should_not_be_parseable("-moz-windows-glass: true"); 1.675 + expression_should_not_be_parseable("-moz-touch-enabled: true"); 1.676 + expression_should_not_be_parseable("-moz-swipe-animation-enabled: true"); 1.677 + 1.678 + // windows theme media queries 1.679 + expression_should_be_parseable("-moz-windows-theme: aero"); 1.680 + expression_should_be_parseable("-moz-windows-theme: aero-lite"); 1.681 + expression_should_be_parseable("-moz-windows-theme: luna-blue"); 1.682 + expression_should_be_parseable("-moz-windows-theme: luna-olive"); 1.683 + expression_should_be_parseable("-moz-windows-theme: luna-silver"); 1.684 + expression_should_be_parseable("-moz-windows-theme: royale"); 1.685 + expression_should_be_parseable("-moz-windows-theme: generic"); 1.686 + expression_should_be_parseable("-moz-windows-theme: zune"); 1.687 + expression_should_be_parseable("-moz-windows-theme: garbage"); 1.688 + expression_should_not_be_parseable("-moz-windows-theme: ''"); 1.689 + expression_should_not_be_parseable("-moz-windows-theme: "); 1.690 + 1.691 + // os version media queries (currently windows only) 1.692 + expression_should_be_parseable("-moz-os-version: windows-xp"); 1.693 + expression_should_be_parseable("-moz-os-version: windows-vista"); 1.694 + expression_should_be_parseable("-moz-os-version: windows-win7"); 1.695 + expression_should_be_parseable("-moz-os-version: windows-win8"); 1.696 + expression_should_not_be_parseable("-moz-os-version: "); 1.697 + 1.698 + // OpenType SVG media features 1.699 + query_should_be_parseable("(-moz-is-glyph)"); 1.700 + query_should_not_be_parseable("not (-moz-is-glyph)"); 1.701 + query_should_not_be_parseable("only (-moz-is-glyph)"); 1.702 + query_should_be_parseable("all and (-moz-is-glyph)"); 1.703 + query_should_be_parseable("not all and (-moz-is-glyph)"); 1.704 + query_should_be_parseable("only all and (-moz-is-glyph)"); 1.705 + 1.706 + query_should_be_parseable("(-moz-is-glyph:0)"); 1.707 + query_should_not_be_parseable("not (-moz-is-glyph:0)"); 1.708 + query_should_not_be_parseable("only (-moz-is-glyph:0)"); 1.709 + query_should_be_parseable("all and (-moz-is-glyph:0)"); 1.710 + query_should_be_parseable("not all and (-moz-is-glyph:0)"); 1.711 + query_should_be_parseable("only all and (-moz-is-glyph:0)"); 1.712 + 1.713 + query_should_be_parseable("(-moz-is-glyph:1)"); 1.714 + query_should_not_be_parseable("not (-moz-is-glyph:1)"); 1.715 + query_should_not_be_parseable("only (-moz-is-glyph:1)"); 1.716 + query_should_be_parseable("all and (-moz-is-glyph:1)"); 1.717 + query_should_be_parseable("not all and (-moz-is-glyph:1)"); 1.718 + query_should_be_parseable("only all and (-moz-is-glyph:1)"); 1.719 + 1.720 + query_should_not_be_parseable("(min--moz-is-glyph:0)"); 1.721 + query_should_not_be_parseable("(max--moz-is-glyph:0)"); 1.722 + query_should_not_be_parseable("(min--moz-is-glyph:1)"); 1.723 + query_should_not_be_parseable("(max--moz-is-glyph:1)"); 1.724 + 1.725 + should_apply("not all and (-moz-is-glyph)"); 1.726 + should_apply("(-moz-is-glyph:0)"); 1.727 + should_apply("not all and (-moz-is-glyph:1)"); 1.728 + should_apply("only all and (-moz-is-glyph:0)"); 1.729 + should_not_apply("(-moz-is-glyph)"); 1.730 + should_not_apply("(-moz-is-glyph:1)"); 1.731 + should_not_apply("not all and (-moz-is-glyph:0)"); 1.732 + should_not_apply("only all and (-moz-is-glyph:1)"); 1.733 + 1.734 + // Parsing tests 1.735 + // bug 454227 1.736 + should_apply_unbalanced("(orientation"); 1.737 + should_not_apply_unbalanced("not all and (orientation"); 1.738 + should_not_apply_unbalanced("(orientation:"); 1.739 + should_apply_unbalanced("all,(orientation:"); 1.740 + should_not_apply_unbalanced("(orientation:,all"); 1.741 + should_apply_unbalanced("not all and (grid"); 1.742 + should_not_apply_unbalanced("only all and (grid"); 1.743 + should_not_apply_unbalanced("(grid"); 1.744 + should_apply_unbalanced("all,(grid"); 1.745 + should_not_apply_unbalanced("(grid,all"); 1.746 + // bug 454226 1.747 + should_apply(",all"); 1.748 + should_apply("all,"); 1.749 + should_apply(",all,"); 1.750 + should_apply("all,badmedium"); 1.751 + should_apply("badmedium,all"); 1.752 + should_not_apply(",badmedium,"); 1.753 + should_apply("all,(badexpression)"); 1.754 + should_apply("(badexpression),all"); 1.755 + should_not_apply("(badexpression),badmedium"); 1.756 + should_not_apply("badmedium,(badexpression)"); 1.757 + should_apply("all,[badsyntax]"); 1.758 + should_apply("[badsyntax],all"); 1.759 + should_not_apply("badmedium,[badsyntax]"); 1.760 + should_not_apply("[badsyntax],badmedium"); 1.761 + // bug 528096 1.762 + should_not_apply_unbalanced("((resolution),all"); 1.763 + should_not_apply_unbalanced("(resolution(),all"); 1.764 + should_not_apply_unbalanced("(resolution (),all"); 1.765 + should_not_apply_unbalanced("(resolution:(),all"); 1.766 + 1.767 + handle_posted_items(); 1.768 +} 1.769 + 1.770 +/* 1.771 + * The cloning tests have to post tests that wait for onload. However, 1.772 + * we also make a bunch of state changes during the tests above. So we 1.773 + * always change state using the change_state call, with both makes the 1.774 + * change immediately and posts an item in the same queue so that we 1.775 + * make the same state change again later. 1.776 + */ 1.777 + 1.778 +var posted_items = []; 1.779 + 1.780 +function change_state(func) 1.781 +{ 1.782 + func(); 1.783 + posted_items.push({state: func}); 1.784 +} 1.785 + 1.786 +function post_clone_test(docurl, testfunc) 1.787 +{ 1.788 + posted_items.push({docurl: docurl, testfunc: testfunc}); 1.789 +} 1.790 + 1.791 +function handle_posted_items() 1.792 +{ 1.793 + if (posted_items.length == 0) { 1.794 + SimpleTest.finish(); 1.795 + return; 1.796 + } 1.797 + 1.798 + if ("state" in posted_items[0]) { 1.799 + var item = posted_items.shift(); 1.800 + item.state(); 1.801 + handle_posted_items(); 1.802 + return; 1.803 + } 1.804 + 1.805 + var docurl = posted_items[0].docurl; 1.806 + iframe.onload = handle_iframe_onload; 1.807 + iframe.src = docurl; 1.808 +} 1.809 + 1.810 +function handle_iframe_onload(event) 1.811 +{ 1.812 + if (event.target != iframe) 1.813 + return; 1.814 + 1.815 + var item = posted_items.shift(); 1.816 + item.testfunc(); 1.817 + handle_posted_items(); 1.818 +} 1.819 + 1.820 +</script> 1.821 +</pre> 1.822 +</body> 1.823 +</html> 1.824 + 1.825 +