Thu, 15 Jan 2015 21:03:48 +0100
Integrate friendly tips from Tor colleagues to make (or not) 4.5 alpha 3;
This includes removal of overloaded (but unused) methods, and addition of
a overlooked call to DataStruct::SetData(nsISupports, uint32_t, bool.)
1 <!DOCTYPE HTML>
2 <html>
3 <!--
4 https://bugzilla.mozilla.org/show_bug.cgi?id=156716
5 -->
6 <head>
7 <title>Test for Bug 156716</title>
8 <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
9 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
10 </head>
11 <body onload="run()">
12 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=156716">Mozilla Bug 156716</a>
13 <iframe id="subdoc" src="media_queries_iframe.html"></iframe>
14 <div id="content" style="display: none">
16 </div>
17 <pre id="test">
18 <script class="testbody" type="application/javascript">
20 /** Test for Bug 156716 **/
22 // Note that many other tests are in test_acid3_test46.html .
24 SimpleTest.waitForExplicitFinish();
26 var iframe;
28 function getScreenPixelsPerCSSPixel() {
29 return SpecialPowers.DOMWindowUtils.screenPixelsPerCSSPixel;
30 }
32 function run() {
33 iframe = document.getElementById("subdoc");
34 var subdoc = iframe.contentDocument;
35 var subwin = iframe.contentWindow;
36 var style = subdoc.getElementById("style");
37 var iframe_style = iframe.style;
38 var body_cs = subdoc.defaultView.getComputedStyle(subdoc.body, "");
40 function query_applies(q) {
41 style.setAttribute("media", q);
42 return body_cs.getPropertyValue("text-decoration") == "underline";
43 }
45 function should_apply(q) {
46 ok(query_applies(q), q + " should apply");
47 test_serialization(q, true, true);
48 }
50 function should_not_apply(q) {
51 ok(!query_applies(q), q + " should not apply");
52 test_serialization(q, true, false);
53 }
55 /* for queries that are parseable standalone but not within CSS */
56 function should_apply_unbalanced(q) {
57 ok(query_applies(q), q + " should apply");
58 }
60 /* for queries that are parseable standalone but not within CSS */
61 function should_not_apply_unbalanced(q) {
62 ok(!query_applies(q), q + " should not apply");
63 }
65 /*
66 * Functions to test whether a query is parseable at all. (Should not
67 * be used for parse errors within expressions.)
68 */
69 var parse_test_style_element = document.createElement("style");
70 parse_test_style_element.type = "text/css";
71 parse_test_style_element.disabled = true; // for performance, hopefully
72 var parse_test_style_text = document.createTextNode("");
73 parse_test_style_element.appendChild(parse_test_style_text);
74 document.getElementsByTagName("head")[0]
75 .appendChild(parse_test_style_element);
77 function query_is_parseable(q) {
78 parse_test_style_text.data = "@media screen, " + q + " {}";
79 var sheet = parse_test_style_element.sheet; // XXX yikes, not live!
80 if (sheet.cssRules.length == 1 &&
81 sheet.cssRules[0].type == CSSRule.MEDIA_RULE)
82 return sheet.cssRules[0].media.mediaText != "screen, not all";
83 ok(false, "unexpected result testing whether query " + q +
84 " is parseable");
85 return true; // doesn't matter, we already failed
86 }
88 function query_should_be_parseable(q) {
89 ok(query_is_parseable(q), "query " + q + " should be parseable");
90 test_serialization(q, false, false);
91 }
93 function query_should_not_be_parseable(q) {
94 ok(!query_is_parseable(q), "query " + q + " should not be parseable");
95 }
97 /*
98 * Functions to test whether a single media expression is parseable.
99 */
100 function expression_is_parseable(e) {
101 style.setAttribute("media", "all and (" + e + ")");
102 return style.sheet.media.mediaText != "not all";
103 }
105 function expression_should_be_parseable(e) {
106 ok(expression_is_parseable(e),
107 "expression " + e + " should be parseable");
108 test_serialization("all and (" + e + ")", false, false);
109 }
111 function expression_should_not_be_parseable(e) {
112 ok(!expression_is_parseable(e),
113 "expression " + e + " should not be parseable");
114 }
116 function test_serialization(q, test_application, should_apply) {
117 style.setAttribute("media", q);
118 var ser1 = style.sheet.media.mediaText;
119 isnot(ser1, "", "serialization of '" + q + "' should not be empty");
120 style.setAttribute("media", ser1);
121 var ser2 = style.sheet.media.mediaText;
122 is(ser2, ser1, "parse+serialize of '" + q + "' should be idempotent");
123 if (test_application) {
124 var applies = body_cs.getPropertyValue("text-decoration") == "underline";
125 is(applies, should_apply,
126 "Media query '" + q + "' should " + (should_apply ? "" : "NOT ") +
127 "apply after serialize + reparse");
128 }
130 // Test cloning
131 var sheet = "@media " + q + " { body { text-decoration: underline } }"
132 var sheeturl = "data:text/css," + escape(sheet);
133 var link = "<link rel='stylesheet' href='" + sheeturl + "'>";
134 var htmldoc = "<!DOCTYPE HTML>" + link + link + "<body>";
135 var docurl = "data:text/html," + escape(htmldoc);
136 post_clone_test(docurl, function() {
137 var clonedoc = iframe.contentDocument;
138 var clonewin = iframe.contentWindow;
139 var links = clonedoc.getElementsByTagName("link");
140 // cause a clone
141 var clonedsheet = links[1].sheet;
142 clonedsheet.insertRule("#nonexistent { color: purple}", 1);
143 // remove the uncloned sheet
144 links[0].parentNode.removeChild(links[0]);
146 var ser3 = clonedsheet.cssRules[0].media.mediaText;
147 is(ser3, ser1, "cloning query '" + q + "' should not change " +
148 "serialization");
149 if (test_application) {
150 var applies = clonewin.getComputedStyle(clonedoc.body, "").
151 textDecoration == "underline";
152 is(applies, should_apply,
153 "Media query '" + q + "' should " + (should_apply ? "" : "NOT ") +
154 "apply after cloning");
155 }
156 });
157 }
159 // The no-type syntax doesn't mix with the not and only keywords.
160 query_should_be_parseable("(orientation)");
161 query_should_not_be_parseable("not (orientation)");
162 query_should_not_be_parseable("only (orientation)");
163 query_should_be_parseable("all and (orientation)");
164 query_should_be_parseable("not all and (orientation)");
165 query_should_be_parseable("only all and (orientation)");
167 query_should_be_parseable("(-moz-device-orientation)");
168 query_should_not_be_parseable("not (-moz-device-orientation)");
169 query_should_not_be_parseable("only (-moz-device-orientation)");
170 query_should_be_parseable("all and (-moz-device-orientation)");
171 query_should_be_parseable("not all and (-moz-device-orientation)");
172 query_should_be_parseable("only all and (-moz-device-orientation)");
174 // Test that the 'not', 'only', 'and', and 'or' keywords are not
175 // allowed as media types.
176 query_should_not_be_parseable("not");
177 query_should_not_be_parseable("and");
178 query_should_not_be_parseable("or");
179 query_should_not_be_parseable("only");
180 query_should_be_parseable("unknowntype");
181 query_should_not_be_parseable("not not");
182 query_should_not_be_parseable("not and");
183 query_should_not_be_parseable("not or");
184 query_should_not_be_parseable("not only");
185 query_should_be_parseable("not unknowntype");
186 query_should_not_be_parseable("only not");
187 query_should_not_be_parseable("only and");
188 query_should_not_be_parseable("only or");
189 query_should_not_be_parseable("only only");
190 query_should_be_parseable("only unknowntype");
191 query_should_not_be_parseable("not and (width)");
192 query_should_not_be_parseable("and and (width)");
193 query_should_not_be_parseable("or and (width)");
194 query_should_not_be_parseable("only and (width)");
195 query_should_be_parseable("unknowntype and (width)");
196 query_should_not_be_parseable("not not and (width)");
197 query_should_not_be_parseable("not and and (width)");
198 query_should_not_be_parseable("not or and (width)");
199 query_should_not_be_parseable("not only and (width)");
200 query_should_be_parseable("not unknowntype and (width)");
201 query_should_not_be_parseable("only not and (width)");
202 query_should_not_be_parseable("only and and (width)");
203 query_should_not_be_parseable("only or and (width)");
204 query_should_not_be_parseable("only only and (width)");
205 query_should_be_parseable("only unknowntype and (width)");
207 var features = [ "width", "height", "device-width", "device-height" ];
208 var feature;
209 var i;
210 for (i in features) {
211 feature = features[i];
212 expression_should_be_parseable(feature);
213 expression_should_be_parseable(feature + ": 0");
214 expression_should_be_parseable(feature + ": 0px");
215 expression_should_be_parseable(feature + ": 0em");
216 expression_should_be_parseable(feature + ": -0");
217 expression_should_be_parseable("min-" + feature + ": -0");
218 expression_should_be_parseable("max-" + feature + ": -0");
219 expression_should_be_parseable(feature + ": -0cm");
220 expression_should_be_parseable(feature + ": 1px");
221 expression_should_be_parseable(feature + ": 0.001mm");
222 expression_should_be_parseable(feature + ": 100000px");
223 expression_should_not_be_parseable(feature + ": -1px");
224 expression_should_not_be_parseable("min-" + feature + ": -1px");
225 expression_should_not_be_parseable("max-" + feature + ": -1px");
226 expression_should_not_be_parseable(feature + ": -0.00001mm");
227 expression_should_not_be_parseable(feature + ": -100000em");
228 expression_should_not_be_parseable("min-" + feature);
229 expression_should_not_be_parseable("max-" + feature);
230 }
232 var content_div = document.getElementById("content");
233 content_div.style.font = "initial";
234 var em_size =
235 getComputedStyle(content_div, "").fontSize.match(/^(\d+)px$/)[1];
237 // in this test, assume the common underlying implementation is correct
238 var width_val = 117; // pick two not-too-round numbers
239 var height_val = 76;
240 change_state(function() {
241 iframe_style.width = width_val + "px";
242 iframe_style.height = height_val + "px";
243 });
244 var device_width = window.screen.width;
245 var device_height = window.screen.height;
246 features = { "width": width_val,
247 "height": height_val,
248 "device-width": device_width,
249 "device-height": device_height };
250 for (feature in features) {
251 var value = features[feature];
252 should_apply("all and (" + feature + ": " + value + "px)");
253 should_not_apply("all and (" + feature + ": " + (value + 1) + "px)");
254 should_not_apply("all and (" + feature + ": " + (value - 1) + "px)");
255 should_apply("all and (min-" + feature + ": " + value + "px)");
256 should_not_apply("all and (min-" + feature + ": " + (value + 1) + "px)");
257 should_apply("all and (min-" + feature + ": " + (value - 1) + "px)");
258 should_apply("all and (max-" + feature + ": " + value + "px)");
259 should_apply("all and (max-" + feature + ": " + (value + 1) + "px)");
260 should_not_apply("all and (max-" + feature + ": " + (value - 1) + "px)");
261 should_not_apply("all and (min-" + feature + ": " +
262 (Math.ceil(value/em_size) + 1) + "em)");
263 should_apply("all and (min-" + feature + ": " +
264 (Math.floor(value/em_size) - 1) + "em)");
265 should_apply("all and (max-" + feature + ": " +
266 (Math.ceil(value/em_size) + 1) + "em)");
267 should_not_apply("all and (max-" + feature + ": " +
268 (Math.floor(value/em_size) - 1) + "em)");
269 should_not_apply("all and (min-" + feature + ": " +
270 (Math.ceil(value/em_size) + 1) + "rem)");
271 should_apply("all and (min-" + feature + ": " +
272 (Math.floor(value/em_size) - 1) + "rem)");
273 should_apply("all and (max-" + feature + ": " +
274 (Math.ceil(value/em_size) + 1) + "rem)");
275 should_not_apply("all and (max-" + feature + ": " +
276 (Math.floor(value/em_size) - 1) + "rem)");
277 }
279 change_state(function() {
280 iframe_style.width = "0";
281 });
282 should_apply("all and (height)");
283 should_not_apply("all and (width)");
284 change_state(function() {
285 iframe_style.height = "0";
286 });
287 should_not_apply("all and (height)");
288 should_not_apply("all and (width)");
289 should_apply("all and (device-height)");
290 should_apply("all and (device-width)");
291 change_state(function() {
292 iframe_style.width = width_val + "px";
293 });
294 should_not_apply("all and (height)");
295 should_apply("all and (width)");
296 change_state(function() {
297 iframe_style.height = height_val + "px";
298 });
299 should_apply("all and (height)");
300 should_apply("all and (width)");
302 // ratio that reduces to 59/40
303 change_state(function() {
304 iframe_style.width = "236px";
305 iframe_style.height = "160px";
306 });
307 expression_should_be_parseable("orientation");
308 expression_should_be_parseable("orientation: portrait");
309 expression_should_be_parseable("orientation: landscape");
310 expression_should_not_be_parseable("min-orientation");
311 expression_should_not_be_parseable("min-orientation: portrait");
312 expression_should_not_be_parseable("min-orientation: landscape");
313 expression_should_not_be_parseable("max-orientation");
314 expression_should_not_be_parseable("max-orientation: portrait");
315 expression_should_not_be_parseable("max-orientation: landscape");
316 should_apply("(orientation)");
317 should_apply("(orientation: landscape)");
318 should_not_apply("(orientation: portrait)");
319 should_apply("not all and (orientation: portrait)");
320 // ratio that reduces to 59/80
321 change_state(function() {
322 iframe_style.height = "320px";
323 });
324 should_apply("(orientation)");
325 should_not_apply("(orientation: landscape)");
326 should_apply("not all and (orientation: landscape)");
327 should_apply("(orientation: portrait)");
329 expression_should_be_parseable("-moz-device-orientation");
330 expression_should_be_parseable("-moz-device-orientation: portrait");
331 expression_should_be_parseable("-moz-device-orientation: landscape");
332 expression_should_not_be_parseable("min--moz-device-orientation");
333 expression_should_not_be_parseable("min--moz-device-orientation: portrait");
334 expression_should_not_be_parseable("min--moz-device-orientation: landscape");
335 expression_should_not_be_parseable("max--moz-device-orientation");
336 expression_should_not_be_parseable("max--moz-device-orientation: portrait");
337 expression_should_not_be_parseable("max--moz-device-orientation: landscape");
339 // determine the actual configuration of the screen and test against it
340 var device_orientation = (device_width > device_height) ? "landscape" : "portrait";
341 var not_device_orientation = (device_orientation == "landscape") ? "portrait" : "landscape";
342 should_apply("(-moz-device-orientation)");
343 should_apply("(-moz-device-orientation: " + device_orientation + ")");
344 should_not_apply("(-moz-device-orientation: " + not_device_orientation + ")");
345 should_apply("not all and (-moz-device-orientation: " + not_device_orientation + ")");
347 should_apply("(aspect-ratio: 59/80)");
348 should_not_apply("(aspect-ratio: 58/80)");
349 should_not_apply("(aspect-ratio: 59/81)");
350 should_not_apply("(aspect-ratio: 60/80)");
351 should_not_apply("(aspect-ratio: 59/79)");
352 should_apply("(aspect-ratio: 177/240)");
353 should_apply("(aspect-ratio: 413/560)");
354 should_apply("(aspect-ratio: 5900/8000)");
355 should_not_apply("(aspect-ratio: 5901/8000)");
356 should_not_apply("(aspect-ratio: 5899/8000)");
357 should_not_apply("(aspect-ratio: 5900/8001)");
358 should_not_apply("(aspect-ratio: 5900/7999)");
359 should_apply("(aspect-ratio)");
361 should_apply("(min-aspect-ratio: 59/80)");
362 should_apply("(min-aspect-ratio: 58/80)");
363 should_apply("(min-aspect-ratio: 59/81)");
364 should_not_apply("(min-aspect-ratio: 60/80)");
365 should_not_apply("(min-aspect-ratio: 59/79)");
366 expression_should_not_be_parseable("min-aspect-ratio");
368 should_apply("(max-aspect-ratio: 59/80)");
369 should_not_apply("(max-aspect-ratio: 58/80)");
370 should_not_apply("(max-aspect-ratio: 59/81)");
371 should_apply("(max-aspect-ratio: 60/80)");
372 should_apply("(max-aspect-ratio: 59/79)");
373 expression_should_not_be_parseable("max-aspect-ratio");
375 var real_dar = device_width + "/" + device_height;
376 var high_dar_1 = (device_width + 1) + "/" + device_height;
377 var high_dar_2 = device_width + "/" + (device_height - 1);
378 var low_dar_1 = (device_width - 1) + "/" + device_height;
379 var low_dar_2 = device_width + "/" + (device_height + 1);
380 should_apply("(device-aspect-ratio: " + real_dar + ")");
381 should_apply("not all and (device-aspect-ratio: " + high_dar_1 + ")");
382 should_not_apply("all and (device-aspect-ratio: " + high_dar_2 + ")");
383 should_not_apply("all and (device-aspect-ratio: " + low_dar_1 + ")");
384 should_apply("not all and (device-aspect-ratio: " + low_dar_2 + ")");
385 should_apply("(device-aspect-ratio)");
387 should_apply("(min-device-aspect-ratio: " + real_dar + ")");
388 should_not_apply("all and (min-device-aspect-ratio: " + high_dar_1 + ")");
389 should_apply("not all and (min-device-aspect-ratio: " + high_dar_2 + ")");
390 should_not_apply("not all and (min-device-aspect-ratio: " + low_dar_1 + ")");
391 should_apply("all and (min-device-aspect-ratio: " + low_dar_2 + ")");
392 expression_should_not_be_parseable("min-device-aspect-ratio");
394 should_apply("all and (max-device-aspect-ratio: " + real_dar + ")");
395 should_apply("(max-device-aspect-ratio: " + high_dar_1 + ")");
396 should_apply("(max-device-aspect-ratio: " + high_dar_2 + ")");
397 should_not_apply("all and (max-device-aspect-ratio: " + low_dar_1 + ")");
398 should_apply("not all and (max-device-aspect-ratio: " + low_dar_2 + ")");
399 expression_should_not_be_parseable("max-device-aspect-ratio");
401 var real_dpr = 1.0 * getScreenPixelsPerCSSPixel();
402 var high_dpr = 1.1 * getScreenPixelsPerCSSPixel();
403 var low_dpr = 0.9 * getScreenPixelsPerCSSPixel();
404 should_apply("all and (max--moz-device-pixel-ratio: " + real_dpr + ")");
405 should_apply("all and (min--moz-device-pixel-ratio: " + real_dpr + ")");
406 should_not_apply("not all and (max--moz-device-pixel-ratio: " + real_dpr + ")");
407 should_not_apply("not all and (min--moz-device-pixel-ratio: " + real_dpr + ")");
408 should_apply("all and (min--moz-device-pixel-ratio: " + low_dpr + ")");
409 should_apply("all and (max--moz-device-pixel-ratio: " + high_dpr + ")");
410 should_not_apply("all and (max--moz-device-pixel-ratio: " + low_dpr + ")");
411 should_not_apply("all and (min--moz-device-pixel-ratio: " + high_dpr + ")");
412 should_apply("not all and (max--moz-device-pixel-ratio: " + low_dpr + ")");
413 should_apply("not all and (min--moz-device-pixel-ratio: " + high_dpr + ")");
414 should_apply("(-moz-device-pixel-ratio: " + real_dpr + ")");
415 should_not_apply("(-moz-device-pixel-ratio: " + high_dpr + ")");
416 should_not_apply("(-moz-device-pixel-ratio: " + low_dpr + ")");
417 should_apply("(-moz-device-pixel-ratio)");
418 expression_should_not_be_parseable("min--moz-device-pixel-ratio");
419 expression_should_not_be_parseable("max--moz-device-pixel-ratio");
421 features = [ "max-aspect-ratio", "device-aspect-ratio" ];
422 for (i in features) {
423 feature = features[i];
424 expression_should_be_parseable(feature + ": 1/1");
425 expression_should_be_parseable(feature + ": 1 /1");
426 expression_should_be_parseable(feature + ": 1 / \t\n1");
427 expression_should_be_parseable(feature + ": 1/\r1");
428 expression_should_not_be_parseable(feature + ": 1");
429 expression_should_not_be_parseable(feature + ": 0.5");
430 expression_should_not_be_parseable(feature + ": 1.0/1");
431 expression_should_not_be_parseable(feature + ": 1/1.0");
432 expression_should_not_be_parseable(feature + ": 1.0/1.0");
433 expression_should_not_be_parseable(feature + ": 0/1");
434 expression_should_not_be_parseable(feature + ": 1/0");
435 expression_should_not_be_parseable(feature + ": 0/0");
436 expression_should_not_be_parseable(feature + ": -1/1");
437 expression_should_not_be_parseable(feature + ": 1/-1");
438 expression_should_not_be_parseable(feature + ": -1/-1");
439 }
441 var is_monochrome = query_applies("all and (min-monochrome: 1)");
442 test_serialization("all and (min-monochrome: 1)", true, is_monochrome);
443 var is_color = query_applies("all and (min-color: 1)");
444 test_serialization("all and (min-color: 1)", true, is_color);
445 isnot(is_monochrome, is_color, "should be either monochrome or color");
447 function depth_query(prefix, depth) {
448 return "all and (" + prefix + (is_color ? "color" : "monochrome") +
449 ":" + depth + ")";
450 }
452 var depth = 0;
453 do {
454 if (depth > 50) {
455 ok(false, "breaking from loop, depth > 50");
456 break;
457 }
458 } while (query_applies(depth_query("min-", ++depth)));
459 --depth;
461 should_apply(depth_query("", depth));
462 should_not_apply(depth_query("", depth - 1));
463 should_not_apply(depth_query("", depth + 1));
464 should_apply(depth_query("max-", depth));
465 should_not_apply(depth_query("max-", depth - 1));
466 should_apply(depth_query("max-", depth + 1));
468 (is_color ? should_apply : should_not_apply)("all and (color)");
469 expression_should_not_be_parseable("max-color");
470 expression_should_not_be_parseable("min-color");
471 (is_color ? should_not_apply : should_apply)("all and (monochrome)");
472 expression_should_not_be_parseable("max-monochrome");
473 expression_should_not_be_parseable("min-monochrome");
474 (is_color ? should_apply : should_not_apply)("not all and (monochrome)");
475 (is_color ? should_not_apply : should_apply)("not all and (color)");
476 (is_color ? should_apply : should_not_apply)("only all and (color)");
477 (is_color ? should_not_apply : should_apply)("only all and (monochrome)");
479 features = [ "color", "min-monochrome", "max-color-index" ];
480 for (i in features) {
481 feature = features[i];
482 expression_should_be_parseable(feature + ": 1");
483 expression_should_be_parseable(feature + ": 327");
484 expression_should_be_parseable(feature + ": 0");
485 expression_should_not_be_parseable(feature + ": 1.0");
486 expression_should_not_be_parseable(feature + ": -1");
487 expression_should_not_be_parseable(feature + ": 1/1");
488 }
490 // Presume that we never support indexed color (at least not usefully
491 // enough to call it indexed color).
492 should_apply("(color-index: 0)");
493 should_not_apply("(color-index: 1)");
494 should_apply("(min-color-index: 0)");
495 should_not_apply("(min-color-index: 1)");
496 should_apply("(max-color-index: 0)");
497 should_apply("(max-color-index: 1)");
498 should_apply("(max-color-index: 157)");
500 features = [ "resolution", "min-resolution", "max-resolution" ];
501 for (i in features) {
502 feature = features[i];
503 expression_should_be_parseable(feature + ": 3dpi");
504 expression_should_be_parseable(feature + ":3dpi");
505 expression_should_be_parseable(feature + ": 3.0dpi");
506 expression_should_be_parseable(feature + ": 3.4dpi");
507 expression_should_be_parseable(feature + "\t: 120dpcm");
508 expression_should_be_parseable(feature + ": 1dppx");
509 expression_should_be_parseable(feature + ": 1.5dppx");
510 expression_should_be_parseable(feature + ": 2.0dppx");
511 expression_should_not_be_parseable(feature + ": 0dpi");
512 expression_should_not_be_parseable(feature + ": -3dpi");
513 expression_should_not_be_parseable(feature + ": 0dppx");
514 }
516 // Find the resolution using max-resolution
517 var resolution = 0;
518 do {
519 ++resolution;
520 if (resolution > 10000) {
521 ok(false, "resolution greater than 10000dpi???");
522 break;
523 }
524 } while (!query_applies("(max-resolution: " + resolution + "dpi)"));
526 // resolution should now be Math.ceil() of the actual resolution.
527 var dpi_high;
528 var dpi_low = resolution - 1;
529 if (query_applies("(min-resolution: " + resolution + "dpi)")) {
530 // It's exact!
531 should_apply("(resolution: " + resolution + "dpi)");
532 should_apply("(resolution: " + Math.floor(resolution/96) + "dppx)");
533 should_not_apply("(resolution: " + (resolution + 1) + "dpi)");
534 should_not_apply("(resolution: " + (resolution - 1) + "dpi)");
535 dpi_high = resolution + 1;
536 } else {
537 // We have no way to test resolution applying since it need not be
538 // an integer.
539 should_not_apply("(resolution: " + resolution + "dpi)");
540 should_not_apply("(resolution: " + (resolution - 1) + "dpi)");
541 dpi_high = resolution;
542 }
544 should_apply("(min-resolution: " + dpi_low + "dpi)");
545 should_not_apply("not all and (min-resolution: " + dpi_low + "dpi)");
546 should_apply("not all and (min-resolution: " + dpi_high + "dpi)");
547 should_not_apply("all and (min-resolution: " + dpi_high + "dpi)");
549 // Test dpcm units based on what we computed in dpi.
550 var dpcm_high = Math.ceil(dpi_high / 2.54);
551 var dpcm_low = Math.floor(dpi_low / 2.54);
552 should_apply("(min-resolution: " + dpcm_low + "dpcm)");
553 should_apply("(max-resolution: " + dpcm_high + "dpcm)");
554 should_not_apply("(max-resolution: " + dpcm_low + "dpcm)");
555 should_apply("not all and (min-resolution: " + dpcm_high + "dpcm)");
557 expression_should_be_parseable("scan");
558 expression_should_be_parseable("scan: progressive");
559 expression_should_be_parseable("scan:interlace");
560 expression_should_not_be_parseable("min-scan:interlace");
561 expression_should_not_be_parseable("scan: 1");
562 expression_should_not_be_parseable("max-scan");
563 expression_should_not_be_parseable("max-scan: progressive");
564 // Assume we don't support tv devices.
565 should_not_apply("(scan)");
566 should_not_apply("(scan: progressive)");
567 should_not_apply("(scan: interlace)");
568 should_apply("not all and (scan)");
569 should_apply("not all and (scan: progressive)");
570 should_apply("not all and (scan: interlace)");
572 expression_should_be_parseable("grid");
573 expression_should_be_parseable("grid: 0");
574 expression_should_be_parseable("grid: 1");
575 expression_should_be_parseable("grid: 1");
576 expression_should_not_be_parseable("min-grid");
577 expression_should_not_be_parseable("min-grid:0");
578 expression_should_not_be_parseable("max-grid: 1");
579 expression_should_not_be_parseable("grid: 2");
580 expression_should_not_be_parseable("grid: -1");
582 // Assume we don't support grid devices
583 should_not_apply("(grid)");
584 should_apply("(grid: 0)");
585 should_not_apply("(grid: 1)");
586 should_not_apply("(grid: 2)");
587 should_not_apply("(grid: -1)");
589 // System metrics
590 expression_should_be_parseable("-moz-scrollbar-start-backward");
591 expression_should_be_parseable("-moz-scrollbar-start-forward");
592 expression_should_be_parseable("-moz-scrollbar-end-backward");
593 expression_should_be_parseable("-moz-scrollbar-end-forward");
594 expression_should_be_parseable("-moz-scrollbar-thumb-proportional");
595 expression_should_be_parseable("-moz-images-in-menus");
596 expression_should_be_parseable("-moz-images-in-buttons");
597 expression_should_be_parseable("-moz-overlay-scrollbars");
598 expression_should_be_parseable("-moz-windows-default-theme");
599 expression_should_be_parseable("-moz-mac-graphite-theme");
600 expression_should_be_parseable("-moz-mac-lion-theme");
601 expression_should_be_parseable("-moz-windows-compositor");
602 expression_should_be_parseable("-moz-windows-classic");
603 expression_should_be_parseable("-moz-windows-glass");
604 expression_should_be_parseable("-moz-touch-enabled");
605 expression_should_be_parseable("-moz-swipe-animation-enabled");
607 expression_should_be_parseable("-moz-scrollbar-start-backward: 0");
608 expression_should_be_parseable("-moz-scrollbar-start-forward: 0");
609 expression_should_be_parseable("-moz-scrollbar-end-backward: 0");
610 expression_should_be_parseable("-moz-scrollbar-end-forward: 0");
611 expression_should_be_parseable("-moz-scrollbar-thumb-proportional: 0");
612 expression_should_be_parseable("-moz-images-in-menus: 0");
613 expression_should_be_parseable("-moz-images-in-buttons: 0");
614 expression_should_be_parseable("-moz-overlay-scrollbars: 0");
615 expression_should_be_parseable("-moz-windows-default-theme: 0");
616 expression_should_be_parseable("-moz-mac-graphite-theme: 0");
617 expression_should_be_parseable("-moz-mac-lion-theme: 0");
618 expression_should_be_parseable("-moz-windows-compositor: 0");
619 expression_should_be_parseable("-moz-windows-classic: 0");
620 expression_should_be_parseable("-moz-windows-glass: 0");
621 expression_should_be_parseable("-moz-touch-enabled: 0");
622 expression_should_be_parseable("-moz-swipe-animation-enabled: 0");
624 expression_should_be_parseable("-moz-scrollbar-start-backward: 1");
625 expression_should_be_parseable("-moz-scrollbar-start-forward: 1");
626 expression_should_be_parseable("-moz-scrollbar-end-backward: 1");
627 expression_should_be_parseable("-moz-scrollbar-end-forward: 1");
628 expression_should_be_parseable("-moz-scrollbar-thumb-proportional: 1");
629 expression_should_be_parseable("-moz-images-in-menus: 1");
630 expression_should_be_parseable("-moz-images-in-buttons: 1");
631 expression_should_be_parseable("-moz-overlay-scrollbars: 1");
632 expression_should_be_parseable("-moz-windows-default-theme: 1");
633 expression_should_be_parseable("-moz-mac-graphite-theme: 1");
634 expression_should_be_parseable("-moz-mac-lion-theme: 1");
635 expression_should_be_parseable("-moz-windows-compositor: 1");
636 expression_should_be_parseable("-moz-windows-classic: 1");
637 expression_should_be_parseable("-moz-windows-glass: 1");
638 expression_should_be_parseable("-moz-touch-enabled: 1");
639 expression_should_be_parseable("-moz-swipe-animation-enabled: 1");
641 expression_should_not_be_parseable("-moz-scrollbar-start-backward: -1");
642 expression_should_not_be_parseable("-moz-scrollbar-start-forward: -1");
643 expression_should_not_be_parseable("-moz-scrollbar-end-backward: -1");
644 expression_should_not_be_parseable("-moz-scrollbar-end-forward: -1");
645 expression_should_not_be_parseable("-moz-scrollbar-thumb-proportional: -1");
646 expression_should_not_be_parseable("-moz-images-in-menus: -1");
647 expression_should_not_be_parseable("-moz-images-in-buttons: -1");
648 expression_should_not_be_parseable("-moz-overlay-scrollbars: -1");
649 expression_should_not_be_parseable("-moz-windows-default-theme: -1");
650 expression_should_not_be_parseable("-moz-mac-graphite-theme: -1");
651 expression_should_not_be_parseable("-moz-mac-lion-theme: -1");
652 expression_should_not_be_parseable("-moz-windows-compositor: -1");
653 expression_should_not_be_parseable("-moz-windows-classic: -1");
654 expression_should_not_be_parseable("-moz-windows-glass: -1");
655 expression_should_not_be_parseable("-moz-touch-enabled: -1");
656 expression_should_not_be_parseable("-moz-swipe-animation-enabled: -1");
658 expression_should_not_be_parseable("-moz-scrollbar-start-backward: true");
659 expression_should_not_be_parseable("-moz-scrollbar-start-forward: true");
660 expression_should_not_be_parseable("-moz-scrollbar-end-backward: true");
661 expression_should_not_be_parseable("-moz-scrollbar-end-forward: true");
662 expression_should_not_be_parseable("-moz-scrollbar-thumb-proportional: true");
663 expression_should_not_be_parseable("-moz-images-in-menus: true");
664 expression_should_not_be_parseable("-moz-images-in-buttons: true");
665 expression_should_not_be_parseable("-moz-overlay-scrollbars: true");
666 expression_should_not_be_parseable("-moz-windows-default-theme: true");
667 expression_should_not_be_parseable("-moz-mac-graphite-theme: true");
668 expression_should_not_be_parseable("-moz-mac-lion-theme: true");
669 expression_should_not_be_parseable("-moz-windows-compositor: true");
670 expression_should_not_be_parseable("-moz-windows-classic: true");
671 expression_should_not_be_parseable("-moz-windows-glass: true");
672 expression_should_not_be_parseable("-moz-touch-enabled: true");
673 expression_should_not_be_parseable("-moz-swipe-animation-enabled: true");
675 // windows theme media queries
676 expression_should_be_parseable("-moz-windows-theme: aero");
677 expression_should_be_parseable("-moz-windows-theme: aero-lite");
678 expression_should_be_parseable("-moz-windows-theme: luna-blue");
679 expression_should_be_parseable("-moz-windows-theme: luna-olive");
680 expression_should_be_parseable("-moz-windows-theme: luna-silver");
681 expression_should_be_parseable("-moz-windows-theme: royale");
682 expression_should_be_parseable("-moz-windows-theme: generic");
683 expression_should_be_parseable("-moz-windows-theme: zune");
684 expression_should_be_parseable("-moz-windows-theme: garbage");
685 expression_should_not_be_parseable("-moz-windows-theme: ''");
686 expression_should_not_be_parseable("-moz-windows-theme: ");
688 // os version media queries (currently windows only)
689 expression_should_be_parseable("-moz-os-version: windows-xp");
690 expression_should_be_parseable("-moz-os-version: windows-vista");
691 expression_should_be_parseable("-moz-os-version: windows-win7");
692 expression_should_be_parseable("-moz-os-version: windows-win8");
693 expression_should_not_be_parseable("-moz-os-version: ");
695 // OpenType SVG media features
696 query_should_be_parseable("(-moz-is-glyph)");
697 query_should_not_be_parseable("not (-moz-is-glyph)");
698 query_should_not_be_parseable("only (-moz-is-glyph)");
699 query_should_be_parseable("all and (-moz-is-glyph)");
700 query_should_be_parseable("not all and (-moz-is-glyph)");
701 query_should_be_parseable("only all and (-moz-is-glyph)");
703 query_should_be_parseable("(-moz-is-glyph:0)");
704 query_should_not_be_parseable("not (-moz-is-glyph:0)");
705 query_should_not_be_parseable("only (-moz-is-glyph:0)");
706 query_should_be_parseable("all and (-moz-is-glyph:0)");
707 query_should_be_parseable("not all and (-moz-is-glyph:0)");
708 query_should_be_parseable("only all and (-moz-is-glyph:0)");
710 query_should_be_parseable("(-moz-is-glyph:1)");
711 query_should_not_be_parseable("not (-moz-is-glyph:1)");
712 query_should_not_be_parseable("only (-moz-is-glyph:1)");
713 query_should_be_parseable("all and (-moz-is-glyph:1)");
714 query_should_be_parseable("not all and (-moz-is-glyph:1)");
715 query_should_be_parseable("only all and (-moz-is-glyph:1)");
717 query_should_not_be_parseable("(min--moz-is-glyph:0)");
718 query_should_not_be_parseable("(max--moz-is-glyph:0)");
719 query_should_not_be_parseable("(min--moz-is-glyph:1)");
720 query_should_not_be_parseable("(max--moz-is-glyph:1)");
722 should_apply("not all and (-moz-is-glyph)");
723 should_apply("(-moz-is-glyph:0)");
724 should_apply("not all and (-moz-is-glyph:1)");
725 should_apply("only all and (-moz-is-glyph:0)");
726 should_not_apply("(-moz-is-glyph)");
727 should_not_apply("(-moz-is-glyph:1)");
728 should_not_apply("not all and (-moz-is-glyph:0)");
729 should_not_apply("only all and (-moz-is-glyph:1)");
731 // Parsing tests
732 // bug 454227
733 should_apply_unbalanced("(orientation");
734 should_not_apply_unbalanced("not all and (orientation");
735 should_not_apply_unbalanced("(orientation:");
736 should_apply_unbalanced("all,(orientation:");
737 should_not_apply_unbalanced("(orientation:,all");
738 should_apply_unbalanced("not all and (grid");
739 should_not_apply_unbalanced("only all and (grid");
740 should_not_apply_unbalanced("(grid");
741 should_apply_unbalanced("all,(grid");
742 should_not_apply_unbalanced("(grid,all");
743 // bug 454226
744 should_apply(",all");
745 should_apply("all,");
746 should_apply(",all,");
747 should_apply("all,badmedium");
748 should_apply("badmedium,all");
749 should_not_apply(",badmedium,");
750 should_apply("all,(badexpression)");
751 should_apply("(badexpression),all");
752 should_not_apply("(badexpression),badmedium");
753 should_not_apply("badmedium,(badexpression)");
754 should_apply("all,[badsyntax]");
755 should_apply("[badsyntax],all");
756 should_not_apply("badmedium,[badsyntax]");
757 should_not_apply("[badsyntax],badmedium");
758 // bug 528096
759 should_not_apply_unbalanced("((resolution),all");
760 should_not_apply_unbalanced("(resolution(),all");
761 should_not_apply_unbalanced("(resolution (),all");
762 should_not_apply_unbalanced("(resolution:(),all");
764 handle_posted_items();
765 }
767 /*
768 * The cloning tests have to post tests that wait for onload. However,
769 * we also make a bunch of state changes during the tests above. So we
770 * always change state using the change_state call, with both makes the
771 * change immediately and posts an item in the same queue so that we
772 * make the same state change again later.
773 */
775 var posted_items = [];
777 function change_state(func)
778 {
779 func();
780 posted_items.push({state: func});
781 }
783 function post_clone_test(docurl, testfunc)
784 {
785 posted_items.push({docurl: docurl, testfunc: testfunc});
786 }
788 function handle_posted_items()
789 {
790 if (posted_items.length == 0) {
791 SimpleTest.finish();
792 return;
793 }
795 if ("state" in posted_items[0]) {
796 var item = posted_items.shift();
797 item.state();
798 handle_posted_items();
799 return;
800 }
802 var docurl = posted_items[0].docurl;
803 iframe.onload = handle_iframe_onload;
804 iframe.src = docurl;
805 }
807 function handle_iframe_onload(event)
808 {
809 if (event.target != iframe)
810 return;
812 var item = posted_items.shift();
813 item.testfunc();
814 handle_posted_items();
815 }
817 </script>
818 </pre>
819 </body>
820 </html>