4 https://bugzilla.mozilla.org/show_bug.cgi?id=156716
7 <title>Test for Bug
156716</title>
8 <script type=
"text/javascript" src=
"/MochiKit/MochiKit.js"></script>
9 <script type=
"text/javascript" src=
"/tests/SimpleTest/SimpleTest.js"></script>
10 <link rel=
"stylesheet" type=
"text/css" href=
"/tests/SimpleTest/test.css" />
13 <a target=
"_blank" href=
"https://bugzilla.mozilla.org/show_bug.cgi?id=156716">Mozilla Bug
156716</a>
14 <iframe id=
"subdoc" src=
"media_queries_iframe.html"></iframe>
15 <div id=
"content" style=
"display: none">
19 <script class=
"testbody" type=
"application/javascript; version=1.7">
21 /** Test for Bug
156716 **/
23 // Note that many other tests are in test_acid3_test46.html .
25 SimpleTest.waitForExplicitFinish();
28 var subdoc = document.getElementById(
"subdoc").contentDocument;
29 var subwin = document.getElementById(
"subdoc").contentWindow;
30 var style = subdoc.getElementById(
"style");
31 var iframe_style = document.getElementById(
"subdoc").style;
32 var body_cs = subdoc.defaultView.getComputedStyle(subdoc.body,
"");
34 function query_applies(q) {
35 style.setAttribute(
"media", q);
36 return body_cs.getPropertyValue(
"text-decoration") ==
"underline";
39 function should_apply(q) {
40 ok(query_applies(q), q +
" should apply");
43 function should_not_apply(q) {
44 ok(!query_applies(q), q +
" should not apply");
48 * Functions to test whether a query is parseable at all. (Should not
49 * be used for parse errors within expressions.)
51 var parse_test_style_element = document.createElement(
"style");
52 parse_test_style_element.type =
"text/css";
53 parse_test_style_element.disabled = true; // for performance, hopefully
54 var parse_test_style_text = document.createTextNode(
"");
55 parse_test_style_element.appendChild(parse_test_style_text);
56 document.getElementsByTagName(
"head")[
0]
57 .appendChild(parse_test_style_element);
59 function query_is_parseable(q) {
60 parse_test_style_text.data =
"@media screen, " + q +
" {}";
61 var sheet = parse_test_style_element.sheet; // XXX yikes, not live!
62 if (sheet.cssRules.length ==
1 &&
63 sheet.cssRules[
0].type == CSSRule.MEDIA_RULE)
64 return sheet.cssRules[
0].media.mediaText !=
"screen";
65 ok(false,
"unexpected result testing whether query " + q +
67 return true; // doesn't matter, we already failed
70 function query_should_be_parseable(q) {
71 ok(query_is_parseable(q),
"query " + q +
" should be parseable");
74 function query_should_not_be_parseable(q) {
75 ok(!query_is_parseable(q),
"query " + q +
" should not be parseable");
79 * Functions to test whether a single media expression is parseable.
81 function expression_is_parseable(e) {
82 style.setAttribute(
"media",
"all and (" + e +
")");
83 return style.sheet.media.mediaText !=
"not all";
86 function expression_should_be_parseable(e) {
87 ok(expression_is_parseable(e),
88 "expression " + e +
" should be parseable");
91 function expression_should_not_be_parseable(e) {
92 ok(!expression_is_parseable(e),
93 "expression " + e +
" should not be parseable");
96 // The no-type syntax doesn't mix with the not and only keywords.
97 query_should_be_parseable(
"(orientation)");
98 query_should_not_be_parseable(
"not (orientation)");
99 query_should_not_be_parseable(
"only (orientation)");
100 query_should_be_parseable(
"all and (orientation)");
101 query_should_be_parseable(
"not all and (orientation)");
102 query_should_be_parseable(
"only all and (orientation)");
104 for each (let feature in [
"width",
"height",
"device-width",
106 expression_should_be_parseable(feature);
107 expression_should_be_parseable(feature +
": 0");
108 expression_should_be_parseable(feature +
": 0px");
109 expression_should_be_parseable(feature +
": 0em");
110 expression_should_be_parseable(feature +
": -0");
111 expression_should_be_parseable(
"min-" + feature +
": -0");
112 expression_should_be_parseable(
"max-" + feature +
": -0");
113 expression_should_be_parseable(feature +
": -0cm");
114 expression_should_be_parseable(feature +
": 1px");
115 expression_should_be_parseable(feature +
": 0.001mm");
116 expression_should_be_parseable(feature +
": 100000px");
117 expression_should_not_be_parseable(feature +
": -1px");
118 expression_should_not_be_parseable(
"min-" + feature +
": -1px");
119 expression_should_not_be_parseable(
"max-" + feature +
": -1px");
120 expression_should_not_be_parseable(feature +
": -0.00001mm");
121 expression_should_not_be_parseable(feature +
": -100000em");
122 expression_should_not_be_parseable(
"min-" + feature);
123 expression_should_not_be_parseable(
"max-" + feature);
126 var content_div = document.getElementById(
"content");
127 content_div.style.font =
"-moz-initial";
129 getComputedStyle(content_div,
"").fontSize.match(/^(\d+)px$/)[
1];
131 // in this test, assume the common underlying implementation is correct
132 let width_val =
117; // pick two not-too-round numbers
134 iframe_style.width = width_val +
"px";
135 iframe_style.height = height_val +
"px";
136 let device_width = window.screen.width;
137 let device_height = window.screen.height;
138 for (let [feature, value] in
139 Iterator({
"width": width_val,
140 "height": height_val,
141 "device-width": device_width,
142 "device-height": device_height })) {
143 should_apply(
"all and (" + feature +
": " + value +
"px)");
144 should_not_apply(
"all and (" + feature +
": " + (value +
1) +
"px)");
145 should_not_apply(
"all and (" + feature +
": " + (value -
1) +
"px)");
146 should_apply(
"all and (min-" + feature +
": " + value +
"px)");
147 should_not_apply(
"all and (min-" + feature +
": " + (value +
1) +
"px)");
148 should_apply(
"all and (min-" + feature +
": " + (value -
1) +
"px)");
149 should_apply(
"all and (max-" + feature +
": " + value +
"px)");
150 should_apply(
"all and (max-" + feature +
": " + (value +
1) +
"px)");
151 should_not_apply(
"all and (max-" + feature +
": " + (value -
1) +
"px)");
152 should_not_apply(
"all and (min-" + feature +
": " +
153 (Math.ceil(value/em_size) +
1) +
"em)");
154 should_apply(
"all and (min-" + feature +
": " +
155 (Math.floor(value/em_size) -
1) +
"em)");
156 should_apply(
"all and (max-" + feature +
": " +
157 (Math.ceil(value/em_size) +
1) +
"em)");
158 should_not_apply(
"all and (max-" + feature +
": " +
159 (Math.floor(value/em_size) -
1) +
"em)");
162 iframe_style.width =
"0";
163 should_apply(
"all and (height)");
164 should_not_apply(
"all and (width)");
165 iframe_style.height =
"0";
166 should_not_apply(
"all and (height)");
167 should_not_apply(
"all and (width)");
168 should_apply(
"all and (device-height)");
169 should_apply(
"all and (device-width)");
170 iframe_style.width = width_val +
"px";
171 should_not_apply(
"all and (height)");
172 should_apply(
"all and (width)");
173 iframe_style.height = height_val +
"px";
174 should_apply(
"all and (height)");
175 should_apply(
"all and (width)");
177 // ratio that reduces to
59/
40
178 iframe_style.width =
"236px";
179 iframe_style.height =
"160px";
180 expression_should_be_parseable(
"orientation");
181 expression_should_be_parseable(
"orientation: portrait");
182 expression_should_be_parseable(
"orientation: landscape");
183 expression_should_not_be_parseable(
"min-orientation");
184 expression_should_not_be_parseable(
"min-orientation: portrait");
185 expression_should_not_be_parseable(
"min-orientation: landscape");
186 expression_should_not_be_parseable(
"max-orientation");
187 expression_should_not_be_parseable(
"max-orientation: portrait");
188 expression_should_not_be_parseable(
"max-orientation: landscape");
189 should_apply(
"(orientation)");
190 should_apply(
"(orientation: landscape)");
191 should_not_apply(
"(orientation: portrait)");
192 should_apply(
"not all and (orientation: portrait)");
193 // ratio that reduces to
59/
80
194 iframe_style.height =
"320px";
195 should_apply(
"(orientation)");
196 should_not_apply(
"(orientation: landscape)");
197 should_apply(
"not all and (orientation: landscape)");
198 should_apply(
"(orientation: portrait)");
200 should_apply(
"(aspect-ratio: 59/80)");
201 should_not_apply(
"(aspect-ratio: 58/80)");
202 should_not_apply(
"(aspect-ratio: 59/81)");
203 should_not_apply(
"(aspect-ratio: 60/80)");
204 should_not_apply(
"(aspect-ratio: 59/79)");
205 should_apply(
"(aspect-ratio: 177/240)");
206 should_apply(
"(aspect-ratio: 413/560)");
207 should_apply(
"(aspect-ratio: 5900/8000)");
208 should_not_apply(
"(aspect-ratio: 5901/8000)");
209 should_not_apply(
"(aspect-ratio: 5899/8000)");
210 should_not_apply(
"(aspect-ratio: 5900/8001)");
211 should_not_apply(
"(aspect-ratio: 5900/7999)");
212 should_apply(
"(aspect-ratio)");
214 should_apply(
"(min-aspect-ratio: 59/80)");
215 should_apply(
"(min-aspect-ratio: 58/80)");
216 should_apply(
"(min-aspect-ratio: 59/81)");
217 should_not_apply(
"(min-aspect-ratio: 60/80)");
218 should_not_apply(
"(min-aspect-ratio: 59/79)");
219 expression_should_not_be_parseable(
"min-aspect-ratio");
221 should_apply(
"(max-aspect-ratio: 59/80)");
222 should_not_apply(
"(max-aspect-ratio: 58/80)");
223 should_not_apply(
"(max-aspect-ratio: 59/81)");
224 should_apply(
"(max-aspect-ratio: 60/80)");
225 should_apply(
"(max-aspect-ratio: 59/79)");
226 expression_should_not_be_parseable(
"max-aspect-ratio");
228 let real_dar = device_width +
"/" + device_height;
229 let high_dar_1 = (device_width +
1) +
"/" + device_height;
230 let high_dar_2 = device_width +
"/" + (device_height -
1);
231 let low_dar_1 = (device_width -
1) +
"/" + device_height;
232 let low_dar_2 = device_width +
"/" + (device_height +
1);
233 should_apply(
"(device-aspect-ratio: " + real_dar +
")");
234 should_apply(
"not all and (device-aspect-ratio: " + high_dar_1 +
")");
235 should_not_apply(
"all and (device-aspect-ratio: " + high_dar_2 +
")");
236 should_not_apply(
"all and (device-aspect-ratio: " + low_dar_1 +
")");
237 should_apply(
"not all and (device-aspect-ratio: " + low_dar_2 +
")");
238 should_apply(
"(device-aspect-ratio)");
240 should_apply(
"(min-device-aspect-ratio: " + real_dar +
")");
241 should_not_apply(
"all and (min-device-aspect-ratio: " + high_dar_1 +
")");
242 should_apply(
"not all and (min-device-aspect-ratio: " + high_dar_2 +
")");
243 should_not_apply(
"not all and (min-device-aspect-ratio: " + low_dar_1 +
")");
244 should_apply(
"all and (min-device-aspect-ratio: " + low_dar_2 +
")");
245 expression_should_not_be_parseable(
"min-device-aspect-ratio");
247 should_apply(
"all and (max-device-aspect-ratio: " + real_dar +
")");
248 should_apply(
"(max-device-aspect-ratio: " + high_dar_1 +
")");
249 should_apply(
"(max-device-aspect-ratio: " + high_dar_2 +
")");
250 should_not_apply(
"all and (max-device-aspect-ratio: " + low_dar_1 +
")");
251 should_apply(
"not all and (max-device-aspect-ratio: " + low_dar_2 +
")");
252 expression_should_not_be_parseable(
"max-device-aspect-ratio");
254 for each (let feature in [
"max-aspect-ratio",
"device-aspect-ratio" ]) {
255 expression_should_be_parseable(feature +
": 1/1");
256 expression_should_be_parseable(feature +
": 1 /1");
257 expression_should_be_parseable(feature +
": 1 / \t\n1");
258 expression_should_be_parseable(feature +
": 1/\r1");
259 expression_should_not_be_parseable(feature +
": 1");
260 expression_should_not_be_parseable(feature +
": 0.5");
261 expression_should_not_be_parseable(feature +
": 1.0/1");
262 expression_should_not_be_parseable(feature +
": 1/1.0");
263 expression_should_not_be_parseable(feature +
": 1.0/1.0");
264 expression_should_not_be_parseable(feature +
": 0/1");
265 expression_should_not_be_parseable(feature +
": 1/0");
266 expression_should_not_be_parseable(feature +
": 0/0");
267 expression_should_not_be_parseable(feature +
": -1/1");
268 expression_should_not_be_parseable(feature +
": 1/-1");
269 expression_should_not_be_parseable(feature +
": -1/-1");
272 var is_monochrome = query_applies(
"all and (min-monochrome: 1)");
273 var is_color = query_applies(
"all and (min-color: 1)");
274 isnot(is_monochrome, is_color,
"should be either monochrome or color");
276 function depth_query(prefix, depth) {
277 return
"all and (" + prefix + (is_color ?
"color" :
"monochrome") +
284 ok(false,
"breaking from loop, depth > 50");
287 } while (query_applies(depth_query(
"min-", ++depth)));
290 should_apply(depth_query(
"", depth));
291 should_not_apply(depth_query(
"", depth -
1));
292 should_not_apply(depth_query(
"", depth +
1));
293 should_apply(depth_query(
"max-", depth));
294 should_not_apply(depth_query(
"max-", depth -
1));
295 should_apply(depth_query(
"max-", depth +
1));
297 (is_color ? should_apply : should_not_apply)(
"all and (color)");
298 expression_should_not_be_parseable(
"max-color");
299 expression_should_not_be_parseable(
"min-color");
300 (is_color ? should_not_apply : should_apply)(
"all and (monochrome)");
301 expression_should_not_be_parseable(
"max-monochrome");
302 expression_should_not_be_parseable(
"min-monochrome");
303 (is_color ? should_apply : should_not_apply)(
"not all and (monochrome)");
304 (is_color ? should_not_apply : should_apply)(
"not all and (color)");
305 (is_color ? should_apply : should_not_apply)(
"only all and (color)");
306 (is_color ? should_not_apply : should_apply)(
"only all and (monochrome)");
308 for each (let feature in [
"color",
"min-monochrome",
"max-color-index" ]) {
309 expression_should_be_parseable(feature +
": 1");
310 expression_should_be_parseable(feature +
": 327");
311 expression_should_be_parseable(feature +
": 0");
312 expression_should_not_be_parseable(feature +
": 1.0");
313 expression_should_not_be_parseable(feature +
": -1");
314 expression_should_not_be_parseable(feature +
": 1/1");
317 // Presume that we never support indexed color (at least not usefully
318 // enough to call it indexed color).
319 should_apply(
"(color-index: 0)");
320 should_not_apply(
"(color-index: 1)");
321 should_apply(
"(min-color-index: 0)");
322 should_not_apply(
"(min-color-index: 1)");
323 should_apply(
"(max-color-index: 0)");
324 should_apply(
"(max-color-index: 1)");
325 should_apply(
"(max-color-index: 157)");
327 for each (let feature in [
"resolution",
"min-resolution",
328 "max-resolution" ]) {
329 expression_should_be_parseable(feature +
": 3dpi");
330 expression_should_be_parseable(feature +
":3dpi");
331 expression_should_not_be_parseable(feature +
": 3.0dpi");
332 expression_should_not_be_parseable(feature +
": 3.4dpi");
333 expression_should_be_parseable(feature +
"\t: 120dpcm");
334 expression_should_not_be_parseable(feature +
": 0dpi");
335 expression_should_not_be_parseable(feature +
": -3dpi");
338 // Find the resolution using max-resolution
342 if (resolution
> 10000) {
343 ok(false,
"resolution greater than 10000dpi???");
346 } while (!query_applies(
"(max-resolution: " + resolution +
"dpi)"));
348 // resolution should now be Math.ceil() of the actual resolution.
350 let dpi_low = resolution -
1;
351 if (query_applies(
"(min-resolution: " + resolution +
"dpi)")) {
353 should_apply(
"(resolution: " + resolution +
"dpi)");
354 should_not_apply(
"(resolution: " + (resolution +
1) +
"dpi)");
355 should_not_apply(
"(resolution: " + (resolution -
1) +
"dpi)");
356 dpi_high = resolution +
1;
358 // We have no way to test resolution applying since it need not be
360 should_not_apply(
"(resolution: " + resolution +
"dpi)");
361 should_not_apply(
"(resolution: " + (resolution -
1) +
"dpi)");
362 dpi_high = resolution;
365 should_apply(
"(min-resolution: " + dpi_low +
"dpi)");
366 should_not_apply(
"not all and (min-resolution: " + dpi_low +
"dpi)");
367 should_apply(
"not all and (min-resolution: " + dpi_high +
"dpi)");
368 should_not_apply(
"all and (min-resolution: " + dpi_high +
"dpi)");
370 // Test dpcm units based on what we computed in dpi.
371 let dpcm_high = Math.ceil(dpi_high /
2.54);
372 let dpcm_low = Math.floor(dpi_low /
2.54);
373 should_apply(
"(min-resolution: " + dpcm_low +
"dpcm)");
374 should_apply(
"(max-resolution: " + dpcm_high +
"dpcm)");
375 should_not_apply(
"(max-resolution: " + dpcm_low +
"dpcm)");
376 should_apply(
"not all and (min-resolution: " + dpcm_high +
"dpcm)");
378 expression_should_be_parseable(
"scan");
379 expression_should_be_parseable(
"scan: progressive");
380 expression_should_be_parseable(
"scan:interlace");
381 expression_should_not_be_parseable(
"min-scan:interlace");
382 expression_should_not_be_parseable(
"scan: 1");
383 expression_should_not_be_parseable(
"max-scan");
384 expression_should_not_be_parseable(
"max-scan: progressive");
385 // Assume we don't support tv devices.
386 should_not_apply(
"(scan)");
387 should_not_apply(
"(scan: progressive)");
388 should_not_apply(
"(scan: interlace)");
389 should_apply(
"not all and (scan)");
390 should_apply(
"not all and (scan: progressive)");
391 should_apply(
"not all and (scan: interlace)");
393 expression_should_be_parseable(
"grid");
394 expression_should_be_parseable(
"grid: 0");
395 expression_should_be_parseable(
"grid: 1");
396 expression_should_be_parseable(
"grid: 1");
397 expression_should_not_be_parseable(
"min-grid");
398 expression_should_not_be_parseable(
"min-grid:0");
399 expression_should_not_be_parseable(
"max-grid: 1");
400 expression_should_not_be_parseable(
"grid: 2");
401 expression_should_not_be_parseable(
"grid: -1");
403 // Assume we don't support grid devices
404 should_not_apply(
"(grid)");
405 should_apply(
"(grid: 0)");
406 should_not_apply(
"(grid: 1)");
407 should_not_apply(
"(grid: 2)");
408 should_not_apply(
"(grid: -1)");
412 should_apply(
"(orientation");
413 should_not_apply(
"not all and (orientation");
414 should_not_apply(
"(orientation:");
415 should_apply(
"all,(orientation:");
416 should_not_apply(
"(orientation:,all");
417 should_apply(
"not all and (grid");
418 should_not_apply(
"only all and (grid");
419 should_not_apply(
"(grid");
420 should_apply(
"all,(grid");
421 should_not_apply(
"(grid,all");
423 should_apply(
",all");
424 should_apply(
"all,");
425 should_apply(
",all,");
426 should_apply(
"all,badmedium");
427 should_apply(
"badmedium,all");
428 should_not_apply(
",badmedium,");
429 should_apply(
"all,(badexpression)");
430 should_apply(
"(badexpression),all");
431 should_not_apply(
"(badexpression),badmedium");
432 should_not_apply(
"badmedium,(badexpression)");
433 should_apply(
"all,[badsyntax]");
434 should_apply(
"[badsyntax],all");
435 should_not_apply(
"badmedium,[badsyntax]");
436 should_not_apply(
"[badsyntax],badmedium");