Wed, 31 Dec 2014 13:27:57 +0100
Ignore runtime configuration files generated during quality assurance.
1 <!DOCTYPE HTML>
2 <html>
3 <!--
4 https://bugzilla.mozilla.org/show_bug.cgi?id=816720
5 -->
6 <head>
7 <title>Test for Bug 816720</title>
8 <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
9 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
10 <style type="text/css" id="style"></style>
11 </head>
12 <body>
14 <pre id="test"></pre>
16 <p><span id=control-serif>........</span></p>
17 <p><span id=control-monospace>........</span></p>
18 <p><span id=test-font>........</span></p>
20 <style id=other-styles>
21 #test { font-size: 16px; animation: test 1s both }
22 #control-serif { font: 16px serif }
23 #test-font { font: 16px UnlikelyFontName, serif }
24 </style>
26 <script type="application/javascript">
28 // Monospace fonts available on all the platforms we're testing on.
29 //
30 // XXX Once bug 817220 is fixed we could instead use the value of
31 // font.name.monospace.x-western as the monospace font to use.
32 var MONOSPACE_FONTS = [
33 "Courier",
34 "Courier New",
35 "Monaco",
36 "DejaVu Sans Mono",
37 "Droid Sans Mono"
38 ];
40 var test = document.getElementById("test");
41 var controlSerif = document.getElementById("control-serif");
42 var controlMonospace = document.getElementById("control-monospace");
43 var testFont = document.getElementById("test-font");
44 var otherStyles = document.getElementById("other-styles");
46 otherStyles.sheet.insertRule("#control-monospace { font: 16px " +
47 MONOSPACE_FONTS + ", serif }", 0);
49 var monospaceWidth = controlMonospace.getBoundingClientRect().width;
50 var serifWidth = controlSerif.getBoundingClientRect().width;
52 // [at-rule type, passing condition, failing condition]
53 var outerRuleInfo = [
54 ["@media", "all", "not all"],
55 ["@-moz-document", "url-prefix('')", "url-prefix('zzz')"],
56 ["@supports", "(color: green)", "(unknown: unknown)"]
57 ];
59 // [rule, function to test whether the rule was successfully inserted and applied]
60 var innerRuleInfo = [
61 ["#test { text-decoration: underline; }",
62 function(aApplied, aParent, aException) {
63 return !aException &&
64 window.getComputedStyle(test, "").textDecoration ==
65 (aApplied ? "underline" : "none");
66 }],
67 ["@page { margin: 4cm; }",
68 function(aApplied, aParent, aException) {
69 // just test whether it threw
70 return !aException;
71 }],
72 ["@keyframes test { from { font-size: 100px; } to { font-size: 100px; } }",
73 function(aApplied, aParent, aException) {
74 return !aException &&
75 window.getComputedStyle(test, "").fontSize ==
76 (aApplied ? "100px" : "16px")
77 }],
78 ["@font-face { font-family: UnlikelyFontName; src: " +
79 MONOSPACE_FONTS.map(function(s) { return "local('" + s + "')" }).join(", ") + "; }",
80 function(aApplied, aParent, aException) {
81 var width = testFont.getBoundingClientRect().width;
82 if (aException) {
83 return false;
84 }
85 if (navigator.oscpu.match(/Linux/) ||
86 navigator.oscpu.match(/Android/) ||
87 SpecialPowers.Services.appinfo.name == "B2G") {
88 return true;
89 }
90 return Math.abs(width - (aApplied ? monospaceWidth : serifWidth)) <= 1; // bug 769194 prevents local()
91 // fonts working on Android
92 }],
93 ["@charset 'UTF-8';",
94 function(aApplied, aParent, aException) {
95 // just test whether it threw
96 return aParent instanceof CSSRule ? aException : !aException;
97 }],
98 ["@import url(nothing.css);",
99 function(aApplied, aParent, aException) {
100 // just test whether it threw
101 return aParent instanceof CSSRule ? aException : !aException;
102 }],
103 ["@namespace test url(http://example.org);",
104 function(aApplied, aParent, aException) {
105 // just test whether it threw
106 return aParent instanceof CSSRule ? aException : !aException;
107 }],
108 ];
110 function runTest()
111 {
112 // First, assert that our assumed available fonts are indeed available
113 // and have expected metrics.
114 ok(monospaceWidth > 0, "monospace text has width");
115 ok(serifWidth > 0, "serif text has width");
116 ok(Math.abs(monospaceWidth - serifWidth) > 1, "monospace and serif text have sufficiently different widths");
118 // And that the #test-font element starts off using the "serif" font.
119 var initialFontTestWidth = testFont.getBoundingClientRect().width;
120 is(initialFontTestWidth, serifWidth);
122 // We construct a style sheet with zero, one or two levels of conditional
123 // grouping rules (taken from outerRuleInfo), with one of the inner rules
124 // at the deepest level.
125 var style = document.getElementById("style");
127 // For each of the outer rule types...
128 for (var outerRule1 = 0; outerRule1 < outerRuleInfo.length; outerRule1++) {
129 // For each of { 0 = don't create an outer rule,
130 // 1 = create an outer rule with a passing condition,
131 // 2 = create an outer rule with a failing condition }...
132 for (var outerRuleCondition1 = 0; outerRuleCondition1 <= 2; outerRuleCondition1++) {
134 // For each of the outer rule types again...
135 for (var outerRule2 = 0; outerRule2 < outerRuleInfo.length; outerRule2++) {
136 // For each of { 0 = don't create an outer rule,
137 // 1 = create an outer rule with a passing condition,
138 // 2 = create an outer rule with a failing condition } again...
139 for (var outerRuleCondition2 = 0; outerRuleCondition2 <= 2; outerRuleCondition2++) {
141 // For each of the inner rule types...
142 for (var innerRule = 0; innerRule < innerRuleInfo.length; innerRule++) {
144 // Clear rules
145 var object = style.sheet;
146 while (object.cssRules.length) {
147 object.deleteRule(0);
148 }
150 // We'll record whether the inner rule should have been applied,
151 // according to whether we put passing or failing conditional
152 // grouping rules around it.
153 var applied = true;
155 if (outerRuleCondition1) {
156 // Create an outer conditional rule.
157 object.insertRule([outerRuleInfo[outerRule1][0],
158 outerRuleInfo[outerRule1][outerRuleCondition1],
159 "{}"].join(" "), 0);
160 object = object.cssRules[0];
162 if (outerRuleCondition1 == 2) {
163 // If we used a failing condition, we don't expect the inner
164 // rule to be applied.
165 applied = false;
166 }
167 }
169 if (outerRuleCondition2) {
170 // Create another outer conditional rule as a child of the first
171 // outer conditional rule (or the style sheet, if we didn't create
172 // a first outer conditional rule).
173 object.insertRule([outerRuleInfo[outerRule2][0],
174 outerRuleInfo[outerRule2][outerRuleCondition2],
175 "{}"].join(" "), 0);
176 object = object.cssRules[0];
178 if (outerRuleCondition2 == 2) {
179 // If we used a failing condition, we don't expect the inner
180 // rule to be applied.
181 applied = false;
182 }
183 }
185 var outer = object instanceof CSSRule ? object.cssText : "style sheet";
186 var inner = innerRuleInfo[innerRule][0];
188 // Insert the inner rule.
189 var exception = null;
190 try {
191 object.insertRule(inner, 0);
192 } catch (e) {
193 exception = e;
194 }
196 ok(innerRuleInfo[innerRule][1](applied, object, exception),
197 "<" + [outerRule1, outerRuleCondition1, outerRule2,
198 outerRuleCondition2, innerRule].join(",") + "> " +
199 "inserting " + inner + " into " + outer.replace(/ *\n */g, ' '));
200 }
201 }
202 }
203 }
204 }
206 SimpleTest.finish();
207 }
209 SimpleTest.waitForExplicitFinish();
210 SpecialPowers.pushPrefEnv({ "set": [["layout.css.supports-rule.enabled", true]] }, runTest);
212 </script>
213 </body>
214 </html>